Merge branch 'overlap_mode_429'
This commit is contained in:
commit
fce433d272
|
@ -142,7 +142,7 @@ int main(int argc, char **argv)
|
|||
void* pixels = NULL;
|
||||
int pitch = 0;
|
||||
SDL_LockTexture(texture, NULL, &pixels, &pitch);
|
||||
SDL_memcpy(pixels, tic->screen, sizeof tic->screen);
|
||||
SDL_memcpy(pixels, tic->screen, TIC80_FULLWIDTH * TIC80_FULLHEIGHT);
|
||||
SDL_UnlockTexture(texture);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,8 @@ extern "C" {
|
|||
|
||||
#define TIC80_WIDTH 240
|
||||
#define TIC80_HEIGHT 136
|
||||
#define TIC80_FULLWIDTH 256
|
||||
#define TIC80_FULLWIDTH_BITS 8
|
||||
#define TIC80_FULLWIDTH (1 << TIC80_FULLWIDTH_BITS)
|
||||
#define TIC80_FULLHEIGHT (TIC80_FULLWIDTH*9/16)
|
||||
|
||||
typedef struct
|
||||
|
@ -49,7 +50,7 @@ typedef struct
|
|||
s32 count;
|
||||
} sound;
|
||||
|
||||
u32 screen[TIC80_FULLWIDTH * TIC80_FULLHEIGHT];
|
||||
u32* screen;
|
||||
|
||||
} tic80;
|
||||
|
||||
|
|
|
@ -696,6 +696,7 @@ static bool loadBinarySection(const char* project, const char* comment, const ch
|
|||
str2buf(ptr, size*2, (u8*)dst + size*index, flip);
|
||||
ptr += size*2 + 1;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
20
src/jsapi.c
20
src/jsapi.c
|
@ -715,6 +715,7 @@ static const struct{duk_c_function func; s32 params;} ApiFunc[] =
|
|||
{
|
||||
{NULL, 0},
|
||||
{NULL, 1},
|
||||
{NULL, 0},
|
||||
{duk_print, 6},
|
||||
{duk_cls, 1},
|
||||
{duk_pix, 3},
|
||||
|
@ -828,3 +829,22 @@ void callJavascriptScanline(tic_mem* memory, s32 row)
|
|||
}
|
||||
else duk_pop(duk);
|
||||
}
|
||||
|
||||
void callJavascriptOverlap(tic_mem* memory)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)memory;
|
||||
duk_context* duk = machine->js;
|
||||
|
||||
const char* OvrFunc = ApiKeywords[2];
|
||||
|
||||
if(duk_get_global_string(duk, OvrFunc))
|
||||
{
|
||||
if(duk_pcall(duk, 0) != 0)
|
||||
{
|
||||
machine->data->error(machine->data->data, duk_safe_to_string(duk, -1));
|
||||
duk_pop(duk);
|
||||
}
|
||||
else duk_pop(duk);
|
||||
}
|
||||
else duk_pop(duk);
|
||||
}
|
22
src/luaapi.c
22
src/luaapi.c
|
@ -1052,7 +1052,7 @@ static void setloaded(lua_State* l, char* name)
|
|||
static const char* const ApiKeywords[] = API_KEYWORDS;
|
||||
static const lua_CFunction ApiFunc[] =
|
||||
{
|
||||
NULL, NULL, lua_print, lua_cls, lua_pix, lua_line, lua_rect,
|
||||
NULL, NULL, NULL, lua_print, lua_cls, lua_pix, lua_line, lua_rect,
|
||||
lua_rectb, lua_spr, lua_btn, lua_btnp, lua_sfx, lua_map, lua_mget,
|
||||
lua_mset, lua_peek, lua_poke, lua_peek4, lua_poke4, lua_memcpy,
|
||||
lua_memset, lua_trace, lua_pmem, lua_time, lua_exit, lua_font, lua_mouse,
|
||||
|
@ -1246,3 +1246,23 @@ void callLuaScanline(tic_mem* memory, s32 row)
|
|||
else lua_pop(lua, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void callLuaOverlap(tic_mem* memory)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)memory;
|
||||
lua_State* lua = machine->lua;
|
||||
|
||||
if (lua)
|
||||
{
|
||||
const char* OvrFunc = ApiKeywords[2];
|
||||
|
||||
lua_getglobal(lua, OvrFunc);
|
||||
if(lua_isfunction(lua, -1))
|
||||
{
|
||||
if(lua_pcall(lua, 0, 0, 0) != LUA_OK)
|
||||
machine->data->error(machine->data->data, lua_tostring(lua, -1));
|
||||
}
|
||||
else lua_pop(lua, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,8 +46,6 @@ typedef struct
|
|||
s32 duration;
|
||||
} Channel;
|
||||
|
||||
typedef void(ScanlineFunc)(tic_mem* memory, s32 row);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s32 l;
|
||||
|
@ -84,7 +82,17 @@ typedef struct
|
|||
Channel channels[TIC_SOUND_CHANNELS];
|
||||
} music;
|
||||
|
||||
ScanlineFunc* scanline;
|
||||
tic_scanline scanline;
|
||||
|
||||
struct
|
||||
{
|
||||
tic_overlap callback;
|
||||
u32 palette[TIC_PALETTE_SIZE];
|
||||
} ovr;
|
||||
|
||||
void (*setpix)(tic_mem* memory, s32 x, s32 y, u8 color);
|
||||
u8 (*getpix)(tic_mem* memory, s32 x, s32 y);
|
||||
|
||||
bool initialized;
|
||||
} MachineState;
|
||||
|
||||
|
@ -134,3 +142,6 @@ void callJavascriptTick(tic_machine* machine);
|
|||
|
||||
void callLuaScanline(tic_mem* memory, s32 row);
|
||||
void callJavascriptScanline(tic_mem* memory, s32 row);
|
||||
|
||||
void callLuaOverlap(tic_mem* memory);
|
||||
void callJavascriptOverlap(tic_mem* memory);
|
||||
|
|
48
src/studio.c
48
src/studio.c
|
@ -1406,29 +1406,6 @@ static void saveProject()
|
|||
else showPopupMessage("SAVE ERROR :(");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return srcPaletteBlit(studio.tic->ram.vram.palette.data);
|
||||
}
|
||||
|
||||
static void screen2buffer(u32* buffer, const u32* pixels, SDL_Rect rect)
|
||||
{
|
||||
pixels += rect.y * TIC80_FULLWIDTH;
|
||||
|
@ -1448,11 +1425,8 @@ static void setCoverImage()
|
|||
if(studio.mode == TIC_RUN_MODE)
|
||||
{
|
||||
enum {Pitch = TIC80_FULLWIDTH*sizeof(u32)};
|
||||
u32* pixels = SDL_malloc(Pitch * TIC80_FULLHEIGHT);
|
||||
|
||||
if(pixels)
|
||||
{
|
||||
tic->api.blit(tic, pixels, tic->api.scanline);
|
||||
tic->api.blit(tic, tic->api.scanline, tic->api.overlap);
|
||||
|
||||
u32* buffer = SDL_malloc(TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32));
|
||||
|
||||
|
@ -1460,7 +1434,7 @@ static void setCoverImage()
|
|||
{
|
||||
SDL_Rect rect = {OFFSET_LEFT, OFFSET_TOP, TIC80_WIDTH, TIC80_HEIGHT};
|
||||
|
||||
screen2buffer(buffer, pixels, rect);
|
||||
screen2buffer(buffer, tic->screen, rect);
|
||||
|
||||
gif_write_animation(studio.tic->cart.cover.data, &studio.tic->cart.cover.size,
|
||||
TIC80_WIDTH, TIC80_HEIGHT, (const u8*)buffer, 1, TIC_FRAMERATE, 1);
|
||||
|
@ -1469,9 +1443,6 @@ static void setCoverImage()
|
|||
|
||||
showPopupMessage("COVER IMAGE SAVED :)");
|
||||
}
|
||||
|
||||
SDL_free(pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1830,7 +1801,7 @@ static void transparentBlit(u32* out, s32 pitch)
|
|||
{
|
||||
const u8* in = studio.tic->ram.vram.screen.data;
|
||||
const u8* end = in + sizeof(studio.tic->ram.vram.screen);
|
||||
const u32* pal = srcPaletteBlit(studio.tic->config.palette.data);
|
||||
const u32* pal = tic_palette_blit(&studio.tic->config.palette);
|
||||
const u32 Delta = (pitch/sizeof *out - TIC80_WIDTH);
|
||||
|
||||
s32 col = 0;
|
||||
|
@ -1891,7 +1862,7 @@ static void drawRecordLabel(u32* frame, s32 pitch, s32 sx, s32 sy, const u32* co
|
|||
for(s32 x = 0; x < sizeof RecLabel[0]*BITS_IN_BYTE; x++)
|
||||
{
|
||||
if(RecLabel[y] & (1 << x))
|
||||
memcpy(&frame[sx + 15 - x + (y+sy)*TIC80_FULLWIDTH], color, sizeof *color);
|
||||
memcpy(&frame[sx + 15 - x + ((y+sy) << TIC80_FULLWIDTH_BITS)], color, sizeof *color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1907,7 +1878,7 @@ static void recordFrame(u32* pixels)
|
|||
|
||||
if(studio.video.frame % TIC_FRAMERATE < TIC_FRAMERATE / 2)
|
||||
{
|
||||
const u32* pal = srcPaletteBlit(studio.tic->config.palette.data);
|
||||
const u32* pal = tic_palette_blit(&studio.tic->config.palette);
|
||||
drawRecordLabel(pixels, TIC80_FULLWIDTH, TIC80_WIDTH-24, 8, &pal[tic_color_red]);
|
||||
}
|
||||
|
||||
|
@ -1932,11 +1903,13 @@ static void blitTexture()
|
|||
SDL_LockTexture(studio.texture, NULL, &pixels, &pitch);
|
||||
|
||||
tic_scanline scanline = NULL;
|
||||
tic_overlap overlap = NULL;
|
||||
|
||||
switch(studio.mode)
|
||||
{
|
||||
case TIC_RUN_MODE:
|
||||
scanline = tic->api.scanline;
|
||||
overlap = tic->api.overlap;
|
||||
break;
|
||||
case TIC_SPRITE_MODE:
|
||||
scanline = studio.sprite.scanline;
|
||||
|
@ -1948,7 +1921,8 @@ static void blitTexture()
|
|||
break;
|
||||
}
|
||||
|
||||
tic->api.blit(tic, pixels, scanline);
|
||||
tic->api.blit(tic, scanline, overlap);
|
||||
SDL_memcpy(pixels, tic->screen, sizeof tic->screen);
|
||||
|
||||
recordFrame(pixels);
|
||||
|
||||
|
@ -2012,7 +1986,7 @@ static void blitCursor(const u8* in)
|
|||
|
||||
{
|
||||
const u8* end = in + sizeof(tic_tile);
|
||||
const u32* pal = paletteBlit();
|
||||
const u32* pal = tic_palette_blit(&studio.tic->ram.vram.palette);
|
||||
u32* out = pixels;
|
||||
|
||||
while(in != end)
|
||||
|
@ -2324,7 +2298,7 @@ static void setWindowIcon()
|
|||
|
||||
u32* pixels = SDL_malloc(Size * Size * sizeof(u32));
|
||||
|
||||
const u32* pal = srcPaletteBlit(studio.tic->config.palette.data);
|
||||
const u32* pal = tic_palette_blit(&studio.tic->config.palette);
|
||||
|
||||
for(s32 j = 0, index = 0; j < Size; j++)
|
||||
for(s32 i = 0; i < Size; i++, index++)
|
||||
|
|
166
src/tic.c
166
src/tic.c
|
@ -145,22 +145,66 @@ static void resetPalette(tic_mem* memory)
|
|||
static const u8 DefaultMapping[] = {16, 50, 84, 118, 152, 186, 220, 254};
|
||||
memcpy(memory->ram.vram.palette.data, memory->cart.palette.data, sizeof(tic_palette));
|
||||
memcpy(memory->ram.vram.mapping, DefaultMapping, sizeof DefaultMapping);
|
||||
memset(&memory->ram.vram.vars, 0, sizeof memory->ram.vram.vars);
|
||||
memory->ram.vram.vars.mask.data = TIC_GAMEPAD_MASK;
|
||||
}
|
||||
|
||||
static inline void setPixel(tic_machine* machine, s32 x, s32 y, u8 color)
|
||||
static inline u8 mapColor(tic_mem* tic, u8 color)
|
||||
{
|
||||
return tic_tool_peek4(tic->ram.vram.mapping, color & 0xf);
|
||||
}
|
||||
|
||||
static void setPixelDma(tic_mem* tic, s32 x, s32 y, u8 color)
|
||||
{
|
||||
tic_tool_poke4(tic->ram.vram.screen.data, y * TIC80_WIDTH + x, mapColor(tic, color));
|
||||
}
|
||||
|
||||
static inline u32* getOvrAddr(tic_mem* tic, s32 x, s32 y)
|
||||
{
|
||||
enum {Top = (TIC80_FULLHEIGHT-TIC80_HEIGHT)/2};
|
||||
enum {Left = (TIC80_FULLWIDTH-TIC80_WIDTH)/2};
|
||||
|
||||
return tic->screen + x + (y << TIC80_FULLWIDTH_BITS) + (Left + Top * TIC80_FULLWIDTH);
|
||||
}
|
||||
|
||||
static void setPixelOvr(tic_mem* tic, s32 x, s32 y, u8 color)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)tic;
|
||||
|
||||
*getOvrAddr(tic, x, y) = *(machine->state.ovr.palette + mapColor(tic, color));
|
||||
}
|
||||
|
||||
static u8 getPixelOvr(tic_mem* tic, s32 x, s32 y)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)tic;
|
||||
|
||||
u32 color = *getOvrAddr(tic, x, y);
|
||||
u32* pal = machine->state.ovr.palette;
|
||||
|
||||
for(s32 i = 0; i < TIC_PALETTE_SIZE; i++, pal++)
|
||||
if(*pal == color)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 getPixelDma(tic_mem* tic, s32 x, s32 y)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)tic;
|
||||
|
||||
return tic_tool_peek4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x);
|
||||
}
|
||||
|
||||
static void setPixel(tic_machine* machine, s32 x, s32 y, u8 color)
|
||||
{
|
||||
if(x < machine->state.clip.l || y < machine->state.clip.t || x >= machine->state.clip.r || y >= machine->state.clip.b) return;
|
||||
|
||||
tic_tool_poke4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x, tic_tool_peek4(machine->memory.ram.vram.mapping, color & 0xf));
|
||||
machine->state.setpix(&machine->memory, x, y, color);
|
||||
}
|
||||
|
||||
static u8 getPixel(tic_machine* machine, s32 x, s32 y)
|
||||
{
|
||||
if(x < 0 || y < 0 || x >= TIC80_WIDTH || y >= TIC80_HEIGHT) return 0;
|
||||
|
||||
return tic_tool_peek4(machine->memory.ram.vram.screen.data, y * TIC80_WIDTH + x);
|
||||
return machine->state.getpix(&machine->memory, x, y);
|
||||
}
|
||||
|
||||
static void drawHLine(tic_machine* machine, s32 x, s32 y, s32 width, u8 color)
|
||||
|
@ -423,6 +467,10 @@ static void api_clip(tic_mem* memory, s32 x, s32 y, s32 width, s32 height)
|
|||
static void api_reset(tic_mem* memory)
|
||||
{
|
||||
resetPalette(memory);
|
||||
|
||||
memset(&memory->ram.vram.vars, 0, sizeof memory->ram.vram.vars);
|
||||
memory->ram.vram.vars.mask.data = TIC_GAMEPAD_MASK;
|
||||
|
||||
api_clip(memory, 0, 0, TIC80_WIDTH, TIC80_HEIGHT);
|
||||
|
||||
soundClear(memory);
|
||||
|
@ -430,6 +478,10 @@ static void api_reset(tic_mem* memory)
|
|||
tic_machine* machine = (tic_machine*)memory;
|
||||
machine->state.initialized = false;
|
||||
machine->state.scanline = NULL;
|
||||
machine->state.ovr.callback = NULL;
|
||||
|
||||
machine->state.setpix = setPixelDma;
|
||||
machine->state.getpix = getPixelDma;
|
||||
|
||||
updateSaveid(memory);
|
||||
}
|
||||
|
@ -494,8 +546,6 @@ static void api_clear(tic_mem* memory, u8 color)
|
|||
{
|
||||
api_rect(memory, machine->state.clip.l, machine->state.clip.t, machine->state.clip.r - machine->state.clip.l, machine->state.clip.b - machine->state.clip.t, color);
|
||||
}
|
||||
|
||||
memory->ram.vram.vars.bg = color & 0xf;
|
||||
}
|
||||
|
||||
static s32 drawChar(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale)
|
||||
|
@ -1163,6 +1213,11 @@ static void api_tick_start(tic_mem* memory, const tic_sound* src)
|
|||
if(prevDown && prevDown == down) (*hold)++;
|
||||
else *hold = 0;
|
||||
}
|
||||
|
||||
resetPalette(memory);
|
||||
|
||||
machine->state.setpix = setPixelDma;
|
||||
machine->state.getpix = getPixelDma;
|
||||
}
|
||||
|
||||
static void api_tick_end(tic_mem* memory)
|
||||
|
@ -1186,6 +1241,10 @@ static void api_tick_end(tic_mem* memory)
|
|||
|
||||
blip_end_frame(machine->blip, EndTime);
|
||||
blip_read_samples(machine->blip, machine->memory.samples.buffer, machine->samplerate / TIC_FRAMERATE);
|
||||
|
||||
machine->state.setpix = setPixelOvr;
|
||||
machine->state.getpix = getPixelOvr;
|
||||
memcpy(machine->state.ovr.palette, tic_palette_blit(&memory->cart.palette), sizeof machine->state.ovr.palette);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1428,6 +1487,7 @@ static void api_tick(tic_mem* memory, tic_tick_data* data)
|
|||
if(done)
|
||||
{
|
||||
machine->state.scanline = memory->script == tic_script_js ? callJavascriptScanline : callLuaScanline;
|
||||
machine->state.ovr.callback = memory->script == tic_script_js ? callJavascriptOverlap : callLuaOverlap;
|
||||
machine->state.initialized = true;
|
||||
}
|
||||
else return;
|
||||
|
@ -1447,6 +1507,14 @@ static void api_scanline(tic_mem* memory, s32 row)
|
|||
machine->state.scanline(memory, row);
|
||||
}
|
||||
|
||||
static void api_overlap(tic_mem* memory)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)memory;
|
||||
|
||||
if(machine->state.initialized)
|
||||
machine->state.ovr.callback(memory);
|
||||
}
|
||||
|
||||
static double api_time(tic_mem* memory)
|
||||
{
|
||||
tic_machine* machine = (tic_machine*)memory;
|
||||
|
@ -1625,90 +1693,36 @@ static inline void memset4(void *dst, u32 val, u32 dwords)
|
|||
#endif
|
||||
}
|
||||
|
||||
static u32* paletteBlit(tic_mem* tic)
|
||||
static void api_blit(tic_mem* tic, tic_scanline scanline, tic_overlap overlap)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static void api_blit(tic_mem* tic, u32* out, tic_scanline scanline)
|
||||
{
|
||||
const u32* pal = paletteBlit(tic);
|
||||
const u32* pal = tic_palette_blit(&tic->ram.vram.palette);
|
||||
|
||||
if(scanline)
|
||||
{
|
||||
scanline(tic, 0);
|
||||
pal = paletteBlit(tic);
|
||||
pal = tic_palette_blit(&tic->ram.vram.palette);
|
||||
}
|
||||
|
||||
enum {Top = (TIC80_FULLHEIGHT-TIC80_HEIGHT)/2, Bottom = Top};
|
||||
enum {Left = (TIC80_FULLWIDTH-TIC80_WIDTH)/2, Right = Left};
|
||||
|
||||
u32* out = tic->screen;
|
||||
|
||||
memset4(&out[0 * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Top);
|
||||
|
||||
u32* rowPtr = out + Top*TIC80_FULLWIDTH;
|
||||
u32* rowPtr = out + (Top*TIC80_FULLWIDTH);
|
||||
u32* colPtr = rowPtr + Left;
|
||||
|
||||
for(s32 r = 0, y = tic->ram.vram.vars.offset.y; r < TIC80_HEIGHT; r++, y++, rowPtr += TIC80_FULLWIDTH)
|
||||
for(s32 r = 0; r < TIC80_HEIGHT; r++, rowPtr += TIC80_FULLWIDTH, colPtr += (Left + Right))
|
||||
{
|
||||
memset4(rowPtr, pal[tic->ram.vram.vars.border], Left);
|
||||
|
||||
if(y >= 0 && y < TIC80_HEIGHT)
|
||||
{
|
||||
u32* colPtr = rowPtr + Left;
|
||||
s32 offset = tic->ram.vram.vars.offset.x;
|
||||
s32 count = TIC80_WIDTH;
|
||||
s32 index = y * TIC80_WIDTH;
|
||||
s32 pos = (r + tic->ram.vram.vars.offset.y + TIC80_HEIGHT) % TIC80_HEIGHT * TIC80_WIDTH;
|
||||
|
||||
if (offset > 0)
|
||||
for(s32 c = 0, x = (tic->ram.vram.vars.offset.x + TIC80_WIDTH) % TIC80_WIDTH; c < TIC80_WIDTH; c++, colPtr++, x++)
|
||||
{
|
||||
memset4(rowPtr + Left, pal[tic->ram.vram.vars.bg], offset);
|
||||
count -= offset;
|
||||
colPtr += offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
count += offset;
|
||||
index -= offset;
|
||||
}
|
||||
|
||||
// copy the first pixel if the line is not alligned to bytes.
|
||||
if (index & 1 && count > 0)
|
||||
{
|
||||
*colPtr++ = pal[tic_tool_peek4(tic->ram.vram.screen.data, index)];
|
||||
index++;
|
||||
count--;
|
||||
}
|
||||
|
||||
for(s32 c = 0, di = index >> 1; c < count >> 1; c++)
|
||||
{
|
||||
// copy two pixels in one cycle
|
||||
u8 val = tic->ram.vram.screen.data[di++];
|
||||
*colPtr++ = pal[val & 0xf];
|
||||
*colPtr++ = pal[val >> 4];
|
||||
}
|
||||
|
||||
// copy the remaining pixel
|
||||
if (count & 1) *colPtr = pal[tic_tool_peek4(tic->ram.vram.screen.data, index + count/2*2)];
|
||||
|
||||
if (offset < 0) memset4(rowPtr + Left + TIC80_WIDTH + offset, pal[tic->ram.vram.vars.bg], -offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset4(rowPtr + Left, pal[tic->ram.vram.vars.bg], TIC80_WIDTH);
|
||||
if(x >= TIC80_WIDTH) x %= TIC80_WIDTH;
|
||||
*colPtr = pal[tic_tool_peek4(tic->ram.vram.screen.data, pos + x)];
|
||||
}
|
||||
|
||||
memset4(rowPtr + (TIC80_FULLWIDTH-Right), pal[tic->ram.vram.vars.border], Right);
|
||||
|
@ -1716,11 +1730,14 @@ static void api_blit(tic_mem* tic, u32* out, tic_scanline scanline)
|
|||
if(scanline && (r < TIC80_HEIGHT-1))
|
||||
{
|
||||
scanline(tic, r+1);
|
||||
pal = paletteBlit(tic);
|
||||
pal = tic_palette_blit(&tic->ram.vram.palette);
|
||||
}
|
||||
}
|
||||
|
||||
memset4(&out[(TIC80_FULLHEIGHT-Bottom) * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Bottom);
|
||||
|
||||
if(overlap)
|
||||
overlap(tic);
|
||||
}
|
||||
|
||||
static void initApi(tic_api* api)
|
||||
|
@ -1757,6 +1774,7 @@ static void initApi(tic_api* api)
|
|||
INIT_API(time);
|
||||
INIT_API(tick);
|
||||
INIT_API(scanline);
|
||||
INIT_API(overlap);
|
||||
INIT_API(reset);
|
||||
INIT_API(pause);
|
||||
INIT_API(resume);
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
|
||||
#define SFX_NOTES {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"}
|
||||
|
||||
#define API_KEYWORDS {"TIC", "scanline", "print", "cls", "pix", "line", "rect", "rectb", \
|
||||
#define API_KEYWORDS {"TIC", "scanline", "OVR", "print", "cls", "pix", "line", "rect", "rectb", \
|
||||
"spr", "btn", "btnp", "sfx", "map", "mget", "mset", "peek", "poke", "peek4", "poke4", \
|
||||
"memcpy", "memset", "trace", "pmem", "time", "exit", "font", "mouse", "circ", "circb", "tri", "textri", \
|
||||
"clip", "music", "sync"}
|
||||
|
@ -368,7 +368,7 @@ typedef union
|
|||
struct
|
||||
{
|
||||
u8 border:TIC_PALETTE_BPP;
|
||||
u8 bg:TIC_PALETTE_BPP;
|
||||
u8 tmp:TIC_PALETTE_BPP;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ TIC80_API void tic80_load(tic80* tic, void* cart, s32 size)
|
|||
tic80->tic.sound.count = tic80->memory->samples.size/sizeof(s16);
|
||||
tic80->tic.sound.samples = tic80->memory->samples.buffer;
|
||||
|
||||
tic80->tic.screen = tic80->memory->screen;
|
||||
|
||||
{
|
||||
tic80->tickData.error = onError;
|
||||
tic80->tickData.trace = onTrace;
|
||||
|
@ -121,7 +123,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);
|
||||
|
||||
tic80->memory->api.blit(tic80->memory, tic->screen, tic80->memory->api.scanline);
|
||||
tic80->memory->api.blit(tic80->memory, tic80->memory->api.scanline, tic80->memory->api.overlap);
|
||||
|
||||
TickCounter++;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct
|
|||
|
||||
typedef struct tic_mem tic_mem;
|
||||
typedef void(*tic_scanline)(tic_mem* memory, s32 row);
|
||||
typedef void(*tic_overlap)(tic_mem* memory);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -96,6 +97,7 @@ typedef struct
|
|||
double (*time) (tic_mem* memory);
|
||||
void (*tick) (tic_mem* memory, tic_tick_data* data);
|
||||
void (*scanline) (tic_mem* memory, s32 row);
|
||||
void (*overlap) (tic_mem* memory);
|
||||
void (*reset) (tic_mem* memory);
|
||||
void (*pause) (tic_mem* memory);
|
||||
void (*resume) (tic_mem* memory);
|
||||
|
@ -107,7 +109,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);
|
||||
void (*blit) (tic_mem* tic, tic_scanline scanline, tic_overlap overlap);
|
||||
|
||||
tic_script_lang (*get_script)(tic_mem* memory);
|
||||
} tic_api;
|
||||
|
@ -129,6 +131,8 @@ struct tic_mem
|
|||
s16* buffer;
|
||||
s32 size;
|
||||
} samples;
|
||||
|
||||
u32 screen[TIC80_FULLWIDTH * TIC80_FULLHEIGHT];
|
||||
};
|
||||
|
||||
tic_mem* tic_create(s32 samplerate);
|
||||
|
|
20
src/tools.c
20
src/tools.c
|
@ -85,3 +85,23 @@ u32 tic_tool_find_closest_color(const tic_rgb* palette, const tic_rgb* color)
|
|||
|
||||
return closetColor;
|
||||
}
|
||||
|
||||
u32* tic_palette_blit(const tic_palette* srcpal)
|
||||
{
|
||||
static u32 pal[TIC_PALETTE_SIZE] = {0};
|
||||
|
||||
const u8* src = srcpal->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;
|
||||
}
|
|
@ -51,3 +51,4 @@ bool tic_tool_parse_note(const char* noteStr, s32* note, s32* octave);
|
|||
s32 tic_tool_get_pattern_id(const tic_track* track, s32 frame, s32 channel);
|
||||
void tic_tool_set_pattern_id(tic_track* track, s32 frame, s32 channel, s32 id);
|
||||
u32 tic_tool_find_closest_color(const tic_rgb* palette, const tic_rgb* color);
|
||||
u32* tic_palette_blit(const tic_palette* src);
|
Loading…
Reference in New Issue