Skip to content

Commit

Permalink
FEATURE: Byte Battle (nesbox#2602)
Browse files Browse the repository at this point in the history
  • Loading branch information
aliceisjustplaying authored May 26, 2024
1 parent 5d60c02 commit b1d765e
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 6 deletions.
58 changes: 57 additions & 1 deletion src/studio/editors/code.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,52 @@ static void history(Code* code)
history_add(code->history);
}

tic_color getCodeColor(Code* code)
{
Bytebattle* bb = getBytebattle(code->studio);

if(bb)
{
s32 size = strlen(code->src) - bb->limit.lower;

if(size <= 0) return tic_color_light_green;

s32 delta = (bb->limit.current - bb->limit.lower) / 2;

if(size <= delta) return tic_color_yellow;
if(size <= delta*2) return tic_color_orange;
return tic_color_red;
}

return tic_color_white;
}

static void drawStatus(Code* code)
{
enum {Height = TIC_FONT_HEIGHT + 1, StatusY = TIC80_HEIGHT - TIC_FONT_HEIGHT};

tic_api_rect(code->tic, 0, TIC80_HEIGHT - Height, TIC80_WIDTH, Height, code->status.color);
Bytebattle* bb = getBytebattle(code->studio);

if(bb)
{
tic_api_rect(code->tic, 0, TIC80_HEIGHT - Height, TIC80_WIDTH, Height, getCodeColor(code));
if(!bb->battle.hidetime)
{
sprintf(code->status.size, "%i/%i", (u32)strlen(code->src), bb->limit.current);

char buf[sizeof "00:00"];
s32 sec = bb->battle.left / 1000;
sprintf(buf, "%02i:%02i", sec / 60, sec % 60);

tic_api_print(code->tic, buf, (TIC80_WIDTH - sizeof "00:00" * TIC_FONT_WIDTH) / 2,
StatusY, getConfig(code->studio)->theme.code.BG, true, 1, false);
}
}
else
{
tic_api_rect(code->tic, 0, TIC80_HEIGHT - Height, TIC80_WIDTH, Height, code->status.color);
}

tic_api_print(code->tic, code->status.line, 0, StatusY, getConfig(code->studio)->theme.code.BG, true, 1, false);
tic_api_print(code->tic, code->status.size, TIC80_WIDTH - (s32)strlen(code->status.size) * TIC_FONT_WIDTH,
StatusY, getConfig(code->studio)->theme.code.BG, true, 1, false);
Expand Down Expand Up @@ -372,6 +413,21 @@ static void getCursorPosition(Code* code, s32* x, s32* y)
}
}

void codeGetPos(Code* code, s32* x, s32* y)
{
getCursorPosition(code, x, y);
}

static void setCursorPosition(Code* code, s32 x, s32 y);
static void parseSyntaxColor(Code*);

void codeSetPos(Code* code, s32 x, s32 y)
{
setCursorPosition(code, x, y);
parseSyntaxColor(code);
code->cursor.delay = 0;
}

static s32 getLinesCount(Code* code)
{
char* text = code->src;
Expand Down
2 changes: 2 additions & 0 deletions src/studio/editors/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,7 @@ struct Code

void initCode(Code*, Studio* studio);
void freeCode(Code*);
void codeGetPos(Code*, s32* x, s32* y);
void codeSetPos(Code*, s32 x, s32 y);

void trimWhitespace(Code*);
8 changes: 5 additions & 3 deletions src/studio/screens/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -4332,9 +4332,7 @@ static void tick(Console* console)
}
else printBack(console, "\n loading cart...");
}

if (getStudioMode(console->studio) != TIC_CONSOLE_MODE) return;


tic_api_cls(tic, TIC_COLOR_BG);
drawConsoleText(console);

Expand All @@ -4359,6 +4357,10 @@ static void tick(Console* console)
if(console->cursor.delay)
console->cursor.delay--;

console->tickCounter++;

if (getStudioMode(console->studio) != TIC_CONSOLE_MODE) return;

drawCursor(console);

if(console->active)
Expand Down
178 changes: 176 additions & 2 deletions src/studio/studio.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ struct Studio
tic_fs* fs;
s32 samplerate;
tic_font systemFont;

Bytebattle bytebattle;
};

#if defined(BUILD_EDITORS)
Expand Down Expand Up @@ -1705,6 +1707,21 @@ static void switchCrtMonitor(Studio* studio)
}
#endif

static u32 getTime()
{
return tic_sys_counter_get() * 1000 / tic_sys_freq_get();
}

static void hideBattleTime(Studio* studio)
{
studio->bytebattle.battle.hidetime = !studio->bytebattle.battle.hidetime;
}

static void startBattle(Studio* studio)
{
studio->bytebattle.battle.started = getTime();
}

#if defined(TIC80_PRO)

static void switchBank(Studio* studio, s32 bank)
Expand Down Expand Up @@ -1850,6 +1867,8 @@ static void processShortcuts(Studio* studio)
}
else if(keyWasPressedOnce(studio, tic_key_f8)) takeScreenshot(studio);
else if(keyWasPressedOnce(studio, tic_key_f9)) startVideoRecord(studio);
else if(keyWasPressedOnce(studio, tic_key_f10)) hideBattleTime(studio);
else if(keyWasPressedOnce(studio, tic_key_f12)) startBattle(studio);
else if(studio->mode == TIC_RUN_MODE && keyWasPressedOnce(studio, tic_key_f7))
setCoverImage(studio);

Expand Down Expand Up @@ -2180,6 +2199,88 @@ static void processMouseStates(Studio* studio)
tic->ram->input.mouse.scrollx *= -1;
}

#if defined(BUILD_EDITORS)
static void doCodeExport(Studio* studio)
{
char pos[sizeof studio->bytebattle.last.postag];
{
s32 x = 0, y = 0;

if(studio->mode != TIC_RUN_MODE)
{
codeGetPos(studio->code, &x, &y);
x++; y++;
}

sprintf(pos, "-- pos: %i,%i\n", x, y);
}

if(strcmp(studio->bytebattle.last.postag, pos) || strcmp(studio->bytebattle.last.code.data, studio->code->src))
{
FILE* file = fopen(studio->bytebattle.exp, "wb");

if(file)
{
strcpy(studio->bytebattle.last.postag, pos);
strcpy(studio->bytebattle.last.code.data, studio->code->src);

fwrite(pos, 1, strlen(pos), file);
fwrite(studio->code->src, 1, strlen(studio->code->src), file);
fclose(file);
}
}
}

static void doCodeImport(Studio* studio)
{
FILE* file = fopen(studio->bytebattle.imp, "rb");

if(file)
{
static tic_code code;
code.data[fread(code.data, 1, sizeof(tic_code), file)] = '\0';

char* end = strchr(code.data, '\n');

if(end)
{
static const char PosTag[] = "-- pos: ";
enum{TagSize = sizeof PosTag - 1};

if(memcmp(code.data, PosTag, TagSize) == 0)
{
char* start = code.data + TagSize;
char* sep = strchr(start, ',');

if(sep)
{
*sep = *end = '\0';
s32 x = atoi(start);
s32 y = atoi(sep + 1);

if(x == 0 && y == 0)
{
if(studio->mode != TIC_RUN_MODE)
runGame(studio);
}
else
{
s32 offset = end - code.data + 1;
memcpy(studio->code->src, code.data + offset, sizeof(tic_code) - offset);
codeSetPos(studio->code, x - 1, y - 1);

if(studio->mode == TIC_RUN_MODE)
setStudioMode(studio, TIC_CODE_MODE);
}
}
}
}

fclose(file);
}
}
#endif

static void blitCursor(Studio* studio)
{
tic_mem* tic = studio->tic;
Expand Down Expand Up @@ -2291,6 +2392,37 @@ void studio_tick(Studio* studio, tic80_input input)

#if defined(BUILD_EDITORS)
tic_net_end(studio->net);

{
Bytebattle* bb = &(studio->bytebattle);
if(bb->battle.started)
{
u32 passed = getTime() - bb->battle.started;
bb->battle.left = bb->battle.time - passed;

if(bb->battle.left > 0)
{
s32 delta = bb->battle.time / (bb->limit.upper - bb->limit.lower);
bb->limit.current = bb->limit.upper - passed / delta;
}
else
{
bb->battle.left = 0;
bb->limit.current = bb->limit.lower;
}
}

if(bb->delay)
if(bb->ticks++ < bb->delay)
return;

if(bb->exp)
doCodeExport(studio);
else if(bb->imp)
doCodeImport(studio);

bb->ticks = 0;
}
#endif
}

Expand Down Expand Up @@ -2394,9 +2526,18 @@ void studio_delete(Studio* studio)
#endif

free(studio->fs);

if(studio->bytebattle.exp) free(studio->bytebattle.exp);
if(studio->bytebattle.imp) free(studio->bytebattle.imp);

free(studio);
}

Bytebattle* getBytebattle(Studio* studio)
{
return studio->bytebattle.exp || studio->bytebattle.imp ? &(studio->bytebattle) : NULL;
}

static StartArgs parseArgs(s32 argc, char **argv)
{
static const char *const usage[] =
Expand All @@ -2405,14 +2546,24 @@ static StartArgs parseArgs(s32 argc, char **argv)
NULL,
};

StartArgs args = {.volume = -1};
StartArgs args = {0};
args.volume = -1;
args.lowerlimit = 256;
args.upperlimit = 512;

struct argparse_option options[] =
{
OPT_HELP(),
#define CMD_PARAMS_DEF(name, ctype, type, post, help) OPT_##type('\0', #name, &args.name, help),
CMD_PARAMS_LIST(CMD_PARAMS_DEF)
#undef CMD_PARAMS_DEF
OPT_GROUP("Byte battle options:\n"),
OPT_STRING('\0', "codeexport", &args.codeexport, "export code to filename"),
OPT_STRING('\0', "codeimport", &args.codeimport, "import code from filename"),
OPT_INTEGER('\0', "delay", &args.delay, "codeexport / codeimport update interval in ticks"),
OPT_INTEGER('\0', "lowerlimit", &args.lowerlimit, "lower limit for code size (256 by default)"),
OPT_INTEGER('\0', "upperlimit", &args.upperlimit, "upper limit for code size (512 by default)"),
OPT_INTEGER('\0', "battletime", &args.battletime, "battletime in minutes"),
OPT_END(),
};

Expand Down Expand Up @@ -2532,6 +2683,8 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f

.samplerate = samplerate,
.net = tic_net_create(TIC_WEBSITE),

.bytebattle = {0},
#endif
.tic = tic_core_create(samplerate, format),
};
Expand Down Expand Up @@ -2631,13 +2784,34 @@ Studio* studio_create(s32 argc, char **argv, s32 samplerate, tic80_pixel_color_f
studio->config->data.soft |= args.soft;
studio->config->data.cli |= args.cli;

if(args.codeexport)
studio->bytebattle.exp = strdup(args.codeexport);
else if(args.codeimport)
studio->bytebattle.imp = strdup(args.codeimport);

studio->bytebattle.delay = args.delay;
studio->bytebattle.limit.lower = args.lowerlimit;

studio->bytebattle.limit.current
= studio->bytebattle.limit.upper
= args.upperlimit;

studio->bytebattle.battle.left
= studio->bytebattle.battle.time
= args.battletime * 60 * 1000;

studioConfigChanged(studio);

if(args.cli)
args.skip = true;

#if defined(BUILD_EDITORS)
if(args.skip)
setStudioMode(studio, TIC_CONSOLE_MODE);
{
studio->console->tick(studio->console);
gotoCode(studio);
}
#endif

return studio;
}
Loading

0 comments on commit b1d765e

Please sign in to comment.