summaryrefslogtreecommitdiff
path: root/src/map.c
blob: 60bc0fc6f4501ea92b2ea772b25bd58bb741535d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#include "map.h"

#include "game.h"
#include "globals.h"
#include "room.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_mixer.h>
#include <stdio.h>

static int readnum(FILE *f)
{
    int neg = fgetc(f) == '-';
    int num = fgetc(f) - '0';
    num *= 10;
    num += fgetc(f) - '0';
    num *= 10;
    num += fgetc(f) - '0';
    return (neg ? -1 : 1) * num;
}

static SDL_Rect *newtile(int row, int col)
{
    SDL_Rect *r = malloc(sizeof(*r));
    r->x        = 16 * col;
    r->y        = 16 * row;
    r->h = r->w = 16;
    return r;
}

static void loadroom(tt_room *r, FILE *f)
{
    int default_floor_id = fgetc(f);
    if (default_floor_id < 'a') default_floor_id -= '0';
    else
        default_floor_id = default_floor_id - 'a' + 10;
    fgetc(f);
    int i, j;
    for (i = 0; i != 4; ++i) r->neighbours[i] = ttmap + fgetc(f);
    r->bodies       = 0;
    r->bodies_count = 0;
    fgetc(f);
    for (i = 0; i != TT_ROOM_H; ++i) {
        for (j = 0; j != TT_ROOM_W; ++j) {
            int type = fgetc(f);
            int id   = fgetc(f);
            int c    = id;
            if (id == ' ') id = '0';
            if (id < 'a') id -= '0';
            else
                id = id - 'a' + 10;
            r->floor[i][j] = 0;
            r->walls[i][j] = 0;
            if (type == '@') {
                ttplayer.room          = r;
                ttplayer.x             = j * 32;
                ttplayer.y             = i * 32;
                ttplayer.xrem          = 0;
                ttplayer.yrem          = 0;
                ttplayer.xwalk         = 0;
                ttplayer.ywalk         = 0;
                ttplayer.rem           = 0;
                ttplayer.money         = 0;
                ttplayer.keys[0]       = 0;
                ttplayer.keys[1]       = 0;
                ttplayer.lenin_pos     = 32 * 9;
                ttplayer.lenin_pos_rem = 0;
                ttplayer.lenin_zhiv    = 0;
                ttplayer.lenin_rem     = 0;
                ttplayer.lenin_vel     = -53;
                ttplayer.variant       = 0;
                ttplayer.tobein_gulag  = 0;
                ttplayer.until_gulag   = 5300;
                r->floor[i][j]         = newtile(0, default_floor_id);
            } else if (type == 'y') {
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 2;
                b->txrcol        = id;
                b->anim          = 1;
                b->rate          = 1;
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == 'b') {
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 3;
                b->txrcol        = id;
                b->anim          = 1;
                b->rate          = 1;
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == 'r') {
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 1;
                b->txrcol        = id;
                b->anim          = 1;
                b->rate          = 1;
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == 'g') {
                r->floor[i][j] = newtile(0, default_floor_id);
                r->bodies_count++;
                r->bodies =
                    realloc(r->bodies, sizeof(tt_body) * r->bodies_count);
                tt_body *b       = r->bodies + r->bodies_count - 1;
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 7;
                b->txrcol        = id;
                b->anim          = 4;
                b->rate          = 150 + (rand() % 50 - 25);
                b->collision_act = colact_grib;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == '^') {
                r->floor[i][j]   = newtile(0, default_floor_id);
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 7;
                b->txrcol        = id;
                b->anim          = 4;
                b->rate          = 150 + (rand() % 50 - 25);
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == ';') {
                r->floor[i][j]   = newtile(0, default_floor_id);
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 9;
                b->txrcol        = id;
                b->anim          = 1;
                b->rate          = 100;
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == '.') {
                r->floor[i][j] = newtile(0, c == ' ' ? default_floor_id : id);
            } else if (type == '*') {
                r->walls[i][j]   = malloc(sizeof(tt_body));
                tt_body *b       = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 8;
                b->txrcol        = id;
                b->anim          = 4;
                b->rate          = 150 + (rand() % 50 - 25);
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == '=') {
                r->floor[i][j] = newtile(0, default_floor_id);
                r->bodies_count++;
                r->bodies =
                    realloc(r->bodies, sizeof(tt_body) * r->bodies_count);
                tt_body *b       = r->bodies + r->bodies_count - 1;
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->rem           = 0;
                b->txrrow        = 0;
                b->txrcol        = 15;
                b->anim          = 1;
                b->rate          = 100;
                b->collision_act = 0;
                b->isdoor        = 0;
            } else if (type == 'k' || type == 'K') {
                r->floor[i][j] = newtile(0, default_floor_id);
                r->bodies_count++;
                r->bodies =
                    realloc(r->bodies, sizeof(tt_body) * r->bodies_count);
                tt_body *b       = r->bodies + r->bodies_count - 1;
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->rem           = 0;
                b->txrrow        = 10;
                b->txrcol        = id + (type == 'K');
                b->anim          = 1;
                b->rate          = 100;
                b->collision_act = colact_key;
                b->isdoor        = 0;
            } else if (type == 'd' || type == 'D') {
                r->floor[i][j] = newtile(0, default_floor_id);
                r->bodies_count++;
                r->bodies =
                    realloc(r->bodies, sizeof(tt_body) * r->bodies_count);
                tt_body *b       = r->bodies + r->bodies_count - 1;
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->rem           = 0;
                b->txrrow        = 4;
                b->txrcol        = id + 8 * (type == 'D');
                b->anim          = 1;
                b->rate          = 100;
                b->collision_act = colact_door;
                b->isdoor        = 1;
                r->walls[i][j]   = malloc(sizeof(tt_body));
                b                = r->walls[i][j];
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->xvel          = 0;
                b->yvel          = 0;
                b->rem           = 0;
                b->txrrow        = 0;
                b->txrcol        = 15;
                b->anim          = 1;
                b->rate          = 100;
                b->collision_act = 0;
                b->isdoor        = 0;
                b->msg           = 0;
                b->msglen        = 0;
            } else if (type == '$') {
                r->floor[i][j] = newtile(0, default_floor_id);
                r->bodies_count++;
                r->bodies =
                    realloc(r->bodies, sizeof(tt_body) * r->bodies_count);
                tt_body *b       = r->bodies + r->bodies_count - 1;
                b->x             = j * 32;
                b->y             = i * 32;
                b->xrem          = 0;
                b->yrem          = 0;
                b->rem           = 0;
                b->txrrow        = 6;
                b->txrcol        = id;
                b->anim          = 4;
                b->rate          = 100 + (rand() % 50 - 25);
                b->collision_act = colact_gulag;
                b->isdoor        = 0;
            }
        }
        fgetc(f);
    }
    for (i = 0; i != r->bodies_count; ++i) {
        r->bodies[i].yvel   = readnum(f);
        r->bodies[i].xvel   = readnum(f);
        r->bodies[i].msg    = 0;
        r->bodies[i].msglen = 0;
        if (fgetc(f) == '=') {
            int c = fgetc(f);
            while (c != EOF && c != '\n') {
                r->bodies[i].msglen++;
                r->bodies[i].msg =
                    realloc(r->bodies[i].msg, r->bodies[i].msglen + 1);
                r->bodies[i].msg[r->bodies[i].msglen - 1] = c;
                c                                         = fgetc(f);
            }
            r->bodies[i].msg[r->bodies[i].msglen] = 0;
        }
    }
}

void tt_map_load()
{
    char path[] = "data/map/0";
    char r      = '0';
    while (r != '~') {
        path[9]     = r;
        FILE *roomf = fopen(path, "r");
        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;
    }
}

void 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) {
                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);
    }
}