diff --git a/app.c b/app.c index 58a06f8..57711c6 100644 --- a/app.c +++ b/app.c @@ -37,58 +37,9 @@ App *app_NewApp() { player->position->velocity = vec2(0, 0); ADD_COMPONENT(player, hitbox); player->hitbox->box.lefttop = vec2(-20, -80); - player->hitbox->box.size = vec2(40, 80); - entity_Commit(app->entity, player); - Entity *hit1 = entity_Create(app->entity, "hit1"); - ADD_COMPONENT(hit1, hitbox); - hit1->hitbox->box.lefttop = vec2(200, 200); - hit1->hitbox->box.size = vec2(100, 400); - hit1->hitbox->fixed = true; - entity_Commit(app->entity, hit1); - - Entity *hit2 = entity_Create(app->entity, "hit2"); - ADD_COMPONENT(hit2, hitbox); - hit2->hitbox->box.lefttop = vec2(700, 200); - hit2->hitbox->box.size = vec2(100, 400); - hit2->hitbox->fixed = true; - entity_Commit(app->entity, hit2); - - Entity *hit3 = entity_Create(app->entity, "hit3"); - ADD_COMPONENT(hit3, hitbox); - hit3->hitbox->box.lefttop = vec2(100, 550); - hit3->hitbox->box.size = vec2(800, 30); - hit3->hitbox->fixed = true; - entity_Commit(app->entity, hit3); - - Entity *text1 = entity_Create(app->entity, "text_plate_large_1"); - ADD_COMPONENT(text1, position); - text1->position->position = vec2(600, 550); - text1->render = render_NewComponent(app, "info_plate"); - misc_InstantiateTextbox(app, text1, "So long lives this,\nAnd this gives life to thee.", misc_TextboxUpright(110, 110), -220); - entity_Commit(app->entity, text1); - - Entity *text2 = entity_Create(app->entity, "text_plate_1"); - ADD_COMPONENT(text2, position); - text2->position->position = vec2(250, 200); - text2->render = render_NewComponent(app, "info_plate_small_1"); - misc_InstantiateTextbox(app, text2, "Press Space to jump.\nYou can jump again midair.", misc_TextboxUpright(70, 70), -180); - entity_Commit(app->entity, text2); - - Entity *text3 = entity_Create(app->entity, "text_plate_2"); - ADD_COMPONENT(text3, position); - text3->position->position = vec2(750, 200); - text3->render = render_NewComponent(app, "info_plate_small_2"); - misc_InstantiateTextbox(app, text3, "Press ; to dash.\nYou can only dash one time midair.", misc_TextboxUpright(70, 70), -180); - entity_Commit(app->entity, text3); - - Entity *respawn1 = entity_Create(app->entity, "respawn1"); - misc_InstantiateHazardRespawn(app, respawn1, box2(300, 500, 400, 50), vec2(500, 550)); - entity_Commit(app->entity, respawn1); - - Entity *hazard1 = entity_Create(app->entity, "hazard1"); - misc_InstantiateHazard(app, hazard1, box2(800, 545, 100, 5)); - entity_Commit(app->entity, hazard1); + app_QueueLoadLevel(app, "intro.txt"); + _app_SwitchLevel(app); return app; } diff --git a/app_file.c b/app_file.c index 3a73a22..358b6ea 100644 --- a/app_file.c +++ b/app_file.c @@ -1,8 +1,14 @@ #include #include "app.h" +#include "entity.h" +#include "mapper_misc.h" #include "particle.h" +#include "physics.h" +#include "render_component.h" #include "types.h" +#include "util/vector.h" +#include "util/assert.h" void app_QueueLoadLevel(App *app, const char *level_name) { @@ -15,13 +21,140 @@ void app_QueueLoadLevel(App *app, const char *level_name) { #define CMD1(str) if (strcmp(cmd, str) == 0) -#define CMD(str) else if (strcmd(cmd, str) == 0) +#define CMD(str) else if (strcmp(cmd, str) == 0) #define TOKEN (strtok(NULL, " ")) #define TOKEN_INT (atoi(TOKEN)) -#define TOKEN_DOUBLE (strtod(TOKEN)) +#define TOKEN_DOUBLE (strtod(TOKEN, NULL)) + + +static vector_Vector *charbuf; + +static void _app_UnescapeTextbox(char *t) { + ASSERT(t && "only can be called with t!=NULL"); + if (!charbuf) + charbuf = vector_Create(sizeof(char)); + else + vector_Clear(charbuf); + size_t len = strlen(t); + + const char bs = '\\', space = ' ', newline = '\n', tab = '\t', zero = '\0'; + + for (int i = 0; i < len; i++) { + if (t[i] == '\\') { + if (i == len - 1) + vector_Push(charbuf, &bs); // Weird case + else { + if (t[i + 1] == 's') + vector_Push(charbuf, &space); + else if (t[i + 1] == 'n') + vector_Push(charbuf, &newline); + else if (t[i + 1] == 't') + vector_Push(charbuf, &tab); + i++; + } + } else + vector_Push(charbuf, &t[i]); + } + vector_Push(charbuf, &zero); +} + // Subsequent tokens can be read by strtok(NULL, " ") -static void _app_LevelCommand(char *cmd) { +static void _app_LevelCommand(App *app, char *cmd) { + CMD1("HITBOX") { + double a, b, c, d; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + c = TOKEN_DOUBLE; + d = TOKEN_DOUBLE; + + Entity *e = entity_Create(app->entity, NULL); + ADD_COMPONENT(e, hitbox); + e->hitbox->box = box2(a, b, c, d); + e->hitbox->fixed = true; + entity_Commit(app->entity, e); + } + + CMD("PLAYER") { + double a, b; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + + Entity *e = entity_Create(app->entity, NULL); + ADD_COMPONENT(e, player); + e->player->hazardRespawn = vec2(a, b); + ADD_COMPONENT(e, position); + e->position->position = vec2(a, b); + e->position->velocity = vec2(0, 0); + ADD_COMPONENT(e, hitbox); + e->hitbox->box.lefttop = vec2(-20, -80); + e->hitbox->box.size = vec2(40, 80); + entity_Commit(app->entity, e); + } + + CMD("HAZARD_RESPAWN") { + double a, b, c, d, e, f; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + c = TOKEN_DOUBLE; + d = TOKEN_DOUBLE; + e = TOKEN_DOUBLE; + f = TOKEN_DOUBLE; + + Entity *en = entity_Create(app->entity, NULL); + misc_InstantiateHazardRespawn(app, en, box2(a, b, c, d), vec2(e, f)); + entity_Commit(app->entity, en); + } + + CMD("HAZARD") { + double a, b, c, d; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + c = TOKEN_DOUBLE; + d = TOKEN_DOUBLE; + + Entity *e = entity_Create(app->entity, NULL); + misc_InstantiateHazard(app, e, box2(a, b, c, d)); + entity_Commit(app->entity, e); + } + + CMD("TEXTBOX") { + double a, b, c, d; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + c = TOKEN_DOUBLE; + d = TOKEN_DOUBLE; + + Entity *e = entity_Create(app->entity, NULL); + char *bundle = TOKEN; + if (bundle != NULL) + e->render = render_NewComponent(app, bundle); + + // We need to compute a position element + Vec2 position = { + .x = a + c / 2.0, + .y = b + d}; + ADD_COMPONENT(e, position); + e->position->position = position; + e->position->velocity = vec2(0.0, 0.0); + + char *text_raw = TOKEN; + if (text_raw) { + _app_UnescapeTextbox(text_raw); + misc_InstantiateTextbox(app, e, vector_Data(charbuf), box2(-c / 2.0, -d, c, d), (-d - 40)); + } + entity_Commit(app->entity, e); + } + + CMD("LEVEL_TRANSITION") { + // TODO + // Entity *e = entity_Create(app->entity, NULL); + // entity_Commit(app->entity, e); + } + + CMD("CUTOFF") { + app->player->cutoff = TOKEN_DOUBLE; + } } @@ -52,10 +185,11 @@ void _app_SwitchLevel(App *app) { char *cmd = strtok(linebuf, " "); if (cmd == NULL) continue; - _app_LevelCommand(cmd); + _app_LevelCommand(app, cmd); } free(app->switch_level); app->switch_level = NULL; + fclose(f); } diff --git a/intro.txt b/intro.txt index 4ab28ab..e81c9ae 100644 --- a/intro.txt +++ b/intro.txt @@ -12,6 +12,6 @@ HITBOX 2309 392 454 503 TEXTBOX 1566 120 123 134 info_plate_small_1 Press\s';'\sto\sdash,\son\sground\sor\smidair.\nYou\scan\sonly\sdash\s1\stime\smidair. HAZARD 1758 733 600 103 HAZARD_RESPAWN 1492 23 297 242 1706 250 -LEVEL_TRANSITION 2624 853 371 76 level1 +LEVEL_TRANSITION 2624 853 371 76 level1.txt TEXTBOX 2577 264 137 132 info_plate_small_2 Jump\sdown\sto\sthe\snext\slevel.\nNow\scomplete\swith\slevel\stransitions! HAZARD_RESPAWN 2315 41 107 368 2372 392