blit function moved to tic core
This commit is contained in:
		
							
								
								
									
										101
									
								
								src/studio.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								src/tic.c
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								src/tic80.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								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++;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user