diff --git a/CMakeLists.txt b/CMakeLists.txt index a71fb23da..4a7bc47b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,6 @@ endif() set(BUILD_PLAYER_DEFAULT OFF) set(BUILD_LIBRETRO_DEFAULT OFF) set(BUILD_TOUCH_INPUT_DEFAULT ${ANDROID}) -set(BUILD_TOOLS OFF) set(BUILD_WITH_ALL_DEFAULT OFF) option(BUILD_STATIC "Static runtime" ${BUILD_STATIC_DEFAULT}) @@ -32,7 +31,8 @@ option(BUILD_SDL "SDL Enabled" ON) option(BUILD_SDLGPU "SDL GPU Enabled" OFF) option(BUILD_SOKOL "Sokol Enabled" OFF) option(BUILD_LIBRETRO "libretro Enabled" ${BUILD_LIBRETRO_DEFAULT}) -option(BUILD_TOOLS "bin2txt prj2cart" ${BUILD_TOOLS}) +option(BUILD_TOOLS "bin2txt prj2cart" OFF) +option(BUILD_EDITORS "Build cart editors" ON) option(BUILD_PRO "Build PRO version" FALSE) option(BUILD_PLAYER "Build standalone players" ${BUILD_PLAYER_DEFAULT}) option(BUILD_TOUCH_INPUT "Build with touch input support" ${BUILD_TOUCH_INPUT_DEFAULT}) diff --git a/cmake/studio.cmake b/cmake/studio.cmake index ce3a0d6db..988f9f103 100644 --- a/cmake/studio.cmake +++ b/cmake/studio.cmake @@ -4,31 +4,37 @@ set(TIC80LIB_DIR ${CMAKE_SOURCE_DIR}/src) set(TIC80STUDIO_SRC - ${TIC80LIB_DIR}/studio/screens/console.c ${TIC80LIB_DIR}/studio/screens/run.c ${TIC80LIB_DIR}/studio/screens/menu.c ${TIC80LIB_DIR}/studio/screens/mainmenu.c - ${TIC80LIB_DIR}/studio/screens/surf.c ${TIC80LIB_DIR}/studio/screens/start.c - ${TIC80LIB_DIR}/studio/editors/code.c - ${TIC80LIB_DIR}/studio/editors/sprite.c - ${TIC80LIB_DIR}/studio/editors/map.c - ${TIC80LIB_DIR}/studio/editors/world.c - ${TIC80LIB_DIR}/studio/editors/sfx.c - ${TIC80LIB_DIR}/studio/editors/music.c ${TIC80LIB_DIR}/studio/studio.c ${TIC80LIB_DIR}/studio/config.c ${TIC80LIB_DIR}/studio/fs.c - ${TIC80LIB_DIR}/studio/net.c ${TIC80LIB_DIR}/ext/md5.c - ${TIC80LIB_DIR}/ext/history.c - ${TIC80LIB_DIR}/ext/gif.c - ${TIC80LIB_DIR}/ext/png.c ${TIC80LIB_DIR}/ext/json.c ) -if(${BUILD_PRO}) - set(TIC80STUDIO_SRC ${TIC80STUDIO_SRC} ${TIC80LIB_DIR}/studio/project.c) +if(BUILD_EDITORS) + set(TIC80STUDIO_SRC ${TIC80STUDIO_SRC} + ${TIC80LIB_DIR}/studio/screens/console.c + ${TIC80LIB_DIR}/studio/screens/surf.c + ${TIC80LIB_DIR}/studio/editors/code.c + ${TIC80LIB_DIR}/studio/editors/sprite.c + ${TIC80LIB_DIR}/studio/editors/map.c + ${TIC80LIB_DIR}/studio/editors/world.c + ${TIC80LIB_DIR}/studio/editors/sfx.c + ${TIC80LIB_DIR}/studio/editors/music.c + ${TIC80LIB_DIR}/studio/net.c + ${TIC80LIB_DIR}/ext/history.c + ${TIC80LIB_DIR}/ext/gif.c + ${TIC80LIB_DIR}/ext/png.c + ) +endif() + +if(BUILD_PRO) + set(TIC80STUDIO_SRC ${TIC80STUDIO_SRC} + ${TIC80LIB_DIR}/studio/project.c) endif() set(TIC80_OUTPUT tic80) @@ -57,4 +63,6 @@ if(BUILD_SDLGPU) target_compile_definitions(tic80studio PUBLIC CRT_SHADER_SUPPORT) endif() -target_compile_definitions(tic80studio PUBLIC BUILD_EDITORS) \ No newline at end of file +if(BUILD_EDITORS) + target_compile_definitions(tic80studio PUBLIC BUILD_EDITORS) +endif() diff --git a/src/studio/config.c b/src/studio/config.c index 42e4b41f9..2cb914c90 100644 --- a/src/studio/config.c +++ b/src/studio/config.c @@ -37,6 +37,8 @@ #define INTEGER_SCALE_DEFAULT true #endif +#define JSON(...) #__VA_ARGS__ + static void readConfig(Config* config) { const char* json = config->cart->code.data; @@ -150,16 +152,48 @@ static void save(Config* config) studioConfigChanged(config->studio); } -static const char OptionsDatPath[] = TIC_LOCAL_VERSION "options.dat"; +static const char OptionsJsonPath[] = TIC_LOCAL "options.json"; + +typedef struct +{ + char data[1024]; +} string; -static void loadConfigData(tic_fs* fs, const char* path, void* dst, s32 size) +static void loadOptions(Config* config) { - s32 dataSize = 0; - u8* data = (u8*)tic_fs_loadroot(fs, path, &dataSize); + s32 size; + u8* data = (u8*)tic_fs_loadroot(config->fs, OptionsJsonPath, &size); if(data) SCOPE(free(data)) - if(dataSize == size) - memcpy(dst, data, size); + { + string json; + snprintf(json.data, sizeof json, "%.*s", size, data); + + if(json_parse(json.data, strlen(json.data))) + { + struct StudioOptions* options = &config->data.options; + +#if defined(CRT_SHADER_SUPPORT) + options->crt = json_bool("crt", 0); +#endif + options->fullscreen = json_bool("fullscreen", 0); + options->vsync = json_bool("vsync", 0); + options->integerScale = json_bool("integerScale", 0); + options->volume = json_int("volume", 0); + options->autosave = json_bool("autosave", 0); + + string mapping; + json_string("mapping", 0, mapping.data, sizeof mapping); + tic_tool_str2buf(mapping.data, strlen(mapping.data), &options->mapping, false); + +#if defined(BUILD_EDITORS) + options->keybindMode = json_int("keybindMode", 0); + options->tabMode = json_int("tabMode", 0); + options->devmode = json_bool("devmode", 0); + options->tabSize = json_int("tabSize", 0); +#endif + } + } } void initConfig(Config* config, Studio* studio, tic_fs* fs) @@ -190,7 +224,7 @@ void initConfig(Config* config, Studio* studio, tic_fs* fs) else saveConfig(config, false); } - loadConfigData(fs, OptionsDatPath, &config->data.options, sizeof config->data.options); + loadOptions(config); #if defined(__TIC_LINUX__) // do not load fullscreen option on Linux @@ -200,9 +234,68 @@ void initConfig(Config* config, Studio* studio, tic_fs* fs) tic_api_reset(config->tic); } +static string data2str(const void* data, s32 size) +{ + string res; + tic_tool_buf2str(data, size, res.data, false); + return res; +} + +static const char* bool2str(bool value) +{ + return value ? "true" : "false"; +} + +static void saveOptions(Config* config) +{ + const struct StudioOptions* options = &config->data.options; + + string buf; + sprintf(buf.data, JSON( + { +#if defined(CRT_SHADER_SUPPORT) + "crt":%s, +#endif + "fullscreen":%s, + "vsync":%s, + "integerScale":%s, + "volume":%i, + "autosave":%s, + "mapping":"%s" +#if defined(BUILD_EDITORS) + , + "keybindMode":%i, + "tabMode":%i, + "devmode":%s, + "tabSize":%i +#endif + }) + , +#if defined(CRT_SHADER_SUPPORT) + bool2str(options->crt), +#endif + bool2str(options->fullscreen), + bool2str(options->vsync), + bool2str(options->integerScale), + options->volume, + bool2str(options->autosave), + data2str(&options->mapping, sizeof options->mapping).data + +#if defined(BUILD_EDITORS) + , + options->keybindMode, + options->tabMode, + bool2str(options->devmode), + options->tabSize +#endif + ); + + tic_fs_saveroot(config->fs, OptionsJsonPath, buf.data, strlen(buf.data), true); +} + void freeConfig(Config* config) { - tic_fs_saveroot(config->fs, OptionsDatPath, &config->data.options, sizeof config->data.options, true); + saveOptions(config); free(config->cart); free(config); diff --git a/src/studio/project.c b/src/studio/project.c index d1d8c70e4..951c1c44a 100644 --- a/src/studio/project.c +++ b/src/studio/project.c @@ -51,17 +51,6 @@ static void makeTag(const char* tag, char* out, s32 bank) else strcpy(out, tag); } -static void buf2str(const void* data, s32 size, char* ptr, bool flip) -{ - enum {Len = 2}; - - for(s32 i = 0; i < size; i++, ptr+=Len) - { - sprintf(ptr, "%02x", ((u8*)data)[i]); - if(flip) SWAP(ptr[0], ptr[1], char); - } -} - static bool bufferEmpty(const u8* data, s32 size) { for(s32 i = 0; i < size; i++) @@ -90,7 +79,7 @@ static char* saveBinaryBuffer(char* ptr, const char* comment, const void* data, sprintf(ptr, "%s %03i:", comment, row); ptr += strlen(ptr); - buf2str(data, size, ptr, flip); + tic_tool_buf2str(data, size, ptr, flip); ptr += strlen(ptr); sprintf(ptr, "\n"); diff --git a/src/studio/screens/run.c b/src/studio/screens/run.c index 313aa74d3..e2e1986e6 100644 --- a/src/studio/screens/run.c +++ b/src/studio/screens/run.c @@ -68,12 +68,10 @@ static const char* data2md5(const void* data, s32 length) } { - enum{Size = 16}; - u8 digest[Size]; + u8 digest[16]; MD5_Final(digest, &c); - for (s32 n = 0; n < Size; ++n) - snprintf(out + n*2, sizeof("ff"), "%02x", digest[n]); + tic_tool_buf2str(digest, sizeof digest, out, false); } return out; diff --git a/src/studio/studio.c b/src/studio/studio.c index 97a1fe63e..e6214cf44 100644 --- a/src/studio/studio.c +++ b/src/studio/studio.c @@ -563,18 +563,7 @@ void toClipboard(const void* data, s32 size, bool flip) { char* ptr = clipboard; - for(s32 i = 0; i < size; i++, ptr+=Len) - { - sprintf(ptr, "%02x", ((u8*)data)[i]); - - if(flip) - { - char tmp = ptr[0]; - ptr[0] = ptr[1]; - ptr[1] = tmp; - } - } - + tic_tool_buf2str(data, size, clipboard, flip); tic_sys_clipboard_set(clipboard); free(clipboard); } @@ -1745,6 +1734,8 @@ static bool enterWasPressedOnce(Studio* studio) keyWasPressedOnce(studio, tic_key_numpadenter); } +#if defined(BUILD_EDITORS) + static bool isDevMode(Studio* studio) { tic_mem* tic = studio->tic; @@ -1759,6 +1750,8 @@ static bool isDevMode(Studio* studio) return getConfig(studio)->options.devmode; } +#endif + static void processShortcuts(Studio* studio) { tic_mem* tic = studio->tic; diff --git a/src/tools.c b/src/tools.c index 6c8f0d279..ab15efc4a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -171,6 +171,15 @@ bool tic_tool_noise(const tic_waveform* wave) return FLAT4(wave->data) && *wave->data % 0xff == 0; } +void tic_tool_buf2str(const void* data, s32 size, char* str, bool flip) +{ + for(s32 i = 0; i < size; i++, str += 2) + { + sprintf(str, "%02x", ((u8*)data)[i]); + if(flip) SWAP(str[0], str[1], char); + } +} + void tic_tool_str2buf(const char* str, s32 size, void* buf, bool flip) { char val[] = "0x00"; diff --git a/src/tools.h b/src/tools.h index 4b4033ed5..60a503c49 100644 --- a/src/tools.h +++ b/src/tools.h @@ -94,6 +94,8 @@ void tic_tool_set_pattern_id(tic_track* track, s32 frame, s32 channel, s32 id bool tic_tool_has_ext(const char* name, const char* ext); s32 tic_tool_get_track_row_sfx(const tic_track_row* row); void tic_tool_set_track_row_sfx(tic_track_row* row, s32 sfx); + +void tic_tool_buf2str(const void* data, s32 size, char* str, bool flip); void tic_tool_str2buf(const char* str, s32 size, void* buf, bool flip); u32 tic_tool_zip(void* dest, s32 destSize, const void* source, s32 size);