1 /* Copyright (C) 1996-1997 Aleksey Volynskov
2 * Copyright (C) 2011 Rambo
3 * Copyright (C) 2020 SovietPony
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License ONLY.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
38 #include "common/streams.h"
39 #include "common/files.h"
42 MB_COMMENT
= -1, MB_END
= 0,
43 MB_WALLNAMES
, MB_BACK
, MB_WTYPE
, MB_FRONT
, MB_THING
, MB_SWITCH
,
49 typedef struct map_header_t
{
54 typedef struct map_block_t
{
60 typedef struct old_thing_t
{
66 static map_block_t blk
;
68 static int G_load (Reader
*h
) {
71 stream_read(g_music
, 8, 1, h
);
73 // F_randmus(g_music);
81 static int IT_load (Reader
*h
) {
86 for (i
= 0; blk
.sz
> 0; ++i
, blk
.sz
-= 8) {
87 t
.x
= stream_read16(h
);
88 t
.y
= stream_read16(h
);
89 t
.t
= stream_read16(h
);
90 t
.f
= stream_read16(h
);
95 if (it
[i
].t
&& (it
[i
].s
& THF_DM
) && !g_dm
) {
100 for (i
= 0, j
= -1; i
< m
; ++i
) {
101 if (it
[i
].t
== TH_PLR1
) {
108 logo("Player 1 point not exists on the map\n");
111 dm_pos
[0].x
= it
[j
].o
.x
;
112 dm_pos
[0].y
= it
[j
].o
.y
;
113 dm_pos
[0].d
= it
[j
].s
& THF_DIR
;
115 for (i
= 0, j
= -1; i
< m
; ++i
) {
116 if (it
[i
].t
== TH_PLR2
) {
123 logo("Player 2 point not exists on the map\n");
126 dm_pos
[1].x
= it
[j
].o
.x
;
127 dm_pos
[1].y
= it
[j
].o
.y
;
128 dm_pos
[1].d
= it
[j
].s
& THF_DIR
;
130 for (i
= 0, j
= 0; i
< m
; ++i
) {
131 if (it
[i
].t
== TH_DMSTART
) {
133 dm_pos
[j
].x
= it
[i
].o
.x
;
134 dm_pos
[j
].y
= it
[i
].o
.y
;
135 dm_pos
[j
].d
= it
[i
].s
& THF_DIR
;
142 logo("Required at least two DM points on the map\n");
147 dm_pl1p
= myrand(dm_pnum
);
149 dm_pl2p
= myrand(dm_pnum
);
150 } while (dm_pl2p
== dm_pl1p
);
156 PL_spawn(&pl1
, dm_pos
[dm_pl1p
].x
, dm_pos
[dm_pl1p
].y
, dm_pos
[dm_pl1p
].d
);
158 PL_spawn(&pl2
, dm_pos
[dm_pl2p
].x
, dm_pos
[dm_pl2p
].y
, dm_pos
[dm_pl2p
].d
);
160 for (i
= 0; i
< m
; ++i
) {
161 if (it
[i
].t
>= TH_CLIP
&& it
[i
].t
< TH_DEMON
) {
163 it
[i
].t
= it
[i
].t
- TH_CLIP
+ I_CLIP
;
164 if (it
[i
].t
>= I_KEYR
&& it
[i
].t
<= I_KEYB
) {
167 } else if (it
[i
].t
>= TH_DEMON
) {
168 MN_spawn(it
[i
].o
.x
, it
[i
].o
.y
, it
[i
].s
& THF_DIR
, it
[i
].t
- TH_DEMON
+ MN_DEMON
);
177 static int SW_load (Reader
*h
) {
182 for (i
= 0; i
< MAXSW
&& blk
.sz
> 0; ++i
, blk
.sz
-= 9) {
183 sw
[i
].x
= stream_read8(h
);
184 sw
[i
].y
= stream_read8(h
);
185 sw
[i
].t
= stream_read8(h
);
186 sw
[i
].tm
= stream_read8(h
); // unused
187 sw
[i
].a
= stream_read8(h
);
188 sw
[i
].b
= stream_read8(h
);
189 sw
[i
].c
= stream_read8(h
);
190 sw
[i
].d
= stream_read8(h
); // unused
191 sw
[i
].f
= stream_read8(h
);
195 if (sw
[i
].t
== SW_SECRET
) {
204 static void unpack (void *buf
, int len
, void *obuf
) {
207 unsigned char *p
= buf
;
208 unsigned char *q
= obuf
;
214 step
= p
[i
] | p
[i
+ 1] << 8;
218 memset(&q
[j
], id
, step
);
223 static int read_array (void *p
, Reader
*h
) {
227 stream_read(p
, FLDW
* FLDH
, 1, h
);
230 buf
= malloc(blk
.sz
);
232 logo("Out of memory\n");
235 stream_read(buf
, blk
.sz
, 1, h
);
236 unpack(buf
, blk
.sz
, p
);
245 static int W_load (Reader
*h
) {
251 memset(walf
, 0, sizeof(walf
));
252 for (i
= 1; i
< 256 && blk
.sz
> 0; i
++, blk
.sz
-= 9) {
253 stream_read(s
, 8, 1, h
);
254 walf
[i
] = stream_read8(h
) ? 1 : 0; // ???
256 if (cp866_strncasecmp(s
, "VTRAP01", 8) == 0) {
263 return read_array(fldb
, h
);
265 return read_array(fld
, h
);
267 return read_array(fldf
, h
);
269 sky_type
= stream_read16(h
);
276 int MAP_load (Reader
*r
) {
280 W_init(); // reset all game data
281 stream_read(hdr
.id
, 8, 1, r
);
282 hdr
.ver
= stream_read16(r
);
283 if (memcmp(hdr
.id
, "Doom2D\x1A", 8) == 0) {
286 blk
.t
= stream_read16(r
);
287 blk
.st
= stream_read16(r
);
288 blk
.sz
= stream_read32(r
);
289 long off
= r
->getpos(r
) + blk
.sz
;
313 logo("Unknown block %d(%d)\n", blk
.t
, blk
.st
);
319 logo("Invalid map header\n");
325 void F_loadmap (char n
[8]) {
327 int r
= F_getresid(n
);
328 FILE *h
= wadh
[wad
[r
].f
];
329 fseek(h
, wad
[r
].o
, SEEK_SET
);
330 FILE_AssignReader(&rd
, h
);
331 if (!MAP_load(&rd
.base
)) {
332 ERR_fatal("Failed to load map");