X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fmap.c;h=d70a4fb3cce021c46cf39b16140f794106ddf0c7;hb=HEAD;hp=7071dd4fe5fd0dcc6583e7a6f89b4a7afc6a8a76;hpb=4a99fe51561ca331df54512eb25c502d0fcd2b55;p=flatwaifu.git diff --git a/src/map.c b/src/map.c index 7071dd4..d70a4fb 100644 --- a/src/map.c +++ b/src/map.c @@ -1,3 +1,20 @@ +/* Copyright (C) 1996-1997 Aleksey Volynskov + * Copyright (C) 2011 Rambo + * Copyright (C) 2020 SovietPony + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License ONLY. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include "map.h" #include "game.h" @@ -8,14 +25,16 @@ #include "view.h" #include "music.h" -#include "files.h" #include "render.h" -#include #include -#include "my.h" +#include #include "error.h" +#include "common/streams.h" +#include "common/files.h" +#include "common/cp866.h" + enum { MB_COMMENT = -1, MB_END = 0, MB_WALLNAMES, MB_BACK, MB_WTYPE, MB_FRONT, MB_THING, MB_SWITCH, @@ -43,10 +62,10 @@ typedef struct old_thing_t { static map_block_t blk; -static int G_load (FILE *h) { +static int G_load (Stream *h) { switch (blk.t) { case MB_MUSIC: - myfread(g_music, 8, 1, h); + stream_read(g_music, 8, 1, h); //if (music_random) { // F_randmus(g_music); //} @@ -56,16 +75,16 @@ static int G_load (FILE *h) { return 0; } -static int IT_load (FILE *h) { +static int IT_load (Stream *h) { int m, i, j; old_thing_t t; switch (blk.t) { case MB_THING: for (i = 0; blk.sz > 0; ++i, blk.sz -= 8) { - t.x = myfread16(h); - t.y = myfread16(h); - t.t = myfread16(h); - t.f = myfread16(h); + t.x = stream_read16(h); + t.y = stream_read16(h); + t.t = stream_read16(h); + t.f = stream_read16(h); it[i].o.x = t.x; it[i].o.y = t.y; it[i].t = t.t; @@ -83,7 +102,8 @@ static int IT_load (FILE *h) { } if (!g_dm) { if (j == -1) { - ERR_fatal("Предмет игрок_1 не найден"); + logo("Player 1 point not exists on the map\n"); + return 0; // error } dm_pos[0].x = it[j].o.x; dm_pos[0].y = it[j].o.y; @@ -97,7 +117,8 @@ static int IT_load (FILE *h) { } if (!g_dm && _2pl) { if (j == -1) { - ERR_fatal("Предмет игрок_2 не найден"); + logo("Player 2 point not exists on the map\n"); + return 0; // error } dm_pos[1].x = it[j].o.x; dm_pos[1].y = it[j].o.y; @@ -115,7 +136,8 @@ static int IT_load (FILE *h) { } } if (g_dm && j < 2) { - ERR_fatal("Меньше 2-ух точек DM"); + logo("Required at least two DM points on the map\n"); + return 0; // error } if (g_dm) { dm_pnum = j; @@ -149,21 +171,21 @@ static int IT_load (FILE *h) { return 0; } -static int SW_load (FILE *h) { +static int SW_load (Stream *h) { int i; switch(blk.t) { case MB_SWITCH2: sw_secrets = 0; for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) { - sw[i].x = myfread8(h); - sw[i].y = myfread8(h); - sw[i].t = myfread8(h); - sw[i].tm = myfread8(h); // unused - sw[i].a = myfread8(h); - sw[i].b = myfread8(h); - sw[i].c = myfread8(h); - sw[i].d = myfread8(h); // unused - sw[i].f = myfread8(h); + sw[i].x = stream_read8(h); + sw[i].y = stream_read8(h); + sw[i].t = stream_read8(h); + sw[i].tm = stream_read8(h); // unused + sw[i].a = stream_read8(h); + sw[i].b = stream_read8(h); + sw[i].c = stream_read8(h); + sw[i].d = stream_read8(h); // unused + sw[i].f = stream_read8(h); sw[i].tm = 0; sw[i].d = 0; sw[i].f |= 0x80; @@ -195,18 +217,19 @@ static void unpack (void *buf, int len, void *obuf) { } } -static int read_array (void *p, FILE *h) { +static int read_array (void *p, Stream *h) { void *buf; switch (blk.st) { case 0: - myfread(p, FLDW * FLDH, 1, h); + stream_read(p, FLDW * FLDH, 1, h); break; case 1: buf = malloc(blk.sz); if (buf == NULL) { - ERR_fatal("Не хватает памяти"); + logo("Out of memory\n"); + return 0; // error } - myfread(buf, blk.sz, 1, h); + stream_read(buf, blk.sz, 1, h); unpack(buf, blk.sz, p); free(buf); break; @@ -216,7 +239,7 @@ static int read_array (void *p, FILE *h) { return 1; } -static int W_load (FILE *h) { +static int W_load (Stream *h) { int i; char s[8]; switch (blk.t) { @@ -224,10 +247,10 @@ static int W_load (FILE *h) { R_begin_load(); memset(walf, 0, sizeof(walf)); for (i = 1; i < 256 && blk.sz > 0; i++, blk.sz -= 9) { - myfread(s, 8, 1, h); - walf[i] = myfread8(h) ? 1 : 0; // ??? + stream_read(s, 8, 1, h); + walf[i] = stream_read8(h) ? 1 : 0; // ??? R_load(s); - if (strncasecmp(s, "VTRAP01", 8) == 0) { + if (cp866_strncasecmp(s, "VTRAP01", 8) == 0) { walf[i] |= 2; } } @@ -240,47 +263,60 @@ static int W_load (FILE *h) { case MB_FRONT: return read_array(fldf, h); case MB_SKY: - sky_type = myfread16(h); + sky_type = stream_read16(h); R_loadsky(sky_type); return 1; } return 0; } -void F_loadmap (char n[8]) { - int r, o; - FILE *h; +int MAP_load (Stream *r) { + int ok = 0; + long off; map_header_t hdr; - W_init(); - r = F_getresid(n); - h = wadh[wad[r].f]; - fseek(h, wad[r].o, SEEK_SET); - myfread(hdr.id, 8, 1, h); - hdr.ver = myfread16(h); - if (memcmp(hdr.id, "Doom2D\x1A", 8) != 0) { - ERR_fatal("%.8s не является уровнем", n); - } - for (;;) { - blk.t = myfread16(h); - blk.st = myfread16(h); - blk.sz = myfread32(h); - if(blk.t == MB_END) { - break; - } - if(blk.t == MB_COMMENT) { - fseek(h, blk.sz, SEEK_CUR); - continue; - } - o = ftell(h) + blk.sz; - if(!G_load(h)) { - if(!W_load(h)) { - if(!IT_load(h)) { - if(!SW_load(h)) { - ERR_fatal("Неизвестный блок %d(%d) в уровне %.8s", blk.t, blk.st, n); - } - } + assert(r != NULL); + W_init(); // reset all game data + stream_read(hdr.id, 8, 1, r); + hdr.ver = stream_read16(r); + if (memcmp(hdr.id, "Doom2D\x1A", 8) == 0) { + ok = 1; + while (ok) { + blk.t = stream_read16(r); + blk.st = stream_read16(r); + blk.sz = stream_read32(r); + off = stream_getpos(r) + blk.sz; + switch (blk.t) { + case MB_MUSIC: + ok = G_load(r); + break; + case MB_WALLNAMES: + case MB_BACK: + case MB_WTYPE: + case MB_FRONT: + case MB_SKY: + ok = W_load(r); + break; + case MB_THING: + ok = IT_load(r); + break; + case MB_SWITCH2: + ok = SW_load(r); + break; + case MB_COMMENT: + /* skip */ + break; + case MB_END: + return ok; + default: + logo("Unknown block %d(%d)\n", blk.t, blk.st); + return 0; // error } + stream_setpos(r, off); } - fseek(h, o, SEEK_SET); + } else { + logo("Invalid map header\n"); + abort(); + ok = 0; } + return ok; }