Merge branch '#341'
This commit is contained in:
commit
61b4511c53
131
src/console.c
131
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 </%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 <PALETTE>\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 </%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"},
|
||||
|
|
|
@ -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);
|
||||
|
|
10
src/luaapi.c
10
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
src/sfx.c
44
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;
|
||||
|
|
76
src/studio.c
76
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);
|
||||
|
|
91
src/tic.c
91
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
|
||||
|
||||
|
|
12
src/tic.h
12
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
|
||||
|
|
Loading…
Reference in New Issue