From 9c6a92f4d278427893d880bcdc7ba670e743a9a8 Mon Sep 17 00:00:00 2001 From: "BADIM-PC\\Vadim" Date: Fri, 3 Nov 2017 19:39:14 +0300 Subject: [PATCH] blit function moved to tic core --- build/windows/example/example.vcxproj | 14 +++- examples/sdl-renderer.c | 4 +- src/studio.c | 101 ++++++-------------------- src/tic.c | 97 +++++++++++++++++++++++++ src/tic80.c | 41 +---------- src/ticapi.h | 2 + 6 files changed, 136 insertions(+), 123 deletions(-) diff --git a/build/windows/example/example.vcxproj b/build/windows/example/example.vcxproj index 138b2b7..24d9f1e 100644 --- a/build/windows/example/example.vcxproj +++ b/build/windows/example/example.vcxproj @@ -22,6 +22,12 @@ + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + {c4d8bc10-ebf6-42bb-9b5d-6712fb428a50} @@ -100,7 +106,7 @@ Windows true - SDL2main.lib;SDL2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) ..\..\..\lib\windows @@ -115,7 +121,7 @@ Windows true - SDL2main.lib;SDL2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) ..\..\..\lib\windows @@ -134,7 +140,7 @@ true true true - SDL2main.lib;SDL2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) ..\..\..\lib\windows @@ -153,7 +159,7 @@ true true true - SDL2main.lib;SDL2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) ..\..\..\lib\windows diff --git a/examples/sdl-renderer.c b/examples/sdl-renderer.c index d80216b..27a4950 100644 --- a/examples/sdl-renderer.c +++ b/examples/sdl-renderer.c @@ -56,9 +56,9 @@ int main(int argc, char **argv) SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); { - SDL_Window* window = SDL_CreateWindow("TIC-80 SDL demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TIC80_WIDTH, TIC80_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); + SDL_Window* window = SDL_CreateWindow("TIC-80 SDL demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TIC80_FULLWIDTH, TIC80_FULLHEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, TIC80_WIDTH, TIC80_HEIGHT); + SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, TIC80_FULLWIDTH, TIC80_FULLHEIGHT); SDL_AudioDeviceID audioDevice = 0; SDL_AudioSpec audioSpec; diff --git a/src/studio.c b/src/studio.c index 90ab75a..f22cbd8 100644 --- a/src/studio.c +++ b/src/studio.c @@ -1399,80 +1399,6 @@ static u32* paletteBlit() return srcPaletteBlit(studio.tic->ram.vram.palette.data); } -inline s32 clamp(s32 a, s32 b, s32 val) -{ - if(val < a) return a; - if(val > b) return b; - - return val; -} - -static void blit(u32* out) -{ - tic_mem* tic = studio.tic; - - const u32* pal = paletteBlit(); - - void(*scanline)(tic_mem* memory, s32 row) = NULL; - - switch(studio.mode) - { - case TIC_RUN_MODE: - scanline = tic->api.scanline; - break; - case TIC_SPRITE_MODE: - scanline = studio.sprite.scanline; - break; - case TIC_MAP_MODE: - scanline = studio.map.scanline; - break; - default: - break; - } - - if(scanline) - { - scanline(tic, 0); - pal = paletteBlit(); - } - - enum {Top = (TIC80_FULLHEIGHT-TIC80_HEIGHT)/2, Bottom = Top}; - enum {Left = (TIC80_FULLWIDTH-TIC80_WIDTH)/2, Right = Left}; - - SDL_memset4(&out[0 * TEXTURE_SIZE], pal[tic->ram.vram.vars.border], TEXTURE_SIZE*Top); - - for(s32 r = 0; r < TIC80_HEIGHT; r++) - { - SDL_memset4(&out[(r+Top) * TEXTURE_SIZE], pal[tic->ram.vram.vars.border], Left); - SDL_memset4(&out[(r+Top) * TEXTURE_SIZE + Left], pal[tic->ram.vram.vars.bg], TIC80_WIDTH); - - { - s32 y = r + tic->ram.vram.vars.offset.y; - - if(y < 0 || y >= TIC80_HEIGHT) continue; - - for(s32 c = 0; c < TIC80_WIDTH; c++) - { - s32 x = c + tic->ram.vram.vars.offset.x; - - if(x < 0 || x >= TIC80_WIDTH) continue; - - out[(c + Left) + (r+Top) * TEXTURE_SIZE] = pal[tic_tool_peek4(tic->ram.vram.screen.data, x + y * TIC80_WIDTH)]; - } - } - - SDL_memset4(&out[(r+Top) * TEXTURE_SIZE + (TIC80_FULLWIDTH-Right)], pal[tic->ram.vram.vars.border], Right); - - if(scanline && (r < TIC80_HEIGHT-1)) - { - scanline(tic, r+1); - pal = paletteBlit(); - } - } - - SDL_memset4(&out[(TIC80_FULLHEIGHT-Bottom) * TEXTURE_SIZE], pal[tic->ram.vram.vars.border], TEXTURE_SIZE*Bottom); -} - static void screen2buffer(u32* buffer, const u8* pixels, s32 pitch) { for(s32 i = 0; i < TIC80_HEIGHT; i++) @@ -1921,6 +1847,7 @@ static void recordFrame(u8* pixels, s32 pitch) static void blitTexture() { + tic_mem* tic = studio.tic; SDL_Rect rect = {0, 0, 0, 0}; calcTextureRect(&rect); @@ -1928,15 +1855,35 @@ static void blitTexture() s32 pitch = 0; SDL_LockTexture(studio.texture, NULL, &pixels, &pitch); - blit(pixels); + tic_scanline scanline = NULL; + + switch(studio.mode) + { + case TIC_RUN_MODE: + scanline = tic->api.scanline; + break; + case TIC_SPRITE_MODE: + scanline = studio.sprite.scanline; + break; + case TIC_MAP_MODE: + scanline = studio.map.scanline; + break; + default: + break; + } + + tic->api.blit(tic, pixels, scanline); recordFrame(pixels, pitch); SDL_UnlockTexture(studio.texture); { - SDL_Rect srcRect = {0, 0, TIC80_WIDTH, TIC80_HEIGHT}; - SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &rect); + // SDL_Rect srcRect = {0, 0, TIC80_WIDTH, TIC80_HEIGHT}; + // SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, &rect); + + SDL_Rect srcRect = {0, 0, TIC80_FULLWIDTH, TIC80_FULLHEIGHT}; + SDL_RenderCopy(studio.renderer, studio.texture, &srcRect, NULL); } } diff --git a/src/tic.c b/src/tic.c index 1cb44fe..1c6d686 100644 --- a/src/tic.c +++ b/src/tic.c @@ -1640,6 +1640,102 @@ static s32 api_save(const tic_cartridge* cart, u8* buffer) return (s32)(buffer - start); } +// copy from SDL2 +inline void memset4(void *dst, u32 val, u32 dwords) +{ +#if defined(__GNUC__) && defined(i386) + s32 u0, u1, u2; + __asm__ __volatile__ ( + "cld \n\t" + "rep ; stosl \n\t" + : "=&D" (u0), "=&a" (u1), "=&c" (u2) + : "0" (dst), "1" (val), "2" (dwords) + : "memory" + ); +#else + u32 _n = (dwords + 3) / 4; + u32 *_p = (u32*)dst; + u32 _val = (val); + if (dwords == 0) + return; + switch (dwords % 4) + { + case 0: do { *_p++ = _val; + case 3: *_p++ = _val; + case 2: *_p++ = _val; + case 1: *_p++ = _val; + } while ( --_n ); + } +#endif +} + +static u32* paletteBlit(tic_mem* tic) +{ + static u32 pal[TIC_PALETTE_SIZE] = {0}; + + const u8* src = tic->ram.vram.palette.data; + + memset(pal, 0xff, sizeof pal); + + u8* dst = (u8*)pal; + const u8* end = src + sizeof(tic_palette); + + enum{RGB = sizeof(tic_rgb)}; + + for(; src != end; dst++, src+=RGB) + for(s32 j = 0; j < RGB; j++) + *dst++ = *(src+(RGB-1)-j); + + return pal; +} + +void api_blit(tic_mem* tic, u32* out, tic_scanline scanline) +{ + const u32* pal = paletteBlit(tic); + + if(scanline) + { + scanline(tic, 0); + pal = paletteBlit(tic); + } + + enum {Top = (TIC80_FULLHEIGHT-TIC80_HEIGHT)/2, Bottom = Top}; + enum {Left = (TIC80_FULLWIDTH-TIC80_WIDTH)/2, Right = Left}; + + memset4(&out[0 * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Top); + + for(s32 r = 0; r < TIC80_HEIGHT; r++) + { + memset4(&out[(r+Top) * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], Left); + memset4(&out[(r+Top) * TIC80_FULLWIDTH + Left], pal[tic->ram.vram.vars.bg], TIC80_WIDTH); + + { + s32 y = r + tic->ram.vram.vars.offset.y; + + if(y < 0 || y >= TIC80_HEIGHT) continue; + + for(s32 c = 0; c < TIC80_WIDTH; c++) + { + s32 x = c + tic->ram.vram.vars.offset.x; + + if(x < 0 || x >= TIC80_WIDTH) continue; + + out[(c + Left) + (r+Top) * TIC80_FULLWIDTH] = pal[tic_tool_peek4(tic->ram.vram.screen.data, x + y * TIC80_WIDTH)]; + } + } + + memset4(&out[(r+Top) * TIC80_FULLWIDTH + (TIC80_FULLWIDTH-Right)], pal[tic->ram.vram.vars.border], Right); + + if(scanline && (r < TIC80_HEIGHT-1)) + { + scanline(tic, r+1); + pal = paletteBlit(tic); + } + } + + memset4(&out[(TIC80_FULLHEIGHT-Bottom) * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Bottom); +} + static void initApi(tic_api* api) { #define INIT_API(func) api->func = api_##func @@ -1684,6 +1780,7 @@ static void initApi(tic_api* api) INIT_API(save); INIT_API(tick_start); INIT_API(tick_end); + INIT_API(blit); #undef INIT_API } diff --git a/src/tic80.c b/src/tic80.c index 81eec0f..11c1799 100644 --- a/src/tic80.c +++ b/src/tic80.c @@ -111,45 +111,6 @@ TIC80_API void tic80_load(tic80* tic, void* cart, s32 size) } } -static u32* srcPaletteBlit(const u8* src) -{ - static u32 pal[TIC_PALETTE_SIZE] = { 0 }; - - memset(pal, 0xff, sizeof pal); - - u8* dst = (u8*)pal; - const u8* end = src + sizeof(tic_palette); - - enum { RGB = sizeof(tic_rgb) }; - - for (; src != end; dst++, src += RGB) - for (s32 j = 0; j < RGB; j++) - *dst++ = *(src + (RGB - 1) - j); - - return pal; -} - -static u32* paletteBlit(tic_mem* memory) -{ - return srcPaletteBlit(memory->ram.vram.palette.data); -} - -static void blit(tic80* tic) -{ - tic80_local* tic80 = (tic80_local*)tic; - - u32* screen = tic->screen; - - for (s32 r = 0, pos = 0; r < TIC80_HEIGHT; r++, screen += TIC80_WIDTH) - { - tic80->memory->api.scanline(tic80->memory, r); - const u32* pal = paletteBlit(tic80->memory); - - for (u32* ptr = screen, c = 0; c < TIC80_WIDTH; c++, ptr++) - *ptr = pal[tic_tool_peek4(tic80->memory->ram.vram.screen.data, pos++)]; - } -} - TIC80_API void tic80_tick(tic80* tic, tic80_input input) { tic80_local* tic80 = (tic80_local*)tic; @@ -160,7 +121,7 @@ TIC80_API void tic80_tick(tic80* tic, tic80_input input) tic80->memory->api.tick(tic80->memory, &tic80->tickData); tic80->memory->api.tick_end(tic80->memory); - blit(tic); + tic80->memory->api.blit(tic80->memory, tic->screen, tic80->memory->api.scanline); TickCounter++; } diff --git a/src/ticapi.h b/src/ticapi.h index 614bb06..2d113d1 100644 --- a/src/ticapi.h +++ b/src/ticapi.h @@ -60,6 +60,7 @@ typedef struct } tic_tick_data; typedef struct tic_mem tic_mem; +typedef void(*tic_scanline)(tic_mem* memory, s32 row); typedef struct { @@ -104,6 +105,7 @@ typedef struct void (*tick_start) (tic_mem* memory, const tic_sound* src); void (*tick_end) (tic_mem* memory); + void (*blit) (tic_mem* tic, u32* out, tic_scanline scanline); tic_script_lang (*get_script)(tic_mem* memory); } tic_api;