From 51415eee3deaed9e0440855735de6f98a107438c Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Tue, 2 Mar 2021 12:10:42 +0300 Subject: Save on F5, Load on F6! --- src/body.h | 4 +- src/game.c | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/globals.c | 1 + src/globals.h | 1 + src/main.c | 1 + src/map.c | 77 +++++++-------- src/player.h | 3 +- 7 files changed, 340 insertions(+), 43 deletions(-) diff --git a/src/body.h b/src/body.h index fcb15bc..441190e 100644 --- a/src/body.h +++ b/src/body.h @@ -2,6 +2,8 @@ #define TT_INCLUDED_BODY +enum { colact_grib = 1, colact_gulag, colact_instgulag }; + typedef struct tt_body { int x; int y; @@ -14,7 +16,7 @@ typedef struct tt_body { int rem; int anim; int rate; - void (*collision_act)(struct tt_body *b); + int collision_act; char *msg; int msglen; } tt_body; diff --git a/src/game.c b/src/game.c index 8e1afaf..d8a9c53 100644 --- a/src/game.c +++ b/src/game.c @@ -1,6 +1,8 @@ #include "game.h" #include +#include +#include "map.h" #include "globals.h" @@ -8,6 +10,258 @@ int magic = 0; static int ticks; +static char *readline(FILE *f) +{ + int c = fgetc(f); + char *res = 0; + int reslen = 0; + while (c != EOF && c != '\n') { + ++reslen; + res = realloc(res, reslen + 1); + res[reslen - 1] = c; + c = fgetc(f); + } + res[reslen] = 0; + return res; +} + +static void outnum(FILE *f, int n) +{ + if (n) { + if (n < 0) { + fputc('-', f); + n *= -1; + } + int pos = 1; + while (n / pos) pos *= 10; + if (pos > 1) pos /= 10; + while (pos) { + fputc('0' + n / pos, f); + n = n % pos; + pos /= 10; + } + } + fputc('\n', f); +} + +static int readnum(FILE *f) +{ + int sign = 1; + int n = 0; + int c = fgetc(f); + if (c == '-') { + sign = -1; + c = fgetc(f); + } + while (c != EOF && c != '\n') { + n *= 10; + n += c - '0'; + c = fgetc(f); + } + return sign * n; +} + +static void save() +{ + FILE *f = fopen("save", "w"); + if (curmus == grib) fputs("g\n", f); + else if (curmus == ussr) fputs("u\n", f); + else if (curmus == stalin) fputs("s\n", f); + else if (curmus == lenin) fputs("l\n", f); + else fputs("0\n", f); + fputc(ttplayer.room - ttmap, f); + fputc('\n', f); + outnum(f, ttplayer.x); + outnum(f, ttplayer.y); + outnum(f, ttplayer.xrem); + outnum(f, ttplayer.yrem); + outnum(f, ttplayer.variant); + outnum(f, ttplayer.rem); + outnum(f, ttplayer.money); + outnum(f, ttplayer.keys[0]); + outnum(f, ttplayer.keys[1]); + outnum(f, ttplayer.tobein_gulag); + outnum(f, ttplayer.until_gulag); + outnum(f, ttplayer.lenin_pos); + outnum(f, ttplayer.lenin_pos_rem); + outnum(f, ttplayer.lenin_vel); + outnum(f, ttplayer.zhiv_lenin); + outnum(f, ttplayer.lenin_rem); + int i; + for (i = '0'; i != '~'; ++i) { + int p, q; + for (p = 0; p != TT_ROOM_H; ++p) { + for (q = 0; q != TT_ROOM_W; ++q) { + SDL_Rect *r = ttmap[i].floor[p][q]; + if (r) { + fputs("1\n", f); + outnum(f, r->x); + outnum(f, r->y); + outnum(f, r->w); + outnum(f, r->h); + } else fputc('\n', f); + tt_body *w = ttmap[i].walls[p][q]; + if (w) { + fputs("1\n", f); + outnum(f, w->x); + outnum(f, w->y); + outnum(f, w->xrem); + outnum(f, w->yrem); + outnum(f, w->xvel); + outnum(f, w->yvel); + outnum(f, w->txrrow); + outnum(f, w->txrcol); + outnum(f, w->rem); + outnum(f, w->anim); + outnum(f, w->rate); + outnum(f, w->collision_act); + outnum(f, w->msglen); + if (w->msg) fputs(w->msg, f); + fputc('\n', f); + } else fputc('\n', f); + } + } + outnum(f, ttmap[i].bodies_count); + for (p = 0; p != ttmap[i].bodies_count; ++p) { + tt_body *b = ttmap[i].bodies + p; + outnum(f, b->x); + outnum(f, b->y); + outnum(f, b->xrem); + outnum(f, b->yrem); + outnum(f, b->xvel); + outnum(f, b->yvel); + outnum(f, b->txrrow); + outnum(f, b->txrcol); + outnum(f, b->rem); + outnum(f, b->anim); + outnum(f, b->rate); + outnum(f, b->collision_act); + outnum(f, b->msglen); + if (b->msg) fputs(b->msg, f); + fputc('\n', f); + } + fputc(ttmap[i].neighbours[0] - ttmap, f); + fputc(ttmap[i].neighbours[1] - ttmap, f); + fputc(ttmap[i].neighbours[2] - ttmap, f); + fputc(ttmap[i].neighbours[3] - ttmap, f); + fputc('\n', f); + } +} + +static void load() +{ + FILE *f = fopen("save", "r"); + int c = fgetc(f); + if (c == 'g') { + if (curmus != grib) { + curmus = grib; + Mix_PlayMusic(grib, -1); + } + } else if (c == 'u') { + if (curmus != ussr) { + curmus = ussr; + Mix_PlayMusic(ussr, -1); + } + } else if (c == 's') { + if (curmus != stalin) { + curmus = stalin; + Mix_PlayMusic(stalin, -1); + } + } else if (c == 'l') { + if (curmus != lenin) { + curmus = lenin; + Mix_PlayMusic(lenin, -1); + } + } else { + curmus = 0; + Mix_PauseMusic(); + } + fgetc(f); + ttplayer.room = ttmap + fgetc(f); + fgetc(f); + ttplayer.x = readnum(f); + ttplayer.y = readnum(f); + ttplayer.xrem = readnum(f); + ttplayer.yrem = readnum(f); + ttplayer.variant = readnum(f); + ttplayer.rem = readnum(f); + ttplayer.money = readnum(f); + ttplayer.keys[0] = readnum(f); + ttplayer.keys[1] = readnum(f); + ttplayer.tobein_gulag = readnum(f); + ttplayer.until_gulag = readnum(f); + ttplayer.lenin_pos = readnum(f); + ttplayer.lenin_pos_rem = readnum(f); + ttplayer.lenin_vel = readnum(f); + ttplayer.zhiv_lenin = readnum(f); + ttplayer.lenin_rem = readnum(f); + tt_map_free(); + int i; + for (i = '0'; i != '~'; ++i) { + int p, q; + for (p = 0; p != TT_ROOM_H; ++p) { + for (q = 0; q != TT_ROOM_W; ++q) { + if (readnum(f)) { + ttmap[i].floor[p][q] = malloc(sizeof(SDL_Rect)); + ttmap[i].floor[p][q]->x = readnum(f); + ttmap[i].floor[p][q]->y = readnum(f); + ttmap[i].floor[p][q]->w = readnum(f); + ttmap[i].floor[p][q]->h = readnum(f); + } else ttmap[i].floor[p][q] = 0; + if (readnum(f)) { + tt_body *b = ttmap[i].walls[p][q] = malloc(sizeof(*b)); + b->x = readnum(f); + b->y = readnum(f); + b->xrem = readnum(f); + b->yrem = readnum(f); + b->xvel = readnum(f); + b->yvel = readnum(f); + b->txrrow = readnum(f); + b->txrcol = readnum(f); + b->rem = readnum(f); + b->anim = readnum(f); + b->rate = readnum(f); + b->collision_act = readnum(f); + b->msglen = readnum(f); + if (b->msglen) b->msg = readline(f); + else { + b->msg = 0; + fgetc(f); + } + } else ttmap[i].walls[p][q] = 0; + } + } + ttmap[i].bodies_count = readnum(f); + ttmap[i].bodies = malloc(ttmap[i].bodies_count * sizeof(tt_body)); + for (p = 0; p != ttmap[i].bodies_count; ++p) { + tt_body *b = ttmap[i].bodies + p; + b->x = readnum(f); + b->y = readnum(f); + b->xrem = readnum(f); + b->yrem = readnum(f); + b->xvel = readnum(f); + b->yvel = readnum(f); + b->txrrow = readnum(f); + b->txrcol = readnum(f); + b->rem = readnum(f); + b->anim = readnum(f); + b->rate = readnum(f); + b->collision_act = readnum(f); + b->msglen = readnum(f); + if (b->msglen) b->msg = readline(f); + else { + b->msg = 0; + fgetc(f); + } + } + ttmap[i].neighbours[0] = ttmap + fgetc(f); + ttmap[i].neighbours[1] = ttmap + fgetc(f); + ttmap[i].neighbours[2] = ttmap + fgetc(f); + ttmap[i].neighbours[3] = ttmap + fgetc(f); + fgetc(f); + } +} + static const char *gulagmsg = " GULAG HAS YOU"; static void directly_gulag(tt_body *b) @@ -15,6 +269,32 @@ static void directly_gulag(tt_body *b) gulagmsg = " Communism is Indestructable"; magic = tt_gotogulag; Mix_PlayMusic(ussr, -1); + curmus = ussr; +} + +static void togulag(tt_body *b) +{ + ttplayer.tobein_gulag = 1; + b->collision_act = 0; + b->anim = 1; + b->txrrow = 0; + b->txrcol = 15; + b->msg = 0; + b->msglen = 0; +} + +static void gribtake(tt_body *b) +{ + curmus = grib; + Mix_PlayMusic(grib, -1); + b->collision_act = 0; + b->anim = 1; + b->txrrow = 0; + b->txrcol = 15; + b->msg = 0; + b->msglen = 0; + ttplayer.variant = 1; + magic = tt_gotofirstroom; } static void step(int d) @@ -54,7 +334,7 @@ static void step(int d) b->txrcol = rand() % 4; b->anim = 4; b->rate = 150 + (rand() % 50 - 25); - b->collision_act = directly_gulag; + b->collision_act = colact_instgulag; b->msg = 0; b->msglen = 0; b->yvel = rand() % 100 - 50; @@ -69,11 +349,13 @@ static void step(int d) if (first_gulag) { first_gulag = 0; Mix_PlayMusic(stalin, -1); + curmus = stalin; } ttplayer.until_gulag -= d; if (ttplayer.until_gulag <= 0) { magic = tt_gotogulag; Mix_PlayMusic(ussr, -1); + curmus = ussr; } } if (xw && yw) { @@ -95,6 +377,7 @@ static void step(int d) if (out) { if (ttplayer.room->neighbours[out - 1] == ttmap + 'L') { Mix_PauseMusic(); + curmus = 0; magic = tt_mausoleum; } else { magic = tt_changeroom + out - 1; @@ -115,7 +398,13 @@ static void step(int d) for (i = 0; i != ttplayer.room->bodies_count; ++i) { tt_body *b = ttplayer.room->bodies + i; SDL_Rect body = { 4 + b->x, 4 + b->y, 24, 24 }; - if (SDL_HasIntersection(&body, &box)) b->collision_act(b); + if (SDL_HasIntersection(&body, &box)) { + switch (b->collision_act) { + case colact_grib: gribtake(b); break; + case colact_gulag: togulag(b); break; + case colact_instgulag: directly_gulag(b); break; + } + } } } } @@ -326,6 +615,7 @@ static void mausoleum() ticks = newticks; newticks = SDL_GetTicks(); Mix_PlayMusic(lenin, -1); + curmus = lenin; while (!q && newticks < ticks + 14300) { int delta = newticks - ticks; SDL_Event e; @@ -561,6 +851,8 @@ void tt_mainloop() else if (code == SDL_SCANCODE_RIGHT) arrr = 1; else if (code == SDL_SCANCODE_DOWN) arrd = 1; else if (code == SDL_SCANCODE_LEFT) arrl = 1; + else if (code == SDL_SCANCODE_F5) save(); + else if (code == SDL_SCANCODE_F6) load(); } else if (e.type == SDL_KEYUP) { int code = e.key.keysym.scancode; if (code == SDL_SCANCODE_W) keyw = 0; diff --git a/src/globals.c b/src/globals.c index 19875b2..69dd671 100644 --- a/src/globals.c +++ b/src/globals.c @@ -11,6 +11,7 @@ Mix_Music *grib; Mix_Music *ussr; Mix_Music *stalin; Mix_Music *lenin; +Mix_Music *curmus; tt_room ttmap[256]; diff --git a/src/globals.h b/src/globals.h index 5cb13fc..c17732c 100644 --- a/src/globals.h +++ b/src/globals.h @@ -19,6 +19,7 @@ extern Mix_Music *grib; extern Mix_Music *ussr; extern Mix_Music *stalin; extern Mix_Music *lenin; +extern Mix_Music *curmus; extern tt_room ttmap[256]; diff --git a/src/main.c b/src/main.c index 8bf0bc9..60fd479 100644 --- a/src/main.c +++ b/src/main.c @@ -34,6 +34,7 @@ int main(int argc, char **argv) ussr = Mix_LoadMUS("data/ussr.ogg"); stalin = Mix_LoadMUS("data/stalin.ogg"); lenin = Mix_LoadMUS("data/lenin.ogg"); + curmus = 0; tt_map_load(); srand(time(0)); diff --git a/src/map.c b/src/map.c index 091a7a9..dc3b114 100644 --- a/src/map.c +++ b/src/map.c @@ -28,32 +28,6 @@ static SDL_Rect *newtile(int row, int col) return r; } -static void do_nothing(tt_body *b) -{} - -static void togulag(tt_body *b) -{ - ttplayer.tobein_gulag = 1; - b->collision_act = do_nothing; - b->anim = 1; - b->txrrow = 0; - b->txrcol = 15; - b->msg = 0; - b->msglen = 0; -} - -static void gribtake(tt_body *b) -{ - Mix_PlayMusic(grib, -1); - b->collision_act = do_nothing; - b->anim = 1; - b->txrrow = 0; - b->txrcol = 15; - b->msg = 0; - b->msglen = 0; - ttplayer.variant = 1; - magic = tt_gotofirstroom; -} static void loadroom(tt_room *r, FILE *f) { @@ -84,8 +58,8 @@ static void loadroom(tt_room *r, FILE *f) ttplayer.ywalk = 0; ttplayer.rem = 0; ttplayer.money = 0; - ttplayer.keys = 0; - ttplayer.the_key = 0; + ttplayer.keys[0] = 0; + ttplayer.keys[1] = 0; ttplayer.lenin_pos = 32 * 9; ttplayer.lenin_pos_rem = 0; ttplayer.zhiv_lenin = 0; @@ -109,7 +83,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 1; b->rate = 1; - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == 'b') { @@ -126,7 +100,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 1; b->rate = 1; - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == 'r') { @@ -143,7 +117,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 1; b->rate = 1; - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == 'g') { @@ -163,7 +137,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 4; b->rate = 150 + (rand() % 50 - 25); - b->collision_act = gribtake; + b->collision_act = colact_grib; b->msg = 0; b->msglen = 0; } else if (type == '^') { @@ -181,7 +155,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 4; b->rate = 150 + (rand() % 50 - 25); - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == ';') { @@ -199,7 +173,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 1; b->rate = 100; - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == '.') { @@ -218,7 +192,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 4; b->rate = 150 + (rand() % 50 - 25); - b->collision_act = do_nothing; + b->collision_act = 0; b->msg = 0; b->msglen = 0; } else if (type == '=') { @@ -236,7 +210,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = 15; b->anim = 1; b->rate = 100; - b->collision_act = do_nothing; + b->collision_act = 0; } else if (type == '$') { r->floor[i][j] = newtile(0, default_floor_id); r->bodies_count++; @@ -252,7 +226,7 @@ static void loadroom(tt_room *r, FILE *f) b->txrcol = id; b->anim = 4; b->rate = 100 + (rand() % 50 - 25); - b->collision_act = togulag; + b->collision_act = colact_gulag; } } fgetc(f); @@ -286,6 +260,21 @@ void tt_map_load() if (roomf) { loadroom(ttmap + r, roomf); fclose(roomf); + } else { + int m = r; + int i, j; + for (i = 0; i != TT_ROOM_H; ++i) { + for (j = 0; j != TT_ROOM_W; ++j) { + ttmap[m].floor[i][j] = 0; + ttmap[m].walls[i][j] = 0; + } + } + ttmap[m].bodies_count = 0; + ttmap[m].bodies = 0; + ttmap[m].neighbours[0] = ttmap + '.'; + ttmap[m].neighbours[1] = ttmap + '.'; + ttmap[m].neighbours[2] = ttmap + '.'; + ttmap[m].neighbours[3] = ttmap + '.'; } ++r; } @@ -294,5 +283,17 @@ void tt_map_load() void tt_map_free() { - return; + int i; + for (i = '0'; i != '~'; ++i) { + int p, q; + for (p = 0; p != TT_ROOM_H; ++p) { + for (q = 0; q != TT_ROOM_W; ++q) { + void *x = ttmap[i].floor[p][q]; + if (x) free(x); + x = ttmap[i].walls[p][q]; + if (x) free(x); + } + } + if (ttmap[i].bodies) free(ttmap[i].bodies); + } } diff --git a/src/player.h b/src/player.h index fca14e6..ea1b687 100644 --- a/src/player.h +++ b/src/player.h @@ -16,8 +16,7 @@ typedef struct tt_player { int variant; int rem; int money; - int keys; - int the_key; + int keys[2]; int tobein_gulag; int until_gulag; -- cgit v1.2.3