Merge branch '#374'

This commit is contained in:
BADIM-PC\Vadim 2017-11-11 17:18:15 +03:00
commit 6034c8f922
8 changed files with 420 additions and 57 deletions

View File

@ -274,16 +274,20 @@ emscripten:
mingw: $(DEMO_ASSETS) $(TIC80_DLL) $(TIC_O) bin/html.o bin/res.o
$(CC) $(TIC_O) bin/html.o bin/res.o $(TIC80_A) $(OPT) $(INCLUDES) $(MINGW_LINKER_FLAGS) -o $(MINGW_OUTPUT)
run: mingw
mingw-pro:
$(eval OPT += -DTIC80_PRO)
make mingw OPT="$(OPT)"
run: mingw-pro
$(MINGW_OUTPUT)
linux64-flto:
linux64-lto:
$(CC) $(LINUX_INCLUDES) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) $(OPT) $(INCLUDES) $(LINUX64_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
linux32-flto:
linux32-lto:
$(CC) $(LINUX_INCLUDES) $(SOURCES) $(TIC80_SRC) $(SOURCES_EXT) $(OPT) $(INCLUDES) $(LINUX32_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
arm-flto:
arm-lto:
$(CC) $(OPT_ARM) $(SOURCES) $(TIC80_SRC) $(OPT) $(INCLUDES) $(LINUX_ARM_LIBS) $(LINUX_LINKER_FLAGS) -flto -o bin/tic
linux:
@ -339,4 +343,4 @@ bin/assets/moondemo.tic.dat: demos/moondemo.tic
$(BIN2TXT) $< $@ -z
clean: $(TIC_O) $(TIC80_O)
$(RM) $(TIC_O) $(TIC80_O)
del bin\*.o

View File

@ -68,21 +68,26 @@ static const char DefaultLuaTicPath[] = TIC_LOCAL "default.tic";
static const char DefaultMoonTicPath[] = TIC_LOCAL "default_moon.tic";
static const char DefaultJSTicPath[] = TIC_LOCAL "default_js.tic";
static const char* getRomName(const char* name)
static const char* getName(const char* name, const char* ext)
{
static char path[FILENAME_MAX];
strcpy(path, name);
size_t ps = strlen(path);
size_t es = strlen(CartExt);
size_t es = strlen(ext);
if(!(ps > es && strstr(path, CartExt) + es == path + ps))
strcat(path, CartExt);
if(!(ps > es && strstr(path, ext) + es == path + ps))
strcat(path, ext);
return path;
}
static const char* getCartName(const char* name)
{
return getName(name, CartExt);
}
static void scrollBuffer(char* buffer)
{
memmove(buffer, buffer + CONSOLE_BUFFER_WIDTH, CONSOLE_BUFFER_SIZE - CONSOLE_BUFFER_WIDTH);
@ -343,7 +348,7 @@ static bool onConsoleLoadSectionCommand(Console* console, const char* param)
if(pos)
{
pos[sizeof(CartExt) - 1] = 0;
const char* name = getRomName(param);
const char* name = getCartName(param);
s32 size = 0;
void* data = fsLoadFile(console->fs, name, &size);
@ -475,7 +480,7 @@ static void onConsoleLoadDemoCommandConfirmed(Console* console, const char* para
else if(strcmp(param, DefaultJSTicPath) == 0)
data = getDemoCart(console, tic_script_js, &size);
const char* name = getRomName(param);
const char* name = getCartName(param);
strcpy(console->romName, name);
@ -490,6 +495,20 @@ static void onConsoleLoadDemoCommandConfirmed(Console* console, const char* para
SDL_free(data);
}
static void onCartLoaded(Console* console, const char* name)
{
strcpy(console->romName, name);
studioRomLoaded();
printBack(console, "\ncart ");
printFront(console, console->romName);
printBack(console, " loaded!\nuse ");
printFront(console, "RUN");
printBack(console, " command to run it\n");
}
static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
{
if(onConsoleLoadSectionCommand(console, param)) return;
@ -497,7 +516,7 @@ static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
if(param)
{
s32 size = 0;
const char* name = getRomName(param);
const char* name = getCartName(param);
void* data = strcmp(name, CONFIG_TIC_PATH) == 0
? fsLoadRootFile(console->fs, name, &size)
@ -507,21 +526,16 @@ static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
{
console->showGameMenu = fsIsInPublicDir(console->fs);
strcpy(console->romName, name);
loadRom(console->tic, data, size, true);
studioRomLoaded();
printBack(console, "\ncart ");
printFront(console, console->romName);
printBack(console, " loaded!\nuse ");
printFront(console, "RUN");
printBack(console, " command to run it\n");
onCartLoaded(console, name);
SDL_free(data);
}
else printBack(console, "\ncart loading error");
else
{
printBack(console, "\ncart loading error");
}
}
else printBack(console, "\ncart name is missing");
@ -676,6 +690,7 @@ typedef struct
static bool printFilename(const char* name, const char* info, s32 id, void* data, bool dir)
{
PrintFileNameData* printData = data;
Console* console = printData->console;
@ -683,6 +698,7 @@ static bool printFilename(const char* name, const char* info, s32 id, void* data
if(dir)
{
printBack(console, "[");
printBack(console, name);
printBack(console, "]");
@ -1546,6 +1562,345 @@ static void onConsoleExportCommand(Console* console, const char* param)
#endif
#if defined(TIC80_PRO)
static const char* getProjectName(const char* name)
{
return getName(name, ".ticp");
}
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)
{
char tmp = ptr[0];
ptr[0] = ptr[1];
ptr[1] = tmp;
}
}
}
static bool bufferEmpty(const u8* data, s32 size)
{
for(s32 i = 0; i < size; i++)
if(*data++)
return false;
return true;
}
static char* saveTextSection(char* ptr, const char* tag, const char* data)
{
if(strlen(data) == 0)
return ptr;
sprintf(ptr, "-- <%s>\n%s\n-- </%s>\n", tag, data, tag);
ptr += strlen(ptr);
return ptr;
}
static char* saveBinaryBuffer(char* ptr, const void* data, s32 size, s32 row, bool flip)
{
if(bufferEmpty(data, size))
return ptr;
sprintf(ptr, "-- %03i:", row);
ptr += strlen(ptr);
buf2str(data, size, ptr, flip);
ptr += strlen(ptr);
sprintf(ptr, "\n");
ptr += strlen(ptr);
return ptr;
}
static char* saveBinarySection(char* ptr, const char* tag, s32 count, const void* data, s32 size, bool flip)
{
if(bufferEmpty(data, size * count))
return ptr;
sprintf(ptr, "\n-- <%s>\n", tag);
ptr += strlen(ptr);
for(s32 i = 0; i < count; i++, data = (u8*)data + size)
ptr = saveBinaryBuffer(ptr, data, size, i, flip);
sprintf(ptr, "-- </%s>\n", tag);
ptr += strlen(ptr);
return ptr;
}
typedef struct {char* tag; s32 count; s32 offset; s32 size; bool flip;} BinarySection;
static const BinarySection BinarySections[] =
{
{"PALETTE", 1, offsetof(tic_cartridge, palette.data), sizeof(tic_palette), false},
{"TILES", TIC_BANK_SPRITES, offsetof(tic_cartridge, gfx.tiles), sizeof(tic_tile), true},
{"SPRITES", TIC_BANK_SPRITES, offsetof(tic_cartridge, gfx.sprites), sizeof(tic_tile), true},
{"MAP", TIC_MAP_HEIGHT, offsetof(tic_cartridge, gfx.map), TIC_MAP_WIDTH, true},
{"WAVES", ENVELOPES_COUNT, offsetof(tic_cartridge,sound.sfx.waveform.envelopes), sizeof(tic_waveform), true},
{"SFX", SFX_COUNT, offsetof(tic_cartridge, sound.sfx.data), sizeof(tic_sound_effect), true},
{"PATTERNS", MUSIC_PATTERNS, offsetof(tic_cartridge, sound.music.patterns), sizeof(tic_track_pattern), true},
{"TRACKS", MUSIC_TRACKS, offsetof(tic_cartridge, sound.music.tracks), sizeof(tic_track), true},
};
static CartSaveResult saveProject(Console* console, const char* name)
{
tic_mem* tic = console->tic;
bool success = false;
if(name && strlen(name))
{
char* stream = (char*)SDL_malloc(sizeof(tic_cartridge) * 3);
if(stream)
{
char* ptr = saveTextSection(stream, "CODE", tic->cart.code.data);
for(s32 i = 0; i < COUNT_OF(BinarySections); i++)
{
const BinarySection* section = &BinarySections[i];
ptr = saveBinarySection(ptr, section->tag, section->count, (u8*)&tic->cart + section->offset, section->size, section->flip);
}
saveBinarySection(ptr, "COVER", 1, &tic->cart.cover, tic->cart.cover.size + sizeof(s32), true);
name = getProjectName(name);
s32 size = strlen(stream);
if(size && fsSaveFile(console->fs, name, stream, size, true))
{
strcpy(console->romName, name);
success = true;
studioRomSaved();
}
SDL_free(stream);
}
}
else if (strlen(console->romName))
{
return saveProject(console, console->romName);
}
else return CART_SAVE_MISSING_NAME;
return success ? CART_SAVE_OK : CART_SAVE_ERROR;
}
static void onConsoleSaveProjectCommandConfirmed(Console* console, const char* param)
{
CartSaveResult rom = saveProject(console, param);
if(rom == CART_SAVE_OK)
{
printBack(console, "\nproject ");
printFront(console, console->romName);
printBack(console, " saved!\n");
}
else if(rom == CART_SAVE_MISSING_NAME)
printBack(console, "\nproject name is missing\n");
else
printBack(console, "\nproject saving error");
commandDone(console);
}
static void onConsoleSaveProjectCommand(Console* console, const char* param)
{
if(param && strlen(param) && fsExistsFile(console->fs, getProjectName(param)))
{
static const char* Rows[] =
{
"THE PROJECT",
"ALREADY EXISTS",
"",
"DO YOU WANT TO",
"OVERWRITE IT?",
};
confirmCommand(console, Rows, COUNT_OF(Rows), param, onConsoleSaveProjectCommandConfirmed);
}
else
{
onConsoleSaveProjectCommandConfirmed(console, param);
}
}
static void 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);
if(start)
{
start += strlen(tagbuf);
if(start < project + strlen(project))
{
sprintf(tagbuf, "\n-- </%s>", tag);
const char* end = SDL_strstr(start, tagbuf);
if(end > start)
SDL_memcpy(dst, start, SDL_min(size, end - start));
}
}
}
static void 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);
if(start)
{
start += strlen(tagbuf);
sprintf(tagbuf, "\n-- </%s>", tag);
const char* end = SDL_strstr(start, tagbuf);
if(end > start)
{
const char* ptr = start;
if(size > 0)
{
while(ptr < end)
{
static char lineStr[] = "999";
memcpy(lineStr, ptr + sizeof("-- ") - 1, sizeof lineStr - 1);
s32 index = SDL_atoi(lineStr);
if(index < count)
{
ptr += sizeof("-- 999:") - 1;
str2buf(ptr, size*2, (u8*)dst + size*index, flip);
ptr += size*2 + 1;
}
}
}
else
{
ptr += sizeof("-- 999:") - 1;
str2buf(ptr, end - ptr, (u8*)dst, flip);
}
}
}
}
static bool loadProject(Console* console, const char* data, s32 size)
{
tic_mem* tic = console->tic;
char* project = (char*)SDL_malloc(size+1);
bool done = false;
if(project)
{
SDL_memcpy(project, data, size);
project[size] = '\0';
tic_cartridge* cart = (tic_cartridge*)SDL_malloc(sizeof(tic_cartridge));
if(cart)
{
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));
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);
}
loadBinarySection(project, "COVER", 1, &cart->cover, -1, true);
SDL_memcpy(&tic->cart, cart, sizeof(tic_cartridge));
SDL_free(cart);
done = true;
}
SDL_free(project);
}
return done;
}
static void onConsoleLoadProjectCommandConfirmed(Console* console, const char* param)
{
if(param)
{
s32 size = 0;
const char* name = getProjectName(param);
void* data = fsLoadFile(console->fs, name, &size);
if(data && loadProject(console, data, size))
{
strcpy(console->romName, name);
studioRomLoaded();
printBack(console, "\nproject ");
printFront(console, console->romName);
printBack(console, " loaded!\nuse ");
printFront(console, "RUN");
printBack(console, " command to run it\n");
SDL_free(data);
}
else
{
printBack(console, "\nproject loading error");
}
}
else printBack(console, "\nproject name is missing");
commandDone(console);
}
static void onConsoleLoadProjectCommand(Console* console, const char* param)
{
if(studioCartChanged())
{
static const char* Rows[] =
{
"YOU HAVE",
"UNSAVED CHANGES",
"",
"DO YOU REALLY WANT",
"TO LOAD PROJECT?",
};
confirmCommand(console, Rows, COUNT_OF(Rows), param, onConsoleLoadProjectCommandConfirmed);
}
else
{
onConsoleLoadProjectCommandConfirmed(console, param);
}
}
#endif
static CartSaveResult saveCartName(Console* console, const char* name)
{
tic_mem* tic = console->tic;
@ -1569,7 +1924,7 @@ static CartSaveResult saveCartName(Console* console, const char* name)
{
s32 size = tic->api.save(&tic->cart, buffer);
name = getRomName(name);
name = getCartName(name);
if(size && fsSaveFile(console->fs, name, buffer, size, true))
{
@ -1617,7 +1972,7 @@ static void onConsoleSaveCommandConfirmed(Console* console, const char* param)
static void onConsoleSaveCommand(Console* console, const char* param)
{
if(param && strlen(param) && fsExistsFile(console->fs, getRomName(param)))
if(param && strlen(param) && fsExistsFile(console->fs, getCartName(param)))
{
static const char* Rows[] =
{
@ -1799,32 +2154,28 @@ static void onConsoleRamCommand(Console* console, const char* param)
"\n| ADDR | INFO | SIZE |" \
"\n+-------+-------------------+-------+");
#define ADDR_RECORD(addr, name) {(s32)((u8*)&addr - (u8*)console->tic), name}
const struct{s32 addr; const char* info;} Layout[] =
static const struct{s32 addr; const char* info;} Layout[] =
{
ADDR_RECORD(console->tic->ram.vram.screen, "SCREEN"),
ADDR_RECORD(console->tic->ram.vram.palette, "PALETTE"),
ADDR_RECORD(console->tic->ram.vram.mapping, "PALETTE MAP"),
ADDR_RECORD(console->tic->ram.vram.vars.colors, "BORDER/BG COLOR"),
ADDR_RECORD(console->tic->ram.vram.vars.offset, "SCREEN OFFSET"),
ADDR_RECORD(console->tic->ram.vram.vars.mask, "GAMEPAD MASK"),
ADDR_RECORD(console->tic->ram.vram.input.gamepad, "GAMEPAD"),
ADDR_RECORD(console->tic->ram.vram.input.reserved, "..."),
ADDR_RECORD(console->tic->ram.gfx.tiles, "SPRITES"),
ADDR_RECORD(console->tic->ram.gfx.map, "MAP"),
ADDR_RECORD(console->tic->ram.persistent, "PERSISTENT MEMORY"),
ADDR_RECORD(console->tic->ram.registers, "SOUND REGISTERS"),
ADDR_RECORD(console->tic->ram.sound.sfx.waveform, "WAVEFORMS"),
ADDR_RECORD(console->tic->ram.sound.sfx.data, "SFX"),
ADDR_RECORD(console->tic->ram.sound.music.patterns.data, "MUSIC PATTERNS"),
ADDR_RECORD(console->tic->ram.sound.music.tracks.data, "MUSIC TRACKS"),
ADDR_RECORD(console->tic->ram.music_pos, "MUSIC POS"),
{TIC_RAM_SIZE, "..."},
{offsetof(tic_ram, vram.screen), "SCREEN"},
{offsetof(tic_ram, vram.palette), "PALETTE"},
{offsetof(tic_ram, vram.mapping), "PALETTE MAP"},
{offsetof(tic_ram, vram.vars.colors), "BORDER/BG COLOR"},
{offsetof(tic_ram, vram.vars.offset), "SCREEN OFFSET"},
{offsetof(tic_ram, vram.vars.mask), "GAMEPAD MASK"},
{offsetof(tic_ram, vram.input.gamepad), "GAMEPAD"},
{offsetof(tic_ram, vram.input.reserved), "..."},
{offsetof(tic_ram, gfx.tiles), "SPRITES"},
{offsetof(tic_ram, gfx.map), "MAP"},
{offsetof(tic_ram, persistent), "PERSISTENT MEMORY"},
{offsetof(tic_ram, registers), "SOUND REGISTERS"},
{offsetof(tic_ram, sound.sfx.waveform), "WAVEFORMS"},
{offsetof(tic_ram, sound.sfx.data), "SFX"},
{offsetof(tic_ram, sound.music.patterns.data), "MUSIC PATTERNS"},
{offsetof(tic_ram, sound.music.tracks.data), "MUSIC TRACKS"},
{offsetof(tic_ram, music_pos), "MUSIC POS"},
{TIC_RAM_SIZE, "..."},
};
#undef ADDR_RECORD
enum{Last = COUNT_OF(Layout)-1};
for(s32 i = 0; i < Last; i++)
@ -1853,6 +2204,10 @@ static const struct
{"new", NULL, "create new cart", onConsoleNewCommand},
{"load", NULL, "load cart", onConsoleLoadCommand},
{"save", NULL, "save cart", onConsoleSaveCommand},
#if defined(TIC80_PRO)
{"loadp", NULL, "load project", onConsoleLoadProjectCommand},
{"savep", NULL, "save project", onConsoleSaveProjectCommand},
#endif
{"run", NULL, "run loaded cart", onConsoleRunCommand},
{"resume", NULL, "resume run cart", onConsoleResumeCommand},
{"dir", "ls", "show list of files", onConsoleDirCommand},

View File

@ -999,7 +999,7 @@ static void copyFromClipboard(Map* map)
{
u8* data = SDL_malloc(size);
str2buf(clipboard, data, true);
str2buf(clipboard, strlen(clipboard), data, true);
if(data[0] * data[1] == size - 2)
{

View File

@ -598,7 +598,7 @@ static void copyFromClipboard(Music* music)
{
u8* data = SDL_malloc(size);
str2buf(clipboard, data, true);
str2buf(clipboard, strlen(clipboard), data, true);
ClipboardHeader header = {0};

View File

@ -342,13 +342,11 @@ void toClipboard(const void* data, s32 size, bool flip)
}
}
void str2buf(const char* str, void* buf, bool flip)
void str2buf(const char* str, s32 size, void* buf, bool flip)
{
char val[] = "0x00";
const char* ptr = str;
s32 size = (s32)strlen(str);
for(s32 i = 0; i < size/2; i++)
{
if(flip)
@ -378,7 +376,7 @@ bool fromClipboard(void* data, s32 size, bool flip)
{
bool valid = strlen(clipboard) == size * 2;
if(valid) str2buf(clipboard, data, flip);
if(valid) str2buf(clipboard, strlen(clipboard), data, flip);
SDL_free(clipboard);

View File

@ -146,7 +146,7 @@ EditorMode getStudioMode();
void exitStudio();
u32 unzip(u8** dest, const u8* source, size_t size);
void str2buf(const char* str, void* buf, bool flip);
void str2buf(const char* str, s32 size, void* buf, bool flip);
void toClipboard(const void* data, s32 size, bool flip);
bool fromClipboard(void* data, s32 size, bool flip);

View File

@ -53,7 +53,7 @@ typedef enum
CHUNK_TEMP3, // 8
CHUNK_SOUND, // 9
CHUNK_WAVEFORM, // 10
CHUNK_OLDMUSIC, // 11
CHUNK_TEMP4, // 11
CHUNK_PALETTE, // 12
CHUNK_PATTERNS, // 13
CHUNK_MUSIC, // 14

View File

@ -31,13 +31,19 @@
#define TIC_VERSION_PATCH 0
#define TIC_VERSION_STATUS ""
#if defined(TIC80_PRO)
#define TIC_VERSION_POST " Pro"
#else
#define TIC_VERSION_POST ""
#endif
#define TIC_MAKE_VERSION(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch))
#define TIC_VERSION TIC_MAKE_VERSION(MYPROJ_VERSION_MAJOR, MYPROJ_VERSION_MINOR, MYPROJ_VERSION_PATCH)
#define DEF2STR2(x) #x
#define DEF2STR(x) DEF2STR2(x)
#define TIC_VERSION_LABEL DEF2STR(TIC_VERSION_MAJOR) "." DEF2STR(TIC_VERSION_MINOR) "." DEF2STR(TIC_VERSION_PATCH) TIC_VERSION_STATUS
#define TIC_VERSION_LABEL DEF2STR(TIC_VERSION_MAJOR) "." DEF2STR(TIC_VERSION_MINOR) "." DEF2STR(TIC_VERSION_PATCH) TIC_VERSION_STATUS TIC_VERSION_POST
#define TIC_PACKAGE "com.nesbox.tic"
#define TIC_NAME "TIC-80"
#define TIC_NAME_FULL TIC_NAME " tiny computer"
@ -302,8 +308,8 @@ typedef struct
typedef struct
{
u8 data [TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32)];
s32 size;
u8 data [TIC80_WIDTH * TIC80_HEIGHT * sizeof(u32)];
} tic_cover_image;
typedef struct