diff --git a/Makefile b/Makefile index b0d01cc..4460316 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ TIC80_H = include/tic80_types.h include/tic80.h include/tic80_config.h src/tic.h TIC_H= src/*.h \ src/ext/*.h -bin/studio.o: src/studio.c src/keycodes.c $(TIC80_H) $(TIC_H) +bin/studio.o: src/studio.c $(TIC80_H) $(TIC_H) $(CC) $< $(OPT) $(INCLUDES) -c -o $@ bin/console.o: src/console.c $(TIC80_H) $(TIC_H) $(DEMO_ASSETS) @@ -258,7 +258,7 @@ bin/menu.o: src/menu.c $(TIC80_H) $(TIC_H) bin/surf.o: src/surf.c $(TIC80_H) $(TIC_H) $(CC) $< $(OPT) $(INCLUDES) -c -o $@ -bin/system.o: src/system.c src/keycodes.c $(TIC80_H) $(TIC_H) +bin/system.o: src/system.c src/keycodes.inl src/kbdlayout.inl $(TIC80_H) $(TIC_H) $(CC) $< $(OPT) $(INCLUDES) -c -o $@ bin/chip.o: src/system/chip.c src/keycodes.c $(TIC80_H) $(TIC_H) diff --git a/src/kbdlayout.inl b/src/kbdlayout.inl new file mode 100644 index 0000000..30e67ce --- /dev/null +++ b/src/kbdlayout.inl @@ -0,0 +1,407 @@ +//0 +tic_key_escape, +tic_key_escape, +tic_key_f1, +tic_key_f1, +tic_key_f2, +tic_key_f2, +tic_key_f3, +tic_key_f3, +tic_key_f4, +tic_key_f4, +tic_key_f5, +tic_key_f5, +tic_key_f6, +tic_key_f6, +tic_key_f7, +tic_key_f7, +tic_key_f8, +tic_key_f8, +tic_key_f9, +tic_key_f9, +tic_key_f10, +tic_key_f10, + +//1 +tic_key_escape, +tic_key_escape, +tic_key_f1, +tic_key_f1, +tic_key_f2, +tic_key_f2, +tic_key_f3, +tic_key_f3, +tic_key_f4, +tic_key_f4, +tic_key_f5, +tic_key_f5, +tic_key_f6, +tic_key_f6, +tic_key_f7, +tic_key_f7, +tic_key_f8, +tic_key_f8, +tic_key_f9, +tic_key_f9, +tic_key_f10, +tic_key_f10, + +//2 +tic_key_tab, +tic_key_tab, +tic_key_grave, +tic_key_grave, +tic_key_leftbracket, +tic_key_leftbracket, +tic_key_rightbracket, +tic_key_rightbracket, +tic_key_semicolon, +tic_key_semicolon, +tic_key_apostrophe, +tic_key_apostrophe, +tic_key_minus, +tic_key_minus, +tic_key_equals, +tic_key_equals, +tic_key_slash, +tic_key_slash, +tic_key_f11, +tic_key_f11, +tic_key_f12, +tic_key_f12, + +//3 +tic_key_tab, +tic_key_tab, +tic_key_grave, +tic_key_grave, +tic_key_leftbracket, +tic_key_leftbracket, +tic_key_rightbracket, +tic_key_rightbracket, +tic_key_semicolon, +tic_key_semicolon, +tic_key_apostrophe, +tic_key_apostrophe, +tic_key_minus, +tic_key_minus, +tic_key_equals, +tic_key_equals, +tic_key_slash, +tic_key_slash, +tic_key_f11, +tic_key_f11, +tic_key_f12, +tic_key_f12, + +//4 +tic_key_1, +tic_key_1, +tic_key_2, +tic_key_2, +tic_key_3, +tic_key_3, +tic_key_4, +tic_key_4, +tic_key_5, +tic_key_5, +tic_key_6, +tic_key_6, +tic_key_7, +tic_key_7, +tic_key_8, +tic_key_8, +tic_key_9, +tic_key_9, +tic_key_0, +tic_key_0, +tic_key_backspace, +tic_key_backspace, + +//5 +tic_key_1, +tic_key_1, +tic_key_2, +tic_key_2, +tic_key_3, +tic_key_3, +tic_key_4, +tic_key_4, +tic_key_5, +tic_key_5, +tic_key_6, +tic_key_6, +tic_key_7, +tic_key_7, +tic_key_8, +tic_key_8, +tic_key_9, +tic_key_9, +tic_key_0, +tic_key_0, +tic_key_backspace, +tic_key_backspace, + +//6 +tic_key_q, +tic_key_q, +tic_key_w, +tic_key_w, +tic_key_e, +tic_key_e, +tic_key_r, +tic_key_r, +tic_key_t, +tic_key_t, +tic_key_y, +tic_key_y, +tic_key_u, +tic_key_u, +tic_key_i, +tic_key_i, +tic_key_o, +tic_key_o, +tic_key_p, +tic_key_p, +tic_key_backslash, +tic_key_backslash, + +//7 +tic_key_q, +tic_key_q, +tic_key_w, +tic_key_w, +tic_key_e, +tic_key_e, +tic_key_r, +tic_key_r, +tic_key_t, +tic_key_t, +tic_key_y, +tic_key_y, +tic_key_u, +tic_key_u, +tic_key_i, +tic_key_i, +tic_key_o, +tic_key_o, +tic_key_p, +tic_key_p, +tic_key_backslash, +tic_key_backslash, + +//8 +tic_key_unknown, +tic_key_a, +tic_key_a, +tic_key_s, +tic_key_s, +tic_key_d, +tic_key_d, +tic_key_f, +tic_key_f, +tic_key_g, +tic_key_g, +tic_key_h, +tic_key_h, +tic_key_j, +tic_key_j, +tic_key_k, +tic_key_k, +tic_key_l, +tic_key_l, +tic_key_return, +tic_key_return, +tic_key_return, + +//9 +tic_key_unknown, +tic_key_a, +tic_key_a, +tic_key_s, +tic_key_s, +tic_key_d, +tic_key_d, +tic_key_f, +tic_key_f, +tic_key_g, +tic_key_g, +tic_key_h, +tic_key_h, +tic_key_j, +tic_key_j, +tic_key_k, +tic_key_k, +tic_key_l, +tic_key_l, +tic_key_return, +tic_key_return, +tic_key_return, + +//10 +tic_key_shift, +tic_key_shift, +tic_key_z, +tic_key_z, +tic_key_x, +tic_key_x, +tic_key_c, +tic_key_c, +tic_key_v, +tic_key_v, +tic_key_b, +tic_key_b, +tic_key_n, +tic_key_n, +tic_key_m, +tic_key_m, +tic_key_comma, +tic_key_comma, +tic_key_period, +tic_key_period, +tic_key_return, +tic_key_return, + +//11 +tic_key_shift, +tic_key_shift, +tic_key_z, +tic_key_z, +tic_key_x, +tic_key_x, +tic_key_c, +tic_key_c, +tic_key_v, +tic_key_v, +tic_key_b, +tic_key_b, +tic_key_n, +tic_key_n, +tic_key_m, +tic_key_m, +tic_key_comma, +tic_key_comma, +tic_key_period, +tic_key_period, +tic_key_return, +tic_key_return, + +//12 +tic_key_ctrl, +tic_key_ctrl, +tic_key_ctrl, +tic_key_alt, +tic_key_alt, +tic_key_alt, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, + +//13 +tic_key_ctrl, +tic_key_ctrl, +tic_key_ctrl, +tic_key_alt, +tic_key_alt, +tic_key_alt, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_space, +tic_key_unknown, +tic_key_unknown, +tic_key_up, +tic_key_up, +tic_key_unknown, +tic_key_unknown, + +//14 +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_up, +tic_key_up, +tic_key_unknown, +tic_key_unknown, + +//15 +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_left, +tic_key_left, +tic_key_down, +tic_key_down, +tic_key_right, +tic_key_right, + +//16 +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_unknown, +tic_key_left, +tic_key_left, +tic_key_down, +tic_key_down, +tic_key_right, +tic_key_right, diff --git a/src/keycodes.c b/src/keycodes.inl similarity index 100% rename from src/keycodes.c rename to src/keycodes.inl diff --git a/src/studio.c b/src/studio.c index aef234e..81c343a 100644 --- a/src/studio.c +++ b/src/studio.c @@ -526,6 +526,11 @@ const StudioConfig* getConfig() return &impl.config->data; } +static bool isRunMode() +{ + return impl.mode == TIC_RUN_MODE; +} + #if defined (TIC80_PRO) static void drawBankIcon(s32 x, s32 y) @@ -1873,6 +1878,7 @@ Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* folder, Sy impl.studio.updateProject = updateStudioProject; impl.studio.exit = exitStudio; impl.studio.config = getConfig; + impl.studio.isRunMode = isRunMode; return &impl.studio; } diff --git a/src/system.c b/src/system.c index 22b7eb7..bab1592 100644 --- a/src/system.c +++ b/src/system.c @@ -39,10 +39,6 @@ static struct tic80_gamepads touch; tic80_gamepads joystick; - bool show; - s32 counter; - s32 alpha; - struct { s32 size; @@ -54,6 +50,16 @@ static struct } part; } gamepad; + struct + { + struct + { + GPU_Image* up; + GPU_Image* down; + } texture; + + } keyboard; + struct { GPU_Image* texture; @@ -162,15 +168,68 @@ static void updateGamepadParts() platform.gamepad.part.y = (SDL_Point){rect.w - 2*tileSize, 0*tileSize + offset}; } +static void initTouchKeyboard() +{ + tic_mem* tic = platform.studio->tic; + + enum{Cols=11*2, Rows=17}; + + // TODO: add touch keyboard to one texture with gamepad (and mouse cursor???) + if(!platform.keyboard.texture.up) + { + platform.keyboard.texture.up = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT); + GPU_SetAnchor(platform.keyboard.texture.up, 0, 0); + GPU_SetImageFilter(platform.keyboard.texture.up, GPU_FILTER_NEAREST); + } + + { + + memcpy(tic->ram.vram.palette.data, platform.studio->config()->cart->bank0.palette.data, sizeof(tic_palette)); + + tic->api.clear(tic, 0); + tic->api.map(tic, &platform.studio->config()->cart->bank0.map, + &platform.studio->config()->cart->bank0.tiles, 8, 0, Cols, Rows, 0, 0, -1, 1); + + // drawKeyboardLabels(0); + + tic->api.blit(tic, NULL, NULL, NULL); + + GPU_UpdateImageBytes(platform.keyboard.texture.up, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32)); + } + + if(!platform.keyboard.texture.down) + { + platform.keyboard.texture.down = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT); + GPU_SetAnchor(platform.keyboard.texture.down, 0, 0); + GPU_SetImageFilter(platform.keyboard.texture.down, GPU_FILTER_NEAREST); + } + + { + memcpy(tic->ram.vram.palette.data, platform.studio->config()->cart->bank0.palette.data, sizeof(tic_palette)); + + tic->api.map(tic, &platform.studio->config()->cart->bank0.map, + &platform.studio->config()->cart->bank0.tiles, TIC_MAP_SCREEN_WIDTH+8, 0, Cols, Rows, 0, 0, -1, 1); + + // drawKeyboardLabels(2); + + tic->api.blit(tic, NULL, NULL, NULL); + + GPU_UpdateImageBytes(platform.keyboard.texture.down, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32)); + } + +} + static void initTouchGamepad() { - platform.studio->tic->api.map(platform.studio->tic, &platform.studio->config()->cart->bank0.map, &platform.studio->config()->cart->bank0.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT, 0, 0, -1, 1); + platform.studio->tic->api.map(platform.studio->tic, &platform.studio->config()->cart->bank0.map, + &platform.studio->config()->cart->bank0.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT, 0, 0, -1, 1); if(!platform.gamepad.texture) { platform.gamepad.texture = GPU_CreateImage(TEXTURE_SIZE, TEXTURE_SIZE, STUDIO_PIXEL_FORMAT); GPU_SetAnchor(platform.gamepad.texture, 0, 0); GPU_SetImageFilter(platform.gamepad.texture, GPU_FILTER_NEAREST); + GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.studio->config()->theme.gamepad.touch.alpha); } u32* data = SDL_malloc(TEXTURE_SIZE * TEXTURE_SIZE * sizeof(u32)); @@ -305,7 +364,7 @@ static void processKeyboard() { static const u8 KeyboardCodes[] = { - #include "keycodes.c" + #include "keycodes.inl" }; tic80_input* input = &platform.studio->tic->ram.input; @@ -330,24 +389,9 @@ static bool checkTouch(const SDL_Rect* rect, s32* x, s32* y) { SDL_TouchID id = SDL_GetTouchDevice(i); - // very strange, but on Android id always == 0 - //if (id) { s32 fingers = SDL_GetNumTouchFingers(id); - if(fingers) - { - platform.gamepad.counter = 0; - - if (!platform.gamepad.show) - { - platform.gamepad.alpha = platform.studio->config()->theme.gamepad.touch.alpha; - GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.gamepad.alpha); - platform.gamepad.show = true; - return false; - } - } - for (s32 f = 0; f < fingers; f++) { SDL_Finger* finger = SDL_GetTouchFinger(id, f); @@ -675,10 +719,47 @@ static void blitSound() else SDL_QueueAudio(platform.audio.device, tic->samples.buffer, tic->samples.size); } +static void renderKeyboard() +{ + SDL_Rect rect; + SDL_GetWindowSize(platform.window, &rect.w, &rect.h); + + GPU_Rect src = {OFFSET_LEFT, OFFSET_TOP, 176, 136}; + GPU_Rect dst = {0, 0, rect.w/src.w, rect.h/src.h}; + + GPU_BlitScale(platform.keyboard.texture.up, &src, platform.gpu.screen, dst.x, dst.y, dst.w, dst.h); + + static const tic_key KbdLayout[] = + { + #include "kbdlayout.inl" + }; + + tic80_input* input = &platform.studio->tic->ram.input; + + enum{Cols=22, Rows=17}; + + for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++) + { + tic_key key = input->keyboard.keys[i]; + if(key > tic_key_unknown) + { + for(s32 k = 0; k < COUNT_OF(KbdLayout); k++) + { + if(key == KbdLayout[k]) + { + GPU_Rect src = {(k % Cols)*TIC_SPRITESIZE + OFFSET_LEFT, (k / Cols)*TIC_SPRITESIZE + OFFSET_TOP, + TIC_SPRITESIZE, TIC_SPRITESIZE}; + + GPU_BlitScale(platform.keyboard.texture.down, &src, platform.gpu.screen, + (src.x - OFFSET_LEFT) * dst.w, (src.y - OFFSET_TOP) * dst.h, dst.w, dst.h); + } + } + } + } +} + static void renderGamepad() { - if(platform.gamepad.show || platform.gamepad.alpha); else return; - const s32 tileSize = platform.gamepad.part.size; const SDL_Point axis = platform.gamepad.part.axis; typedef struct { bool press; s32 x; s32 y;} Tile; @@ -695,33 +776,15 @@ static void renderGamepad() {platform.studio->tic->ram.input.gamepads.first.y, platform.gamepad.part.y.x, platform.gamepad.part.y.y}, }; - enum {ButtonsCount = 8}; - for(s32 i = 0; i < COUNT_OF(Tiles); i++) { const Tile* tile = Tiles + i; - GPU_Rect src = {(tile->press ? ButtonsCount + i : i) * TIC_SPRITESIZE, 0, TIC_SPRITESIZE, TIC_SPRITESIZE}; + GPU_Rect src = {i * TIC_SPRITESIZE, tile->press ? TIC_SPRITESIZE : 0, TIC_SPRITESIZE, TIC_SPRITESIZE}; GPU_Rect dest = {tile->x, tile->y, tileSize, tileSize}; GPU_BlitScale(platform.gamepad.texture, &src, platform.gpu.screen, dest.x, dest.y, (float)dest.w / TIC_SPRITESIZE, (float)dest.h / TIC_SPRITESIZE); } - - if(!platform.gamepad.show && platform.gamepad.alpha) - { - enum {Step = 3}; - - if(platform.gamepad.alpha - Step >= 0) platform.gamepad.alpha -= Step; - else platform.gamepad.alpha = 0; - - GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.gamepad.alpha); - } - - platform.gamepad.counter = platform.gamepad.touch.data ? 0 : platform.gamepad.counter+1; - - // wait 5 seconds and hide touch gamepad - if(platform.gamepad.counter >= 5 * TIC_FRAMERATE) - platform.gamepad.show = false; } static void blitCursor(const u8* in) @@ -1135,7 +1198,10 @@ static void gpuTick() } renderCursor(); - renderGamepad(); + + platform.studio->isRunMode() + ? renderGamepad() + : renderKeyboard(); } GPU_Flip(platform.gpu.screen); @@ -1198,6 +1264,7 @@ static s32 start(s32 argc, char **argv, const char* folder) } initTouchGamepad(); + initTouchKeyboard(); platform.gpu.texture = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT); GPU_SetAnchor(platform.gpu.texture, 0, 0); @@ -1252,6 +1319,12 @@ static s32 start(s32 argc, char **argv, const char* folder) if(platform.gamepad.texture) GPU_FreeImage(platform.gamepad.texture); + if(platform.keyboard.texture.up) + GPU_FreeImage(platform.keyboard.texture.up); + + if(platform.keyboard.texture.down) + GPU_FreeImage(platform.keyboard.texture.down); + if(platform.mouse.texture) GPU_FreeImage(platform.mouse.texture); diff --git a/src/system.h b/src/system.h index c9490e1..fffca6a 100644 --- a/src/system.h +++ b/src/system.h @@ -91,6 +91,8 @@ typedef struct void (*updateProject)(); const StudioConfig* (*config)(); + // TODO: remove this method, system has to know nothing about current mode + bool (*isRunMode)(); } Studio; TIC80_API Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* appFolder, System* system);