diff --git a/src/jsapi.c b/src/jsapi.c index 23c6449..858b150 100644 --- a/src/jsapi.c +++ b/src/jsapi.c @@ -809,7 +809,7 @@ void callJavascriptTick(tic_machine* machine) } } -void callJavascriptScanline(tic_mem* memory, s32 row) +void callJavascriptScanline(tic_mem* memory, s32 row, void* data) { tic_machine* machine = (tic_machine*)memory; duk_context* duk = machine->js; @@ -830,7 +830,7 @@ void callJavascriptScanline(tic_mem* memory, s32 row) else duk_pop(duk); } -void callJavascriptOverlap(tic_mem* memory) +void callJavascriptOverlap(tic_mem* memory, void* data) { tic_machine* machine = (tic_machine*)memory; duk_context* duk = machine->js; diff --git a/src/luaapi.c b/src/luaapi.c index b8931b5..638d803 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -1227,7 +1227,7 @@ void callLuaTick(tic_machine* machine) } } -void callLuaScanline(tic_mem* memory, s32 row) +void callLuaScanline(tic_mem* memory, s32 row, void* data) { tic_machine* machine = (tic_machine*)memory; lua_State* lua = machine->lua; @@ -1247,7 +1247,7 @@ void callLuaScanline(tic_mem* memory, s32 row) } } -void callLuaOverlap(tic_mem* memory) +void callLuaOverlap(tic_mem* memory, void* data) { tic_machine* machine = (tic_machine*)memory; lua_State* lua = machine->lua; diff --git a/src/machine.h b/src/machine.h index 529d1b6..1f966b6 100644 --- a/src/machine.h +++ b/src/machine.h @@ -140,8 +140,8 @@ bool initJavascript(tic_machine* machine, const char* code); void callLuaTick(tic_machine* machine); void callJavascriptTick(tic_machine* machine); -void callLuaScanline(tic_mem* memory, s32 row); -void callJavascriptScanline(tic_mem* memory, s32 row); +void callLuaScanline(tic_mem* memory, s32 row, void* data); +void callJavascriptScanline(tic_mem* memory, s32 row, void* data); -void callLuaOverlap(tic_mem* memory); -void callJavascriptOverlap(tic_mem* memory); +void callLuaOverlap(tic_mem* memory, void* data); +void callJavascriptOverlap(tic_mem* memory, void* data); diff --git a/src/map.c b/src/map.c index 4c4538d..c18b9ff 100644 --- a/src/map.c +++ b/src/map.c @@ -349,6 +349,13 @@ static void drawSheet(Map* map, s32 x, s32 y) SDL_Rect rect = {x, y, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE}; map->tic->api.rect_border(map->tic, rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2, (tic_color_white)); +} + +static void drawSheetOvr(Map* map, s32 x, s32 y) +{ + if(!map->sheet.show)return; + + SDL_Rect rect = {x, y, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE}; if(checkMousePos(&rect)) { @@ -821,6 +828,8 @@ static void drawSelection(Map* map) static void drawGrid(Map* map) { + tic_mem* tic = map->tic; + s32 scrollX = map->scroll.x % TIC_SPRITESIZE; s32 scrollY = map->scroll.y % TIC_SPRITESIZE; @@ -828,10 +837,9 @@ static void drawGrid(Map* map) { if(j >= 0 && j < TIC80_HEIGHT) for(s32 i = 0; i < TIC80_WIDTH; i++) - { - s32 index = i + j*TIC80_WIDTH; - u8 color = tic_tool_peek4(map->tic->ram.vram.screen.data, index); - tic_tool_poke4(map->tic->ram.vram.screen.data, index, (color+1)%TIC_PALETTE_SIZE); + { + u8 color = tic->api.get_pixel(tic, i, j); + tic->api.pixel(tic, i, j, (color+1)%TIC_PALETTE_SIZE); } } @@ -842,15 +850,14 @@ static void drawGrid(Map* map) { if((i+scrollY) % TIC_SPRITESIZE) { - s32 index = j + i*TIC80_WIDTH; - u8 color = tic_tool_peek4(map->tic->ram.vram.screen.data, index); - tic_tool_poke4(map->tic->ram.vram.screen.data, index, (color+1)%TIC_PALETTE_SIZE); + u8 color = tic->api.get_pixel(tic, j, i); + tic->api.pixel(tic, j, i, (color+1)%TIC_PALETTE_SIZE); } } } } -static void drawMap(Map* map) +static void drawMapOvr(Map* map) { SDL_Rect rect = {MAP_X, MAP_Y, MAP_WIDTH, MAP_HEIGHT}; @@ -858,7 +865,7 @@ static void drawMap(Map* map) s32 scrollY = map->scroll.y % TIC_SPRITESIZE; map->tic->api.map(map->tic, &map->tic->cart.gfx, map->scroll.x / TIC_SPRITESIZE, map->scroll.y / TIC_SPRITESIZE, - TIC_MAP_SCREEN_WIDTH + 1, TIC_MAP_SCREEN_HEIGHT + 1, -scrollX, -scrollY, 0, 1); + TIC_MAP_SCREEN_WIDTH + 1, TIC_MAP_SCREEN_HEIGHT + 1, -scrollX, -scrollY, -1, 1); if(map->canvas.grid || map->scroll.active) drawGrid(map); @@ -1112,7 +1119,6 @@ static void tick(Map* map) map->tic->api.clear(map->tic, TIC_COLOR_BG); - drawMap(map); drawSheet(map, TIC80_WIDTH - TIC_SPRITESHEET_SIZE - 1, TOOLBAR_SIZE); drawMapToolbar(map, TIC80_WIDTH - 9*TIC_FONT_WIDTH, 1); drawToolbar(map->tic, TIC_COLOR_BG, false); @@ -1131,9 +1137,14 @@ static void onStudioEvent(Map* map, StudioEvent event) } } -static void scanline(tic_mem* tic, s32 row) +static void overlap(tic_mem* tic, void* data) { - memcpy(tic->ram.vram.palette.data, row < TOOLBAR_SIZE ? tic->config.palette.data : tic->cart.palette.data, sizeof(tic_palette)); + Map* map = (Map*)data; + + tic->api.clip(tic, 0, TOOLBAR_SIZE, TIC80_WIDTH - (map->sheet.show ? TIC_SPRITESHEET_SIZE+2 : 0), TIC80_HEIGHT - TOOLBAR_SIZE); + drawMapOvr(map); + tic->api.clip(tic, 0, 0, TIC80_WIDTH, TIC80_HEIGHT); + drawSheetOvr(map, TIC80_WIDTH - TIC_SPRITESHEET_SIZE - 1, TOOLBAR_SIZE); } void initMap(Map* map, tic_mem* tic) @@ -1176,7 +1187,7 @@ void initMap(Map* map, tic_mem* tic) }, .history = history_create(&tic->cart.gfx.map, sizeof tic->cart.gfx.map), .event = onStudioEvent, - .scanline = scanline, + .overlap = overlap, }; normalizeMap(&map->scroll.x, &map->scroll.y); diff --git a/src/map.h b/src/map.h index 8d11256..fbd6b5f 100644 --- a/src/map.h +++ b/src/map.h @@ -80,7 +80,7 @@ struct Map void(*tick)(Map*); void(*event)(Map*, StudioEvent); - void(*scanline)(tic_mem* tic, s32 row); + void(*overlap)(tic_mem* tic, void* data); }; -void initMap(Map*, tic_mem*); \ No newline at end of file +void initMap(Map*, tic_mem*); diff --git a/src/sprite.c b/src/sprite.c index fe9b7d1..a5d7656 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -370,6 +370,17 @@ static void drawCanvas(Sprite* sprite, s32 x, s32 y) sprite->tic->api.rect(sprite->tic, x, y, CANVAS_SIZE, CANVAS_SIZE, (tic_color_black)); sprite->tic->api.rect(sprite->tic, x-1, y + CANVAS_SIZE+1, CANVAS_SIZE+2, 1, (tic_color_black)); + if(!sprite->editPalette) + { + if(sprite->mode == SPRITE_DRAW_MODE) + { + drawBrushSlider(sprite, x - 15, y + 20); + } + } +} + +static void drawCanvasOvr(Sprite* sprite, s32 x, s32 y) +{ SDL_Rect rect = getSpriteRect(sprite); s32 r = rect.x + rect.w; s32 b = rect.y + rect.h; @@ -390,7 +401,6 @@ static void drawCanvas(Sprite* sprite, s32 x, s32 y) switch(sprite->mode) { case SPRITE_DRAW_MODE: - drawBrushSlider(sprite, x - 15, y + 20); processDrawCanvasMouse(sprite, x, y, rect.x, rect.y); break; case SPRITE_PICK_MODE: processPickerCanvasMouse(sprite, x, y, rect.x, rect.y); break; @@ -521,7 +531,7 @@ static void drawRGBSlider(Sprite* sprite, s32 x, s32 y, u8* value) static const u8 Icon[] = { 0b11100000, - 0b10100000, + 0b11100000, 0b11100000, 0b00000000, 0b00000000, @@ -550,7 +560,6 @@ static void drawRGBSlider(Sprite* sprite, s32 x, s32 y, u8* value) s32 offset = x + *value * (Size-1) / Max - 1; drawBitIcon(offset, y, Icon, (tic_color_black)); drawBitIcon(offset, y-1, Icon, (tic_color_white)); - sprite->tic->api.pixel(sprite->tic, offset+1, y, sprite->color); } { @@ -747,6 +756,18 @@ static void drawRGBSliders(Sprite* sprite, s32 x, s32 y) drawRGBTools(sprite, x - 18, y + 26); } +static void drawRGBSlidersOvr(Sprite* sprite, s32 x, s32 y) +{ + enum{Gap = 6, Count = sizeof(tic_rgb), Size = CANVAS_SIZE, Max = 255}; + + u8* data = &sprite->tic->cart.palette.data[sprite->color * Count]; + + for(s32 i = 0; i < Count; i++) + { + sprite->tic->api.pixel(sprite->tic, x + data[i] * (Size-1) / Max, y + Gap*i, sprite->color); + } +} + static void drawPalette(Sprite* sprite, s32 x, s32 y) { SDL_Rect rect = {x, y, PALETTE_WIDTH-1, PALETTE_HEIGHT-1}; @@ -774,43 +795,16 @@ static void drawPalette(Sprite* sprite, s32 x, s32 y) } sprite->tic->api.rect(sprite->tic, rect.x-1, rect.y-1, rect.w+2, rect.h+2, (tic_color_white)); - - for(s32 row = 0, i = 0; row < PALETTE_ROWS; row++) - for(s32 col = 0; col < PALETTE_COLS; col++) - sprite->tic->api.rect(sprite->tic, x + col * PALETTE_CELL_SIZE, y + row * PALETTE_CELL_SIZE, PALETTE_CELL_SIZE-1, PALETTE_CELL_SIZE-1, i++); - sprite->tic->api.rect(sprite->tic, rect.x-1, rect.y+rect.h+1, PALETTE_WIDTH+1, 1, (tic_color_black)); { s32 offsetX = x + (sprite->color % PALETTE_COLS) * PALETTE_CELL_SIZE; s32 offsetY = y + (sprite->color / PALETTE_COLS) * PALETTE_CELL_SIZE; - sprite->tic->api.rect(sprite->tic, offsetX - 1, offsetY - 1, PALETTE_CELL_SIZE + 1, PALETTE_CELL_SIZE + 1, sprite->color); - sprite->tic->api.rect_border(sprite->tic, offsetX - 2, offsetY - 2, PALETTE_CELL_SIZE + 3, PALETTE_CELL_SIZE + 3, (tic_color_white)); - if(offsetY > y) sprite->tic->api.rect(sprite->tic, offsetX - 2, rect.y + rect.h+2, PALETTE_CELL_SIZE+3, 1, (tic_color_black)); } - { - static const u8 Icon[] = - { - 0b00000000, - 0b00111000, - 0b01000100, - 0b01000100, - 0b01000100, - 0b00111000, - 0b00000000, - 0b00000000, - }; - - s32 offsetX = x + (sprite->color2 % PALETTE_COLS) * PALETTE_CELL_SIZE; - s32 offsetY = y + (sprite->color2 / PALETTE_COLS) * PALETTE_CELL_SIZE; - - drawBitIcon(offsetX, offsetY, Icon, sprite->color2 == (tic_color_white) ? (tic_color_black) : (tic_color_white)); - } - { static const u8 Icon[] = { @@ -854,6 +848,40 @@ static void drawPalette(Sprite* sprite, s32 x, s32 y) } } +static void drawPaletteOvr(Sprite* sprite, s32 x, s32 y) +{ + for(s32 row = 0, i = 0; row < PALETTE_ROWS; row++) + for(s32 col = 0; col < PALETTE_COLS; col++) + sprite->tic->api.rect(sprite->tic, x + col * PALETTE_CELL_SIZE, y + row * PALETTE_CELL_SIZE, PALETTE_CELL_SIZE-1, PALETTE_CELL_SIZE-1, i++); + + { + s32 offsetX = x + (sprite->color % PALETTE_COLS) * PALETTE_CELL_SIZE; + s32 offsetY = y + (sprite->color / PALETTE_COLS) * PALETTE_CELL_SIZE; + + sprite->tic->api.rect(sprite->tic, offsetX - 1, offsetY - 1, PALETTE_CELL_SIZE + 1, PALETTE_CELL_SIZE + 1, sprite->color); + sprite->tic->api.rect_border(sprite->tic, offsetX - 2, offsetY - 2, PALETTE_CELL_SIZE + 3, PALETTE_CELL_SIZE + 3, (tic_color_white)); + } + + { + static const u8 Icon[] = + { + 0b00000000, + 0b00111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b00111000, + 0b00000000, + 0b00000000, + }; + + s32 offsetX = x + (sprite->color2 % PALETTE_COLS) * PALETTE_CELL_SIZE; + s32 offsetY = y + (sprite->color2 / PALETTE_COLS) * PALETTE_CELL_SIZE; + + drawBitIcon(offsetX, offsetY, Icon, sprite->color2 == (tic_color_white) ? (tic_color_black) : (tic_color_white)); + } +} + static void clearCanvasSelection(Sprite* sprite) { SDL_memset(&sprite->select.rect, 0, sizeof(SDL_Rect)); @@ -904,6 +932,11 @@ static void drawSheet(Sprite* sprite, s32 x, s32 y) selectSprite(sprite, getMouseX() - x - offset, getMouseY() - y - offset); } } +} + +static void drawSheetOvr(Sprite* sprite, s32 x, s32 y) +{ + SDL_Rect rect = {x, y, TIC_SPRITESHEET_SIZE, TIC_SPRITESHEET_SIZE}; for(s32 j = 0, index = (sprite->index - sprite->index % TIC_BANK_SPRITES); j < rect.h; j += TIC_SPRITESIZE) for(s32 i = 0; i < rect.w; i += TIC_SPRITESIZE, index++) @@ -1480,9 +1513,16 @@ static void onStudioEvent(Sprite* sprite, StudioEvent event) } } -static void scanline(tic_mem* tic, s32 row) +static void overlap(tic_mem* tic, void* data) { - memcpy(tic->ram.vram.palette.data, row < TOOLBAR_SIZE ? tic->config.palette.data : tic->cart.palette.data, sizeof(tic_palette)); + Sprite* sprite = (Sprite*)data; + + if(sprite->editPalette) + drawRGBSlidersOvr(sprite, 24, 91); + + drawCanvasOvr(sprite, 24, 20); + drawPaletteOvr(sprite, 24, 112); + drawSheetOvr(sprite, TIC80_WIDTH - TIC_SPRITESHEET_SIZE - 1, 7); } void initSprite(Sprite* sprite, tic_mem* tic) @@ -1513,6 +1553,6 @@ void initSprite(Sprite* sprite, tic_mem* tic) .mode = SPRITE_DRAW_MODE, .history = history_create(tic->cart.gfx.tiles, TIC_SPRITES * sizeof(tic_tile)), .event = onStudioEvent, - .scanline = scanline, + .overlap = overlap, }; } \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index f12bba5..a147108 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -61,7 +61,7 @@ struct Sprite void (*tick)(Sprite*); void (*event)(Sprite*, StudioEvent); - void (*scanline)(tic_mem* tic, s32 row); + void (*overlap)(tic_mem* tic, void* data); }; void initSprite(Sprite*, tic_mem*); \ No newline at end of file diff --git a/src/studio.c b/src/studio.c index 86699ff..492013a 100644 --- a/src/studio.c +++ b/src/studio.c @@ -57,6 +57,8 @@ #define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2) #define OFFSET_TOP ((TIC80_FULLHEIGHT-TIC80_HEIGHT)/2) +#define POPUP_DUR (TIC_FRAMERATE*2) + typedef struct { u8 data[16]; @@ -670,7 +672,7 @@ const u8* getKeyboard() static void showPopupMessage(const char* text) { - studio.popup.counter = TIC_FRAMERATE * 2; + studio.popup.counter = POPUP_DUR; strcpy(studio.popup.message, text); } @@ -1425,7 +1427,7 @@ static void setCoverImage() { enum {Pitch = TIC80_FULLWIDTH*sizeof(u32)}; - tic->api.blit(tic, tic->api.scanline, tic->api.overlap); + tic->api.blit(tic, tic->api.scanline, tic->api.overlap, NULL); u32* buffer = SDL_malloc(TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32)); @@ -1912,6 +1914,7 @@ static void blitTexture() tic_scanline scanline = NULL; tic_overlap overlap = NULL; + void* data = NULL; switch(studio.mode) { @@ -1920,16 +1923,18 @@ static void blitTexture() overlap = tic->api.overlap; break; case TIC_SPRITE_MODE: - scanline = studio.sprite.scanline; + overlap = studio.sprite.overlap; + data = &studio.sprite; break; case TIC_MAP_MODE: - scanline = studio.map.scanline; + overlap = studio.map.overlap; + data = &studio.map; break; default: break; } - tic->api.blit(tic, scanline, overlap); + tic->api.blit(tic, scanline, overlap, data); SDL_memcpy(pixels, tic->screen, sizeof tic->screen); recordFrame(pixels); @@ -2052,6 +2057,28 @@ static void useSystemPalette() memcpy(studio.tic->ram.vram.palette.data, studio.tic->config.palette.data, sizeof(tic_palette)); } +static void drawPopup() +{ + if(studio.popup.counter > 0) + { + studio.popup.counter--; + + s32 anim = 0; + + enum{Dur = TIC_FRAMERATE/2}; + + if(studio.popup.counter < Dur) + anim = -((Dur - studio.popup.counter) * (TIC_FONT_HEIGHT+1) / Dur); + else if(studio.popup.counter >= (POPUP_DUR - Dur)) + anim = (((POPUP_DUR - Dur) - studio.popup.counter) * (TIC_FONT_HEIGHT+1) / Dur); + + studio.tic->api.rect(studio.tic, 0, anim, TIC80_WIDTH, TIC_FONT_HEIGHT+1, (tic_color_red)); + studio.tic->api.text(studio.tic, studio.popup.message, + (s32)(TIC80_WIDTH - strlen(studio.popup.message)*TIC_FONT_WIDTH)/2, + anim + 1, (tic_color_white)); + } +} + static void renderStudio() { tic_mem* tic = studio.tic; @@ -2102,14 +2129,7 @@ static void renderStudio() default: break; } - if(studio.popup.counter > 0) - { - studio.popup.counter--; - - studio.tic->api.rect(studio.tic, 0, TIC80_HEIGHT - TIC_FONT_HEIGHT - 1, TIC80_WIDTH, TIC80_HEIGHT, (tic_color_red)); - studio.tic->api.text(studio.tic, studio.popup.message, (s32)(TIC80_WIDTH - strlen(studio.popup.message)*TIC_FONT_WIDTH)/2, - TIC80_HEIGHT - TIC_FONT_HEIGHT, (tic_color_white)); - } + drawPopup(); if(getConfig()->noSound) SDL_memset(tic->ram.registers, 0, sizeof tic->ram.registers); diff --git a/src/tic.c b/src/tic.c index 85b95fa..c6bb8a2 100644 --- a/src/tic.c +++ b/src/tic.c @@ -1510,20 +1510,20 @@ static void api_tick(tic_mem* memory, tic_tick_data* data) : callLuaTick(machine); } -static void api_scanline(tic_mem* memory, s32 row) +static void api_scanline(tic_mem* memory, s32 row, void* data) { tic_machine* machine = (tic_machine*)memory; if(machine->state.initialized) - machine->state.scanline(memory, row); + machine->state.scanline(memory, row, data); } -static void api_overlap(tic_mem* memory) +static void api_overlap(tic_mem* memory, void* data) { tic_machine* machine = (tic_machine*)memory; if(machine->state.initialized) - machine->state.ovr.callback(memory); + machine->state.ovr.callback(memory, data); } static double api_time(tic_mem* memory) @@ -1704,13 +1704,13 @@ static inline void memset4(void *dst, u32 val, u32 dwords) #endif } -static void api_blit(tic_mem* tic, tic_scanline scanline, tic_overlap overlap) +static void api_blit(tic_mem* tic, tic_scanline scanline, tic_overlap overlap, void* data) { const u32* pal = tic_palette_blit(&tic->ram.vram.palette); if(scanline) { - scanline(tic, 0); + scanline(tic, 0, data); pal = tic_palette_blit(&tic->ram.vram.palette); } @@ -1740,7 +1740,7 @@ static void api_blit(tic_mem* tic, tic_scanline scanline, tic_overlap overlap) if(scanline && (r < TIC80_HEIGHT-1)) { - scanline(tic, r+1); + scanline(tic, r+1, data); pal = tic_palette_blit(&tic->ram.vram.palette); } } @@ -1748,7 +1748,7 @@ static void api_blit(tic_mem* tic, tic_scanline scanline, tic_overlap overlap) memset4(&out[(TIC80_FULLHEIGHT-Bottom) * TIC80_FULLWIDTH], pal[tic->ram.vram.vars.border], TIC80_FULLWIDTH*Bottom); if(overlap) - overlap(tic); + overlap(tic, data); } static void initApi(tic_api* api) diff --git a/src/tic80.c b/src/tic80.c index d340b6a..64a97ec 100644 --- a/src/tic80.c +++ b/src/tic80.c @@ -123,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, tic80->memory->api.scanline, tic80->memory->api.overlap); + tic80->memory->api.blit(tic80->memory, tic80->memory->api.scanline, tic80->memory->api.overlap, NULL); TickCounter++; } diff --git a/src/ticapi.h b/src/ticapi.h index 2159339..144cc62 100644 --- a/src/ticapi.h +++ b/src/ticapi.h @@ -62,8 +62,8 @@ typedef struct } tic_tick_data; typedef struct tic_mem tic_mem; -typedef void(*tic_scanline)(tic_mem* memory, s32 row); -typedef void(*tic_overlap)(tic_mem* memory); +typedef void(*tic_scanline)(tic_mem* memory, s32 row, void* data); +typedef void(*tic_overlap)(tic_mem* memory, void* data); typedef struct { @@ -96,8 +96,8 @@ typedef struct void (*music_frame) (tic_mem* memory, s32 track, s32 frame, s32 row, bool loop); 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 (*scanline) (tic_mem* memory, s32 row, void* data); + void (*overlap) (tic_mem* memory, void* data); void (*reset) (tic_mem* memory); void (*pause) (tic_mem* memory); void (*resume) (tic_mem* memory); @@ -109,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, tic_scanline scanline, tic_overlap overlap); + void (*blit) (tic_mem* tic, tic_scanline scanline, tic_overlap overlap, void* data); tic_script_lang (*get_script)(tic_mem* memory); } tic_api;