From b1068cc81eccfaa2e74b6c8dfd109915986c3fbf Mon Sep 17 00:00:00 2001 From: "BADIM-PC\\Vadim" Date: Wed, 22 Nov 2017 10:20:12 +0300 Subject: [PATCH] live cart reloading fixes #374 --- src/console.c | 41 ++++++++++++++++++++++++++-------- src/fs.c | 12 ++++++++++ src/fs.h | 1 + src/studio.c | 61 +++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/console.c b/src/console.c index 4e479c4..281d011 100644 --- a/src/console.c +++ b/src/console.c @@ -618,12 +618,13 @@ static s32 saveProject(Console* console, void* buffer) return strlen(stream); } -static void loadTextSection(const char* project, const char* tag, void* dst, s32 size) +static bool loadTextSection(const char* project, const char* tag, void* dst, s32 size) { char tagbuf[64]; sprintf(tagbuf, "-- <%s>\n", tag); const char* start = SDL_strstr(project, tagbuf); + bool done = false; if(start) { @@ -635,17 +636,23 @@ static void loadTextSection(const char* project, const char* tag, void* dst, s32 const char* end = SDL_strstr(start, tagbuf); if(end > start) + { SDL_memcpy(dst, start, SDL_min(size, end - start)); + done = true; + } } } + + return done; } -static void loadBinarySection(const char* project, const char* tag, s32 count, void* dst, s32 size, bool flip) +static bool loadBinarySection(const char* project, const char* tag, s32 count, void* dst, s32 size, bool flip) { char tagbuf[64]; sprintf(tagbuf, "-- <%s>\n", tag); const char* start = SDL_strstr(project, tagbuf); + bool done = false; if(start) { @@ -680,8 +687,12 @@ static void loadBinarySection(const char* project, const char* tag, s32 count, v ptr += sizeof("-- 999:") - 1; str2buf(ptr, end - ptr, (u8*)dst, flip); } + + done = true; } } + + return done; } static bool loadProject(Console* console, const char* data, s32 size, tic_cartridge* dst) @@ -710,21 +721,22 @@ static bool loadProject(Console* console, const char* data, s32 size, tic_cartri SDL_memset(cart, 0, sizeof(tic_cartridge)); SDL_memcpy(&cart->palette, &tic->config.palette.data, sizeof(tic_palette)); - loadTextSection(project, "CODE", cart->code.data, sizeof(tic_code)); + if(loadTextSection(project, "CODE", cart->code.data, sizeof(tic_code))) + done = true; for(s32 i = 0; i < COUNT_OF(BinarySections); i++) { const BinarySection* section = &BinarySections[i]; - loadBinarySection(project, section->tag, section->count, (u8*)cart + section->offset, section->size, section->flip); + if(loadBinarySection(project, section->tag, section->count, (u8*)cart + section->offset, section->size, section->flip)) + done = true; } - loadBinarySection(project, "COVER", 1, &cart->cover, -1, true); + if(loadBinarySection(project, "COVER", 1, &cart->cover, -1, true)) + done = true; SDL_memcpy(dst, cart, sizeof(tic_cartridge)); SDL_free(cart); - - done = true; } SDL_free(project); @@ -744,10 +756,21 @@ static void updateProject(Console* console) if(data) { - loadProject(console, data, size, &tic->cart); + tic_cartridge* cart = SDL_malloc(sizeof(tic_cartridge)); + + if(cart) + { + if(loadProject(console, data, size, cart)) + { + SDL_memcpy(&tic->cart, cart, sizeof(tic_cartridge)); + + studioRomLoaded(); + } + + SDL_free(cart); + } SDL_free(data); - studioRomLoaded(); } } } diff --git a/src/fs.c b/src/fs.c index 1dcdb4f..44c8f9c 100644 --- a/src/fs.c +++ b/src/fs.c @@ -618,6 +618,18 @@ bool fsExistsFile(FileSystem* fs, const char* name) return fsExists(getFilePath(fs, name)); } +u64 fsMDate(FileSystem* fs, const char* name) +{ + struct tic_stat_struct s; + + if(tic_stat(UTF8ToString(getFilePath(fs, name)), &s) == 0 && S_ISREG(s.st_mode)) + { + return s.st_mtime; + } + + return 0; +} + bool fsSaveFile(FileSystem* fs, const char* name, const void* data, size_t size, bool overwrite) { if(!overwrite) diff --git a/src/fs.h b/src/fs.h index 7188673..b93fd43 100644 --- a/src/fs.h +++ b/src/fs.h @@ -60,6 +60,7 @@ void* fsLoadFile(FileSystem* fs, const char* name, s32* size); void* fsLoadRootFile(FileSystem* fs, const char* name, s32* size); void fsMakeDir(FileSystem* fs, const char* name); bool fsExistsFile(FileSystem* fs, const char* name); +u64 fsMDate(FileSystem* fs, const char* name); const char* fsBasename(const char *path); const char* fsFilename(const char *path); diff --git a/src/studio.c b/src/studio.c index ffa7899..266dcf0 100644 --- a/src/studio.c +++ b/src/studio.c @@ -78,7 +78,11 @@ static struct tic80_local* tic80local; tic_mem* tic; - CartHash hash; + struct + { + CartHash hash; + u64 mdate; + }cart; SDL_Window* window; SDL_Renderer* renderer; @@ -199,6 +203,11 @@ static struct .texture = NULL, .audioDevice = 0, + .cart = + { + .mdate = 0, + }, + .joysticks = {NULL, NULL, NULL, NULL}, .mode = TIC_START_MODE, @@ -919,7 +928,12 @@ static void initModules() static void updateHash() { - md5(&studio.tic->cart, sizeof(tic_cartridge), studio.hash.data); + md5(&studio.tic->cart, sizeof(tic_cartridge), studio.cart.hash.data); +} + +static void updateMDate() +{ + studio.cart.mdate = fsMDate(studio.console.fs, studio.console.romName); } static void updateTitle() @@ -936,6 +950,7 @@ void studioRomSaved() { updateTitle(); updateHash(); + updateMDate(); } void studioRomLoaded() @@ -944,6 +959,7 @@ void studioRomLoaded() updateTitle(); updateHash(); + updateMDate(); } bool studioCartChanged() @@ -951,7 +967,7 @@ bool studioCartChanged() CartHash hash; md5(&studio.tic->cart, sizeof(tic_cartridge), hash.data); - return memcmp(hash.data, studio.hash.data, sizeof(CartHash)) != 0; + return memcmp(hash.data, studio.cart.hash.data, sizeof(CartHash)) != 0; } static void updateGamepadParts(); @@ -1682,12 +1698,16 @@ static void processMouseInput() studio.tic->ram.vram.input.gamepad.pressed = studio.mouse.state->down ? 1 : 0; } +#if defined(TIC80_PRO) + static void reloadConfirm(bool yes, void* data) { if(yes) studio.console.updateProject(&studio.console); } +#endif + SDL_Event* pollEvent() { static SDL_Event event; @@ -1734,26 +1754,33 @@ SDL_Event* pollEvent() if(studio.mode != TIC_START_MODE) { - if(studioCartChanged()) - { - static const char* Rows[] = - { - "", - "CART HAS CHANGED!", - "", - "DO YOU WANT", - "TO RELOAD IT?" - }; + Console* console = &studio.console; - showDialog(Rows, COUNT_OF(Rows), reloadConfirm, NULL); + u64 mdate = fsMDate(console->fs, console->romName); + + if(mdate > studio.cart.mdate) + { + if(studioCartChanged()) + { + static const char* Rows[] = + { + "", + "CART HAS CHANGED!", + "", + "DO YOU WANT", + "TO RELOAD IT?" + }; + + showDialog(Rows, COUNT_OF(Rows), reloadConfirm, NULL); + } + else console->updateProject(console); } - else studio.console.updateProject(&studio.console); } #endif { - studio.console.codeLiveReload.reload(&studio.console,studio.code.data); - if(studio.code.update) + studio.console.codeLiveReload.reload(&studio.console, studio.code.data); + if(studio.console.codeLiveReload.active && studio.code.update) studio.code.update(&studio.code); } break;