diff --git a/src/console.c b/src/console.c index cbd9732..6f2a21e 100644 --- a/src/console.c +++ b/src/console.c @@ -565,6 +565,22 @@ static char* saveTextSection(char* ptr, const char* data) return ptr; } +static char* saveTextSectionBank(char* ptr, const char* comment, const char* tag, const char* data) +{ + if(strlen(data) == 0) + return ptr; + + sprintf(ptr, "%s <%s>\n", comment, tag); + ptr += strlen(ptr); + + ptr = saveTextSection(ptr, data); + + sprintf(ptr, "%s \n\n", comment, tag); + ptr += strlen(ptr); + + return ptr; +} + static char* saveBinaryBuffer(char* ptr, const char* comment, const void* data, s32 size, s32 row, bool flip) { if(bufferEmpty(data, size)) @@ -599,38 +615,58 @@ static char* saveBinarySection(char* ptr, const char* comment, const char* tag, return ptr; } -typedef struct {char* tag; s32 count; s32 offset; s32 size; bool flip;} BinarySection; +typedef struct {char* tag; s32 count; s32 offset; s32 size;} BinarySection; static const BinarySection BinarySections[] = { - {"PALETTE", 1, offsetof(tic_cartridge, palette.data), sizeof(tic_palette), false}, - {"TILES", TIC_BANK_SPRITES, offsetof(tic_cartridge, bank0.tiles), sizeof(tic_tile), true}, - {"SPRITES", TIC_BANK_SPRITES, offsetof(tic_cartridge, bank0.sprites), sizeof(tic_tile), true}, - {"MAP", TIC_MAP_HEIGHT, offsetof(tic_cartridge, bank0.map), TIC_MAP_WIDTH, true}, - {"WAVES", ENVELOPES_COUNT, offsetof(tic_cartridge, bank0.sfx.waveform.envelopes), sizeof(tic_waveform), true}, - {"SFX", SFX_COUNT, offsetof(tic_cartridge, bank0.sfx.data), sizeof(tic_sound_effect), true}, - {"PATTERNS", MUSIC_PATTERNS, offsetof(tic_cartridge, bank0.music.patterns), sizeof(tic_track_pattern), true}, - {"TRACKS", MUSIC_TRACKS, offsetof(tic_cartridge, bank0.music.tracks), sizeof(tic_track), true}, + {"TILES", TIC_BANK_SPRITES, offsetof(tic_bank, tiles), sizeof(tic_tile)}, + {"SPRITES", TIC_BANK_SPRITES, offsetof(tic_bank, sprites), sizeof(tic_tile)}, + {"MAP", TIC_MAP_HEIGHT, offsetof(tic_bank, map), TIC_MAP_WIDTH}, + {"WAVES", ENVELOPES_COUNT, offsetof(tic_bank, sfx.waveform), sizeof(tic_waveform)}, + {"SFX", SFX_COUNT, offsetof(tic_bank, sfx.samples), sizeof(tic_sample)}, + {"PATTERNS", MUSIC_PATTERNS, offsetof(tic_bank, music.patterns), sizeof(tic_track_pattern)}, + {"TRACKS", MUSIC_TRACKS, offsetof(tic_bank, music.tracks), sizeof(tic_track)}, }; +static void makeTag(const char* tag, char* out, s32 bank) +{ + if(bank) sprintf(out, "%s%i", tag, bank); + else strcpy(out, tag); +} + static s32 saveProject(Console* console, void* buffer, const char* comment) { tic_mem* tic = console->tic; char* stream = buffer; char* ptr = saveTextSection(stream, tic->cart.bank0.code.data); + char tag[16]; + + for(s32 b = 1; b < TIC_BANKS; b++) + { + makeTag("CODE", tag, b); + ptr = saveTextSectionBank(ptr, comment, tag, tic->cart.banks[b].code.data); + } for(s32 i = 0; i < COUNT_OF(BinarySections); i++) { const BinarySection* section = &BinarySections[i]; - ptr = saveBinarySection(ptr, comment, section->tag, section->count, (u8*)&tic->cart + section->offset, section->size, section->flip); - } - saveBinarySection(ptr, comment, "COVER", 1, &tic->cart.cover, tic->cart.cover.size + sizeof(s32), true); + for(s32 b = 0; b < TIC_BANKS; b++) + { + makeTag(section->tag, tag, b); + + ptr = saveBinarySection(ptr, comment, tag, section->count, + (u8*)&tic->cart.banks[b] + section->offset, section->size, true); + } + } + + ptr = saveBinarySection(ptr, comment, "PALETTE", 1, &tic->cart.palette, sizeof(tic_palette), false); + ptr = saveBinarySection(ptr, comment, "COVER", 1, &tic->cart.cover, tic->cart.cover.size + sizeof(s32), true); return strlen(stream); } -static bool loadTextSection(const char* project, const char* comment, void* dst, s32 size) +static bool loadTextSection(const char* project, const char* comment, char* dst, s32 size) { bool done = false; @@ -639,16 +675,31 @@ static bool loadTextSection(const char* project, const char* comment, void* dst, { char tagbuf[64]; + char tag[16]; for(s32 i = 0; i < COUNT_OF(BinarySections); i++) { - sprintf(tagbuf, "\n%s <%s>\n", comment, BinarySections[i].tag); + for(s32 b = 0; b < TIC_BANKS; b++) + { + makeTag(BinarySections[i].tag, tag, b); + + sprintf(tagbuf, "\n%s <%s>\n", comment, tag); + + const char* ptr = SDL_strstr(project, tagbuf); + + if(ptr && ptr < end) + end = ptr; + } + } + + { + sprintf(tagbuf, "\n%s \n", comment); const char* ptr = SDL_strstr(project, tagbuf); if(ptr && ptr < end) end = ptr; - } + } } if(end > start) @@ -660,6 +711,32 @@ static bool loadTextSection(const char* project, const char* comment, void* dst, return done; } +static bool loadTextSectionBank(const char* project, const char* comment, const char* tag, char* dst, s32 size) +{ + char tagbuf[64]; + sprintf(tagbuf, "%s <%s>\n", comment, tag); + + const char* start = SDL_strstr(project, tagbuf); + bool done = false; + + if(start) + { + start += strlen(tagbuf); + + sprintf(tagbuf, "\n%s ", comment, tag); + const char* end = SDL_strstr(start, tagbuf); + + if(end > start) + { + SDL_memcpy(dst, start, SDL_min(size, end - start)); + + done = true; + } + } + + return done; +} + static bool loadBinarySection(const char* project, const char* comment, const char* tag, s32 count, void* dst, s32 size, bool flip) { char tagbuf[64]; @@ -737,17 +814,35 @@ static bool loadProject(Console* console, const char* name, const char* data, s3 SDL_memcpy(&cart->palette, &tic->config.palette.data, sizeof(tic_palette)); const char* comment = projectComment(name); + char tag[16]; if(loadTextSection(project, comment, cart->bank0.code.data, sizeof(tic_code))) done = true; + for(s32 b = 1; b < TIC_BANKS; b++) + { + makeTag("CODE", tag, b); + + if(loadTextSectionBank(project, comment, tag, cart->banks[b].code.data, sizeof(tic_code))) + done = true; + } + for(s32 i = 0; i < COUNT_OF(BinarySections); i++) { const BinarySection* section = &BinarySections[i]; - if(loadBinarySection(project, comment, section->tag, section->count, (u8*)cart + section->offset, section->size, section->flip)) - done = true; + + for(s32 b = 0; b < TIC_BANKS; b++) + { + makeTag(section->tag, tag, b); + + if(loadBinarySection(project, comment, tag, section->count, (u8*)&cart->banks[b] + section->offset, section->size, true)) + done = true; + } } + if(loadBinarySection(project, comment, "PALETTE", 1, &cart->palette, sizeof(tic_palette), false)) + done = true; + if(loadBinarySection(project, comment, "COVER", 1, &cart->cover, -1, true)) done = true; @@ -2143,7 +2238,7 @@ static void onConsoleRamCommand(Console* console, const char* param) {offsetof(tic_ram, persistent), "PERSISTENT MEMORY"}, {offsetof(tic_ram, registers), "SOUND REGISTERS"}, {offsetof(tic_ram, sfx.waveform), "WAVEFORMS"}, - {offsetof(tic_ram, sfx.data), "SFX"}, + {offsetof(tic_ram, sfx.samples), "SFX"}, {offsetof(tic_ram, music.patterns.data), "MUSIC PATTERNS"}, {offsetof(tic_ram, music.tracks.data), "MUSIC TRACKS"}, {offsetof(tic_ram, music_pos), "MUSIC POS"}, diff --git a/src/jsapi.c b/src/jsapi.c index e28bd80..3289671 100644 --- a/src/jsapi.c +++ b/src/jsapi.c @@ -257,7 +257,7 @@ static duk_ret_t duk_sfx(duk_context* duk) { if(index >= 0) { - tic_sound_effect* effect = memory->ram.sfx.data + index; + tic_sample* effect = memory->ram.sfx.samples.data + index; note = effect->note; octave = effect->octave; @@ -703,9 +703,9 @@ static duk_ret_t duk_sync(duk_context* duk) { tic_mem* memory = (tic_mem*)getDukMachine(duk); - bool toCart = duk_is_null_or_undefined(duk, 0) ? true : duk_to_boolean(duk, 0); - const char* section = duk_is_null_or_undefined(duk, 1) ? NULL : duk_to_string(duk, 1); - s32 bank = duk_is_null_or_undefined(duk, 2) ? 0 : duk_to_int(duk, 2); + const char* section = duk_is_null_or_undefined(duk, 0) ? NULL : duk_to_string(duk, 0); + s32 bank = duk_is_null_or_undefined(duk, 1) ? 0 : duk_to_int(duk, 1); + bool toCart = duk_is_null_or_undefined(duk, 2) ? false : duk_to_boolean(duk, 2); if(bank >= 0 && bank < TIC_BANKS) memory->api.sync(memory, section, bank, toCart); diff --git a/src/luaapi.c b/src/luaapi.c index f702c35..e6d7359 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -682,7 +682,7 @@ static s32 lua_sfx(lua_State* lua) { if (index >= 0) { - tic_sound_effect* effect = memory->ram.sfx.data + index; + tic_sample* effect = memory->ram.sfx.samples.data + index; note = effect->note; octave = effect->octave; @@ -747,21 +747,21 @@ static s32 lua_sync(lua_State* lua) { tic_mem* memory = (tic_mem*)getLuaMachine(lua); - bool toCart = true; + bool toCart = false; const char* section = NULL; s32 bank = 0; if(lua_gettop(lua) >= 1) { - toCart = lua_toboolean(lua, 1); + section = lua_tostring(lua, 1); if(lua_gettop(lua) >= 2) { - section = lua_tostring(lua, 2); + bank = getLuaNumber(lua, 2); if(lua_gettop(lua) >= 3) { - bank = getLuaNumber(lua, 3); + toCart = lua_toboolean(lua, 3); } } } diff --git a/src/sfx.c b/src/sfx.c index cda5368..17710d8 100644 --- a/src/sfx.c +++ b/src/sfx.c @@ -104,9 +104,9 @@ static void drawSwitch(Sfx* sfx, s32 x, s32 y, const char* label, s32 value, voi } } -static tic_sound_effect* getEffect(Sfx* sfx) +static tic_sample* getEffect(Sfx* sfx) { - return sfx->src->data + sfx->index; + return sfx->src->samples.data + sfx->index; } static void setIndex(Sfx* sfx, s32 delta) @@ -116,7 +116,7 @@ static void setIndex(Sfx* sfx, s32 delta) static void setSpeed(Sfx* sfx, s32 delta) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); effect->speed += delta; @@ -129,14 +129,14 @@ static void drawTopPanel(Sfx* sfx, s32 x, s32 y) drawSwitch(sfx, x, y, "IDX", sfx->index, setIndex); - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); drawSwitch(sfx, x += Gap, y, "SPD", effect->speed, setSpeed); } static void setLoopStart(Sfx* sfx, s32 delta) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); tic_sound_loop* loop = effect->loops + sfx->canvasTab; loop->start += delta; @@ -146,7 +146,7 @@ static void setLoopStart(Sfx* sfx, s32 delta) static void setLoopSize(Sfx* sfx, s32 delta) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); tic_sound_loop* loop = effect->loops + sfx->canvasTab; loop->size += delta; @@ -160,7 +160,7 @@ static void drawLoopPanel(Sfx* sfx, s32 x, s32 y) enum {Gap = 2}; - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); tic_sound_loop* loop = effect->loops + sfx->canvasTab; drawSwitch(sfx, x, y += Gap + TIC_FONT_HEIGHT, "", loop->size, setLoopSize); @@ -248,7 +248,7 @@ static void drawWaveButtons(Sfx* sfx, s32 x, s32 y) if(checkMouseClick(&iconRect, SDL_BUTTON_LEFT)) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); for(s32 c = 0; c < SFX_TICKS; c++) effect->data[c].wave = i; } @@ -270,7 +270,7 @@ static void drawWaveButtons(Sfx* sfx, s32 x, s32 y) // draw full icon { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); u8 start = effect->data[0].wave; bool full = true; for(s32 c = 1; c < SFX_TICKS; c++) @@ -310,7 +310,7 @@ static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y) sfx->tic->api.text(sfx->tic, Labels[i], rect.x, rect.y, i == sfx->canvasTab ? (tic_color_white) : (tic_color_dark_gray)); } - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); switch(sfx->canvasTab) { @@ -372,7 +372,7 @@ static void drawCanvas(Sfx* sfx, s32 x, s32 y) SDL_Rect rect = {x, y, CANVAS_WIDTH, CANVAS_HEIGHT}; - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); if(checkMousePos(&rect)) { @@ -447,7 +447,7 @@ static void drawCanvas(Sfx* sfx, s32 x, s32 y) static void drawPiano(Sfx* sfx, s32 x, s32 y) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); static const s32 ButtonIndixes[] = {0, 2, 4, 5, 7, 9, 11, 1, 3, -1, 6, 8, 10}; @@ -514,7 +514,7 @@ static void drawPiano(Sfx* sfx, s32 x, s32 y) static void drawOctavePanel(Sfx* sfx, s32 x, s32 y) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); static const char Label[] = "OCT"; sfx->tic->api.text(sfx->tic, Label, x, y, (tic_color_white)); @@ -545,7 +545,7 @@ static void playSound(Sfx* sfx) { if(sfx->play.active) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); if(sfx->play.note != effect->note) { @@ -573,8 +573,8 @@ static void redo(Sfx* sfx) static void copyToClipboard(Sfx* sfx) { - tic_sound_effect* effect = getEffect(sfx); - toClipboard(effect, sizeof(tic_sound_effect), true); + tic_sample* effect = getEffect(sfx); + toClipboard(effect, sizeof(tic_sample), true); } static void copyWaveToClipboard(Sfx* sfx) @@ -585,8 +585,8 @@ static void copyWaveToClipboard(Sfx* sfx) static void resetSfx(Sfx* sfx) { - tic_sound_effect* effect = getEffect(sfx); - memset(effect, 0, sizeof(tic_sound_effect)); + tic_sample* effect = getEffect(sfx); + memset(effect, 0, sizeof(tic_sample)); history_add(sfx->history); } @@ -613,9 +613,9 @@ static void cutWaveToClipboard(Sfx* sfx) static void copyFromClipboard(Sfx* sfx) { - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); - if(fromClipboard(effect, sizeof(tic_sound_effect), true, false)) + if(fromClipboard(effect, sizeof(tic_sample), true, false)) history_add(sfx->history); } @@ -660,7 +660,7 @@ static void processKeyboard(Sfx* sfx) keyboardButton = i; } - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); if(keyboardButton >= 0) { @@ -808,7 +808,7 @@ static void drawSfxToolbar(Sfx* sfx) } } - tic_sound_effect* effect = getEffect(sfx); + tic_sample* effect = getEffect(sfx); { static const char* Notes[] = SFX_NOTES; diff --git a/src/studio.c b/src/studio.c index 0f7573e..77156ec 100644 --- a/src/studio.c +++ b/src/studio.c @@ -204,12 +204,12 @@ static struct struct { - Code* code [TIC_EDITOR_BANKS]; - Sprite* sprite [TIC_EDITOR_BANKS]; - Map* map [TIC_EDITOR_BANKS]; - Sfx* sfx [TIC_EDITOR_BANKS]; - Music* music [TIC_EDITOR_BANKS]; - } editor; + Code* code; + Sprite* sprite; + Map* map; + Sfx* sfx; + Music* music; + } editor[TIC_EDITOR_BANKS]; struct { @@ -332,7 +332,7 @@ tic_map* getBankMap() void playSystemSfx(s32 id) { - const tic_sound_effect* effect = &studio.tic->config.bank0.sfx.data[id]; + const tic_sample* effect = &studio.tic->config.bank0.sfx.samples.data[id]; studio.tic->api.sfx_ex(studio.tic, id, effect->note, effect->octave, -1, 0, MAX_VOLUME, 0); } @@ -777,31 +777,31 @@ void setStudioEvent(StudioEvent event) { case TIC_CODE_MODE: { - Code* code = studio.editor.code[studio.bank.index.code]; + Code* code = studio.editor[studio.bank.index.code].code; code->event(code, event); } break; case TIC_SPRITE_MODE: { - Sprite* sprite = studio.editor.sprite[studio.bank.index.sprites]; + Sprite* sprite = studio.editor[studio.bank.index.sprites].sprite; sprite->event(sprite, event); } break; case TIC_MAP_MODE: { - Map* map = studio.editor.map[studio.bank.index.map]; + Map* map = studio.editor[studio.bank.index.map].map; map->event(map, event); } break; case TIC_SFX_MODE: { - Sfx* sfx = studio.editor.sfx[studio.bank.index.sfx]; + Sfx* sfx = studio.editor[studio.bank.index.sfx].sfx; sfx->event(sfx, event); } break; case TIC_MUSIC_MODE: { - Music* music = studio.editor.music[studio.bank.index.music]; + Music* music = studio.editor[studio.bank.index.music].music; music->event(music, event); } break; @@ -879,7 +879,7 @@ void drawBitIcon(s32 x, s32 y, const u8* ptr, u8 color) static void initWorldMap() { - initWorld(studio.world, studio.tic, studio.editor.map[studio.bank.index.map]); + initWorld(studio.world, studio.tic, studio.editor[studio.bank.index.map].map); } static void initRunMode() @@ -1093,11 +1093,11 @@ static void initModules() for(s32 i = 0; i < TIC_EDITOR_BANKS; i++) { - initCode(studio.editor.code[i], studio.tic, &tic->cart.banks[i].code); - initSprite(studio.editor.sprite[i], studio.tic, &tic->cart.banks[i].tiles); - initMap(studio.editor.map[i], studio.tic, &tic->cart.banks[i].map); - initSfx(studio.editor.sfx[i], studio.tic, &tic->cart.banks[i].sfx); - initMusic(studio.editor.music[i], studio.tic, &tic->cart.banks[i].music); + initCode(studio.editor[i].code, studio.tic, &tic->cart.banks[i].code); + initSprite(studio.editor[i].sprite, studio.tic, &tic->cart.banks[i].tiles); + initMap(studio.editor[i].map, studio.tic, &tic->cart.banks[i].map); + initSfx(studio.editor[i].sfx, studio.tic, &tic->cart.banks[i].sfx); + initMusic(studio.editor[i].music, studio.tic, &tic->cart.banks[i].music); } initWorldMap(); @@ -1800,7 +1800,7 @@ static bool processShortcuts(SDL_KeyboardEvent* event) case SDLK_ESCAPE: case SDLK_AC_BACK: { - Code* code = studio.editor.code[studio.bank.index.code]; + Code* code = studio.editor[studio.bank.index.code].code; if(studio.mode == TIC_CODE_MODE && code->mode != TEXT_EDIT_MODE) { @@ -1938,7 +1938,7 @@ SDL_Event* pollEvent() #endif { - Code* code = studio.editor.code[studio.bank.index.code]; + Code* code = studio.editor[studio.bank.index.code].code; studio.console->codeLiveReload.reload(studio.console, code->src); if(studio.console->codeLiveReload.active && code->update) code->update(code); @@ -2103,14 +2103,14 @@ static void blitTexture() break; case TIC_SPRITE_MODE: { - Sprite* sprite = studio.editor.sprite[studio.bank.index.sprites]; + Sprite* sprite = studio.editor[studio.bank.index.sprites].sprite; overlap = sprite->overlap; data = sprite; } break; case TIC_MAP_MODE: { - Map* map = studio.editor.map[studio.bank.index.map]; + Map* map = studio.editor[studio.bank.index.map].map; overlap = map->overlap; data = map; } @@ -2307,31 +2307,31 @@ static void renderStudio() case TIC_RUN_MODE: studio.run->tick(studio.run); break; case TIC_CODE_MODE: { - Code* code = studio.editor.code[studio.bank.index.code]; + Code* code = studio.editor[studio.bank.index.code].code; code->tick(code); } break; case TIC_SPRITE_MODE: { - Sprite* sprite = studio.editor.sprite[studio.bank.index.sprites]; + Sprite* sprite = studio.editor[studio.bank.index.sprites].sprite; sprite->tick(sprite); } break; case TIC_MAP_MODE: { - Map* map = studio.editor.map[studio.bank.index.map]; + Map* map = studio.editor[studio.bank.index.map].map; map->tick(map); } break; case TIC_SFX_MODE: { - Sfx* sfx = studio.editor.sfx[studio.bank.index.sfx]; + Sfx* sfx = studio.editor[studio.bank.index.sfx].sfx; sfx->tick(sfx); } break; case TIC_MUSIC_MODE: { - Music* music = studio.editor.music[studio.bank.index.music]; + Music* music = studio.editor[studio.bank.index.music].music; music->tick(music); } break; @@ -2527,7 +2527,7 @@ static void updateSystemFont() void studioConfigChanged() { - Code* code = studio.editor.code[studio.bank.index.code]; + Code* code = studio.editor[studio.bank.index.code].code; if(code->update) code->update(code); @@ -2614,11 +2614,11 @@ static void onFSInitialized(FileSystem* fs) { for(s32 i = 0; i < TIC_EDITOR_BANKS; i++) { - studio.editor.code[i] = SDL_malloc(sizeof(Code)); - studio.editor.sprite[i] = SDL_malloc(sizeof(Sprite)); - studio.editor.map[i] = SDL_malloc(sizeof(Map)); - studio.editor.sfx[i] = SDL_malloc(sizeof(Sfx)); - studio.editor.music[i] = SDL_malloc(sizeof(Music)); + studio.editor[i].code = SDL_malloc(sizeof(Code)); + studio.editor[i].sprite = SDL_malloc(sizeof(Sprite)); + studio.editor[i].map = SDL_malloc(sizeof(Map)); + studio.editor[i].sfx = SDL_malloc(sizeof(Sfx)); + studio.editor[i].music = SDL_malloc(sizeof(Music)); } studio.start = SDL_malloc(sizeof(Start)); @@ -2726,11 +2726,11 @@ s32 main(s32 argc, char **argv) { for(s32 i = 0; i < TIC_EDITOR_BANKS; i++) { - SDL_free(studio.editor.code[i]); - SDL_free(studio.editor.sprite[i]); - SDL_free(studio.editor.map[i]); - SDL_free(studio.editor.sfx[i]); - SDL_free(studio.editor.music[i]); + SDL_free(studio.editor[i].code); + SDL_free(studio.editor[i].sprite); + SDL_free(studio.editor[i].map); + SDL_free(studio.editor[i].sfx); + SDL_free(studio.editor[i].music); } SDL_free(studio.start); diff --git a/src/tic.c b/src/tic.c index 73f0d53..65c49b0 100644 --- a/src/tic.c +++ b/src/tic.c @@ -53,7 +53,7 @@ typedef enum CHUNK_TEMP, // 6 CHUNK_TEMP2, // 7 CHUNK_TEMP3, // 8 - CHUNK_SOUND, // 9 + CHUNK_SAMPLES, // 9 CHUNK_WAVEFORM, // 10 CHUNK_TEMP4, // 11 CHUNK_PALETTE, // 12 @@ -64,13 +64,16 @@ typedef enum typedef struct { - ChunkType type:8; - u32 size:24; + ChunkType type:5; + u32 bank:TIC_BANK_BITS; + u32 size:16; // max chunk size is 64K + u32 temp:8; } Chunk; -STATIC_ASSERT(rom_chunk_size, sizeof(Chunk) == 4); +STATIC_ASSERT(tic_bank_bits, TIC_BANK_BITS == 3); +STATIC_ASSERT(tic_chunk_size, sizeof(Chunk) == 4); STATIC_ASSERT(tic_map, sizeof(tic_map) < 1024*32); -STATIC_ASSERT(tic_sound_effect, sizeof(tic_sound_effect) == 66); +STATIC_ASSERT(tic_sample, sizeof(tic_sample) == 66); STATIC_ASSERT(tic_track_pattern, sizeof(tic_track_pattern) == 3*MUSIC_PATTERN_ROWS); STATIC_ASSERT(tic_track, sizeof(tic_track) == 3*MUSIC_FRAMES+3); STATIC_ASSERT(tic_vram, sizeof(tic_vram) == TIC_VRAM_SIZE); @@ -357,7 +360,7 @@ static void channelSfx(tic_mem* memory, s32 index, s32 note, s32 octave, s32 dur if(index >= 0) { struct {s8 speed:SFX_SPEED_BITS;} temp = {speed}; - c->speed = speed == temp.speed ? speed : machine->sound.sfx->data[index].speed; + c->speed = speed == temp.speed ? speed : machine->sound.sfx->samples.data[index].speed; } // start index of idealized piano @@ -1061,7 +1064,7 @@ static void sfx(tic_mem* memory, s32 index, s32 freq, Channel* channel, tic_soun return; } - const tic_sound_effect* effect = &machine->sound.sfx->data[index]; + const tic_sample* effect = &machine->sound.sfx->samples.data[index]; s32 pos = ++channel->tick; s8 speed = channel->speed; @@ -1325,26 +1328,29 @@ static void initCover(tic_mem* tic) static void api_sync(tic_mem* tic, const char* section, s32 bank, bool toCart) { - static const struct {const char* name; s32 cart; s32 ram; s32 size;} Sections[] = + static const struct {const char* name; s32 bank; s32 ram; s32 size;} Sections[] = { - {"tiles", offsetof(tic_cartridge, bank0.tiles), offsetof(tic_ram, tiles), sizeof(tic_tiles)}, - {"sprites", offsetof(tic_cartridge, bank0.sprites), offsetof(tic_ram, sprites), sizeof(tic_tiles)}, - {"map", offsetof(tic_cartridge, bank0.map), offsetof(tic_ram, map), sizeof(tic_map)}, - {"sfx", offsetof(tic_cartridge, bank0.sfx), offsetof(tic_ram, sfx), sizeof(tic_sfx)}, - {"music", offsetof(tic_cartridge, bank0.music), offsetof(tic_ram, music), sizeof(tic_music)}, + {"tiles", offsetof(tic_bank, tiles), offsetof(tic_ram, tiles), sizeof(tic_tiles)}, + {"sprites", offsetof(tic_bank, sprites), offsetof(tic_ram, sprites), sizeof(tic_tiles)}, + {"map", offsetof(tic_bank, map), offsetof(tic_ram, map), sizeof(tic_map)}, + {"sfx", offsetof(tic_bank, sfx), offsetof(tic_ram, sfx), sizeof(tic_sfx)}, + {"music", offsetof(tic_bank, music), offsetof(tic_ram, music), sizeof(tic_music)}, }; assert(bank >= 0 && bank < TIC_BANKS); - s32 bankOffset = bank * sizeof(tic_bank); - for(s32 i = 0; i < COUNT_OF(Sections); i++) { if(section == NULL || (section && strcmp(section, Sections[i].name) == 0)) toCart - ? memcpy((u8*)&tic->cart + Sections[i].cart + bankOffset, (u8*)&tic->ram + Sections[i].ram, Sections[i].size) - : memcpy((u8*)&tic->ram + Sections[i].ram, (u8*)&tic->cart + Sections[i].cart + bankOffset, Sections[i].size); + ? memcpy((u8*)&tic->cart.banks[bank] + Sections[i].bank, (u8*)&tic->ram + Sections[i].ram, Sections[i].size) + : memcpy((u8*)&tic->ram + Sections[i].ram, (u8*)&tic->cart.banks[bank] + Sections[i].bank, Sections[i].size); } + + if(section == NULL || (section && strcmp(section, "pal") == 0)) + toCart + ? memcpy(&tic->cart.palette, &tic->ram.vram.palette, sizeof(tic_palette)) + : memcpy(&tic->ram.vram.palette, &tic->cart.palette, sizeof(tic_palette)); } static void cart2ram(tic_mem* memory) @@ -1607,17 +1613,17 @@ static void api_load(tic_cartridge* cart, const u8* buffer, s32 size, bool palet switch(chunk.type) { - case CHUNK_TILES: LOAD_CHUNK(cart->bank0.tiles); break; - case CHUNK_SPRITES: LOAD_CHUNK(cart->bank0.sprites); break; - case CHUNK_MAP: LOAD_CHUNK(cart->bank0.map); break; - case CHUNK_CODE: LOAD_CHUNK(cart->bank0.code); break; - case CHUNK_SOUND: LOAD_CHUNK(cart->bank0.sfx.data); break; - case CHUNK_WAVEFORM: LOAD_CHUNK(cart->bank0.sfx.waveform); break; - case CHUNK_MUSIC: LOAD_CHUNK(cart->bank0.music.tracks.data); break; - case CHUNK_PATTERNS: LOAD_CHUNK(cart->bank0.music.patterns.data); break; + case CHUNK_TILES: LOAD_CHUNK(cart->banks[chunk.bank].tiles); break; + case CHUNK_SPRITES: LOAD_CHUNK(cart->banks[chunk.bank].sprites); break; + case CHUNK_MAP: LOAD_CHUNK(cart->banks[chunk.bank].map); break; + case CHUNK_CODE: LOAD_CHUNK(cart->banks[chunk.bank].code); break; + case CHUNK_SAMPLES: LOAD_CHUNK(cart->banks[chunk.bank].sfx.samples); break; + case CHUNK_WAVEFORM: LOAD_CHUNK(cart->banks[chunk.bank].sfx.waveform); break; + case CHUNK_MUSIC: LOAD_CHUNK(cart->banks[chunk.bank].music.tracks); break; + case CHUNK_PATTERNS: LOAD_CHUNK(cart->banks[chunk.bank].music.patterns); break; case CHUNK_PALETTE: if(palette) - LOAD_CHUNK(cart->palette); + LOAD_CHUNK(cart->palette); break; case CHUNK_COVER: LOAD_CHUNK(cart->cover.data); @@ -1649,11 +1655,11 @@ static s32 calcBufferSize(const void* buffer, s32 size) return size; } -static u8* saveFixedChunk(u8* buffer, ChunkType type, const void* from, s32 size) +static u8* saveFixedChunk(u8* buffer, ChunkType type, const void* from, s32 size, s32 bank) { if(size) { - Chunk chunk = {type, size}; + Chunk chunk = {.type = type, .bank = bank, .size = size}; memcpy(buffer, &chunk, sizeof(Chunk)); buffer += sizeof(Chunk); memcpy(buffer, from, size); @@ -1663,30 +1669,33 @@ static u8* saveFixedChunk(u8* buffer, ChunkType type, const void* from, s32 size return buffer; } -static u8* saveChunk(u8* buffer, ChunkType type, const void* from, s32 size) +static u8* saveChunk(u8* buffer, ChunkType type, const void* from, s32 size, s32 bank) { s32 chunkSize = calcBufferSize(from, size); - return saveFixedChunk(buffer, type, from, chunkSize); + return saveFixedChunk(buffer, type, from, chunkSize, bank); } static s32 api_save(const tic_cartridge* cart, u8* buffer) { u8* start = buffer; - #define SAVE_CHUNK(id, from) saveChunk(buffer, id, &from, sizeof(from)) + #define SAVE_CHUNK(ID, FROM, BANK) saveChunk(buffer, ID, &FROM, sizeof(FROM), BANK) - buffer = SAVE_CHUNK(CHUNK_TILES, cart->bank0.tiles); - buffer = SAVE_CHUNK(CHUNK_SPRITES, cart->bank0.sprites); - buffer = SAVE_CHUNK(CHUNK_MAP, cart->bank0.map); - buffer = SAVE_CHUNK(CHUNK_CODE, cart->bank0.code); - buffer = SAVE_CHUNK(CHUNK_SOUND, cart->bank0.sfx.data); - buffer = SAVE_CHUNK(CHUNK_WAVEFORM, cart->bank0.sfx.waveform); - buffer = SAVE_CHUNK(CHUNK_PATTERNS, cart->bank0.music.patterns.data); - buffer = SAVE_CHUNK(CHUNK_MUSIC, cart->bank0.music.tracks.data); - buffer = SAVE_CHUNK(CHUNK_PALETTE, cart->palette); + for(s32 i = 0; i < TIC_BANKS; i++) + { + buffer = SAVE_CHUNK(CHUNK_TILES, cart->banks[i].tiles, i); + buffer = SAVE_CHUNK(CHUNK_SPRITES, cart->banks[i].sprites, i); + buffer = SAVE_CHUNK(CHUNK_MAP, cart->banks[i].map, i); + buffer = SAVE_CHUNK(CHUNK_CODE, cart->banks[i].code, i); + buffer = SAVE_CHUNK(CHUNK_SAMPLES, cart->banks[i].sfx.samples, i); + buffer = SAVE_CHUNK(CHUNK_WAVEFORM, cart->banks[i].sfx.waveform, i); + buffer = SAVE_CHUNK(CHUNK_PATTERNS, cart->banks[i].music.patterns, i); + buffer = SAVE_CHUNK(CHUNK_MUSIC, cart->banks[i].music.tracks, i); + } - buffer = saveFixedChunk(buffer, CHUNK_COVER, cart->cover.data, cart->cover.size); + buffer = SAVE_CHUNK(CHUNK_PALETTE, cart->palette, 0); + buffer = saveFixedChunk(buffer, CHUNK_COVER, cart->cover.data, cart->cover.size, 0); #undef SAVE_CHUNK diff --git a/src/tic.h b/src/tic.h index 4a76585..e3af097 100644 --- a/src/tic.h +++ b/src/tic.h @@ -107,7 +107,8 @@ #define TIC_CODE_SIZE (0x10000) -#define TIC_BANKS 8 +#define TIC_BANK_BITS 3 +#define TIC_BANKS (1 << TIC_BANK_BITS) #define SFX_NOTES {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"} @@ -203,7 +204,7 @@ typedef struct tic_sound_loop loops[4]; }; -} tic_sound_effect; +} tic_sample; typedef struct { @@ -250,10 +251,15 @@ typedef struct tic_track data[MUSIC_TRACKS]; } tic_tracks; +typedef struct +{ + tic_sample data[SFX_COUNT]; +} tic_samples; + typedef struct { tic_waveforms waveform; - tic_sound_effect data[SFX_COUNT]; + tic_samples samples; }tic_sfx; typedef struct