/** WIP raycasting demo for Pokitto. Don't forget to compile with -O3! author: Miloslav "drummyfish" Ciz license: CC0 */ //#define RAYCAST_TINY #include #define VERTICAL_FOV UNITS_PER_SQUARE // for raycastlib #include "raycastlib.h" #include "Pokitto.h" #define SUBSAMPLE 2 #define SCREEN_WIDTH 110 #define SCREEN_HEIGHT 88 #define SUBSAMPLED_WIDTH (SCREEN_WIDTH / SUBSAMPLE) #define SUBSAMPLED_HEIGHT (SCREEN_HEIGHT / SUBSAMPLE) #define MIDDLE_ROW (SCREEN_HEIGHT / 2) #define MIDDLE_COLUMN (SCREEN_WIDTH / 2) #define SPRITES 6 Pokitto::Core p; Unit zBuffer[SUBSAMPLED_WIDTH]; #define LEVEL_X_RES 29 #define LEVEL_Y_RES 21 const signed char levelFloor[] = { 40,40,40,40,40,40,40,40,48,40,48,40,40,40,40,40,40,48,40,48,40,48,40,48,48,24,24,26,28, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,40, 2, 2, 2,40,32,32,32,32,32,32,32,48, 2, 2, 2,26, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,40, 2, 2, 2,40, 0, 0, 0, 0, 0,32,32,40, 2, 2, 2,26, 40,16,12, 8, 4, 0,48, 0, 0, 0, 0, 0,24, 2,24, 8,24, 0, 0, 9, 9, 0,28,32,48, 2, 2, 2,24, 40,20,48,48,48,48,48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0,24,32,40, 0, 0, 0,24, 40,24,48,40,40,40,40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20,32,48, 0, 0, 0,24, 40,28,32,32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,16,32,40, 0, 0, 0,24, 40,32,32,32,32,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,32,32,32,32,32,48, 0, 0, 0,24, 40, 0,48,40,40,40,40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,-3,-8,-8,-5,-2, 0, 0, 0, 0,24, 40, 0, 3,-8,-8,-8,32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,-3,-8,-8, 0, 0, 0, 0, 0, 0,24, 40, 0, 6,-8,-8,-8,32, 0, 0, 0,48,48, 0,48,48, 0, 0,36,32,36,-8,-8, 0, 0, 0, 0, 0, 0,24, 40, 0,48,-8,-8,-8,32,32,32,32,40, 1, 0, 1,40,32,32,32,32,32,-8,-8, 0, 0, 0, 0, 0, 0,24, 40, 0,48,-8,-8,-8,-8,-8,-8,-8,-8, 0, 0, 0,-8,-8,-8,36,32,36,-8,-8, 0, 0, 0, 0, 0, 0,24, 40, 0,48,-8,-8,-8,-8,-8,-8,-8,-8, 0, 0, 0,-8,-8,-8,-8,-8,-8,-8,-8, 0, 0, 0, 0, 0, 0,24, 40, 0,48, 0,-2,-2, 0,-8,-8,-8,-8, 0, 0, 0,-8,-8, 0, 0, 0, 0, 0, 0, 0, 0,24,24,15,24,24, 40, 0, 0, 0,-2,-2, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,24, 0, 0, 0,24, 40, 0, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24, 0, 0, 0,24, 40,24,48,-2,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24, 0,24,48,48,-2,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24, 0,24,48,48,48,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24, 0, 0, 0,24, 0,24,24,24,32,32,32,27,24,27,30,34,36,38,36,34,36,34,34,32,32,33,37,39,24,24,24,24,24 }; const signed char levelCeiling[] = { 40,40,40,40,40,40,40,99,99,99,99,99,40,40,40,40,40,40,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,20,99,99,99,99,99,40,99,99,99,99,40,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,20,99,99,99,99,99,40,99,99,99,99,40,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,48,99,99,99,99,99,24,24,24,24,24,40,99,99,99,99,99,99,99,99,99,99,99, 40,99,48,48,48,48,48,99,99,99,99,99,42,42,42,42,42,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,48,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,48,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,48,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,24,24,24,24, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,24,24,24,24, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,25,27,29,24, 40,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,25,27,29,24, 40,24,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,25,27,29,24, 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,25,27,29,24, 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,25,27,29,24, 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,24,24,24,24,24,24 }; const unsigned char image[] = { 32, 32 // width, height ,0x12,0x65,0x65,0x6d,0x24,0x64,0x5b,0x12,0x12,0x64,0x5b,0x5b,0x12,0x51 ,0x12,0x09,0x00,0x6d,0x6d,0x6d,0x24,0x5b,0x5b,0x52,0x12,0x5b,0x52,0x5b ,0x12,0x5b,0x52,0x09,0x12,0x5b,0x5b,0x5b,0x52,0x5b,0x5b,0x52,0x00,0x64 ,0x64,0x52,0x52,0x52,0x5b,0x00,0x09,0x6d,0x5b,0x5a,0x5b,0x5b,0x5a,0x51 ,0x12,0x64,0x5b,0x52,0x5b,0x52,0x5b,0x08,0x12,0x24,0x5b,0x5b,0x5b,0x5b ,0x09,0x11,0x00,0x64,0x5b,0x5b,0x5a,0x09,0x09,0x08,0x00,0x5b,0x5b,0x5b ,0x5a,0x64,0x12,0x51,0x00,0x64,0x5b,0x52,0x52,0x11,0x09,0x09,0x12,0x24 ,0x5b,0x5b,0x52,0x5a,0x12,0x09,0x00,0x5b,0x52,0x09,0x12,0x09,0x09,0x09 ,0x00,0x24,0x5a,0x5a,0x5b,0x51,0x12,0x08,0x09,0x25,0x5b,0x52,0x5b,0x52 ,0x11,0x09,0x12,0x64,0x5b,0x52,0x09,0x11,0x12,0x09,0x00,0x12,0x00,0x12 ,0x00,0x00,0x00,0x08,0x09,0x64,0x5b,0x51,0x12,0x11,0x12,0x08,0x09,0x64 ,0x5a,0x5b,0x12,0x12,0x09,0x09,0x12,0x65,0x5c,0x52,0x5a,0x5b,0x51,0x09 ,0x00,0x64,0x6d,0x6d,0x5c,0x65,0x64,0x09,0x00,0x24,0x64,0x5b,0x09,0x12 ,0x11,0x00,0x09,0x64,0x5b,0x52,0x52,0x12,0x12,0x08,0x00,0x64,0x52,0x52 ,0x52,0x52,0x5b,0x09,0x00,0x6d,0x5b,0x5b,0x52,0x5b,0x51,0x09,0x00,0x1b ,0x5b,0x12,0x12,0x12,0x12,0x09,0x12,0x5b,0x11,0x09,0x11,0x09,0x09,0x09 ,0x09,0x5b,0x09,0x09,0x09,0x09,0x09,0x09,0x12,0x65,0x5b,0x5b,0x5b,0x52 ,0x5b,0x09,0x00,0x64,0x12,0x63,0x5b,0x12,0x5b,0x09,0x00,0x00,0x00,0x00 ,0x00,0x09,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b ,0x64,0x5b,0x09,0x5b,0x52,0x09,0x09,0x5b,0x11,0x52,0x09,0x12,0x09,0x08 ,0x00,0x1b,0x1b,0x23,0x1b,0x5a,0x5b,0x11,0x12,0x64,0x64,0x6d,0x24,0x5b ,0x5b,0x09,0x00,0x5b,0x5a,0x52,0x52,0x09,0x08,0x09,0x12,0x5b,0x52,0x11 ,0x5a,0x11,0x12,0x08,0x08,0x1b,0x52,0x52,0x5b,0x5a,0x09,0x09,0x12,0x64 ,0x5b,0x64,0x12,0x12,0x12,0x08,0x00,0x00,0x00,0x12,0x09,0x00,0x09,0x00 ,0x12,0x24,0x5a,0x52,0x12,0x12,0x12,0x08,0x12,0x1b,0x12,0x5a,0x49,0x5a ,0x52,0x09,0x12,0x6d,0x5b,0x52,0x5a,0x12,0x09,0x09,0x12,0x65,0x64,0x6d ,0x6d,0x64,0x64,0x5b,0x00,0x5a,0x08,0x08,0x09,0x09,0x08,0x09,0x00,0x5b ,0x5a,0x11,0x51,0x51,0x5a,0x09,0x12,0x6d,0x5b,0x5b,0x12,0x11,0x12,0x09 ,0x00,0x65,0x5b,0x64,0x5b,0x5b,0x5b,0x52,0x00,0x00,0x12,0x12,0x12,0x09 ,0x00,0x00,0x00,0x5a,0x52,0x52,0x09,0x52,0x09,0x09,0x12,0x63,0x5b,0x5a ,0x09,0x5b,0x11,0x08,0x00,0x65,0x5b,0x5b,0x52,0x5b,0x52,0x52,0x00,0x65 ,0x6d,0x64,0x65,0x64,0x64,0x5b,0x00,0x5b,0x12,0x09,0x11,0x09,0x09,0x09 ,0x09,0x5b,0x11,0x08,0x09,0x09,0x09,0x08,0x00,0x64,0x64,0x5b,0x5b,0x5b ,0x5b,0x09,0x00,0x5b,0x5b,0x5b,0x5b,0x5b,0x52,0x52,0x00,0x64,0x51,0x52 ,0x52,0x52,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x5b ,0x5b,0x5b,0x52,0x52,0x5b,0x09,0x12,0x65,0x5b,0x5b,0x5b,0x52,0x5b,0x09 ,0x00,0x63,0x5a,0x51,0x51,0x51,0x5a,0x08,0x12,0x24,0x64,0x65,0x24,0x64 ,0x64,0x5b,0x00,0x5b,0x5b,0x52,0x5b,0x5b,0x52,0x09,0x00,0x64,0x5b,0x5b ,0x12,0x52,0x5a,0x09,0x12,0x24,0x52,0x52,0x09,0x52,0x52,0x08,0x12,0x64 ,0x64,0x5b,0x5b,0x5b,0x64,0x52,0x00,0x6d,0x5b,0x52,0x5b,0x52,0x52,0x08 ,0x00,0x5b,0x5b,0x52,0x52,0x5b,0x52,0x09,0x00,0x1b,0x52,0x51,0x5a,0x52 ,0x09,0x09,0x12,0x64,0x52,0x5c,0x5b,0x64,0x5b,0x51,0x09,0x6d,0x5b,0x52 ,0x5b,0x52,0x11,0x09,0x00,0x64,0x5a,0x64,0x5b,0x52,0x5b,0x08,0x00,0x11 ,0x09,0x49,0x08,0x09,0x00,0x09,0x00,0x64,0x64,0x5b,0x52,0x5b,0x5b,0x09 ,0x12,0x65,0x64,0x5b,0x52,0x5b,0x52,0x09,0x12,0x64,0x64,0x64,0x52,0x09 ,0x5c,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x64,0x5b,0x64 ,0x52,0x5b,0x52,0x49,0x00,0x64,0x5b,0x52,0x52,0x5b,0x51,0x09,0x09,0x5b ,0x09,0x09,0x09,0x08,0x09,0x12,0x00,0x6d,0x24,0x6d,0x24,0x64,0x64,0x5b ,0x00,0x64,0x63,0x5b,0x5b,0x52,0x52,0x09,0x12,0x64,0x5b,0x5b,0x52,0x11 ,0x5b,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x12,0x6d,0x64,0x5b ,0x52,0x64,0x5b,0x52,0x12,0x6d,0x5b,0x5b,0x5b,0x5b,0x5b,0x09,0x00,0x64 ,0x11,0x5a,0x52,0x5b,0x52,0x09,0x00,0x5b,0x5a,0x63,0x5a,0x23,0x12,0x00 ,0x12,0x6d,0x5b,0x11,0x5b,0x64,0x64,0x52,0x12,0x63,0x5b,0x5b,0x5b,0x5b ,0x52,0x08,0x00,0x5c,0x52,0x5b,0x5b,0x52,0x52,0x08,0x08,0x5b,0x52,0x51 ,0x09,0x52,0x5a,0x09,0x00,0x6d,0x52,0x11,0x52,0x5b,0x52,0x09,0x12,0x64 ,0x5a,0x5b,0x52,0x5b,0x5b,0x08,0x00,0x5b,0x52,0x09,0x09,0x09,0x09,0x09 ,0x09,0x24,0x52,0x09,0x12,0x09,0x52,0x08,0x00,0x5b,0x5a,0x52,0x12,0x5b ,0x5b,0x09,0x00,0x65,0x52,0x5b,0x5b,0x52,0x11,0x09,0x09,0x00,0x00,0x00 ,0x00,0x12,0x00,0x08,0x00,0x5b,0x52,0x51,0x09,0x09,0x09,0x09,0x00,0x64 ,0x5b,0x52,0x52,0x09,0x5b,0x09,0x12,0x6d,0x5b,0x5b,0x5b,0x5b,0x5a,0x11 ,0x00,0x6d,0x6d,0x24,0x64,0x64,0x5b,0x5b,0x00,0x5a,0x12,0x52,0x12,0x09 ,0x12,0x08,0x00,0x5b,0x12,0x09,0x09,0x09,0x08,0x09,0x00,0x64,0x5b,0x5b ,0x52,0x5a,0x5b,0x09,0x12,0x6d,0x64,0x5a,0x5b,0x5b,0x5b,0x5b,0x00,0x5a ,0x11,0x52,0x09,0x12,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x12,0x12,0x12 ,0x12,0x64,0x52,0x5b,0x5b,0x5b,0x5b,0x09,0x12,0x6d,0x12,0x5b,0x12,0x52 ,0x5b,0x52,0x09,0x5a,0x09,0x51,0x09,0x09,0x09,0x09,0x09,0x5c,0x64,0x6d ,0x1b,0x24,0x64,0x08,0x12,0x64,0x5b,0x52,0x5b,0x5b,0x52,0x09,0x00,0x5b ,0x5b,0x52,0x11,0x5b,0x12,0x09,0x08,0x5b,0x5a,0x09,0x51,0x52,0x12,0x08 ,0x00,0x5b,0x5b,0x11,0x5b,0x5b,0x5b,0x08,0x09,0x5b,0x12,0x52,0x52,0x09 ,0x09,0x09,0x00,0x6d,0x5b,0x52,0x52,0x12,0x12,0x09,0x08,0x11,0x00,0x49 ,0x09,0x00,0x09,0x00,0x00,0x6d,0x12,0x5b,0x52,0x5b,0x52,0x09,0x00,0x00 ,0x09,0x09,0x12,0x00,0x12,0x00,0x00,0x64,0x52,0x5b,0x52,0x5b,0x52,0x09 ,0x09,0x00,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x64,0x52,0x5b,0x5b,0x52 ,0x52,0x09 }; const unsigned char image2[] = { 32, 32 // width, height ,0xff,0xff,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xb7,0x77 ,0xbf,0x77,0x76,0x76,0x6e,0x6d,0x6d,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e ,0x76,0x76,0x6e,0x25,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0x76,0x77,0x76,0x76 ,0x76,0x76,0x6e,0x6e,0x76,0x76,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d ,0x6d,0x6d,0x6d,0x6e,0x6e,0x6d,0x6d,0x6d,0xff,0xbf,0xbf,0x76,0x77,0x76 ,0x76,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e,0x6e,0x76,0x76,0x6e,0x6d,0x6d ,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x65,0x6d,0x65,0xbf,0xbf ,0x77,0x76,0x76,0x76,0x76,0x76,0x76,0x6e,0x76,0x76,0x6e,0x6e,0x76,0x76 ,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x65,0x65,0x6d,0x6d,0x65,0x65,0x6d,0x65 ,0x6d,0x6d,0xbf,0xbf,0x76,0x76,0x76,0x25,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c ,0x1c,0x1c,0x24,0x25,0x25,0x24,0x1c,0x1c,0x1c,0x1c,0x1c,0x24,0x24,0x24 ,0x24,0x25,0x6d,0x65,0x6d,0x6d,0xbf,0xbf,0x77,0x76,0x76,0x24,0x1c,0x1c ,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x24,0x25,0x65,0x25,0x24,0x1c,0x1c,0x1c ,0x24,0x24,0x24,0x1c,0x24,0x6d,0x6d,0x6d,0x6e,0x6d,0xbf,0xbf,0x76,0x76 ,0x76,0x1c,0x1c,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e,0x6e,0x76,0x76,0x76 ,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x76,0x77,0x6d,0x6d,0x6e,0x6d ,0xbf,0xbf,0x77,0x76,0x76,0x1c,0x24,0x76,0x76,0x76,0x76,0x6e,0x6e,0x6e ,0x76,0x76,0x77,0x77,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x76,0xb7 ,0x6e,0x6e,0x6e,0x25,0xbf,0xbf,0x77,0x76,0x76,0x24,0x24,0x77,0x76,0x76 ,0x76,0x76,0x6e,0x6e,0x76,0x76,0x77,0x77,0x76,0x6e,0x6d,0x6d,0x6d,0x6d ,0x6d,0x6d,0x76,0xbf,0x76,0x6e,0x6d,0x24,0xbf,0xbf,0x77,0x76,0x77,0x24 ,0x25,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x6e ,0x6d,0x6d,0x6d,0x6d,0x6d,0x6d,0x77,0xbf,0x6e,0x6d,0x6d,0x25,0xbf,0xbf ,0x77,0x77,0x77,0x25,0x25,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76 ,0x76,0x76,0x76,0x76,0x6e,0x6d,0x6d,0x6d,0x65,0x6d,0xbf,0xbf,0x6e,0x6d ,0x6e,0x25,0xbf,0xbf,0x77,0x76,0xb7,0x25,0x65,0x76,0x76,0x6e,0x76,0x76 ,0x76,0x76,0x76,0x6e,0x6e,0x76,0x76,0x76,0x6e,0x6d,0x6d,0x6d,0x65,0x6e ,0xbf,0xbf,0x6d,0x65,0x6e,0x6d,0xbf,0xbf,0x77,0x76,0x77,0x25,0x25,0x77 ,0x76,0x6e,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e,0x6e,0x76,0x77,0x76,0x6e ,0x6d,0x6d,0x6d,0x6e,0xbf,0xbf,0x6d,0x65,0x76,0x6d,0xff,0xbf,0xbf,0xbf ,0xbf,0x24,0x25,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x6e,0x6e,0x6e,0x6e ,0x76,0x76,0x76,0x6e,0x6e,0x6e,0x76,0x76,0xbf,0xbf,0x6d,0x6d,0x76,0x6e ,0xff,0xbf,0xbf,0xbf,0xbf,0x24,0x6d,0x76,0x76,0x76,0x76,0x76,0x76,0x6e ,0x6e,0x6d,0x6e,0x6e,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0xbf,0x77 ,0x65,0x6d,0x76,0x6e,0xbf,0xbf,0x77,0x77,0x77,0x25,0x6d,0x77,0x77,0x76 ,0x76,0x76,0x76,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x76,0x76,0x77,0x77,0x76 ,0x76,0x6e,0x77,0x76,0x65,0x6d,0x6e,0x76,0xbf,0xbf,0x77,0x76,0x76,0x25 ,0x6d,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x6e,0x6d,0x6d,0x6e,0x6d,0x6e ,0x76,0x77,0x76,0x76,0x6e,0x6d,0x77,0x77,0x65,0x6d,0x76,0x6d,0xff,0xbf ,0xbf,0x77,0x77,0x24,0x6d,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x6d,0x6d ,0x6d,0x6e,0x6d,0x6e,0x6e,0x76,0x6e,0x6d,0x6d,0x65,0x76,0x77,0x25,0x6d ,0x6e,0x6e,0xff,0xbf,0xbf,0x77,0x77,0x24,0x65,0x77,0x77,0x76,0x76,0x76 ,0x76,0x76,0x6e,0x6d,0x6e,0x6e,0x6e,0x6d,0x6e,0x6e,0x6d,0x6d,0x6d,0x6d ,0x76,0x77,0x25,0x25,0x76,0x6e,0xff,0xbf,0xbf,0xb7,0x77,0x25,0x24,0x77 ,0x77,0x76,0x76,0x76,0x6e,0x6e,0x76,0x6e,0x6e,0x76,0x6e,0x6e,0x6e,0x6e ,0x6d,0x6d,0x6d,0x6d,0x76,0x77,0x25,0x25,0x6d,0x6d,0xff,0xbf,0x77,0x77 ,0x77,0x25,0x24,0x76,0x76,0x76,0x76,0x76,0x6e,0x6e,0x76,0x6e,0x6e,0x76 ,0x76,0x76,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x76,0x76,0x24,0x24,0x6d,0x24 ,0xbf,0xbf,0x77,0x77,0x77,0x24,0x24,0x76,0x76,0x76,0x76,0x76,0x76,0x76 ,0x76,0x76,0x76,0x76,0x76,0x76,0x6e,0x6e,0x6d,0x6d,0x6d,0x65,0x76,0x76 ,0x25,0x25,0x6d,0x24,0xff,0xbf,0xbf,0xbf,0xbf,0x24,0x24,0x77,0x77,0x77 ,0x76,0x76,0x76,0x76,0x76,0x6e,0x6e,0x76,0x76,0x6e,0x6e,0x6e,0x6d,0x65 ,0x6d,0x6d,0x76,0x76,0x25,0x65,0x6d,0x24,0xff,0xbf,0xbf,0xbf,0xbf,0x25 ,0x24,0x77,0xb7,0x77,0x76,0x77,0x76,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e ,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x77,0x76,0x25,0x6d,0x6d,0x24,0xff,0xbf ,0xbf,0xbf,0xbf,0x6d,0x65,0xbf,0xbf,0x77,0x76,0x77,0x76,0x76,0x76,0x76 ,0x76,0x6e,0x6e,0x6e,0x76,0x6e,0x6d,0x6d,0x6d,0x6d,0x77,0x76,0x25,0x25 ,0x25,0x24,0xff,0xbf,0xbf,0xbf,0xbf,0x6d,0x6d,0xbf,0xbf,0xbf,0x77,0x76 ,0x76,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e,0x76,0x6e,0x6d,0x6d,0x6d,0x6d ,0x77,0x76,0x25,0x65,0x65,0x1c,0xff,0xbf,0xbf,0xbf,0xbf,0x6e,0x76,0xbf ,0xff,0xff,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf ,0xbf,0xbf,0xbf,0xbf,0x77,0xbf,0x65,0x6d,0x6d,0x1c,0xff,0xbf,0xbf,0xbf ,0xbf,0xbf,0xbf,0xff,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf ,0xbf,0xbf,0xbf,0xbf,0x77,0xbf,0xbf,0xbf,0xbf,0x77,0x65,0x6d,0x65,0x1c ,0xff,0xbf,0xbf,0x77,0xbf,0xbf,0xbf,0x77,0x76,0x76,0x76,0x76,0x76,0x76 ,0x76,0x76,0x6e,0x76,0x6e,0x6e,0x6e,0x6e,0x6d,0x6e,0x6e,0x6d,0x6d,0x65 ,0x6d,0x6d,0x65,0x24,0xff,0xbf,0x77,0x77,0xbf,0xbf,0xb7,0x77,0x76,0x76 ,0x77,0x77,0x77,0x76,0x76,0x76,0x6e,0x6e,0x76,0x76,0x6e,0x6e,0x6d,0x6e ,0x6e,0x6d,0x6d,0x65,0x6d,0x6d,0x65,0x1c,0xff,0xbf,0xbf,0xbf,0xbf,0xbf ,0xbf,0x77,0x76,0x77,0x77,0x77,0x76,0x76,0x76,0x6e,0x6e,0x76,0x76,0x76 ,0x6e,0x6e,0x6d,0x6d,0x6d,0x6d,0x6d,0x65,0x6d,0x6d,0x6d,0x1c,0xbf,0x25 ,0x1c,0x24,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c ,0x1c,0x1c,0x24,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c ,0x1c,0x1c }; const unsigned char image3[] = { 32, 32 // width, height ,0x65,0x1d,0x01,0x1c,0x12,0x0a,0x01,0x13,0x14,0x6e,0x2e,0x0b,0x1c,0x1d ,0x2e,0x1d,0x13,0x0b,0x13,0x65,0x1d,0x1d,0x13,0x66,0x6f,0x6e,0x65,0x6f ,0x77,0x7f,0x6f,0x6f,0x1d,0x14,0x13,0x6e,0x6e,0x66,0x6f,0x77,0x77,0x6f ,0x66,0x66,0x13,0x25,0x0a,0x01,0x6e,0x66,0x01,0x12,0x02,0x01,0x1b,0x6e ,0x77,0x77,0x77,0x77,0x77,0x6f,0x6f,0x6e,0x1c,0x1d,0x1c,0x77,0x67,0x6f ,0x6f,0x77,0x67,0x77,0x77,0x66,0x13,0x0a,0x14,0x77,0x66,0x6f,0x77,0x66 ,0x1b,0x13,0x66,0x77,0x6f,0x77,0x6f,0x6f,0x6f,0x26,0x6e,0x1d,0x25,0x14 ,0x13,0x6e,0x6f,0x6f,0x77,0x6f,0x77,0x77,0x77,0x1d,0x1d,0x01,0x25,0x67 ,0x7f,0x6f,0x6f,0x66,0x66,0x14,0x66,0x6f,0x7f,0x6f,0x77,0x6f,0x1d,0x25 ,0x1d,0x66,0x1d,0x65,0x14,0x2e,0x26,0x77,0x6d,0x67,0x6f,0x25,0x6f,0x5e ,0x5d,0x0b,0x5d,0x6f,0x6f,0x26,0x1d,0x77,0x66,0x1c,0x13,0x6f,0x6f,0x6f ,0x66,0x67,0x66,0x65,0x6e,0x1c,0x1b,0x0a,0x01,0x1d,0x65,0x1e,0x6f,0x6e ,0x67,0x66,0x66,0x65,0x14,0x1c,0x25,0x65,0x6e,0x66,0x66,0x6e,0x66,0x1c ,0x02,0x1d,0x77,0x6e,0x77,0x66,0x25,0x13,0x5c,0x1d,0x0a,0x14,0x0b,0x14 ,0x6e,0x65,0x1d,0x66,0x1d,0x66,0x1d,0x66,0x14,0x25,0x14,0x6e,0x66,0x25 ,0x66,0x5d,0x66,0x25,0x0a,0x6e,0x6f,0x6f,0x6e,0x1d,0x13,0x65,0x5c,0x01 ,0x0a,0x15,0x1d,0x0a,0x01,0x5d,0x6e,0x5c,0x25,0x1d,0x1e,0x26,0x1d,0x1b ,0x14,0x25,0x25,0x1d,0x14,0x1d,0x14,0x13,0x01,0x25,0x6e,0x25,0x25,0x25 ,0x1d,0x1c,0x01,0x0a,0x14,0x14,0x5d,0x14,0x14,0x0a,0x1d,0x5d,0x1c,0x6e ,0x1d,0x65,0x5d,0x1d,0x0a,0x01,0x14,0x1c,0x25,0x0a,0x01,0x12,0x1c,0x0b ,0x01,0x1c,0x14,0x25,0x0b,0x1b,0x25,0x14,0x25,0x02,0x1d,0x25,0x1d,0x09 ,0x13,0x1c,0x1d,0x66,0x1d,0x1c,0x0b,0x14,0x0b,0x65,0x2d,0x09,0x0a,0x09 ,0x14,0x66,0x6f,0x66,0x66,0x1c,0x0a,0x01,0x0b,0x14,0x66,0x1c,0x1d,0x1c ,0x66,0x66,0x65,0x6e,0x1c,0x09,0x1c,0x1d,0x14,0x1c,0x0b,0x01,0x1d,0x6e ,0x77,0x66,0x1c,0x1c,0x6e,0x6f,0x6f,0x77,0x7f,0x77,0x5e,0x6e,0x6f,0x67 ,0x6f,0x6f,0x0a,0x0a,0x66,0x67,0x66,0x25,0x13,0x1c,0x24,0x14,0x25,0x1c ,0x0b,0x1d,0x6e,0x77,0x7f,0x77,0x5e,0x1c,0x65,0x6f,0x7f,0x6e,0x6f,0x77 ,0x6f,0x67,0x6f,0x6f,0x66,0x25,0x14,0x6f,0x6f,0x77,0x6f,0x67,0x6e,0x13 ,0x0a,0x09,0x13,0x12,0x1d,0x66,0x6f,0x66,0x5e,0x6e,0x66,0x25,0x14,0x25 ,0x26,0x25,0x6f,0x1d,0x77,0x6f,0x66,0x6e,0x66,0x1c,0x12,0x6f,0x6f,0x67 ,0x77,0x1d,0x77,0x13,0x66,0x77,0x6f,0x6f,0x6f,0x77,0x6f,0x66,0x77,0x77 ,0x6f,0x6e,0x13,0x25,0x26,0x25,0x66,0x65,0x66,0x66,0x6e,0x66,0x6e,0x14 ,0x09,0x66,0x6f,0x6e,0x2f,0x6e,0x26,0x1c,0x6f,0x66,0x6f,0x7f,0x6f,0x7f ,0x6f,0x6f,0x6e,0x6e,0x66,0x6f,0x13,0x13,0x1d,0x66,0x1d,0x25,0x66,0x65 ,0x6e,0x1d,0x1d,0x0a,0x14,0x6f,0x77,0x77,0x2e,0x25,0x1c,0x0a,0x65,0x6f ,0x6f,0x6f,0x7f,0x6f,0x77,0x77,0x66,0x6f,0x6e,0x6e,0x25,0x14,0x01,0x0a ,0x09,0x0a,0x0b,0x14,0x1d,0x0a,0x14,0x13,0x66,0x6f,0x6f,0x25,0x1c,0x5d ,0x65,0x01,0x66,0x1e,0x6f,0x6f,0x6f,0x77,0x6f,0x6f,0x6e,0x6f,0x66,0x1d ,0x1d,0x0a,0x66,0x6f,0x66,0x2e,0x6e,0x6e,0x14,0x13,0x12,0x14,0x6f,0x6f ,0x6e,0x6e,0x25,0x0a,0x13,0x12,0x6e,0x6f,0x66,0x6f,0x66,0x65,0x66,0x6f ,0x66,0x25,0x66,0x25,0x0a,0x01,0x6e,0x77,0x77,0x6f,0x6f,0x6e,0x6e,0x14 ,0x1d,0x6e,0x1b,0x25,0x1d,0x1c,0x1d,0x14,0x01,0x25,0x25,0x66,0x6e,0x6f ,0x1d,0x6f,0x66,0x1d,0x1d,0x1d,0x6e,0x1d,0x0b,0x6e,0x6f,0x77,0x7f,0x6f ,0x77,0x77,0x66,0x66,0x13,0x5d,0x13,0x0a,0x01,0x1c,0x13,0x0a,0x6e,0x09 ,0x1d,0x65,0x25,0x66,0x66,0x6e,0x65,0x25,0x65,0x6e,0x1d,0x65,0x13,0x65 ,0x6f,0x77,0x67,0x7f,0x6f,0x77,0x6f,0x6e,0x14,0x1c,0x1c,0x6e,0x77,0x6e ,0x77,0x6f,0x25,0x0a,0x1c,0x1d,0x1d,0x66,0x1d,0x6e,0x15,0x26,0x25,0x5e ,0x25,0x13,0x1d,0x77,0x77,0x66,0x66,0x6e,0x6f,0x77,0x7f,0x6e,0x12,0x13 ,0x66,0x77,0x6f,0x77,0x6f,0x77,0x26,0x6f,0x0b,0x25,0x1c,0x25,0x25,0x25 ,0x66,0x1d,0x1b,0x25,0x0a,0x1d,0x6e,0x67,0x67,0x6f,0x66,0x1d,0x65,0x6e ,0x67,0x6f,0x6e,0x13,0x77,0x7f,0x67,0x77,0x77,0x77,0x6f,0x6e,0x5d,0x13 ,0x14,0x1d,0x1c,0x1d,0x1d,0x14,0x1d,0x0a,0x09,0x1c,0x66,0x77,0x66,0x67 ,0x6e,0x1c,0x65,0x66,0x66,0x6d,0x1c,0x09,0x6e,0x67,0x6f,0x7f,0x6f,0x77 ,0x6f,0x6e,0x66,0x0a,0x01,0x13,0x1d,0x14,0x65,0x14,0x02,0x01,0x1d,0x1c ,0x13,0x66,0x2e,0x66,0x77,0x6e,0x1e,0x25,0x25,0x6e,0x0a,0x13,0x6e,0x67 ,0x26,0x67,0x6f,0x77,0x67,0x6f,0x1d,0x6e,0x14,0x0a,0x01,0x13,0x01,0x25 ,0x66,0x77,0x66,0x65,0x1c,0x0b,0x66,0x25,0x66,0x66,0x25,0x6e,0x66,0x1d ,0x14,0x0a,0x1d,0x66,0x66,0x66,0x6f,0x6e,0x6f,0x6f,0x5d,0x1d,0x0a,0x25 ,0x26,0x6f,0x6f,0x6f,0x7f,0x6f,0x6f,0x6f,0x77,0x0a,0x09,0x1d,0x6f,0x6e ,0x15,0x25,0x1c,0x1d,0x1d,0x13,0x25,0x66,0x1c,0x6e,0x66,0x26,0x66,0x66 ,0x25,0x1c,0x0a,0x66,0x6f,0x7f,0x6f,0x6f,0x6f,0x66,0x6f,0x77,0x6e,0x66 ,0x0a,0x1b,0x26,0x1d,0x5e,0x1d,0x65,0x13,0x0a,0x1d,0x66,0x6e,0x25,0x6e ,0x1d,0x1d,0x6e,0x25,0x13,0x1d,0x14,0x5e,0x77,0x27,0x7f,0x77,0x7f,0x67 ,0x66,0x67,0x1d,0x1d,0x13,0x09,0x76,0x66,0x24,0x1c,0x1b,0x13,0x13,0x1d ,0x25,0x25,0x5e,0x1d,0x6e,0x25,0x1c,0x25,0x66,0x1d,0x09,0x1d,0x77,0x6f ,0x66,0x6f,0x66,0x66,0x66,0x6e,0x65,0x66,0x65,0x1c,0x1d,0x1d,0x65,0x14 ,0x1c,0x25,0x0a,0x0a,0x0a,0x25,0x1d,0x66,0x14,0x25,0x66,0x6e,0x1d,0x25 ,0x09,0x1c,0x66,0x77,0x6f,0x66,0x7f,0x77,0x1d,0x6e,0x1c,0x1d,0x1d,0x0a ,0x25,0x66,0x1d,0x25,0x13,0x0a,0x1d,0x14,0x1e,0x13,0x1d,0x14,0x65,0x66 ,0x66,0x25,0x1d,0x14,0x0a,0x14,0x15,0x65,0x7f,0x77,0x66,0x25,0x1d,0x1d ,0x1d,0x6e,0x1c,0x14,0x13,0x65,0x1d,0x1c,0x0a,0x0a,0x65,0x1d,0x25,0x0a ,0x1c,0x1d,0x1c,0x25,0x1d,0x1c,0x14,0x01,0x1b,0x0a,0x1d,0x65,0x6f,0x1d ,0x66,0x65,0x6e,0x66,0x1d,0x14,0x0a,0x0a,0x1b,0x12,0x1c,0x0a,0x14,0x6e ,0x66,0x25 }; const unsigned char sprite[] = { 32, 32 // width, height ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff ,0x00,0x52,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x52,0x76,0x76,0x64 ,0x00,0xff,0xff,0x00,0x64,0x76,0xff,0x52,0x64,0x00,0x00,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x52 ,0x09,0x76,0x52,0x64,0x00,0xff,0xff,0x00,0x76,0xff,0xff,0x52,0x64,0x52 ,0x64,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0x00,0x52,0x00,0x52,0x64,0x09,0x64,0x00,0xff,0xff,0x00,0xff,0xff ,0xff,0x52,0x52,0x64,0x52,0x64,0x64,0x00,0x00,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0x00,0x52,0x00,0x52,0x09,0x76,0x52,0x64,0x00,0xff ,0xff,0x00,0xff,0x76,0xff,0x52,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x00 ,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x52,0x09,0x52,0x52,0x76 ,0x09,0x64,0x00,0xff,0xff,0x00,0x76,0x76,0xff,0x64,0x64,0x64,0x64,0x64 ,0x64,0x64,0x64,0x64,0x64,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x00,0x52 ,0x52,0x52,0x09,0x64,0x52,0x52,0x00,0xff,0xff,0x00,0x76,0xff,0xff,0x64 ,0x64,0x64,0x09,0x52,0x64,0x64,0x76,0x64,0x64,0x64,0x64,0x00,0x00,0xff ,0xff,0xff,0x00,0x52,0x09,0x09,0x52,0x76,0x09,0x52,0x00,0xff,0xff,0x00 ,0xff,0x76,0xff,0x52,0x64,0x64,0x09,0x09,0x52,0x52,0x64,0x64,0x64,0x52 ,0x64,0x64,0x64,0x00,0x00,0xff,0x00,0x52,0x52,0x09,0x09,0x64,0x09,0x64 ,0x00,0xff,0xff,0x00,0x76,0x76,0xff,0x52,0x64,0x52,0x09,0x09,0x09,0x52 ,0x09,0x52,0x76,0x64,0x52,0x64,0x52,0x64,0x52,0x00,0x00,0x52,0x09,0x52 ,0x09,0x64,0x52,0x64,0x00,0xff,0xff,0x00,0x76,0x76,0xff,0x64,0x64,0x64 ,0x00,0x09,0x52,0x09,0x52,0x09,0x52,0x52,0x76,0x64,0x64,0x52,0x52,0x64 ,0x52,0x00,0x09,0x09,0x09,0x76,0x52,0x64,0x00,0xff,0xff,0x00,0xff,0x76 ,0xff,0x64,0x64,0x52,0x00,0x00,0x00,0x09,0x09,0x52,0x52,0x09,0x52,0x52 ,0x76,0x76,0x52,0x52,0x52,0x52,0x52,0x09,0x09,0x76,0x52,0x52,0x00,0xff ,0xff,0x00,0x76,0x76,0xff,0x52,0x64,0x64,0x00,0xff,0xff,0x00,0x00,0x09 ,0x52,0x52,0x52,0x52,0x52,0x52,0x76,0x64,0x52,0x64,0x52,0x64,0x00,0x76 ,0x09,0x64,0x00,0xff,0xff,0x00,0x76,0x76,0x76,0x64,0x52,0x64,0x00,0xff ,0xff,0xff,0xff,0x00,0x00,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x76,0x76 ,0x64,0x64,0x00,0x64,0x09,0x52,0x00,0xff,0xff,0x00,0x76,0x76,0xff,0x52 ,0x64,0x52,0x00,0xff,0xff,0xff,0xff,0x00,0x52,0x64,0x64,0x52,0x52,0x52 ,0x52,0x52,0x52,0x09,0x64,0x76,0x00,0x64,0x09,0x52,0x00,0xff,0xff,0x00 ,0x76,0x64,0x76,0x52,0x52,0x64,0x00,0xff,0xff,0x00,0x00,0x64,0x64,0x64 ,0x64,0x64,0x64,0x52,0x52,0x52,0x09,0x52,0x52,0x52,0x00,0x76,0x09,0x52 ,0x00,0xff,0xff,0x00,0x76,0x76,0x76,0x52,0x52,0x52,0x00,0x00,0x00,0x76 ,0x76,0x64,0x76,0x64,0x64,0x64,0x52,0x52,0x09,0x52,0x52,0x09,0x52,0x09 ,0x00,0x64,0x52,0x52,0x00,0xff,0xff,0x00,0x64,0x76,0x76,0x52,0x52,0x52 ,0x00,0x76,0xff,0x76,0x64,0x76,0x64,0x64,0x52,0x52,0x52,0x52,0x52,0x52 ,0x52,0x09,0x09,0x00,0x00,0x64,0x09,0x64,0x00,0xff,0xff,0x00,0x76,0x76 ,0xff,0x52,0x64,0xff,0xff,0x76,0x76,0x76,0x76,0x64,0x52,0x52,0x52,0x52 ,0x52,0x52,0x52,0x00,0x00,0x00,0x00,0x09,0x00,0x52,0x52,0x52,0x00,0xff ,0xff,0x00,0x76,0x76,0xff,0xff,0xff,0x76,0x76,0x76,0x76,0x64,0x52,0x52 ,0x52,0x09,0x52,0x52,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x64 ,0x09,0x52,0x00,0xff,0xff,0x00,0x76,0x76,0x76,0x76,0x76,0x76,0x76,0x64 ,0x52,0x52,0x09,0x52,0x52,0x52,0x52,0x00,0x00,0x00,0x00,0xff,0x00,0x00 ,0x00,0x00,0x00,0x64,0x09,0x52,0x00,0xff,0xff,0x00,0x64,0x76,0x64,0x76 ,0x76,0x64,0x52,0x09,0x52,0x09,0x52,0x09,0x52,0x00,0x00,0x00,0x00,0xff ,0xff,0xff,0x00,0x09,0x00,0x09,0x00,0x52,0x09,0x52,0x00,0xff,0xff,0x00 ,0x76,0x64,0x76,0x64,0x52,0x09,0x09,0x09,0x09,0x52,0x52,0x00,0x00,0xff ,0xff,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x09,0x00,0x00,0x52,0x52,0x52 ,0x00,0xff,0xff,0x00,0x64,0x64,0x52,0x09,0x09,0x09,0x09,0x52,0x52,0x00 ,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0x09,0x00,0x00 ,0x00,0x64,0x09,0x52,0x00,0xff,0xff,0x00,0x09,0x09,0x09,0x09,0x09,0x52 ,0x52,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x52,0x09,0x52,0x00,0xff,0xff,0x00,0x09,0x09 ,0x09,0x09,0x52,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 ,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x09,0x00,0x64,0x52,0x52,0x00,0xff ,0xff,0xff,0x00,0x00,0x52,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x09,0x52 ,0x52,0x52,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xff,0xff ,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00 ,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff }; inline uint8_t sampleImage(const unsigned char *image, Unit x, Unit y) { // TODO: optimize x = wrap(x,UNITS_PER_SQUARE); y = wrap(y,UNITS_PER_SQUARE); int32_t index = image[1] * ((image[1] * x) / UNITS_PER_SQUARE) + (image[0] * y) / UNITS_PER_SQUARE; return image[2 + index]; } void drawSprite(const unsigned char *sprite, int16_t x, int16_t y, Unit depth, int16_t size) { // TODO: optimize x -= size / 2; y -= size / 2; Unit step = UNITS_PER_SQUARE / size; uint8_t c; int16_t jTo = size - max(0,y + size - 88); int16_t iTo = size - max(0,x + size - 110); for (Unit i = max(-1 * x,0); i < iTo; ++i) { int16_t xPos = x + i; if (zBuffer[xPos / SUBSAMPLE] <= depth) continue; for (Unit j = max(-1 * y,0); j < jTo; ++j) { c = sampleImage(sprite,(i * UNITS_PER_SQUARE) / size,(j * UNITS_PER_SQUARE) / size); if (c != 0xff) p.display.drawPixel(xPos,y + j,c); } } } // r: 3 bits, g: 3 bits, b: 2 bits inline uint8_t rgbToIndex(uint8_t r, uint8_t g, uint8_t b) { return (r & 0b00000111) | ((g & 0b00000111) << 3) | ((b & 0b00000011) << 6); } inline uint8_t addIntensity(uint8_t color, int intensity) { uint8_t r = color & 0b00000111; uint8_t g = (color & 0b00111000) >> 3; uint8_t b = (color & 0b11000000) >> 6; if (intensity >= 0) { r += intensity; r = r > 7 ? 7 : r; g += intensity; g = g > 7 ? 7 : g; b += intensity / 2; b = b > 3 ? 3 : b; } else { intensity *= -1; r = (intensity > r) ? 0 : r - intensity; g = (intensity > g) ? 0 : g - intensity; intensity /= 2; b = intensity > b ? 0 : b - intensity; } return rgbToIndex(r,g,b); } class Sprite { public: Vector2D mPosition; Unit mHeight; }; class Character { public: Camera mCamera; Character() { mCamera.position.x = 961;//UNITS_PER_SQUARE * 1; mCamera.position.y = 7381;//UNITS_PER_SQUARE * 5; mCamera.direction = -575;//200; mCamera.fovAngle = UNITS_PER_SQUARE / 4; mCamera.height = UNITS_PER_SQUARE / 2; mCamera.resolution.x = 110 / SUBSAMPLE; mCamera.resolution.y = 88; } }; Character player; Sprite sprites[SPRITES]; Unit floorHeight(int16_t x, int16_t y) { if (x >= 0 && x < LEVEL_X_RES && y >= 0 && y < LEVEL_Y_RES) return (levelFloor[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x] * UNITS_PER_SQUARE) / 8; return 0; } Unit ceilingHeight(int16_t x, int16_t y) { signed char v = 99; if (x >= 0 && x < LEVEL_X_RES && y >= 0 && y < LEVEL_Y_RES) v = levelCeiling[(LEVEL_Y_RES - y -1) * LEVEL_X_RES + x]; return (v * UNITS_PER_SQUARE) / 8; } inline void pixelFunc(PixelInfo pixel) { if (pixel.position.y == MIDDLE_ROW) zBuffer[pixel.position.x] = pixel.depth; uint8_t c; Unit depth = pixel.depth - UNITS_PER_SQUARE; if (depth < 0) depth = 0; int intensity = 7 - (depth * 7) / (UNITS_PER_SQUARE * 5); if (intensity < 0) intensity = 0; if (pixel.isWall) { if ((pixel.hit.direction == 0 || pixel.hit.direction == 2)) intensity -= 2; if (intensity < 0) intensity = 0; c = sampleImage(image2,pixel.hit.textureCoord,pixel.textureCoordY); c = addIntensity(c,intensity - 3); } else c = rgbToIndex(intensity/2,intensity,intensity/3); uint8_t *buf = p.display.screenbuffer; buf += pixel.position.x * SUBSAMPLE; buf += pixel.position.y * p.display.width; for (uint8_t i = 0; i < SUBSAMPLE - 1; ++i) *buf++ = c; *buf = c; } unsigned short pal[256]; void draw() { RayConstraints c; c.maxHits = 16; c.maxSteps = 16; c.computeTextureCoords = 1; render(player.mCamera,floorHeight,ceilingHeight,pixelFunc,c); Unit previousDepth; for (uint8_t i = 0; i < SPRITES; ++i) { PixelInfo pos = mapToScreen(sprites[i].mPosition,sprites[i].mHeight,player.mCamera); if (pos.depth > 0) drawSprite(sprite,pos.position.x * SUBSAMPLE,pos.position.y, pos.depth,perspectiveScale(32,pos.depth)); if (i != 0 && pos.depth > previousDepth) { Sprite tmp = sprites[i]; sprites[i] = sprites[i - 1]; sprites[i - 1] = tmp; } previousDepth = pos.depth; } p.display.setColor(rgbToIndex(7,7,3)); p.display.setCursor(1,1); p.display.print(divRoundDown(player.mCamera.position.x,UNITS_PER_SQUARE)); p.display.print(" "); p.display.print(divRoundDown(player.mCamera.position.y,UNITS_PER_SQUARE)); p.display.print(" "); p.display.print(player.mCamera.direction); } int main() { #define placeSprite(I,X,Y,Z)\ sprites[I].mPosition.x = X * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;\ sprites[I].mPosition.y = Y * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2;\ sprites[I].mHeight = Z * UNITS_PER_SQUARE + UNITS_PER_SQUARE / 2; placeSprite(0,5,7,0) placeSprite(1,6,7,0) placeSprite(2,5,8,0) placeSprite(3,6,8,0) placeSprite(4,-1,-2,1) placeSprite(5,12,5,1) #undef placeSprite p.begin(); for (uint8_t r = 0; r < 8; ++r) for (uint8_t g = 0; g < 8; ++g) for (uint8_t b = 0; b < 4; ++b) pal[rgbToIndex(r,g,b)] = p.display.RGBto565(36 * r, 36 * g, 85 * b); p.display.load565Palette(&pal[0]); // load a palette the same way as any other palette in any other screen mode p.display.persistence = 1; p.setFrameRate(60); p.display.setFont(fontTiny); while (p.isRunning()) { if (p.update()) { draw(); const int16_t step = max(UNITS_PER_SQUARE / 5,1); const int16_t step2 = max(UNITS_PER_SQUARE / 40,1); Vector2D d = angleToDirection(player.mCamera.direction); d.x = (d.x * step) / UNITS_PER_SQUARE; d.y = (d.y * step) / UNITS_PER_SQUARE; if (d.x == 0 && d.y == 0) { d.x = d.x > 0 ? step : -step; d.y = d.y > 0 ? step : -step; } bool strafe = p.aBtn(); if (p.upBtn()) { if (strafe) player.mCamera.height += step; else { player.mCamera.position.x += d.x; player.mCamera.position.y += d.y; } } else if (p.downBtn()) { if (strafe) player.mCamera.height -= step; else { player.mCamera.position.x -= d.x; player.mCamera.position.y -= d.y; } } if (strafe) { d = angleToDirection(player.mCamera.direction + UNITS_PER_SQUARE / 4); d.x = (d.x * step) / UNITS_PER_SQUARE; d.y = (d.y * step) / UNITS_PER_SQUARE; } int addition = 0; if (p.rightBtn()) addition = 1; else if (p.leftBtn()) addition = -1; if (strafe) { player.mCamera.position.x += addition * d.x; player.mCamera.position.y += addition * d.y; } else player.mCamera.direction += addition * step2; player.mCamera.height = max(floorHeight(player.mCamera.position.x / UNITS_PER_SQUARE,player.mCamera.position.y / UNITS_PER_SQUARE) + UNITS_PER_SQUARE / 2,player.mCamera.height); } } return 0; }