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/>.
34 #include "common/streams.h"
35 #include "common/files.h"
36 #include "common/cp866.h"
39 MB_COMMENT
= -1, MB_END
= 0,
40 MB_WALLNAMES
, MB_BACK
, MB_WTYPE
, MB_FRONT
, MB_THING
, MB_SWITCH
,
46 typedef struct map_header_t
{
51 typedef struct map_block_t
{
57 typedef struct old_thing_t
{
63 static map_block_t blk
;
65 static int G_load (Stream
*h
) {
68 stream_read(g_music
, 8, 1, h
);
70 // F_randmus(g_music);
78 static int IT_load (Stream
*h
) {
83 for (i
= 0; blk
.sz
> 0; ++i
, blk
.sz
-= 8) {
84 t
.x
= stream_read16(h
);
85 t
.y
= stream_read16(h
);
86 t
.t
= stream_read16(h
);
87 t
.f
= stream_read16(h
);
92 if (it
[i
].t
&& (it
[i
].s
& THF_DM
) && !g_dm
) {
97 for (i
= 0, j
= -1; i
< m
; ++i
) {
98 if (it
[i
].t
== TH_PLR1
) {
105 logo("Player 1 point not exists on the map\n");
108 dm_pos
[0].x
= it
[j
].o
.x
;
109 dm_pos
[0].y
= it
[j
].o
.y
;
110 dm_pos
[0].d
= it
[j
].s
& THF_DIR
;
112 for (i
= 0, j
= -1; i
< m
; ++i
) {
113 if (it
[i
].t
== TH_PLR2
) {
120 logo("Player 2 point not exists on the map\n");
123 dm_pos
[1].x
= it
[j
].o
.x
;
124 dm_pos
[1].y
= it
[j
].o
.y
;
125 dm_pos
[1].d
= it
[j
].s
& THF_DIR
;
127 for (i
= 0, j
= 0; i
< m
; ++i
) {
128 if (it
[i
].t
== TH_DMSTART
) {
130 dm_pos
[j
].x
= it
[i
].o
.x
;
131 dm_pos
[j
].y
= it
[i
].o
.y
;
132 dm_pos
[j
].d
= it
[i
].s
& THF_DIR
;
139 logo("Required at least two DM points on the map\n");
144 dm_pl1p
= myrand(dm_pnum
);
146 dm_pl2p
= myrand(dm_pnum
);
147 } while (dm_pl2p
== dm_pl1p
);
153 PL_spawn(&pl1
, dm_pos
[dm_pl1p
].x
, dm_pos
[dm_pl1p
].y
, dm_pos
[dm_pl1p
].d
);
155 PL_spawn(&pl2
, dm_pos
[dm_pl2p
].x
, dm_pos
[dm_pl2p
].y
, dm_pos
[dm_pl2p
].d
);
157 for (i
= 0; i
< m
; ++i
) {
158 if (it
[i
].t
>= TH_CLIP
&& it
[i
].t
< TH_DEMON
) {
160 it
[i
].t
= it
[i
].t
- TH_CLIP
+ I_CLIP
;
161 if (it
[i
].t
>= I_KEYR
&& it
[i
].t
<= I_KEYB
) {
164 } else if (it
[i
].t
>= TH_DEMON
) {
165 MN_spawn(it
[i
].o
.x
, it
[i
].o
.y
, it
[i
].s
& THF_DIR
, it
[i
].t
- TH_DEMON
+ MN_DEMON
);
174 static int SW_load (Stream
*h
) {
179 for (i
= 0; i
< MAXSW
&& blk
.sz
> 0; ++i
, blk
.sz
-= 9) {
180 sw
[i
].x
= stream_read8(h
);
181 sw
[i
].y
= stream_read8(h
);
182 sw
[i
].t
= stream_read8(h
);
183 sw
[i
].tm
= stream_read8(h
); // unused
184 sw
[i
].a
= stream_read8(h
);
185 sw
[i
].b
= stream_read8(h
);
186 sw
[i
].c
= stream_read8(h
);
187 sw
[i
].d
= stream_read8(h
); // unused
188 sw
[i
].f
= stream_read8(h
);
192 if (sw
[i
].t
== SW_SECRET
) {
201 static void unpack (void *buf
, int len
, void *obuf
) {
204 unsigned char *p
= buf
;
205 unsigned char *q
= obuf
;
211 step
= p
[i
] | p
[i
+ 1] << 8;
215 memset(&q
[j
], id
, step
);
220 static int read_array (void *p
, Stream
*h
) {
224 stream_read(p
, FLDW
* FLDH
, 1, h
);
227 buf
= malloc(blk
.sz
);
229 logo("Out of memory\n");
232 stream_read(buf
, blk
.sz
, 1, h
);
233 unpack(buf
, blk
.sz
, p
);
242 static int W_load (Stream
*h
) {
248 memset(walf
, 0, sizeof(walf
));
249 for (i
= 1; i
< 256 && blk
.sz
> 0; i
++, blk
.sz
-= 9) {
250 stream_read(s
, 8, 1, h
);
251 walf
[i
] = stream_read8(h
) ? 1 : 0; // ???
253 if (cp866_strncasecmp(s
, "VTRAP01", 8) == 0) {
260 return read_array(fldb
, h
);
262 return read_array(fld
, h
);
264 return read_array(fldf
, h
);
266 sky_type
= stream_read16(h
);
273 int MAP_load (Stream
*r
) {
277 W_init(); // reset all game data
278 stream_read(hdr
.id
, 8, 1, r
);
279 hdr
.ver
= stream_read16(r
);
280 if (memcmp(hdr
.id
, "Doom2D\x1A", 8) == 0) {
283 blk
.t
= stream_read16(r
);
284 blk
.st
= stream_read16(r
);
285 blk
.sz
= stream_read32(r
);
286 long off
= stream_getpos(r
) + blk
.sz
;
310 logo("Unknown block %d(%d)\n", blk
.t
, blk
.st
);
313 stream_setpos(r
, off
);
316 logo("Invalid map header\n");