Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 1
// Emacs style mode select   -*- C++ -*-
2
//-----------------------------------------------------------------------------
3
//
4
// $Id:$
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
11
//
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15
// for more details.
16
//
17
// $Log:$
18
//
19
// DESCRIPTION:
20
//	Archiving: SaveGame I/O.
21
//
22
//-----------------------------------------------------------------------------
23
 
24
static const char
25
rcsid[] = "$Id: p_tick.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
26
 
27
#include "i_system.h"
28
#include "z_zone.h"
29
#include "p_local.h"
30
 
31
// State.
32
#include "doomstat.h"
33
#include "r_state.h"
34
 
35
byte*		save_p;
36
 
37
 
38
// Pads save_p to a 4-byte boundary
39
//  so that the load/save works on SGI&Gecko.
40
#define PADSAVEP()	save_p += (4 - ((int) save_p & 3)) & 3
41
 
42
 
43
 
44
//
45
// P_ArchivePlayers
46
//
47
void P_ArchivePlayers (void)
48
{
49
    int		i;
50
    int		j;
51
    player_t*	dest;
52
 
53
    for (i=0 ; i
54
    {
55
	if (!playeringame[i])
56
	    continue;
57
 
58
	PADSAVEP();
59
 
60
	dest = (player_t *)save_p;
61
	memcpy (dest,&players[i],sizeof(player_t));
62
	save_p += sizeof(player_t);
63
	for (j=0 ; j
64
	{
65
	    if (dest->psprites[j].state)
66
	    {
67
		dest->psprites[j].state
68
		    = (state_t *)(dest->psprites[j].state-states);
69
	    }
70
	}
71
    }
72
}
73
 
74
 
75
 
76
//
77
// P_UnArchivePlayers
78
//
79
void P_UnArchivePlayers (void)
80
{
81
    int		i;
82
    int		j;
83
 
84
    for (i=0 ; i
85
    {
86
	if (!playeringame[i])
87
	    continue;
88
 
89
	PADSAVEP();
90
 
91
	memcpy (&players[i],save_p, sizeof(player_t));
92
	save_p += sizeof(player_t);
93
 
94
	// will be set when unarc thinker
95
	players[i].mo = NULL;
96
	players[i].message = NULL;
97
	players[i].attacker = NULL;
98
 
99
	for (j=0 ; j
100
	{
101
	    if (players[i]. psprites[j].state)
102
	    {
103
		players[i]. psprites[j].state
104
		    = &states[ (int)players[i].psprites[j].state ];
105
	    }
106
	}
107
    }
108
}
109
 
110
 
111
//
112
// P_ArchiveWorld
113
//
114
void P_ArchiveWorld (void)
115
{
116
    int			i;
117
    int			j;
118
    sector_t*		sec;
119
    line_t*		li;
120
    side_t*		si;
121
    short*		put;
122
 
123
    put = (short *)save_p;
124
 
125
    // do sectors
126
    for (i=0, sec = sectors ; i
127
    {
128
	*put++ = sec->floorheight >> FRACBITS;
129
	*put++ = sec->ceilingheight >> FRACBITS;
130
	*put++ = sec->floorpic;
131
	*put++ = sec->ceilingpic;
132
	*put++ = sec->lightlevel;
133
	*put++ = sec->special;		// needed?
134
	*put++ = sec->tag;		// needed?
135
    }
136
 
137
 
138
    // do lines
139
    for (i=0, li = lines ; i
140
    {
141
	*put++ = li->flags;
142
	*put++ = li->special;
143
	*put++ = li->tag;
144
	for (j=0 ; j<2 ; j++)
145
	{
146
	    if (li->sidenum[j] == -1)
147
		continue;
148
 
149
	    si = &sides[li->sidenum[j]];
150
 
151
	    *put++ = si->textureoffset >> FRACBITS;
152
	    *put++ = si->rowoffset >> FRACBITS;
153
	    *put++ = si->toptexture;
154
	    *put++ = si->bottomtexture;
155
	    *put++ = si->midtexture;
156
	}
157
    }
158
 
159
    save_p = (byte *)put;
160
}
161
 
162
 
163
 
164
//
165
// P_UnArchiveWorld
166
//
167
void P_UnArchiveWorld (void)
168
{
169
    int			i;
170
    int			j;
171
    sector_t*		sec;
172
    line_t*		li;
173
    side_t*		si;
174
    short*		get;
175
 
176
    get = (short *)save_p;
177
 
178
    // do sectors
179
    for (i=0, sec = sectors ; i
180
    {
181
	sec->floorheight = *get++ << FRACBITS;
182
	sec->ceilingheight = *get++ << FRACBITS;
183
	sec->floorpic = *get++;
184
	sec->ceilingpic = *get++;
185
	sec->lightlevel = *get++;
186
	sec->special = *get++;		// needed?
187
	sec->tag = *get++;		// needed?
188
	sec->specialdata = 0;
189
	sec->soundtarget = 0;
190
    }
191
 
192
    // do lines
193
    for (i=0, li = lines ; i
194
    {
195
	li->flags = *get++;
196
	li->special = *get++;
197
	li->tag = *get++;
198
	for (j=0 ; j<2 ; j++)
199
	{
200
	    if (li->sidenum[j] == -1)
201
		continue;
202
	    si = &sides[li->sidenum[j]];
203
	    si->textureoffset = *get++ << FRACBITS;
204
	    si->rowoffset = *get++ << FRACBITS;
205
	    si->toptexture = *get++;
206
	    si->bottomtexture = *get++;
207
	    si->midtexture = *get++;
208
	}
209
    }
210
    save_p = (byte *)get;
211
}
212
 
213
 
214
 
215
 
216
 
217
//
218
// Thinkers
219
//
220
typedef enum
221
{
222
    tc_end,
223
    tc_mobj
224
 
225
} thinkerclass_t;
226
 
227
 
228
 
229
//
230
// P_ArchiveThinkers
231
//
232
void P_ArchiveThinkers (void)
233
{
234
    thinker_t*		th;
235
    mobj_t*		mobj;
236
 
237
    // save off the current thinkers
238
    for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
239
    {
240
	if (th->function.acp1 == (actionf_p1)P_MobjThinker)
241
	{
242
	    *save_p++ = tc_mobj;
243
	    PADSAVEP();
244
	    mobj = (mobj_t *)save_p;
245
	    memcpy (mobj, th, sizeof(*mobj));
246
	    save_p += sizeof(*mobj);
247
	    mobj->state = (state_t *)(mobj->state - states);
248
 
249
	    if (mobj->player)
250
		mobj->player = (player_t *)((mobj->player-players) + 1);
251
	    continue;
252
	}
253
 
254
	// I_Error ("P_ArchiveThinkers: Unknown thinker function");
255
    }
256
 
257
    // add a terminating marker
258
    *save_p++ = tc_end;
259
}
260
 
261
 
262
 
263
//
264
// P_UnArchiveThinkers
265
//
266
void P_UnArchiveThinkers (void)
267
{
268
    byte		tclass;
269
    thinker_t*		currentthinker;
270
    thinker_t*		next;
271
    mobj_t*		mobj;
272
 
273
    // remove all the current thinkers
274
    currentthinker = thinkercap.next;
275
    while (currentthinker != &thinkercap)
276
    {
277
	next = currentthinker->next;
278
 
279
	if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
280
	    P_RemoveMobj ((mobj_t *)currentthinker);
281
	else
282
	    Z_Free (currentthinker);
283
 
284
	currentthinker = next;
285
    }
286
    P_InitThinkers ();
287
 
288
    // read in saved thinkers
289
    while (1)
290
    {
291
	tclass = *save_p++;
292
	switch (tclass)
293
	{
294
	  case tc_end:
295
	    return; 	// end of list
296
 
297
	  case tc_mobj:
298
	    PADSAVEP();
299
	    mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
300
	    memcpy (mobj, save_p, sizeof(*mobj));
301
	    save_p += sizeof(*mobj);
302
	    mobj->state = &states[(int)mobj->state];
303
	    mobj->target = NULL;
304
	    if (mobj->player)
305
	    {
306
		mobj->player = &players[(int)mobj->player-1];
307
		mobj->player->mo = mobj;
308
	    }
309
	    P_SetThingPosition (mobj);
310
	    mobj->info = &mobjinfo[mobj->type];
311
	    mobj->floorz = mobj->subsector->sector->floorheight;
312
	    mobj->ceilingz = mobj->subsector->sector->ceilingheight;
313
	    mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
314
	    P_AddThinker (&mobj->thinker);
315
	    break;
316
 
317
	  default:
318
	    I_Error ("Unknown tclass %i in savegame",tclass);
319
	}
320
 
321
    }
322
 
323
}
324
 
325
 
326
//
327
// P_ArchiveSpecials
328
//
329
enum
330
{
331
    tc_ceiling,
332
    tc_door,
333
    tc_floor,
334
    tc_plat,
335
    tc_flash,
336
    tc_strobe,
337
    tc_glow,
338
    tc_endspecials
339
 
340
} specials_e;
341
 
342
 
343
 
344
//
345
// Things to handle:
346
//
347
// T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
348
// T_VerticalDoor, (vldoor_t: sector_t * swizzle),
349
// T_MoveFloor, (floormove_t: sector_t * swizzle),
350
// T_LightFlash, (lightflash_t: sector_t * swizzle),
351
// T_StrobeFlash, (strobe_t: sector_t *),
352
// T_Glow, (glow_t: sector_t *),
353
// T_PlatRaise, (plat_t: sector_t *), - active list
354
//
355
void P_ArchiveSpecials (void)
356
{
357
    thinker_t*		th;
358
    ceiling_t*		ceiling;
359
    vldoor_t*		door;
360
    floormove_t*	floor;
361
    plat_t*		plat;
362
    lightflash_t*	flash;
363
    strobe_t*		strobe;
364
    glow_t*		glow;
365
    int			i;
366
 
367
    // save off the current thinkers
368
    for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
369
    {
370
	if (th->function.acv == (actionf_v)NULL)
371
	{
372
	    for (i = 0; i < MAXCEILINGS;i++)
373
		if (activeceilings[i] == (ceiling_t *)th)
374
		    break;
375
 
376
	    if (i
377
	    {
378
		*save_p++ = tc_ceiling;
379
		PADSAVEP();
380
		ceiling = (ceiling_t *)save_p;
381
		memcpy (ceiling, th, sizeof(*ceiling));
382
		save_p += sizeof(*ceiling);
383
		ceiling->sector = (sector_t *)(ceiling->sector - sectors);
384
	    }
385
	    continue;
386
	}
387
 
388
	if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
389
	{
390
	    *save_p++ = tc_ceiling;
391
	    PADSAVEP();
392
	    ceiling = (ceiling_t *)save_p;
393
	    memcpy (ceiling, th, sizeof(*ceiling));
394
	    save_p += sizeof(*ceiling);
395
	    ceiling->sector = (sector_t *)(ceiling->sector - sectors);
396
	    continue;
397
	}
398
 
399
	if (th->function.acp1 == (actionf_p1)T_VerticalDoor)
400
	{
401
	    *save_p++ = tc_door;
402
	    PADSAVEP();
403
	    door = (vldoor_t *)save_p;
404
	    memcpy (door, th, sizeof(*door));
405
	    save_p += sizeof(*door);
406
	    door->sector = (sector_t *)(door->sector - sectors);
407
	    continue;
408
	}
409
 
410
	if (th->function.acp1 == (actionf_p1)T_MoveFloor)
411
	{
412
	    *save_p++ = tc_floor;
413
	    PADSAVEP();
414
	    floor = (floormove_t *)save_p;
415
	    memcpy (floor, th, sizeof(*floor));
416
	    save_p += sizeof(*floor);
417
	    floor->sector = (sector_t *)(floor->sector - sectors);
418
	    continue;
419
	}
420
 
421
	if (th->function.acp1 == (actionf_p1)T_PlatRaise)
422
	{
423
	    *save_p++ = tc_plat;
424
	    PADSAVEP();
425
	    plat = (plat_t *)save_p;
426
	    memcpy (plat, th, sizeof(*plat));
427
	    save_p += sizeof(*plat);
428
	    plat->sector = (sector_t *)(plat->sector - sectors);
429
	    continue;
430
	}
431
 
432
	if (th->function.acp1 == (actionf_p1)T_LightFlash)
433
	{
434
	    *save_p++ = tc_flash;
435
	    PADSAVEP();
436
	    flash = (lightflash_t *)save_p;
437
	    memcpy (flash, th, sizeof(*flash));
438
	    save_p += sizeof(*flash);
439
	    flash->sector = (sector_t *)(flash->sector - sectors);
440
	    continue;
441
	}
442
 
443
	if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
444
	{
445
	    *save_p++ = tc_strobe;
446
	    PADSAVEP();
447
	    strobe = (strobe_t *)save_p;
448
	    memcpy (strobe, th, sizeof(*strobe));
449
	    save_p += sizeof(*strobe);
450
	    strobe->sector = (sector_t *)(strobe->sector - sectors);
451
	    continue;
452
	}
453
 
454
	if (th->function.acp1 == (actionf_p1)T_Glow)
455
	{
456
	    *save_p++ = tc_glow;
457
	    PADSAVEP();
458
	    glow = (glow_t *)save_p;
459
	    memcpy (glow, th, sizeof(*glow));
460
	    save_p += sizeof(*glow);
461
	    glow->sector = (sector_t *)(glow->sector - sectors);
462
	    continue;
463
	}
464
    }
465
 
466
    // add a terminating marker
467
    *save_p++ = tc_endspecials;
468
 
469
}
470
 
471
 
472
//
473
// P_UnArchiveSpecials
474
//
475
void P_UnArchiveSpecials (void)
476
{
477
    byte		tclass;
478
    ceiling_t*		ceiling;
479
    vldoor_t*		door;
480
    floormove_t*	floor;
481
    plat_t*		plat;
482
    lightflash_t*	flash;
483
    strobe_t*		strobe;
484
    glow_t*		glow;
485
 
486
 
487
    // read in saved thinkers
488
    while (1)
489
    {
490
	tclass = *save_p++;
491
	switch (tclass)
492
	{
493
	  case tc_endspecials:
494
	    return;	// end of list
495
 
496
	  case tc_ceiling:
497
	    PADSAVEP();
498
	    ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
499
	    memcpy (ceiling, save_p, sizeof(*ceiling));
500
	    save_p += sizeof(*ceiling);
501
	    ceiling->sector = §ors[(int)ceiling->sector];
502
	    ceiling->sector->specialdata = ceiling;
503
 
504
	    if (ceiling->thinker.function.acp1)
505
		ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
506
 
507
	    P_AddThinker (&ceiling->thinker);
508
	    P_AddActiveCeiling(ceiling);
509
	    break;
510
 
511
	  case tc_door:
512
	    PADSAVEP();
513
	    door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
514
	    memcpy (door, save_p, sizeof(*door));
515
	    save_p += sizeof(*door);
516
	    door->sector = §ors[(int)door->sector];
517
	    door->sector->specialdata = door;
518
	    door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
519
	    P_AddThinker (&door->thinker);
520
	    break;
521
 
522
	  case tc_floor:
523
	    PADSAVEP();
524
	    floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
525
	    memcpy (floor, save_p, sizeof(*floor));
526
	    save_p += sizeof(*floor);
527
	    floor->sector = §ors[(int)floor->sector];
528
	    floor->sector->specialdata = floor;
529
	    floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
530
	    P_AddThinker (&floor->thinker);
531
	    break;
532
 
533
	  case tc_plat:
534
	    PADSAVEP();
535
	    plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
536
	    memcpy (plat, save_p, sizeof(*plat));
537
	    save_p += sizeof(*plat);
538
	    plat->sector = §ors[(int)plat->sector];
539
	    plat->sector->specialdata = plat;
540
 
541
	    if (plat->thinker.function.acp1)
542
		plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
543
 
544
	    P_AddThinker (&plat->thinker);
545
	    P_AddActivePlat(plat);
546
	    break;
547
 
548
	  case tc_flash:
549
	    PADSAVEP();
550
	    flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
551
	    memcpy (flash, save_p, sizeof(*flash));
552
	    save_p += sizeof(*flash);
553
	    flash->sector = §ors[(int)flash->sector];
554
	    flash->thinker.function.acp1 = (actionf_p1)T_LightFlash;
555
	    P_AddThinker (&flash->thinker);
556
	    break;
557
 
558
	  case tc_strobe:
559
	    PADSAVEP();
560
	    strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
561
	    memcpy (strobe, save_p, sizeof(*strobe));
562
	    save_p += sizeof(*strobe);
563
	    strobe->sector = §ors[(int)strobe->sector];
564
	    strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash;
565
	    P_AddThinker (&strobe->thinker);
566
	    break;
567
 
568
	  case tc_glow:
569
	    PADSAVEP();
570
	    glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
571
	    memcpy (glow, save_p, sizeof(*glow));
572
	    save_p += sizeof(*glow);
573
	    glow->sector = §ors[(int)glow->sector];
574
	    glow->thinker.function.acp1 = (actionf_p1)T_Glow;
575
	    P_AddThinker (&glow->thinker);
576
	    break;
577
 
578
	  default:
579
	    I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
580
		     "in savegame",tclass);
581
	}
582
 
583
    }
584
 
585
}
586