Subversion Repositories eduke32

Rev

Rev 8685 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5196 hendricks2 1
//-------------------------------------------------------------------------
2
/*
3
Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
 
5
This file is part of Shadow Warrior version 1.2
6
 
7
Shadow Warrior is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
 
16
See the GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21
 
22
Original Source: 1997 - Frank Maddin and Jim Norwood
23
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24
*/
25
//-------------------------------------------------------------------------
26
 
27
// JSECTOR.C
28
// This is all Jim's programming having to do with sectors.
29
 
30
#include "build.h"
31
 
32
#include "keys.h"
33
#include "names2.h"
34
#include "jnames.h"
35
#include "panel.h"
36
#include "game.h"
37
#include "tags.h"
38
#include "sector.h"
39
#include "player.h"
40
#include "sprite.h"
41
#include "reserve.h"
42
#include "jsector.h"
43
#include "jtags.h"
44
#include "lists.h"
45
#include "pal.h"
46
#include "parent.h"
47
 
48
 
49
// V A R I A B L E   D E C L A R A T I O N S //////////////////////////////////////////////////////
50
 
51
MIRRORTYPE mirror[MAXMIRRORS];
52
 
53
short mirrorcnt; //, floormirrorcnt;
54
//short floormirrorsector[MAXMIRRORS];
5198 hendricks2 55
SWBOOL mirrorinview;
5196 hendricks2 56
 
5198 hendricks2 57
SWBOOL MirrorMoveSkip16 = 0;
5196 hendricks2 58
 
59
// Voxel stuff
5198 hendricks2 60
//SWBOOL bVoxelsOn = TRUE;                  // Turn voxels on by default
61
SWBOOL bSpinBobVoxels = FALSE;            // Do twizzly stuff to voxels, but
5196 hendricks2 62
// not by default
5198 hendricks2 63
SWBOOL bAutoSize = TRUE;                  // Autosizing on/off
5196 hendricks2 64
 
65
//extern int chainnumpages;
66
extern AMB_INFO ambarray[];
67
extern short NormalVisibility;
68
 
69
extern ParentalStruct aVoxelArray[MAXTILES];
70
 
71
// F U N C T I O N S //////////////////////////////////////////////////////////////////////////////
72
 
73
 
74
/////////////////////////////////////////////////////
75
//  SpawnWallSound
76
/////////////////////////////////////////////////////
5198 hendricks2 77
void
5196 hendricks2 78
SpawnWallSound(short sndnum, short i)
79
{
80
    short SpriteNum;
5201 hendricks2 81
    vec3_t mid;
5196 hendricks2 82
    SPRITEp sp;
83
    int handle;
84
 
85
    SpriteNum = COVERinsertsprite(0, STAT_DEFAULT);
86
    if (SpriteNum < 0)
87
        return;
88
 
89
    sp = &sprite[SpriteNum];
90
    sp->cstat = 0;
91
    sp->extra = 0;
92
    // Get wall midpoint for offset in mirror view
5201 hendricks2 93
    mid.x = (wall[i].x + wall[wall[i].point2].x) / 2;
94
    mid.y = (wall[i].y + wall[wall[i].point2].y) / 2;
95
    mid.z = (sector[wall[i].nextsector].ceilingz + sector[wall[i].nextsector].floorz) / 2;
96
    setspritez(SpriteNum, &mid);
5196 hendricks2 97
    sp = &sprite[SpriteNum];
98
 
99
    handle = PlaySound(sndnum, &sp->x, &sp->y, &sp->z, v3df_dontpan | v3df_doppler);
100
    if (handle != -1)
101
        Set3DSoundOwner(SpriteNum);
102
}
103
 
104
short
105
CheckTileSound(short picnum)
106
{
107
    short sndnum = -1;
108
 
109
    switch (picnum)
110
    {
111
    case 163:                           // Sizzly Lava
112
    case 167:
113
        sndnum = DIGI_VOLCANOSTEAM1;
114
        break;
115
    case 175:                           // Flowing Lava
116
        sndnum = DIGI_ERUPTION;
117
        break;
118
    case 179:                           // Bubbly lava
119
        sndnum = DIGI_LAVAFLOW1;
120
        break;
121
    case 300:                           // Water fall tile
122
        sndnum = DIGI_WATERFALL1;
123
        break;
124
    case 334:                           // Teleporter Pad
125
        sndnum = DIGI_ENGROOM1;
126
        break;
127
    case 2690:                          // Jet engine fan
128
        sndnum = DIGI_JET;
129
        break;
130
    case 2672:                          // X-Ray Machine engine
131
        sndnum = DIGI_ENGROOM5;
132
        break;
133
    case 768:                           // Electricity
134
//          sndnum = DIGI_;
135
        break;
136
    case 2714:                          // Pachinko Machine
137
//          sndnum = DIGI_;
138
        break;
139
    case 2782:                          // Telepad
140
        sndnum = DIGI_ENGROOM4;
141
        break;
142
    case 3382:                          // Gears
143
        sndnum = DIGI_ENGROOM5;
144
        break;
145
    case 2801:                          // Computers
146
    case 2804:
147
    case 2807:
148
    case 3352:
149
    case 3385:
150
    case 3389:
151
    case 3393:
152
    case 3397:
153
    case 3401:
154
    case 3405:
155
//          sndnum = DIGI_;
156
        break;
157
    case 3478:                          // Radar screen
158
//          sndnum = DIGI_;
159
        break;
160
    default:
161
        sndnum = -1;
162
        break;
163
    }
164
    return sndnum;
165
}
166
 
167
/////////////////////////////////////////////////////
168
//  Initialize any of my special use sprites
169
/////////////////////////////////////////////////////
170
void
171
JS_SpriteSetup(void)
172
{
173
    SPRITEp sp;
8685 ny00123 174
    short SpriteNum = 0, NextSprite;
5196 hendricks2 175
    USERp u;
8685 ny00123 176
    short i;
5196 hendricks2 177
    int handle;
178
 
179
 
180
    TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite)
181
    {
182
        short tag;
183
 
184
        sp = &sprite[SpriteNum];
185
        tag = sp->hitag;
186
 
187
        // Non static camera. Camera sprite will be drawn!
188
        if (tag == MIRROR_CAM && sprite[SpriteNum].picnum != ST1)
189
        {
190
            // Just change it to static, sprite has all the info I need
191
//          u = SpawnUser(SpriteNum, sp->picnum, NULL);
192
//          RESET(sp->cstat, CSTAT_SPRITE_BLOCK);
193
//          SET(sp->cstat, CSTAT_SPRITE_BLOCK_HITSCAN);
194
            change_sprite_stat(SpriteNum, STAT_SPAWN_SPOT);
195
        }
196
 
197
        switch (sprite[SpriteNum].picnum)
198
        {
199
        case ST1:
200
            if (tag == MIRROR_CAM)
201
            {
202
                // Just change it to static, sprite has all the info I need
203
                // ST1 cameras won't move with SOBJ's!
204
                change_sprite_stat(SpriteNum, STAT_ST1);
205
            }
206
            else if (tag == MIRROR_SPAWNSPOT)
207
            {
208
                // Just change it to static, sprite has all the info I need
209
                change_sprite_stat(SpriteNum, STAT_ST1);
210
            }
211
            else if (tag == AMBIENT_SOUND)
212
            {
213
                change_sprite_stat(SpriteNum, STAT_AMBIENT);
214
                // PlaySound(sp->lotag, &sp->x, &sp->y, &sp->z, v3df_ambient
215
                // | v3df_init | v3df_doppler);
216
            }
217
            else if (tag == TAG_ECHO_SOUND)
218
            {
219
                change_sprite_stat(SpriteNum, STAT_ECHO);
220
            }
221
            else if (tag == TAG_DRIPGEN)
222
            {
223
                ANIMATOR GenerateDrips;
224
 
225
                u = SpawnUser(SpriteNum, 0, NULL);
226
 
227
                ASSERT(u != NULL);
228
                u->RotNum = 0;
229
                u->WaitTics = sp->lotag * 120;
230
 
231
                u->ActorActionFunc = GenerateDrips;
232
 
233
                change_sprite_stat(SpriteNum, STAT_NO_STATE);
234
                SET(sp->cstat, CSTAT_SPRITE_INVISIBLE);
235
            }
236
            break;
237
        // Sprites in editart that should play ambient sounds
238
        // automatically
239
        case 380:
240
        case 396:
241
        case 430:
242
        case 443:
243
        case 512:
244
        case 521:
245
        case 541:
246
        case 2720:
247
        case 3143:
248
        case 3157:
249
            handle = PlaySound(DIGI_FIRE1, &sp->x, &sp->y, &sp->z, v3df_follow|v3df_dontpan|v3df_doppler);
250
            if (handle != -1)
251
                Set3DSoundOwner(SpriteNum);
252
            break;
253
        case 795:
254
        case 880:
255
            handle = PlaySound(DIGI_WATERFLOW1, &sp->x, &sp->y, &sp->z, v3df_follow|v3df_dontpan|v3df_doppler);
256
            if (handle != -1)
257
                Set3DSoundOwner(SpriteNum);
258
            break;
259
        case 460:  // Wind Chimes
260
            handle = PlaySound(79, &sp->x, &sp->y, &sp->z, v3df_ambient | v3df_init
261
                               | v3df_doppler | v3df_follow);
262
            if (handle != -1)
263
                Set3DSoundOwner(SpriteNum);
264
            break;
265
 
266
        }
267
    }
268
    // Check for certain walls to make sounds
269
    for (i = 0; i < numwalls; i++)
270
    {
271
        short picnum;
272
 
273
 
274
        picnum = wall[i].picnum;
275
 
276
        // Set the don't stick bit for liquid tiles
277
        switch (picnum)
278
        {
279
        case 175:
280
        case 179:
281
        case 300:
282
        case 320:
283
        case 330:
284
        case 352:
285
        case 780:
286
        case 890:
287
        case 2608:
288
        case 2616:
289
            //case 3834:
290
            SET(wall[i].extra, WALLFX_DONT_STICK);
291
            break;
292
        }
293
 
294
#if 0
8686 ny00123 295
        short sndnum;
5196 hendricks2 296
        if ((sndnum = CheckTileSound(picnum)) != -1)
297
        {
298
            SpawnWallSound(sndnum, i);
299
        }
300
        picnum = wall[i].overpicnum;
301
        if ((sndnum = CheckTileSound(picnum)) != -1)
302
        {
303
            SpawnWallSound(sndnum, i);
304
        }
305
#endif
306
    }
307
}
308
 
309
 
310
/////////////////////////////////////////////////////
311
//  Initialize the mirrors
312
/////////////////////////////////////////////////////
313
void
314
JS_InitMirrors(void)
315
{
8685 ny00123 316
    short startwall, endwall;
317
    int i, j, s;
5196 hendricks2 318
    short SpriteNum = 0, NextSprite;
5198 hendricks2 319
    SWBOOL Found_Cam = FALSE;
5196 hendricks2 320
 
321
 
322
    // Set all the mirror struct values to -1
323
    memset(mirror, 0xFF, sizeof(mirror));
324
 
325
    mirrorinview = FALSE;               // Initially set global mirror flag
326
    // to no mirrors seen
327
 
328
    // Scan wall tags for mirrors
329
    mirrorcnt = 0;
5204 hendricks2 330
    tilesiz[MIRROR].x = 0;
331
    tilesiz[MIRROR].y = 0;
5196 hendricks2 332
 
333
    for (i = 0; i < MAXMIRRORS; i++)
334
    {
5204 hendricks2 335
        tilesiz[i + MIRRORLABEL].x = 0;
336
        tilesiz[i + MIRRORLABEL].y = 0;
5196 hendricks2 337
        mirror[i].campic = -1;
338
        mirror[i].camsprite = -1;
339
        mirror[i].camera = -1;
340
        mirror[i].ismagic = FALSE;
341
    }
342
 
343
    for (i = 0; i < numwalls; i++)
344
    {
345
        s = wall[i].nextsector;
346
        if ((s >= 0) && (wall[i].overpicnum == MIRROR) && (wall[i].cstat & 32))
347
        {
348
            if ((sector[s].floorstat & 1) == 0)
349
            {
350
                wall[i].overpicnum = MIRRORLABEL + mirrorcnt;
351
                wall[i].picnum = MIRRORLABEL + mirrorcnt;
352
                sector[s].ceilingpicnum = MIRRORLABEL + mirrorcnt;
353
                sector[s].floorpicnum = MIRRORLABEL + mirrorcnt;
354
                sector[s].floorstat |= 1;
355
                mirror[mirrorcnt].mirrorwall = i;
356
                mirror[mirrorcnt].mirrorsector = s;
357
                mirror[mirrorcnt].numspawnspots = 0;
358
                mirror[mirrorcnt].ismagic = FALSE;
359
                if (wall[i].lotag == TAG_WALL_MAGIC_MIRROR)
360
                {
361
                    short ii, nextii;
362
                    SPRITEp sp;
363
 
364
                    mirror[mirrorcnt].ismagic = TRUE;
365
                    Found_Cam = FALSE;
366
                    TRAVERSE_SPRITE_STAT(headspritestat[STAT_ST1], ii, nextii)
367
                    {
368
                        sp = &sprite[ii];
369
                        // if correct type and matches
370
                        if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
371
                        {
372
                            mirror[mirrorcnt].camera = ii;
373
                            // Set up camera varialbes
374
                            SP_TAG5(sp) = sp->ang;      // Set current angle to
375
                            // sprite angle
376
                            Found_Cam = TRUE;
377
                        }
378
                    }
379
 
380
                    ii = nextii = 0;
381
                    TRAVERSE_SPRITE_STAT(headspritestat[STAT_SPAWN_SPOT], ii, nextii)
382
                    {
383
 
384
                        sp = &sprite[ii];
385
 
386
                        // if correct type and matches
387
                        if (sp->hitag == MIRROR_CAM && sp->lotag == wall[i].hitag)
388
                        {
389
                            mirror[mirrorcnt].camera = ii;
390
                            // Set up camera varialbes
391
                            SP_TAG5(sp) = sp->ang;      // Set current angle to
392
                            // sprite angle
393
                            Found_Cam = TRUE;
394
                        }
395
                    }
396
 
397
                    if (!Found_Cam)
398
                    {
7500 hendricks2 399
                        printf("Cound not find the camera view sprite for match %d\n",TrackerCast(wall[i].hitag));
400
                        printf("Map Coordinates: x = %d, y = %d\n",TrackerCast(wall[i].x),TrackerCast(wall[i].y));
5196 hendricks2 401
                        exit(0);
402
                    }
403
 
404
                    Found_Cam = FALSE;
405
                    if (TEST_BOOL1(&sprite[mirror[mirrorcnt].camera]))
406
                    {
407
                        TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite)
408
                        {
409
                            sp = &sprite[SpriteNum];
410
                            if (sp->picnum >= CAMSPRITE && sp->picnum < CAMSPRITE + 8 &&
411
                                sp->hitag == wall[i].hitag)
412
                            {
413
                                mirror[mirrorcnt].campic = sp->picnum;
414
                                mirror[mirrorcnt].camsprite = SpriteNum;
415
 
416
                                // JBF: commenting out this line results in the screen in $BULLET being visible
5204 hendricks2 417
                                tilesiz[mirror[mirrorcnt].campic].x = tilesiz[mirror[mirrorcnt].campic].y = 0;
5196 hendricks2 418
 
419
                                Found_Cam = TRUE;
420
                            }
421
                        }
422
 
423
                        if (!Found_Cam)
424
                        {
425
                            printf("Did not find drawtotile for camera number %d\n",mirrorcnt);
7500 hendricks2 426
                            printf("wall[%d].hitag == %d\n",i,TrackerCast(wall[i].hitag));
427
                            printf("Map Coordinates: x = %d, y = %d\n", TrackerCast(wall[i].x), TrackerCast(wall[i].y));
5196 hendricks2 428
                            exit(0);
429
                        }
430
                    }
431
 
432
                    // For magic mirrors, set allowable viewing time to 30
433
                    // secs
434
                    // Base rate is supposed to be 120, but time is double
435
                    // what I expect
436
                    mirror[mirrorcnt].maxtics = 60 * 30;
437
 
438
                }
439
 
440
                mirror[mirrorcnt].mstate = m_normal;
441
 
442
                // Set tics used to none
443
                mirror[mirrorcnt].tics = 0;
444
 
445
                if (mirror[mirrorcnt].ismagic)
446
                {
447
                    //DSPRINTF(ds, "mirror.mirrorwall %d", mirror[mirrorcnt].mirrorwall);
448
                    MONO_PRINT(ds);
449
                    //DSPRINTF(ds, "mirror.mirrorsector %d", mirror[mirrorcnt].mirrorsector);
450
                    MONO_PRINT(ds);
451
                    //DSPRINTF(ds, "mirror.camera %d", mirror[mirrorcnt].camera);
452
                    MONO_PRINT(ds);
453
                }
454
 
455
                mirrorcnt++;
456
                ASSERT(mirrorcnt < MAXMIRRORS);
457
            }
458
            else
459
                wall[i].overpicnum = sector[s].ceilingpicnum;
460
        }
461
    }
462
 
463
    // Invalidate textures in sector behind mirror
464
    for (i = 0; i < mirrorcnt; i++)
465
    {
466
        startwall = sector[mirror[i].mirrorsector].wallptr;
467
        endwall = startwall + sector[mirror[i].mirrorsector].wallnum;
468
        for (j = startwall; j < endwall; j++)
469
        {
470
            wall[j].picnum = MIRROR;
471
            wall[j].overpicnum = MIRROR;
472
        }
473
    }
474
 
475
}                                   // InitMirrors
476
 
477
/////////////////////////////////////////////////////
478
//  Draw a 3d screen to a specific tile
479
/////////////////////////////////////////////////////
480
#if 1
481
void drawroomstotile(int daposx, int daposy, int daposz,
482
                     short daang, int dahoriz, short dacursectnum, short tilenume)
483
{
484
    if (waloff[tilenume] == 0)
7509 hendricks2 485
        tileLoad(tilenume);
5196 hendricks2 486
 
487
    PRODUCTION_ASSERT(waloff[tilenume]);
488
 
7509 hendricks2 489
    renderSetTarget(tilenume, tilesiz[tilenume].x, tilesiz[tilenume].y);
5196 hendricks2 490
 
491
    drawrooms(daposx, daposy, daposz, daang, dahoriz, dacursectnum);
492
    analyzesprites(daposx, daposy, daposz, FALSE);
7509 hendricks2 493
    renderDrawMasks();
5196 hendricks2 494
 
7509 hendricks2 495
    renderRestoreTarget();
5196 hendricks2 496
 
497
    squarerotatetile(tilenume);
498
 
7509 hendricks2 499
    tileInvalidate(tilenume, -1, -1);
5196 hendricks2 500
}
501
#else
502
void
503
drawroomstotile(int daposx, int daposy, int daposz,
504
                short daang, int dahoriz, short dacursectnum, short tilenume)
505
{
506
 
507
    int i, j, k, bakchainnumpages, bakvidoption;
508
    intptr_t bakframeplace;
5984 hendricks2 509
    vec2_t bakwindowxy1, bakwindowxy2;
510
    int xsiz, ysiz;
5196 hendricks2 511
    char *ptr1, *ptr2;
512
 
513
    // DRAWROOMS TO TILE BACKUP&SET CODE
5204 hendricks2 514
    xsiz = tilesiz[tilenume].x;
515
    ysiz = tilesiz[tilenume].y;
5196 hendricks2 516
    // bakchainnumpages = chainnumpages;
517
    bakchainnumpages = numpages;
518
    // chainnumpages = 0;
519
    numpages = 0;
520
    bakvidoption = vidoption;
521
    vidoption = 1;
522
    if (waloff[tilenume] == 0)
523
        loadtile(tilenume);
524
    bakframeplace = frameplace;
525
    frameplace = waloff[tilenume];
5984 hendricks2 526
    bakwindowxy1 = windowxy1;
527
    bakwindowxy2 = windowxy2;
5196 hendricks2 528
    setview(0, 0, xsiz - 1, ysiz - 1);
529
    setvlinebpl(xsiz);
530
    j = 0;
531
    for (i = 0; i <= ysiz; i++)
532
    {
533
        ylookup[i] = j, j += xsiz;
534
    }
535
 
536
    // DRAWS TO TILE HERE
537
    drawrooms(daposx, daposy, daposz, daang, dahoriz, dacursectnum + MAXSECTORS);
538
    analyzesprites(daposx, daposy, daposz, FALSE);
7509 hendricks2 539
    renderDrawMasks();
5196 hendricks2 540
 
541
    setviewback();
542
 
543
    // ROTATE TILE (supports square tiles only for rotation part)
544
    if (xsiz == ysiz)
545
    {
546
        k = (xsiz << 1);
547
        for (i = xsiz - 1; i >= 0; i--)
548
        {
549
            ptr1 = (char *)(waloff[tilenume] + i * (xsiz + 1));
550
            ptr2 = ptr1;
551
            if ((i & 1) != 0)
552
            {
553
                ptr1--;
554
                ptr2 -= xsiz;
555
                swapchar(ptr1, ptr2);
556
            }
557
            for (j = (i >> 1) - 1; j >= 0; j--)
558
            {
559
                ptr1 -= 2;
560
                ptr2 -= k;
561
                swapchar2(ptr1, ptr2, xsiz);
562
                // swapchar(ptr1,ptr2);
563
                // swapchar(ptr1+1,ptr2+xsiz);
564
            }
565
        }
566
    }
567
 
568
    // DRAWROOMS TO TILE RESTORE CODE
5984 hendricks2 569
    setview(bakwindowxy1.x, bakwindowxy1.y, bakwindowxy2.x, bakwindowxy2.y);
5196 hendricks2 570
    // chainnumpages = bakchainnumpages;
571
    numpages = bakchainnumpages;
572
    vidoption = bakvidoption;
573
    frameplace = bakframeplace;
574
    j = 0;
575
    // if (chainnumpages >= 2)
576
    if (numpages >= 2)
577
    {
578
        for (i = 0; i <= ysiz; i++)
579
            ylookup[i] = j, j += (xdim >> 2);
580
    }
581
    else
582
    {
583
        for (i = 0; i <= ysiz; i++)
584
            ylookup[i] = j, j += xdim;
585
    }
586
    setvlinebpl(ylookup[1]);
587
}
588
#endif
589
 
590
void
591
JS_ProcessEchoSpot()
592
{
593
    short i,nexti;
594
    SPRITEp tp;
595
    int j,dist;
596
    PLAYERp pp = Player+screenpeek;
5198 hendricks2 597
    int16_t reverb;
598
    SWBOOL reverb_set = FALSE;
5196 hendricks2 599
 
600
    // Process echo sprites
601
    TRAVERSE_SPRITE_STAT(headspritestat[STAT_ECHO], i, nexti)
602
    {
603
        dist = 0x7fffffff;
604
 
605
        tp = &sprite[i];
606
 
607
        j = klabs(tp->x - pp->posx);
608
        j += klabs(tp->y - pp->posy);
609
        if (j < dist)
610
            dist = j;
611
 
612
        if (dist <= SP_TAG4(tp)) // tag4 = ang
613
        {
614
            reverb = SP_TAG2(tp);
615
            if (reverb > 200) reverb = 200;
616
            if (reverb < 100) reverb = 100;
617
 
618
            COVER_SetReverb(reverb);
619
            reverb_set = TRUE;
620
        }
621
    }
622
    if (!TEST(pp->Flags, PF_DIVING) && !reverb_set && pp->Reverb <= 0)
623
        COVER_SetReverb(0);
624
}
625
 
626
/////////////////////////////////////////////////////
627
//  Draw one mirror, the one closest to player
628
//  Cams and see to teleporters do NOT support room above room!
629
/////////////////////////////////////////////////////
630
#define MAXCAMDIST 8000
631
 
632
int camloopcnt = 0;                    // Timer to cycle through player
633
// views
634
short camplayerview = 1;                // Don't show yourself!
635
 
636
void
637
JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
638
{
8685 ny00123 639
    int j, cnt;
640
    int dist;
641
    int tposx, tposy; // Camera
642
    int *longptr;
7509 hendricks2 643
    fix16_t tang;
5196 hendricks2 644
 
645
//    long tx, ty, tz, tpang;             // Interpolate so mirror doesn't
646
    // drift!
5198 hendricks2 647
    SWBOOL bIsWallMirror = FALSE;
5196 hendricks2 648
 
649
    MirrorMoveSkip16 = (MirrorMoveSkip16 + 1) & 15;
650
 
8050 pogokeen 651
    camloopcnt += (int32_t) (totalclock - ototalclock);
5196 hendricks2 652
    if (camloopcnt > (60 * 5))          // 5 seconds per player view
653
    {
654
        camloopcnt = 0;
655
        camplayerview++;
656
        if (camplayerview >= numplayers)
657
            camplayerview = 1;
658
    }
659
 
660
    // WARNING!  Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 <-- JBF: wrong
661
    longptr = (int *)&gotpic[MIRRORLABEL >> 3];
662
    if (longptr && (longptr[0] || longptr[1]))
663
    {
664
        for (cnt = MAXMIRRORS - 1; cnt >= 0; cnt--)
665
            //if (TEST_GOTPIC(cnt + MIRRORLABEL) || TEST_GOTPIC(cnt + CAMSPRITE))
8299 hendricks2 666
            if (TEST_GOTPIC(cnt + MIRRORLABEL) || ((unsigned)mirror[cnt].campic < MAXTILES && TEST_GOTPIC(mirror[cnt].campic)))
5196 hendricks2 667
            {
668
                bIsWallMirror = FALSE;
669
                if (TEST_GOTPIC(cnt + MIRRORLABEL))
670
                {
671
                    bIsWallMirror = TRUE;
672
                    RESET_GOTPIC(cnt + MIRRORLABEL);
673
                }
674
                //else if (TEST_GOTPIC(cnt + CAMSPRITE))
8299 hendricks2 675
                else if ((unsigned)mirror[cnt].campic < MAXTILES && TEST_GOTPIC(mirror[cnt].campic))
5196 hendricks2 676
                {
677
                    //RESET_GOTPIC(cnt + CAMSPRITE);
678
                    RESET_GOTPIC(mirror[cnt].campic);
679
                }
680
 
681
                mirrorinview = TRUE;
682
 
6254 hendricks2 683
//                tx = pp->oposx + mulscale16(pp->posx - pp->oposx, smoothratio);
684
//                ty = pp->oposy + mulscale16(pp->posy - pp->oposy, smoothratio);
685
//                tz = pp->oposz + mulscale16(pp->posz - pp->oposz, smoothratio);
686
//                tpang = pp->oang + mulscale16(((pp->pang + 1024 - pp->oang) & 2047) - 1024, smoothratio);
5196 hendricks2 687
 
688
 
689
                dist = 0x7fffffff;
690
 
691
                if (bIsWallMirror)
692
                {
693
                    j = klabs(wall[mirror[cnt].mirrorwall].x - tx);
694
                    j += klabs(wall[mirror[cnt].mirrorwall].y - ty);
695
                    if (j < dist)
696
                        dist = j;
697
                }
698
                else
699
                {
700
                    SPRITEp tp;
701
 
702
                    tp = &sprite[mirror[cnt].camsprite];
703
 
704
                    j = klabs(tp->x - tx);
705
                    j += klabs(tp->y - ty);
706
                    if (j < dist)
707
                        dist = j;
708
                }
709
 
710
 
711
 
712
//              //DSPRINTF(ds,"mirror.tics == %ul", mirror[i].tics);
713
//              MONO_PRINT(ds);
714
 
715
 
716
                if (mirror[cnt].ismagic)
717
                {
718
                    SPRITEp sp=NULL;
719
                    int camhoriz;
8685 ny00123 720
                    short w;
5196 hendricks2 721
                    int dx, dy, dz, tdx, tdy, tdz, midx, midy;
722
 
723
 
724
                    ASSERT(mirror[cnt].camera != -1);
725
 
726
                    sp = &sprite[mirror[cnt].camera];
727
 
728
                    ASSERT(sp);
729
 
8686 ny00123 730
                    // char tvisibility;
5207 hendricks2 731
                    // tvisibility = g_visibility;
732
//                  g_visibility <<= 1;       // Make mirror darker
5196 hendricks2 733
 
734
                    // Make TV cam style mirror seem to shimmer
735
//                  if (mirror[cnt].ismagic && STD_RANDOM_P2(256) > 128)
5207 hendricks2 736
//                      g_visibility -= STD_RANDOM_P2(128);
5196 hendricks2 737
 
738
                    // Calculate the angle of the mirror wall
739
                    w = mirror[cnt].mirrorwall;
740
 
741
                    // Get wall midpoint for offset in mirror view
742
                    midx = (wall[w].x + wall[wall[w].point2].x) / 2;
743
                    midy = (wall[w].y + wall[wall[w].point2].y) / 2;
744
 
745
                    // Finish finding offsets
746
                    tdx = klabs(midx - tx);
747
                    tdy = klabs(midy - ty);
748
 
749
                    if (midx >= tx)
750
                        dx = sp->x - tdx;
751
                    else
752
                        dx = sp->x + tdx;
753
 
754
                    if (midy >= ty)
755
                        dy = sp->y - tdy;
756
                    else
757
                        dy = sp->y + tdy;
758
 
759
                    tdz = klabs(tz - sp->z);
760
                    if (tz >= sp->z)
761
                        dz = sp->z + tdz;
762
                    else
763
                        dz = sp->z - tdz;
764
 
765
 
766
                    // Is it a TV cam or a teleporter that shows destination?
767
                    // TRUE = It's a TV cam
768
                    mirror[cnt].mstate = m_normal;
769
                    if (TEST_BOOL1(sp))
770
                        mirror[cnt].mstate = m_viewon;
771
 
772
                    // Show teleport destination
773
                    // NOTE: Adding MAXSECTORS lets you draw a room, even if
774
                    // you are outside of it!
7529 hendricks2 775
                    if (mirror[cnt].mstate != m_viewon)
5196 hendricks2 776
                    {
5204 hendricks2 777
                        tilesiz[MIRROR].x = tilesiz[MIRROR].y = 0;
5196 hendricks2 778
                        // Set TV camera sprite size to 0 to show mirror
779
                        // behind in this case!
780
 
781
                        if (mirror[cnt].campic != -1)
5204 hendricks2 782
                            tilesiz[mirror[cnt].campic].x = tilesiz[mirror[cnt].campic].y = 0;
5196 hendricks2 783
                        drawrooms(dx, dy, dz, tpang, tphoriz, sp->sectnum + MAXSECTORS);
784
                        analyzesprites(dx, dy, dz, FALSE);
7509 hendricks2 785
                        renderDrawMasks();
5196 hendricks2 786
                    }
787
                    else
788
                    {
5198 hendricks2 789
                        SWBOOL DoCam = FALSE;
5196 hendricks2 790
 
791
                        if (mirror[cnt].campic == -1)
792
                        {
793
                            TerminateGame();
794
                            printf("Missing campic for mirror %d\n",cnt);
795
                            printf("Map Coordinates: x = %d, y = %d\n",midx,midy);
796
                            exit(0);
797
                        }
798
 
799
                        // BOOL2 = Oscilate camera
800
                        if (TEST_BOOL2(sp) && MoveSkip2 == 0)
801
                        {
802
                            if (TEST_BOOL3(sp)) // If true add increment to
803
                            // angle else subtract
804
                            {
805
                                // Store current angle in TAG5
806
                                SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) + 4));
807
 
808
                                // TAG6 = Turn radius
809
                                if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
810
                                {
811
                                    RESET_BOOL3(sp);    // Reverse turn
812
                                    // direction.
813
                                }
814
                            }
815
                            else
816
                            {
817
                                // Store current angle in TAG5
818
                                SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) - 4));
819
 
820
                                // TAG6 = Turn radius
821
                                if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
822
                                {
823
                                    SET_BOOL3(sp);      // Reverse turn
824
                                    // direction.
825
                                }
826
                            }
827
                        }
828
                        else if (!TEST_BOOL2(sp))
829
                        {
830
                            SP_TAG5(sp) = sp->ang;      // Copy sprite angle to
831
                            // tag5
832
                        }
833
 
834
                        // See if there is a horizon value.  0 defaults to
835
                        // 100!
836
                        if (SP_TAG7(sp) != 0)
837
                        {
838
                            camhoriz = SP_TAG7(sp);
839
                            if (camhoriz > PLAYER_HORIZ_MAX)
840
                                camhoriz = PLAYER_HORIZ_MAX;
841
                            else if (camhoriz < PLAYER_HORIZ_MIN)
842
                                camhoriz = PLAYER_HORIZ_MIN;
843
                        }
844
                        else
845
                            camhoriz = 100;     // Default
846
 
847
                        // If player is dead still then update at MoveSkip4
848
                        // rate.
849
                        if (pp->posx == pp->oposx && pp->posy == pp->oposy && pp->posz == pp->oposz)
850
                            DoCam = TRUE;
851
 
852
 
853
                        // Set up the tile for drawing
5204 hendricks2 854
                        tilesiz[mirror[cnt].campic].x = tilesiz[mirror[cnt].campic].y = 128;
5196 hendricks2 855
 
856
                        if (MirrorMoveSkip16 == 0 || (DoCam && (MoveSkip4 == 0)))
857
                        {
858
                            if (dist < MAXCAMDIST)
859
                            {
860
                                PLAYERp cp = Player + camplayerview;
861
 
862
                                if (TEST_BOOL11(sp) && numplayers > 1)
863
                                {
864
                                    drawroomstotile(cp->posx, cp->posy, cp->posz, cp->pang, cp->horiz, cp->cursectnum, mirror[cnt].campic);
865
                                }
866
                                else
867
                                {
868
                                    drawroomstotile(sp->x, sp->y, sp->z, SP_TAG5(sp), camhoriz, sp->sectnum, mirror[cnt].campic);
869
                                }
870
                            }
871
                        }
872
                    }
873
                }
874
                else
875
                {
876
                    // It's just a mirror
877
                    // Prepare drawrooms for drawing mirror and calculate
878
                    // reflected
879
                    // position into tposx, tposy, and tang (tposz == cposz)
880
                    // Must call preparemirror before drawrooms and
881
                    // completemirror after drawrooms
882
 
8588 hendricks2 883
                    renderPrepareMirror(tx, ty, tz, fix16_from_int(tpang), fix16_from_int(tphoriz),
5201 hendricks2 884
                                  mirror[cnt].mirrorwall, /*mirror[cnt].mirrorsector,*/ &tposx, &tposy, &tang);
5196 hendricks2 885
 
7509 hendricks2 886
                    drawrooms(tposx, tposy, tz, fix16_to_int(tang), tphoriz, mirror[cnt].mirrorsector + MAXSECTORS);
5196 hendricks2 887
 
888
                    analyzesprites(tposx, tposy, tz, TRUE);
7509 hendricks2 889
                    renderDrawMasks();
5196 hendricks2 890
 
7509 hendricks2 891
                    renderCompleteMirror();   // Reverse screen x-wise in this
5196 hendricks2 892
                    // function
893
                }
894
 
895
 
5207 hendricks2 896
                // g_visibility = tvisibility;
897
                // g_visibility = NormalVisibility;
5196 hendricks2 898
 
899
                // drawrooms(tx, ty, tz, tpang, tphoriz, pp->cursectnum);
900
                // Clean up anything that the camera view might have done
901
                SetFragBar(pp);
5204 hendricks2 902
                tilesiz[MIRROR].x = tilesiz[MIRROR].y = 0;
5196 hendricks2 903
                wall[mirror[cnt].mirrorwall].overpicnum = MIRRORLABEL + cnt;
904
            }
905
            else
906
                mirrorinview = FALSE;
907
    }
908
}
909
 
910
void
8519 hendricks2 911
DoAutoSize(tspriteptr_t tspr)
5196 hendricks2 912
{
913
    if (!bAutoSize)
914
        return;
915
 
916
    switch (tspr->picnum)
917
    {
918
    case ICON_STAR:                     // 1793
919
        break;
920
    case ICON_UZI:                      // 1797
921
        tspr->xrepeat = 43;
922
        tspr->yrepeat = 40;
923
        break;
924
    case ICON_UZIFLOOR:         // 1807
925
        tspr->xrepeat = 43;
926
        tspr->yrepeat = 40;
927
        break;
928
    case ICON_LG_UZI_AMMO:              // 1799
929
        break;
930
    case ICON_HEART:                    // 1824
931
        break;
932
    case ICON_HEART_LG_AMMO:            // 1820
933
        break;
934
    case ICON_GUARD_HEAD:               // 1814
935
        break;
936
    case ICON_FIREBALL_LG_AMMO: // 3035
937
        break;
938
    case ICON_ROCKET:                   // 1843
939
        break;
940
    case ICON_SHOTGUN:                  // 1794
941
        tspr->xrepeat = 57;
942
        tspr->yrepeat = 58;
943
        break;
944
    case ICON_LG_ROCKET:                // 1796
945
        break;
946
    case ICON_LG_SHOTSHELL:             // 1823
947
        break;
948
    case ICON_MICRO_GUN:                // 1818
949
        break;
950
    case ICON_MICRO_BATTERY:            // 1800
951
        break;
952
    case ICON_GRENADE_LAUNCHER: // 1817
953
        tspr->xrepeat = 54;
954
        tspr->yrepeat = 52;
955
        break;
956
    case ICON_LG_GRENADE:               // 1831
957
        break;
958
    case ICON_LG_MINE:                  // 1842
959
        break;
960
    case ICON_RAIL_GUN:         // 1811
961
        tspr->xrepeat = 50;
962
        tspr->yrepeat = 54;
963
        break;
964
    case ICON_RAIL_AMMO:                // 1812
965
        break;
966
    case ICON_SM_MEDKIT:                // 1802
967
        break;
968
    case ICON_MEDKIT:                   // 1803
969
        break;
970
    case ICON_CHEMBOMB:
971
        tspr->xrepeat = 64;
972
        tspr->yrepeat = 47;
973
        break;
974
    case ICON_FLASHBOMB:
975
        tspr->xrepeat = 32;
976
        tspr->yrepeat = 34;
977
        break;
978
    case ICON_NUKE:
979
        break;
980
    case ICON_CALTROPS:
981
        tspr->xrepeat = 37;
982
        tspr->yrepeat = 30;
983
        break;
984
    case ICON_BOOSTER:                  // 1810
985
        tspr->xrepeat = 30;
986
        tspr->yrepeat = 38;
987
        break;
988
    case ICON_HEAT_CARD:                // 1819
989
        tspr->xrepeat = 46;
990
        tspr->yrepeat = 47;
991
        break;
992
    case ICON_REPAIR_KIT:               // 1813
993
        break;
994
    case ICON_EXPLOSIVE_BOX:            // 1801
995
        break;
996
    case ICON_ENVIRON_SUIT:             // 1837
997
        break;
998
    case ICON_FLY:                      // 1782
999
        break;
1000
    case ICON_CLOAK:                    // 1826
1001
        break;
1002
    case ICON_NIGHT_VISION:             // 3031
1003
        tspr->xrepeat = 59;
1004
        tspr->yrepeat = 71;
1005
        break;
1006
    case ICON_NAPALM:                   // 3046
1007
        break;
1008
    case ICON_RING:                     // 3050
1009
        break;
1010
    case ICON_RINGAMMO:         // 3054
1011
        break;
1012
    case ICON_NAPALMAMMO:               // 3058
1013
        break;
1014
    case ICON_GRENADE:                  // 3059
1015
        break;
1016
    case ICON_ARMOR:                    // 3030
1017
        tspr->xrepeat = 82;
1018
        tspr->yrepeat = 84;
1019
        break;
1020
    case BLUE_KEY:                      // 1766
1021
        break;
1022
    case RED_KEY:                       // 1770
1023
        break;
1024
    case GREEN_KEY:                     // 1774
1025
        break;
1026
    case YELLOW_KEY:                    // 1778
1027
        break;
1028
    case BLUE_CARD:
1029
    case RED_CARD:
1030
    case GREEN_CARD:
1031
    case YELLOW_CARD:
1032
        tspr->xrepeat = 36;
1033
        tspr->yrepeat = 33;
1034
        break;
1035
    case GOLD_SKELKEY:
1036
    case SILVER_SKELKEY:
1037
    case BRONZE_SKELKEY:
1038
    case RED_SKELKEY:
1039
        tspr->xrepeat = 39;
1040
        tspr->yrepeat = 45;
1041
        break;
1042
    case SKEL_LOCKED:
1043
    case SKEL_UNLOCKED:
1044
        tspr->xrepeat = 47;
1045
        tspr->yrepeat = 40;
1046
        break;
1047
    case RAMCARD_LOCKED:
1048
    case RAMCARD_UNLOCKED:
1049
    case CARD_LOCKED:
1050
    case CARD_UNLOCKED:
1051
        break;
1052
    default:
1053
        break;
1054
    }
1055
}
1056
 
1057
// Rotation angles for sprites
1058
short rotang = 0;
1059
 
1060
void
8519 hendricks2 1061
JAnalyzeSprites(tspriteptr_t tspr)
5196 hendricks2 1062
{
1063
    rotang += 4;
1064
    if (rotang > 2047)
1065
        rotang = 0;
1066
 
1067
 
1068
    // Take care of autosizing
1069
    DoAutoSize(tspr);
1070
 
7509 hendricks2 1071
    if (videoGetRenderMode() >= REND_POLYMOST && md_tilehasmodel(tspr->picnum, 0) >= 0 && usemodels) return;
5196 hendricks2 1072
 
8596 hendricks2 1073
    Bassert((unsigned)tspr->owner < MAXSPRITES);
1074
 
5196 hendricks2 1075
    // Check for voxels
1076
    //if (bVoxelsOn)
8596 hendricks2 1077
    if (gs.Voxels && usevoxels && videoGetRenderMode() != REND_POLYMER)
5196 hendricks2 1078
    {
8596 hendricks2 1079
        if (aVoxelArray[tspr->picnum].Voxel >= 0 && !(spriteext[tspr->owner].flags&SPREXT_NOTMD))
5196 hendricks2 1080
        {
1081
            // Turn on voxels
1082
            tspr->picnum = aVoxelArray[tspr->picnum].Voxel;     // Get the voxel number
1083
            tspr->cstat |= 48;          // Set stat to voxelize sprite
1084
        }
1085
    }
1086
    else
1087
    {
1088
        switch (tspr->picnum)
1089
        {
1090
        case 764: // Gun barrel
8596 hendricks2 1091
            if (!usevoxels || videoGetRenderMode() == REND_POLYMER || (spriteext[tspr->owner].flags&SPREXT_NOTMD))
1092
            {
1093
                tspr->cstat |= 16;
1094
                break;
1095
            }
5196 hendricks2 1096
 
1097
            if (aVoxelArray[tspr->picnum].Voxel >= 0)
1098
            {
1099
                // Turn on voxels
1100
                tspr->picnum = aVoxelArray[tspr->picnum].Voxel;     // Get the voxel number
1101
                tspr->cstat |= 48;          // Set stat to voxelize sprite
1102
            }
1103
            break;
1104
        }
1105
    }
1106
}
1107
 
1108
//////////////////////////////////////////////////////////////////////////////////////////////
1109
// Parental Lockout Stuff
1110
//////////////////////////////////////////////////////////////////////////////////////////////
1111
OrgTileList orgwalllist;                // The list containing orginal wall
1112
// pics
1113
OrgTileList orgwalloverlist;            // The list containing orginal wall
1114
// over pics
1115
OrgTileList orgsectorceilinglist;       // The list containing orginal sector
1116
// ceiling pics
1117
OrgTileList orgsectorfloorlist;         // The list containing orginal sector
1118
// floor pics
1119
 
1120
void
1121
InsertOrgTile(OrgTileP tp, OrgTileListP thelist)
1122
{
1123
    ASSERT(tp);
1124
    ASSERT(ValidPtr(tp));
1125
 
1126
    // if list is empty, insert at front
1127
    if (EMPTY(thelist))
1128
    {
1129
        INSERT(thelist, tp);
1130
        return;
1131
    }
1132
 
1133
    // Otherwise insert it at end
1134
    INSERT_TAIL(thelist, tp);
1135
    return;
1136
}
1137
 
1138
 
1139
OrgTileP
1140
InitOrgTile(OrgTileListP thelist)
1141
{
1142
    OrgTileP tp;
1143
 
1144
 
7503 hendricks2 1145
    tp = (OrgTileP)CallocMem(sizeof(OrgTile), 1);
5196 hendricks2 1146
 
1147
    ASSERT(tp);
1148
 
1149
    InsertOrgTile(tp, thelist);
1150
 
1151
    return tp;
1152
}
1153
 
5198 hendricks2 1154
void
5196 hendricks2 1155
KillOrgTile(OrgTileP tp)
1156
{
1157
    ASSERT(tp);
1158
    ASSERT(ValidPtr(tp));
1159
 
5200 hendricks2 1160
    REMOVE(tp);
5196 hendricks2 1161
 
1162
    FreeMem(tp);
1163
}
1164
 
1165
OrgTileP
1166
FindOrgTile(short index, OrgTileListP thelist)
1167
{
1168
    OrgTileP tp, next_tp;
1169
 
1170
    if (EMPTY(thelist))
1171
        return NULL;
1172
 
1173
    TRAVERSE(thelist, tp, next_tp)
1174
    {
1175
        if (tp->index == index)
1176
            return tp;
1177
    }
1178
 
1179
    return NULL;
1180
}
1181
 
1182
// Call this at terminate game time
5198 hendricks2 1183
void
5196 hendricks2 1184
JS_UnInitLockouts(void)
1185
{
1186
    OrgTileP tp=NULL, next_tp=NULL;
1187
 
1188
 
1189
    TRAVERSE(&orgwalllist, tp, next_tp)
1190
    {
1191
        KillOrgTile(tp);
1192
    }
1193
    TRAVERSE(&orgwalloverlist, tp, next_tp)
1194
    {
1195
        KillOrgTile(tp);
1196
    }
1197
    TRAVERSE(&orgsectorceilinglist, tp, next_tp)
1198
    {
1199
        KillOrgTile(tp);
1200
    }
1201
    TRAVERSE(&orgsectorfloorlist, tp, next_tp)
1202
    {
1203
        KillOrgTile(tp);
1204
    }
1205
}
1206
 
1207
/////////////////////////////////////////////////////
1208
//  Initialize the original tiles list
1209
//  Creates a list of all orginal tiles and their
1210
//  replacements.  Several tiles can use the same
1211
//  replacement tilenum, so the list is built
1212
//  using the original tilenums as a basis for
1213
//  memory allocation
1214
//  t == 1 - wall
1215
//  t == 2 - overpicnum
1216
//  t == 3 - ceiling
1217
//  t == 4 - floor
1218
/////////////////////////////////////////////////////
1219
void
1220
JS_PlockError(short wall_num, short t)
1221
{
1222
    TerminateGame();
1223
    printf("ERROR: JS_InitLockouts(), out of range tile number\n");
1224
    switch (t)
1225
    {
1226
    case 1:
7500 hendricks2 1227
        printf("wall %d, x %d, y %d, pic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].picnum));
5196 hendricks2 1228
        break;
1229
    case 2:
7500 hendricks2 1230
        printf("wall %d, x %d, y %d, OVERpic %d\n", wall_num, TrackerCast(wall[wall_num].x), TrackerCast(wall[wall_num].y), TrackerCast(wall[wall_num].overpicnum));
5196 hendricks2 1231
        break;
1232
    case 3:
7500 hendricks2 1233
        printf("sector %d, ceiling %d\n", wall_num, TrackerCast(sector[wall_num].ceilingpicnum));
5196 hendricks2 1234
        break;
1235
    case 4:
7500 hendricks2 1236
        printf("sector %d, floor %d\n", wall_num, TrackerCast(sector[wall_num].floorpicnum));
5196 hendricks2 1237
        break;
1238
    }
1239
    exit(0);
1240
}
1241
 
1242
void
1243
JS_InitLockouts(void)
1244
{
8685 ny00123 1245
    short i;
5196 hendricks2 1246
    OrgTileP tp;
1247
 
1248
    INITLIST(&orgwalllist);             // The list containing orginal wall
1249
    // pics
1250
    INITLIST(&orgwalloverlist);         // The list containing orginal wall
1251
    // over pics
1252
    INITLIST(&orgsectorceilinglist);    // The list containing orginal sector
1253
    // ceiling pics
1254
    INITLIST(&orgsectorfloorlist);      // The list containing orginal sector
1255
    // floor pics
1256
 
1257
    // Check all walls
1258
    for (i = 0; i < numwalls; i++)
1259
    {
1260
        short picnum;
1261
 
1262
        picnum = wall[i].picnum;
1263
        if (aVoxelArray[picnum].Parental >= INVISTILE)
1264
            JS_PlockError(i,1);
1265
 
1266
        if (aVoxelArray[picnum].Parental >= 0)
1267
        {
1268
            if ((tp = FindOrgTile(i, &orgwalllist)) == NULL)
1269
                tp = InitOrgTile(&orgwalllist);
1270
            tp->index = i;
1271
            tp->orgpicnum = wall[i].picnum;
1272
        }
1273
 
1274
        picnum = wall[i].overpicnum;
1275
        if (aVoxelArray[picnum].Parental >= INVISTILE)
1276
            JS_PlockError(i,2);
1277
 
1278
        if (aVoxelArray[picnum].Parental >= 0)
1279
        {
1280
            if ((tp = FindOrgTile(i, &orgwalloverlist)) == NULL)
1281
                tp = InitOrgTile(&orgwalloverlist);
1282
            tp->index = i;
1283
            tp->orgpicnum = wall[i].overpicnum;
1284
        }
1285
    }
1286
    // Check all ceilings and floors
1287
    for (i = 0; i < numsectors; i++)
1288
    {
1289
        short picnum;
1290
 
1291
        picnum = sector[i].ceilingpicnum;
1292
        if (aVoxelArray[picnum].Parental >= INVISTILE)
1293
            JS_PlockError(i,3);
1294
 
1295
        if (aVoxelArray[picnum].Parental >= 0)
1296
        {
1297
            if ((tp = FindOrgTile(i, &orgsectorceilinglist)) == NULL)
1298
                tp = InitOrgTile(&orgsectorceilinglist);
1299
            tp->index = i;
1300
            tp->orgpicnum = sector[i].ceilingpicnum;
1301
        }
1302
 
1303
        picnum = sector[i].floorpicnum;
1304
        if (aVoxelArray[picnum].Parental >= INVISTILE)
1305
            JS_PlockError(i,2);
1306
 
1307
        if (aVoxelArray[picnum].Parental >= 0)
1308
        {
1309
            if ((tp = FindOrgTile(i, &orgsectorfloorlist)) == NULL)
1310
                tp = InitOrgTile(&orgsectorfloorlist);
1311
            tp->index = i;
1312
            tp->orgpicnum = sector[i].floorpicnum;
1313
        }
1314
    }
1315
}
1316
 
1317
/////////////////////////////////////////////////////
1318
//  Switch back and forth between locked out stuff
1319
/////////////////////////////////////////////////////
1320
void
1321
JS_ToggleLockouts(void)
1322
{
8685 ny00123 1323
    short i;
5196 hendricks2 1324
    OrgTileP tp;
1325
 
1326
 
1327
    // Check all walls
1328
    for (i = 0; i < numwalls; i++)
1329
    {
1330
        short picnum;
1331
 
1332
        if (gs.ParentalLock)
1333
        {
1334
            picnum = wall[i].picnum;
1335
            ASSERT(aVoxelArray[picnum].Parental < INVISTILE);   // Invalid, walls can't
1336
            // be invisible
1337
            if (aVoxelArray[picnum].Parental >= 0)
1338
            {
1339
                wall[i].picnum = aVoxelArray[picnum].Parental;
1340
            }
1341
        }
1342
        else if ((tp = FindOrgTile(i, &orgwalllist)) != NULL)
1343
            wall[i].picnum = tp->orgpicnum;     // Restore them
1344
 
1345
 
1346
        if (gs.ParentalLock)
1347
        {
1348
            picnum = wall[i].overpicnum;
1349
            ASSERT(aVoxelArray[picnum].Parental < INVISTILE);   // Invalid, walls can't
1350
            // be invisible
1351
            if (aVoxelArray[picnum].Parental >= 0)
1352
            {
1353
                wall[i].overpicnum = aVoxelArray[picnum].Parental;
1354
            }
1355
        }
1356
        else if ((tp = FindOrgTile(i, &orgwalloverlist)) != NULL)
1357
            wall[i].overpicnum = tp->orgpicnum; // Restore them
1358
    }
1359
 
1360
    // Check all sectors
1361
    for (i = 0; i < numsectors; i++)
1362
    {
1363
        short picnum;
1364
 
1365
        if (gs.ParentalLock)
1366
        {
1367
            picnum = sector[i].ceilingpicnum;
1368
            ASSERT(aVoxelArray[picnum].Parental < INVISTILE);   // Invalid, walls can't
1369
            // be invisible
1370
            if (aVoxelArray[picnum].Parental >= 0)
1371
            {
1372
                sector[i].ceilingpicnum = aVoxelArray[picnum].Parental;
1373
            }
1374
        }
1375
        else if ((tp = FindOrgTile(i, &orgsectorceilinglist)) != NULL)
1376
            sector[i].ceilingpicnum = tp->orgpicnum;    // Restore them
1377
 
1378
 
1379
        if (gs.ParentalLock)
1380
        {
1381
            picnum = sector[i].floorpicnum;
1382
            ASSERT(aVoxelArray[picnum].Parental < INVISTILE);   // Invalid, walls can't
1383
            // be invisible
1384
            if (aVoxelArray[picnum].Parental >= 0)
1385
            {
1386
                sector[i].floorpicnum = aVoxelArray[picnum].Parental;
1387
            }
1388
        }
1389
        else if ((tp = FindOrgTile(i, &orgsectorfloorlist)) != NULL)
1390
            sector[i].floorpicnum = tp->orgpicnum;      // Restore them
1391
    }
1392
}
1393
 
1394
////////////////////////////////////////////////////////////////////////////////////////////////
1395
 
1396
void
5202 hendricks2 1397
UnlockKeyLock(short key_num, short hit_sprite)
5196 hendricks2 1398
{
1399
    SPRITEp sp;
1400
    int SpriteNum = 0, NextSprite = 0, color = 0;
1401
 
1402
    // Get palette by looking at key number
1403
    switch (key_num - 1)
1404
    {
1405
    case 0:                             // RED_KEY
1406
        color = PALETTE_PLAYER9;
1407
        break;
1408
    case 1:                             // BLUE_KEY
1409
        color = PALETTE_PLAYER7;
1410
        break;
1411
    case 2:                             // GREEN_KEY
1412
        color = PALETTE_PLAYER6;
1413
        break;
1414
    case 3:                             // YELLOW_KEY
1415
        color = PALETTE_PLAYER4;
1416
        break;
1417
    case 4:                             // SILVER_SKELKEY
1418
        color = PALETTE_PLAYER4;
1419
        break;
1420
    case 5:                             // GOLD_SKELKEY
1421
        color = PALETTE_PLAYER1;
1422
        break;
1423
    case 6:                             // BRONZE_SKELKEY
1424
        color = PALETTE_PLAYER8;
1425
        break;
1426
    case 7:                             // RED_SKELKEY
1427
        color = PALETTE_PLAYER9;
1428
        break;
1429
    }
1430
 
1431
    TRAVERSE_SPRITE_STAT(headspritestat[0], SpriteNum, NextSprite)
1432
    {
1433
        sp = &sprite[SpriteNum];
1434
 
1435
        switch (sp->picnum)
1436
        {
1437
        case SKEL_LOCKED:
1438
            if (sp->pal == color)
1439
            {
1440
                PlaySound(DIGI_UNLOCK, &sp->x, &sp->y, &sp->z, v3df_doppler | v3df_dontpan);
5202 hendricks2 1441
                if (SpriteNum == hit_sprite)
5196 hendricks2 1442
                    sp->picnum = SKEL_UNLOCKED;
1443
            }
1444
            break;
1445
        case RAMCARD_LOCKED:
1446
            if (sp->pal == color)
1447
            {
1448
                PlaySound(DIGI_CARDUNLOCK, &sp->x, &sp->y, &sp->z, v3df_doppler | v3df_dontpan);
1449
                sp->picnum = RAMCARD_UNLOCKED;
1450
            }
1451
            break;
1452
        case CARD_LOCKED:
1453
            if (sp->pal == color)
1454
            {
1455
                PlaySound(DIGI_RAMUNLOCK, &sp->x, &sp->y, &sp->z, v3df_doppler | v3df_dontpan);
5202 hendricks2 1456
                if (SpriteNum == hit_sprite)
5196 hendricks2 1457
                    sp->picnum = CARD_UNLOCKED;
1458
                else
1459
                    sp->picnum = CARD_UNLOCKED+1;
1460
            }
1461
            break;
1462
        }
1463
 
1464
    }
1465
}