From: DeaDDooMER Date: Fri, 24 Apr 2020 06:58:48 +0000 (+0400) Subject: map: move map loading to separate file X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=efb17348438f10c929e2e9807013969f71802661;p=flatwaifu.git map: move map loading to separate file --- diff --git a/src/files.c b/src/files.c index 47aaa71..f8543ff 100644 --- a/src/files.c +++ b/src/files.c @@ -47,7 +47,8 @@ typedef struct { int d_start, d_end; mwad_t wad[MAX_WAD]; -map_block_t blk; +char wads[MAX_WADS][__MAX_PATH]; +FILE* wadh[MAX_WADS]; static byte seq[255]; static byte seqn; @@ -60,9 +61,6 @@ static int m_start, m_end; static int s_start, s_end; static int wad_num; -static char wads[MAX_WADS][__MAX_PATH]; -static FILE* wadh[MAX_WADS]; - static char f_drive[__MAX_DRIVE]; static char f_dir[__MAX_DIR]; static char f_name[__MAX_FNAME]; @@ -355,44 +353,6 @@ void F_readstrz (FILE* h,char *s,int m) { } */ -void F_loadmap (char n[8]) { - int r, o; - FILE *h; - 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); - } - } - } - } - fseek(h, o, SEEK_SET); - } -} - /*void F_freemus(void) { int i; diff --git a/src/files.h b/src/files.h index ee1b8bb..66896ed 100644 --- a/src/files.h +++ b/src/files.h @@ -44,7 +44,8 @@ typedef struct { extern int d_start, d_end; extern mwad_t wad[MAX_WAD]; -extern map_block_t blk; +extern char wads[MAX_WADS][__MAX_PATH]; +extern FILE* wadh[MAX_WADS]; void F_startup (void); void F_addwad (const char *fn); @@ -59,6 +60,5 @@ int F_getreslen (int r); void F_nextmus (char *s); void F_randmus (char *s); void F_readstr (FILE* h, char *s, int m); -void F_loadmap (char n[8]); #endif /* FILES_H_INCLUDED */ diff --git a/src/game.c b/src/game.c index 3ba9f41..8510833 100644 --- a/src/game.c +++ b/src/game.c @@ -95,19 +95,6 @@ static void set_trans(int st) { g_trans=1;g_transt=0; } -int G_load (FILE *h) { - switch (blk.t) { - case MB_MUSIC: - myfread(g_music, 8, 1, h); - if (music_random) { - F_randmus(g_music); - } - F_loadmus(g_music); - return 1; - } - return 0; -} - void load_game (int n) { F_freemus(); W_init(); diff --git a/src/game.h b/src/game.h index f4f1a70..adbc757 100644 --- a/src/game.h +++ b/src/game.h @@ -4,7 +4,6 @@ #include "glob.h" #include "view.h" // pos_t #include "player.h" // player_t -#include // FILE extern byte transdraw; extern byte _2pl; @@ -27,7 +26,6 @@ extern int lt_ypos; extern int g_trans; -int G_load (FILE *h); void load_game (int n); void G_start (void); void G_init (void); diff --git a/src/items.c b/src/items.c index 65f39e2..32c4af5 100644 --- a/src/items.c +++ b/src/items.c @@ -68,99 +68,6 @@ void IT_init (void) { rsndtm = 0; } -int IT_load (FILE *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); - it[i].o.x = t.x; - it[i].o.y = t.y; - it[i].t = t.t; - it[i].s = t.f; - if (it[i].t && (it[i].s & THF_DM) && !g_dm) { - it[i].t=0; - } - } - m = i; - for (i = 0, j = -1; i < m; ++i) { - if (it[i].t == TH_PLR1) { - j = i; - it[i].t = 0; - } - } - if (!g_dm) { - if (j == -1) { - ERR_fatal("Предмет игрок_1 не найден"); - } - dm_pos[0].x = it[j].o.x; - dm_pos[0].y = it[j].o.y; - dm_pos[0].d = it[j].s & THF_DIR; - } - for (i = 0, j = -1; i < m; ++i) { - if (it[i].t == TH_PLR2) { - j = i; - it[i].t = 0; - } - } - if (!g_dm && _2pl) { - if (j == -1) { - ERR_fatal("Предмет игрок_2 не найден"); - } - dm_pos[1].x = it[j].o.x; - dm_pos[1].y = it[j].o.y; - dm_pos[1].d = it[j].s & THF_DIR; - } - for (i = 0, j = 0; i < m; ++i) { - if (it[i].t == TH_DMSTART) { - if (g_dm) { - dm_pos[j].x = it[i].o.x; - dm_pos[j].y = it[i].o.y; - dm_pos[j].d = it[i].s & THF_DIR; - } - it[i].t = 0; - ++j; - } - } - if (g_dm && j < 2) { - ERR_fatal("Меньше 2-ух точек DM"); - } - if (g_dm) { - dm_pnum = j; - dm_pl1p = myrand(dm_pnum); - do { - dm_pl2p = myrand(dm_pnum); - } while (dm_pl2p == dm_pl1p); - } else { - dm_pl1p = 0; - dm_pl2p = 1; - dm_pnum = 2; - } - PL_spawn(&pl1, dm_pos[dm_pl1p].x, dm_pos[dm_pl1p].y, dm_pos[dm_pl1p].d); - if (_2pl) { - PL_spawn(&pl2, dm_pos[dm_pl2p].x, dm_pos[dm_pl2p].y, dm_pos[dm_pl2p].d); - } - for (i = 0; i < m; ++i) { - if (it[i].t >= TH_CLIP && it[i].t < TH_DEMON) { - it[i].s = 0; - it[i].t = it[i].t - TH_CLIP + I_CLIP; - if (it[i].t >= I_KEYR && it[i].t <= I_KEYB) { - it[i].t |= 0x8000; - } - } else if (it[i].t >= TH_DEMON) { - MN_spawn(it[i].o.x, it[i].o.y, it[i].s & THF_DIR, it[i].t - TH_DEMON + MN_DEMON); - it[i].t = 0; - } - } - return 1; - } - return 0; -} - static void takesnd (int t) { if(tsndtm) return; t&=0x7FFF; diff --git a/src/items.h b/src/items.h index 011188a..bebb46d 100644 --- a/src/items.h +++ b/src/items.h @@ -44,7 +44,6 @@ extern int itm_rtime; void IT_alloc (void); void IT_init (void); -int IT_load (FILE *h); void IT_act (void); void IT_spawn (int x, int y, int t); void IT_drop_ammo (int t, int n, int x, int y); diff --git a/src/map.c b/src/map.c new file mode 100644 index 0000000..dfc7b70 --- /dev/null +++ b/src/map.c @@ -0,0 +1,286 @@ +#include "map.h" + +#include "game.h" +#include "items.h" +#include "things.h" +#include "monster.h" +#include "switch.h" +#include "view.h" + +#include "music.h" +#include "files.h" +#include "render.h" + +#include +#include +#include "my.h" +#include "error.h" + +enum { + MB_COMMENT = -1, MB_END = 0, + MB_WALLNAMES, MB_BACK, MB_WTYPE, MB_FRONT, MB_THING, MB_SWITCH, + MB_MUSIC, MB_SKY, + MB_SWITCH2, + MB__UNKNOWN +}; + +typedef struct map_header_t { + char id[8]; + short ver; +} map_header_t; + +typedef struct map_block_t { + short t; + short st; + int sz; +} map_block_t; + +typedef struct old_thing_t { + short x, y; + short t; + unsigned short f; +} old_thing_t; + +static map_block_t blk; + +static int G_load (FILE *h) { + switch (blk.t) { + case MB_MUSIC: + myfread(g_music, 8, 1, h); + if (music_random) { + F_randmus(g_music); + } + F_loadmus(g_music); + return 1; + } + return 0; +} + +static int IT_load (FILE *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); + it[i].o.x = t.x; + it[i].o.y = t.y; + it[i].t = t.t; + it[i].s = t.f; + if (it[i].t && (it[i].s & THF_DM) && !g_dm) { + it[i].t=0; + } + } + m = i; + for (i = 0, j = -1; i < m; ++i) { + if (it[i].t == TH_PLR1) { + j = i; + it[i].t = 0; + } + } + if (!g_dm) { + if (j == -1) { + ERR_fatal("Предмет игрок_1 не найден"); + } + dm_pos[0].x = it[j].o.x; + dm_pos[0].y = it[j].o.y; + dm_pos[0].d = it[j].s & THF_DIR; + } + for (i = 0, j = -1; i < m; ++i) { + if (it[i].t == TH_PLR2) { + j = i; + it[i].t = 0; + } + } + if (!g_dm && _2pl) { + if (j == -1) { + ERR_fatal("Предмет игрок_2 не найден"); + } + dm_pos[1].x = it[j].o.x; + dm_pos[1].y = it[j].o.y; + dm_pos[1].d = it[j].s & THF_DIR; + } + for (i = 0, j = 0; i < m; ++i) { + if (it[i].t == TH_DMSTART) { + if (g_dm) { + dm_pos[j].x = it[i].o.x; + dm_pos[j].y = it[i].o.y; + dm_pos[j].d = it[i].s & THF_DIR; + } + it[i].t = 0; + ++j; + } + } + if (g_dm && j < 2) { + ERR_fatal("Меньше 2-ух точек DM"); + } + if (g_dm) { + dm_pnum = j; + dm_pl1p = myrand(dm_pnum); + do { + dm_pl2p = myrand(dm_pnum); + } while (dm_pl2p == dm_pl1p); + } else { + dm_pl1p = 0; + dm_pl2p = 1; + dm_pnum = 2; + } + PL_spawn(&pl1, dm_pos[dm_pl1p].x, dm_pos[dm_pl1p].y, dm_pos[dm_pl1p].d); + if (_2pl) { + PL_spawn(&pl2, dm_pos[dm_pl2p].x, dm_pos[dm_pl2p].y, dm_pos[dm_pl2p].d); + } + for (i = 0; i < m; ++i) { + if (it[i].t >= TH_CLIP && it[i].t < TH_DEMON) { + it[i].s = 0; + it[i].t = it[i].t - TH_CLIP + I_CLIP; + if (it[i].t >= I_KEYR && it[i].t <= I_KEYB) { + it[i].t |= 0x8000; + } + } else if (it[i].t >= TH_DEMON) { + MN_spawn(it[i].o.x, it[i].o.y, it[i].s & THF_DIR, it[i].t - TH_DEMON + MN_DEMON); + it[i].t = 0; + } + } + return 1; + } + return 0; +} + +static int SW_load (FILE *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].tm = 0; + sw[i].d = 0; + sw[i].f |= 0x80; + if (sw[i].t == SW_SECRET) { + ++sw_secrets; + } + } + return 1; + } + return 0; +} + +static void unpack (void *buf, int len, void *obuf) { + int i = 0; + int j = 0; + unsigned char *p = buf; + unsigned char *q = obuf; + while (i < len) { + int id = p[i]; + int step = 1; + i += 1; + if (id == 0xff) { + step = p[i] | p[i + 1] << 8; + id = p[i + 2]; + i += 3; + } + memset(&q[j], id, step); + j += step; + } +} + +static int read_array (void *p, FILE *h) { + void *buf; + switch (blk.st) { + case 0: + myfread(p, FLDW * FLDH, 1, h); + break; + case 1: + buf = malloc(blk.sz); + if (buf == NULL) { + ERR_fatal("Не хватает памяти"); + } + myfread(buf, blk.sz, 1, h); + unpack(buf, blk.sz, p); + free(buf); + break; + default: + return 0; + } + return 1; +} + +static int W_load (FILE *h) { + int i; + char s[8]; + switch (blk.t) { + case MB_WALLNAMES: + 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; // ??? + R_load(s); + if (strncasecmp(s, "VTRAP01", 8) == 0) { + walf[i] |= 2; + } + } + R_end_load(); + return 1; + case MB_BACK: + return read_array(fldb, h); + case MB_WTYPE: + return read_array(fld, h); + case MB_FRONT: + return read_array(fldf, h); + case MB_SKY: + sky_type = myfread16(h); + R_loadsky(sky_type); + return 1; + } + return 0; +} + +void F_loadmap (char n[8]) { + int r, o; + FILE *h; + 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); + } + } + } + } + fseek(h, o, SEEK_SET); + } +} diff --git a/src/map.h b/src/map.h index e630ff0..9aa0b45 100644 --- a/src/map.h +++ b/src/map.h @@ -1,175 +1,6 @@ -/**************************************************************************\ -* * -* Форматы карт Doom'а 2D Версия 2 * -* * -* Prikol Software 10.VII.1996 * -* * -* Разрешается свободно распространять этот файл, при условии сохранения * -* ссылки на Prikol Software, версии и даты выпуска файла. * -* * -* Этот include-файл расчитан на WATCOM C 10.0 и DOS4GW * -* Вы можете переделать его на любой другой язык/компилятор, но сохраните * -* этот файл (если собираетесь его распространять), а в своем укажите, * -* что он изменен (переделан). * -* * -\**************************************************************************/ - -/* - Copyright (C) Prikol Software 1996-1997 - Copyright (C) Aleksey Volynskov 1996-1997 - - This file is part of the Doom2D:Rembo project. - - Doom2D:Rembo is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation. - - Doom2D:Rembo 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 or - write to the Free Software Foundation, Inc., - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - #ifndef MAP_H_INCLUDED #define MAP_H_INCLUDED -/* Старый формат - версия 1.04 alpha (и раньше) - - названия текстур (old_wall_t) - кончается пустой строкой (old_wall_t.n[0]==0) - - фон - массив 100x100 байт - номера текстур - - тип стенок - массив 100x100 байт: - 0 - пусто - 1 - стена - 2 - закрытая дверь - 3 - открытая дверь - 4 - ступенька - - передний план - массив 100x100 байт - номера текстур - - вещи, монстры и др. (old_thing_t) - кончается нулевым типом (old_thing_t.t==0) - - переключатели (old_switch_t) - кончается нулевым типом (old_switch_t.t==0) - -*/ - -typedef struct{ - char n[8]; // название текстуры - char t; // тип: 0-сплошная 1-"решётка" -}old_wall_t; - -typedef struct{ - short x,y; // координаты - short t; // тип - unsigned short f; // флаги -}old_thing_t; - -typedef struct{ - unsigned char x,y; // координаты/8 - unsigned char t; // тип - unsigned char tm; // должно быть 0 - unsigned char a,b; // обычно - координаты/8 двери - unsigned short c; // не используется (вроде бы) -}old_switch_t; - -/* Новый формат - начиная с версии 1.05 alpha - - заголовок карты (map_header_t) - - блоки (map_block_t) - кончается блоком MB_END (map_block_t.t==MB_END) - -*/ - -typedef struct{ - char id[8]; // "подпись" - "Doom2D\x1A" - short ver; // версия карты -}map_header_t; - -typedef struct{ - short t; // тип блока - short st; // подтип (метод упаковки, например) - // если не используется, то должен быть 0 - // (для будущей совместимости) - int sz; // размер (сколько байт после этой структуры) -}map_block_t; - -enum{ - MB_COMMENT=-1,MB_END=0, - MB_WALLNAMES,MB_BACK,MB_WTYPE,MB_FRONT,MB_THING,MB_SWITCH, - MB_MUSIC,MB_SKY, - MB_SWITCH2, - MB__UNKNOWN -}; - -/* Версия 0 (Doom2D версии 1.05 alpha) - - MB_COMMENT - комментарий - - MB_WALLNAMES - названия текстур (см. старую версию) - количество - по размеру блока - - MB_BACK,MB_WTYPE,MB_FRONT - фон,тип,передний план (см. старую версию) - подтип 0 - без упаковки (как в старой версии) - - MB_THING - вещи,монстры и др. (см. старую версию) - количество - по размеру блока - - MB_SWITCH - переключатели (см. старую версию) - количество - по размеру блока - -*/ - -/* Версия 1 (Doom2D версии 1.06 alpha) - - MB_WALLNAMES - добавлены псевдо-текстуры _WATER_* - где * это 0=вода,1=кислота,2=кровь - - MB_WTYPE - добавлен новый тип 5 - вода - - MB_MUSIC - новый блок - название музыки (8 байт) - - MB_SKY - новый блок - тип неба (2 байта - short) - 1 = облака - 2 = город - 3 = ад - -*/ - -#define SW_PL_PRESS 1 -#define SW_MN_PRESS 2 -#define SW_PL_NEAR 4 -#define SW_MN_NEAR 8 -#define SW_KEY_R 16 -#define SW_KEY_G 32 -#define SW_KEY_B 64 - -typedef struct{ - unsigned char x,y; // координаты/8 - unsigned char t; // тип - unsigned char tm; // должно быть 0 - unsigned char a,b; // обычно - координаты/8 двери - unsigned short c; // не используется (вроде бы) - unsigned char f; // флаги -}switch2_t; - -/* Версия 2 (Doom2D версии 1.17 alpha) - - блок MB_SWITCH заменен на MB_SWITCH2 (см. switch2_t) - -*/ - -#define LAST_MAP_VER 2 // Самая последняя версия карты +void F_loadmap (char n[8]); #endif /* MAP_H_INCLUDED */ diff --git a/src/switch.c b/src/switch.c index d95e152..719f0dd 100644 --- a/src/switch.c +++ b/src/switch.c @@ -41,33 +41,6 @@ static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele; static int swsnd; static byte cht, chto, chf, f_ch; -int SW_load (FILE *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].tm = 0; - sw[i].d = 0; - sw[i].f |= 0x80; - if (sw[i].t == SW_SECRET) { - ++sw_secrets; - } - } - return 1; - } - return 0; -} - void SW_alloc (void) { sndswn=Z_getsnd("SWTCHN"); sndswx=Z_getsnd("SWTCHX"); diff --git a/src/switch.h b/src/switch.h index d0d586c..fd448e3 100644 --- a/src/switch.h +++ b/src/switch.h @@ -22,7 +22,6 @@ #ifndef SWITCH_H_INCLUDED #define SWITCH_H_INCLUDED -#include // FILE #include "view.h" // obj_t #define MAXSW 100 @@ -43,7 +42,6 @@ typedef struct { extern int sw_secrets; extern sw_t sw[MAXSW]; -int SW_load (FILE *h); void SW_alloc (void); void SW_init (void); void Z_water_trap (obj_t *o); diff --git a/src/view.c b/src/view.c index 6a81329..80e753f 100644 --- a/src/view.c +++ b/src/view.c @@ -58,74 +58,3 @@ void W_init (void) { MN_init(); R_loadsky(1); } - -static void unpack (void *buf, int len, void *obuf) { - int i = 0; - int j = 0; - unsigned char *p = buf; - unsigned char *q = obuf; - while (i < len) { - int id = p[i]; - int step = 1; - i += 1; - if (id == 0xff) { - step = p[i] | p[i + 1] << 8; - id = p[i + 2]; - i += 3; - } - memset(&q[j], id, step); - j += step; - } -} - -int W_load (FILE *h) { - int i; - char s[8]; - void *p, *buf; - switch (blk.t) { - case MB_WALLNAMES: - 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; // ??? - R_load(s); - if (strncasecmp(s, "VTRAP01", 8) == 0) { - walf[i] |= 2; - } - } - R_end_load(); - return 1; - case MB_BACK: - p = fldb; - goto unp; - case MB_WTYPE: - p = fld; - goto unp; - case MB_FRONT: - p = fldf; - unp: - switch (blk.st) { - case 0: - myfread(p, FLDW * FLDH, 1, h); - break; - case 1: - buf = malloc(blk.sz); - if (buf == NULL) { - ERR_fatal("Не хватает памяти"); - } - myfread(buf, blk.sz, 1, h); - unpack(buf, blk.sz, p); - free(buf); - break; - default: - return 0; - } - return 1; - case MB_SKY: - sky_type = myfread16(h); - R_loadsky(sky_type); - return 1; - } - return 0; -} diff --git a/src/view.h b/src/view.h index a88e0f6..d2fd96e 100644 --- a/src/view.h +++ b/src/view.h @@ -66,6 +66,5 @@ extern byte fldf[FLDH][FLDW]; extern byte fld[FLDH][FLDW]; void W_init (void); -int W_load (FILE *h); #endif /* VIEW_H_INCLUDED */