summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/body.h4
-rw-r--r--src/game.c296
-rw-r--r--src/globals.c1
-rw-r--r--src/globals.h1
-rw-r--r--src/main.c1
-rw-r--r--src/map.c77
-rw-r--r--src/player.h3
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 <SDL2/SDL.h>
+#include <stdio.h>
+#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;