Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8557 maxcodehac 1
// WL_ACT1.C
2
 
3
#include "wl_def.h"
4
#pragma hdrstop
5
 
6
/*
7
=============================================================================
8
 
9
                                                        STATICS
10
 
11
=============================================================================
12
*/
13
 
14
 
15
statobj_t       statobjlist[MAXSTATS];
16
statobj_t       *laststatobj;
17
 
18
 
19
struct
20
{
21
    short      picnum;
22
    wl_stat_t  type;
23
    uint32_t   specialFlags;    // they are ORed to the statobj_t flags
24
} statinfo[] =
25
{
26
    {SPR_STAT_0},                           // puddle          spr1v
27
    {SPR_STAT_1,block},                     // Green Barrel    "
28
    {SPR_STAT_2,block},                     // Table/chairs    "
29
    {SPR_STAT_3,block,FL_FULLBRIGHT},       // Floor lamp      "
30
    {SPR_STAT_4,none,FL_FULLBRIGHT},        // Chandelier      "
31
    {SPR_STAT_5,block},                     // Hanged man      "
32
    {SPR_STAT_6,bo_alpo},                   // Bad food        "
33
    {SPR_STAT_7,block},                     // Red pillar      "
34
    //
35
    // NEW PAGE
36
    //
37
    {SPR_STAT_8,block},                     // Tree            spr2v
38
    {SPR_STAT_9},                           // Skeleton flat   "
39
    {SPR_STAT_10,block},                    // Sink            " (SOD:gibs)
40
    {SPR_STAT_11,block},                    // Potted plant    "
41
    {SPR_STAT_12,block},                    // Urn             "
42
    {SPR_STAT_13,block},                    // Bare table      "
43
    {SPR_STAT_14,none,FL_FULLBRIGHT},       // Ceiling light   "
44
    #ifndef SPEAR
45
    {SPR_STAT_15},                          // Kitchen stuff   "
46
    #else
47
    {SPR_STAT_15,block},                    // Gibs!
48
    #endif
49
    //
50
    // NEW PAGE
51
    //
52
    {SPR_STAT_16,block},                    // suit of armor   spr3v
53
    {SPR_STAT_17,block},                    // Hanging cage    "
54
    {SPR_STAT_18,block},                    // SkeletoninCage  "
55
    {SPR_STAT_19},                          // Skeleton relax  "
56
    {SPR_STAT_20,bo_key1},                  // Key 1           "
57
    {SPR_STAT_21,bo_key2},                  // Key 2           "
58
    {SPR_STAT_22,block},                    // stuff             (SOD:gibs)
59
    {SPR_STAT_23},                          // stuff
60
    //
61
    // NEW PAGE
62
    //
63
    {SPR_STAT_24,bo_food},                  // Good food       spr4v
64
    {SPR_STAT_25,bo_firstaid},              // First aid       "
65
    {SPR_STAT_26,bo_clip},                  // Clip            "
66
    {SPR_STAT_27,bo_machinegun},            // Machine gun     "
67
    {SPR_STAT_28,bo_chaingun},              // Gatling gun     "
68
    {SPR_STAT_29,bo_cross},                 // Cross           "
69
    {SPR_STAT_30,bo_chalice},               // Chalice         "
70
    {SPR_STAT_31,bo_bible},                 // Bible           "
71
    //
72
    // NEW PAGE
73
    //
74
    {SPR_STAT_32,bo_crown},                 // crown           spr5v
75
    {SPR_STAT_33,bo_fullheal,FL_FULLBRIGHT},// one up          "
76
    {SPR_STAT_34,bo_gibs},                  // gibs            "
77
    {SPR_STAT_35,block},                    // barrel          "
78
    {SPR_STAT_36,block},                    // well            "
79
    {SPR_STAT_37,block},                    // Empty well      "
80
    {SPR_STAT_38,bo_gibs},                  // Gibs 2          "
81
    {SPR_STAT_39,block},                    // flag            "
82
    //
83
    // NEW PAGE
84
    //
85
    #ifndef SPEAR
86
    {SPR_STAT_40,block},                    // Call Apogee          spr7v
87
    #else
88
    {SPR_STAT_40},                          // Red light
89
    #endif
90
    //
91
    // NEW PAGE
92
    //
93
    {SPR_STAT_41},                          // junk            "
94
    {SPR_STAT_42},                          // junk            "
95
    {SPR_STAT_43},                          // junk            "
96
    #ifndef SPEAR
97
    {SPR_STAT_44},                          // pots            "
98
    #else
99
    {SPR_STAT_44,block},                    // Gibs!
100
    #endif
101
    {SPR_STAT_45,block},                    // stove           " (SOD:gibs)
102
    {SPR_STAT_46,block},                    // spears          " (SOD:gibs)
103
    {SPR_STAT_47},                          // vines           "
104
    //
105
    // NEW PAGE
106
    //
107
    #ifdef SPEAR
108
    {SPR_STAT_48,block},                    // marble pillar
109
    {SPR_STAT_49,bo_25clip},                // bonus 25 clip
110
    {SPR_STAT_50,block},                    // truck
111
    {SPR_STAT_51,bo_spear},                 // SPEAR OF DESTINY!
112
    #endif
113
 
114
    {SPR_STAT_26,bo_clip2},                 // Clip            "
115
#ifdef USE_DIR3DSPR
116
    // These are just two examples showing the new way of using dir 3d sprites.
117
    // You can find the allowed values in the objflag_t enum in wl_def.h.
118
    {SPR_STAT_47,none,FL_DIR_VERT_MID},
119
    {SPR_STAT_47,block,FL_DIR_HORIZ_MID},
120
#endif
121
    {-1}                                    // terminator
122
};
123
 
124
/*
125
===============
126
=
127
= InitStaticList
128
=
129
===============
130
*/
131
 
132
void InitStaticList (void)
133
{
134
    laststatobj = &statobjlist[0];
135
}
136
 
137
 
138
 
139
/*
140
===============
141
=
142
= SpawnStatic
143
=
144
===============
145
*/
146
 
147
void SpawnStatic (int tilex, int tiley, int type)
148
{
149
    laststatobj->shapenum = statinfo[type].picnum;
150
    laststatobj->tilex = tilex;
151
    laststatobj->tiley = tiley;
152
    laststatobj->visspot = &spotvis[tilex][tiley];
153
 
154
    switch (statinfo[type].type)
155
    {
156
        case block:
157
            actorat[tilex][tiley] = (objtype *) 64;          // consider it a blocking tile
158
        case none:
159
            laststatobj->flags = 0;
160
            break;
161
 
162
        case    bo_cross:
163
        case    bo_chalice:
164
        case    bo_bible:
165
        case    bo_crown:
166
        case    bo_fullheal:
167
            if (!loadedgame)
168
                gamestate.treasuretotal++;
169
 
170
        case    bo_firstaid:
171
        case    bo_key1:
172
        case    bo_key2:
173
        case    bo_key3:
174
        case    bo_key4:
175
        case    bo_clip:
176
        case    bo_25clip:
177
        case    bo_machinegun:
178
        case    bo_chaingun:
179
        case    bo_food:
180
        case    bo_alpo:
181
        case    bo_gibs:
182
        case    bo_spear:
183
            laststatobj->flags = FL_BONUS;
184
            laststatobj->itemnumber = statinfo[type].type;
185
            break;
186
    }
187
 
188
    laststatobj->flags |= statinfo[type].specialFlags;
189
 
190
    laststatobj++;
191
 
192
    if (laststatobj == &statobjlist[MAXSTATS])
193
        Quit ("Too many static objects!\n");
194
}
195
 
196
 
197
/*
198
===============
199
=
200
= PlaceItemType
201
=
202
= Called during game play to drop actors' items.  It finds the proper
203
= item number based on the item type (bo_???).  If there are no free item
204
= spots, nothing is done.
205
=
206
===============
207
*/
208
 
209
void PlaceItemType (int itemtype, int tilex, int tiley)
210
{
211
    int type;
212
    statobj_t *spot;
213
 
214
    //
215
    // find the item number
216
    //
217
    for (type=0; ; type++)
218
    {
219
        if (statinfo[type].picnum == -1)                    // end of list
220
            Quit ("PlaceItemType: couldn't find type!");
221
        if (statinfo[type].type == itemtype)
222
            break;
223
    }
224
 
225
    //
226
    // find a spot in statobjlist to put it in
227
    //
228
    for (spot=&statobjlist[0]; ; spot++)
229
    {
230
        if (spot==laststatobj)
231
        {
232
            if (spot == &statobjlist[MAXSTATS])
233
                return;                                     // no free spots
234
            laststatobj++;                                  // space at end
235
            break;
236
        }
237
 
238
        if (spot->shapenum == -1)                           // -1 is a free spot
239
            break;
240
    }
241
    //
242
    // place it
243
    //
244
    spot->shapenum = statinfo[type].picnum;
245
    spot->tilex = tilex;
246
    spot->tiley = tiley;
247
    spot->visspot = &spotvis[tilex][tiley];
248
    spot->flags = FL_BONUS | statinfo[type].specialFlags;
249
    spot->itemnumber = statinfo[type].type;
250
}
251
 
252
 
253
 
254
/*
255
=============================================================================
256
 
257
                                  DOORS
258
 
259
doorobjlist[] holds most of the information for the doors
260
 
261
doorposition[] holds the amount the door is open, ranging from 0 to 0xffff
262
        this is directly accessed by AsmRefresh during rendering
263
 
264
The number of doors is limited to 64 because a spot in tilemap holds the
265
        door number in the low 6 bits, with the high bit meaning a door center
266
        and bit 6 meaning a door side tile
267
 
268
Open doors conect two areas, so sounds will travel between them and sight
269
        will be checked when the player is in a connected area.
270
 
271
Areaconnect is incremented/decremented by each door. If >0 they connect
272
 
273
Every time a door opens or closes the areabyplayer matrix gets recalculated.
274
        An area is true if it connects with the player's current spor.
275
 
276
=============================================================================
277
*/
278
 
279
#define DOORWIDTH       0x7800
280
#define OPENTICS        300
281
 
282
doorobj_t       doorobjlist[MAXDOORS],*lastdoorobj;
283
short           doornum;
284
 
285
word            doorposition[MAXDOORS];             // leading edge of door 0=closed
286
                                                    // 0xffff = fully open
287
 
288
byte            areaconnect[NUMAREAS][NUMAREAS];
289
 
290
boolean         areabyplayer[NUMAREAS];
291
 
292
 
293
/*
294
==============
295
=
296
= ConnectAreas
297
=
298
= Scans outward from playerarea, marking all connected areas
299
=
300
==============
301
*/
302
 
303
void RecursiveConnect (int areanumber)
304
{
305
    int i;
306
 
307
    for (i=0;i
308
    {
309
        if (areaconnect[areanumber][i] && !areabyplayer[i])
310
        {
311
            areabyplayer[i] = true;
312
            RecursiveConnect (i);
313
        }
314
    }
315
}
316
 
317
 
318
void ConnectAreas (void)
319
{
320
    memset (areabyplayer,0,sizeof(areabyplayer));
321
    areabyplayer[player->areanumber] = true;
322
    RecursiveConnect (player->areanumber);
323
}
324
 
325
 
326
void InitAreas (void)
327
{
328
    memset (areabyplayer,0,sizeof(areabyplayer));
329
    if (player->areanumber < NUMAREAS)
330
        areabyplayer[player->areanumber] = true;
331
}
332
 
333
 
334
 
335
/*
336
===============
337
=
338
= InitDoorList
339
=
340
===============
341
*/
342
 
343
void InitDoorList (void)
344
{
345
    memset (areabyplayer,0,sizeof(areabyplayer));
346
    memset (areaconnect,0,sizeof(areaconnect));
347
 
348
    lastdoorobj = &doorobjlist[0];
349
    doornum = 0;
350
}
351
 
352
 
353
/*
354
===============
355
=
356
= SpawnDoor
357
=
358
===============
359
*/
360
 
361
void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
362
{
363
    word *map;
364
 
365
    if (doornum==MAXDOORS)
366
        Quit ("64+ doors on level!");
367
 
368
    doorposition[doornum] = 0;              // doors start out fully closed
369
    lastdoorobj->tilex = tilex;
370
    lastdoorobj->tiley = tiley;
371
    lastdoorobj->vertical = vertical;
372
    lastdoorobj->lock = lock;
373
    lastdoorobj->action = dr_closed;
374
 
375
    actorat[tilex][tiley] = (objtype *)(uintptr_t)(doornum | 0x80);   // consider it a solid wall
376
 
377
    //
378
    // make the door tile a special tile, and mark the adjacent tiles
379
    // for door sides
380
    //
381
    tilemap[tilex][tiley] = doornum | 0x80;
382
    map = mapsegs[0] + (tiley<
383
    if (vertical)
384
    {
385
        *map = *(map-1);                        // set area number
386
        tilemap[tilex][tiley-1] |= 0x40;
387
        tilemap[tilex][tiley+1] |= 0x40;
388
    }
389
    else
390
    {
391
        *map = *(map-mapwidth);                                 // set area number
392
        tilemap[tilex-1][tiley] |= 0x40;
393
        tilemap[tilex+1][tiley] |= 0x40;
394
    }
395
 
396
    doornum++;
397
    lastdoorobj++;
398
}
399
 
400
//===========================================================================
401
 
402
/*
403
=====================
404
=
405
= OpenDoor
406
=
407
=====================
408
*/
409
 
410
void OpenDoor (int door)
411
{
412
    if (doorobjlist[door].action == dr_open)
413
        doorobjlist[door].ticcount = 0;         // reset open time
414
    else
415
        doorobjlist[door].action = dr_opening;  // start it opening
416
}
417
 
418
 
419
/*
420
=====================
421
=
422
= CloseDoor
423
=
424
=====================
425
*/
426
 
427
void CloseDoor (int door)
428
{
429
    int     tilex,tiley,area;
430
    objtype *check;
431
 
432
    //
433
    // don't close on anything solid
434
    //
435
    tilex = doorobjlist[door].tilex;
436
    tiley = doorobjlist[door].tiley;
437
 
438
    if (actorat[tilex][tiley])
439
        return;
440
 
441
    if (player->tilex == tilex && player->tiley == tiley)
442
        return;
443
 
444
    if (doorobjlist[door].vertical)
445
    {
446
        if ( player->tiley == tiley )
447
        {
448
            if ( ((player->x+MINDIST) >>TILESHIFT) == tilex )
449
                return;
450
            if ( ((player->x-MINDIST) >>TILESHIFT) == tilex )
451
                return;
452
        }
453
        check = actorat[tilex-1][tiley];
454
        if (ISPOINTER(check) && ((check->x+MINDIST) >> TILESHIFT) == tilex )
455
            return;
456
        check = actorat[tilex+1][tiley];
457
        if (ISPOINTER(check) && ((check->x-MINDIST) >> TILESHIFT) == tilex )
458
            return;
459
    }
460
    else if (!doorobjlist[door].vertical)
461
    {
462
        if (player->tilex == tilex)
463
        {
464
            if ( ((player->y+MINDIST) >>TILESHIFT) == tiley )
465
                return;
466
            if ( ((player->y-MINDIST) >>TILESHIFT) == tiley )
467
                return;
468
        }
469
        check = actorat[tilex][tiley-1];
470
        if (ISPOINTER(check) && ((check->y+MINDIST) >> TILESHIFT) == tiley )
471
            return;
472
        check = actorat[tilex][tiley+1];
473
        if (ISPOINTER(check) && ((check->y-MINDIST) >> TILESHIFT) == tiley )
474
            return;
475
    }
476
 
477
 
478
    //
479
    // play door sound if in a connected area
480
    //
481
    area = *(mapsegs[0] + (doorobjlist[door].tiley<
482
        +doorobjlist[door].tilex)-AREATILE;
483
    if (areabyplayer[area])
484
    {
485
        PlaySoundLocTile(CLOSEDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley); // JAB
486
    }
487
 
488
    doorobjlist[door].action = dr_closing;
489
    //
490
    // make the door space solid
491
    //
492
    actorat[tilex][tiley] = (objtype *)(uintptr_t)(door | 0x80);
493
}
494
 
495
 
496
 
497
/*
498
=====================
499
=
500
= OperateDoor
501
=
502
= The player wants to change the door's direction
503
=
504
=====================
505
*/
506
 
507
void OperateDoor (int door)
508
{
509
    int lock;
510
 
511
    lock = doorobjlist[door].lock;
512
    if (lock >= dr_lock1 && lock <= dr_lock4)
513
    {
514
        if ( ! (gamestate.keys & (1 << (lock-dr_lock1) ) ) )
515
        {
516
            SD_PlaySound (NOWAYSND);                // locked
517
            return;
518
        }
519
    }
520
 
521
    switch (doorobjlist[door].action)
522
    {
523
        case dr_closed:
524
        case dr_closing:
525
            OpenDoor (door);
526
            break;
527
        case dr_open:
528
        case dr_opening:
529
            CloseDoor (door);
530
            break;
531
    }
532
}
533
 
534
 
535
//===========================================================================
536
 
537
/*
538
===============
539
=
540
= DoorOpen
541
=
542
= Close the door after three seconds
543
=
544
===============
545
*/
546
 
547
void DoorOpen (int door)
548
{
549
    if ( (doorobjlist[door].ticcount += (short) tics) >= OPENTICS)
550
        CloseDoor (door);
551
}
552
 
553
 
554
 
555
/*
556
===============
557
=
558
= DoorOpening
559
=
560
===============
561
*/
562
 
563
void DoorOpening (int door)
564
{
565
    unsigned area1,area2;
566
    word *map;
567
    int32_t position;
568
 
569
    position = doorposition[door];
570
    if (!position)
571
    {
572
        //
573
        // door is just starting to open, so connect the areas
574
        //
575
        map = mapsegs[0] + (doorobjlist[door].tiley<
576
            +doorobjlist[door].tilex;
577
 
578
        if (doorobjlist[door].vertical)
579
        {
580
            area1 = *(map+1);
581
            area2 = *(map-1);
582
        }
583
        else
584
        {
585
            area1 = *(map-mapwidth);
586
            area2 = *(map+mapwidth);
587
        }
588
        area1 -= AREATILE;
589
        area2 -= AREATILE;
590
 
591
        if (area1 < NUMAREAS && area2 < NUMAREAS)
592
        {
593
            areaconnect[area1][area2]++;
594
            areaconnect[area2][area1]++;
595
 
596
            if (player->areanumber < NUMAREAS)
597
                ConnectAreas ();
598
 
599
            if (areabyplayer[area1])
600
                PlaySoundLocTile(OPENDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);  // JAB
601
        }
602
    }
603
 
604
    //
605
    // slide the door by an adaptive amount
606
    //
607
    position += tics<<10;
608
    if (position >= 0xffff)
609
    {
610
        //
611
        // door is all the way open
612
        //
613
        position = 0xffff;
614
        doorobjlist[door].ticcount = 0;
615
        doorobjlist[door].action = dr_open;
616
        actorat[doorobjlist[door].tilex][doorobjlist[door].tiley] = 0;
617
    }
618
 
619
    doorposition[door] = (word) position;
620
}
621
 
622
 
623
/*
624
===============
625
=
626
= DoorClosing
627
=
628
===============
629
*/
630
 
631
void DoorClosing (int door)
632
{
633
    unsigned area1,area2;
634
    word *map;
635
    int32_t position;
636
    int tilex,tiley;
637
 
638
    tilex = doorobjlist[door].tilex;
639
    tiley = doorobjlist[door].tiley;
640
 
641
    if ( ((int)(uintptr_t)actorat[tilex][tiley] != (door | 0x80))
642
        || (player->tilex == tilex && player->tiley == tiley) )
643
    {                       // something got inside the door
644
        OpenDoor (door);
645
        return;
646
    };
647
 
648
    position = doorposition[door];
649
 
650
    //
651
    // slide the door by an adaptive amount
652
    //
653
    position -= tics<<10;
654
    if (position <= 0)
655
    {
656
        //
657
        // door is closed all the way, so disconnect the areas
658
        //
659
        position = 0;
660
 
661
        doorobjlist[door].action = dr_closed;
662
 
663
        map = mapsegs[0] + (doorobjlist[door].tiley<
664
 
665
        if (doorobjlist[door].vertical)
666
        {
667
            area1 = *(map+1);
668
            area2 = *(map-1);
669
        }
670
        else
671
        {
672
            area1 = *(map-mapwidth);
673
            area2 = *(map+mapwidth);
674
        }
675
        area1 -= AREATILE;
676
        area2 -= AREATILE;
677
 
678
        if (area1 < NUMAREAS && area2 < NUMAREAS)
679
        {
680
            areaconnect[area1][area2]--;
681
            areaconnect[area2][area1]--;
682
 
683
            if (player->areanumber < NUMAREAS)
684
                ConnectAreas ();
685
        }
686
    }
687
 
688
    doorposition[door] = (word) position;
689
}
690
 
691
 
692
 
693
 
694
/*
695
=====================
696
=
697
= MoveDoors
698
=
699
= Called from PlayLoop
700
=
701
=====================
702
*/
703
 
704
void MoveDoors (void)
705
{
706
    int door;
707
 
708
    if (gamestate.victoryflag)              // don't move door during victory sequence
709
        return;
710
 
711
    for (door = 0; door < doornum; door++)
712
    {
713
        switch (doorobjlist[door].action)
714
        {
715
            case dr_open:
716
                DoorOpen (door);
717
                break;
718
 
719
            case dr_opening:
720
                DoorOpening(door);
721
                break;
722
 
723
            case dr_closing:
724
                DoorClosing(door);
725
                break;
726
        }
727
    }
728
}
729
 
730
 
731
/*
732
=============================================================================
733
 
734
                                PUSHABLE WALLS
735
 
736
=============================================================================
737
*/
738
 
739
word pwallstate;
740
word pwallpos;                  // amount a pushable wall has been moved (0-63)
741
word pwallx,pwally;
742
byte pwalldir,pwalltile;
743
int dirs[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
744
 
745
/*
746
===============
747
=
748
= PushWall
749
=
750
===============
751
*/
752
 
753
void PushWall (int checkx, int checky, int dir)
754
{
755
    int oldtile, dx, dy;
756
 
757
    if (pwallstate)
758
        return;
759
 
760
    oldtile = tilemap[checkx][checky];
761
    if (!oldtile)
762
        return;
763
 
764
    dx = dirs[dir][0];
765
    dy = dirs[dir][1];
766
 
767
    if (actorat[checkx+dx][checky+dy])
768
    {
769
        SD_PlaySound (NOWAYSND);
770
        return;
771
    }
772
    actorat[checkx+dx][checky+dy] = (objtype *)(uintptr_t) (tilemap[checkx+dx][checky+dy] = oldtile);
773
 
774
    gamestate.secretcount++;
775
    pwallx = checkx;
776
    pwally = checky;
777
    pwalldir = dir;
778
    pwallstate = 1;
779
    pwallpos = 0;
780
    pwalltile = tilemap[pwallx][pwally];
781
    tilemap[pwallx][pwally] = 64;
782
    tilemap[pwallx+dx][pwally+dy] = 64;
783
    *(mapsegs[1]+(pwally<
784
    *(mapsegs[0]+(pwally<tiley<tilex); // set correct floorcode (BrotherTank's fix)
785
 
786
    SD_PlaySound (PUSHWALLSND);
787
}
788
 
789
 
790
 
791
/*
792
=================
793
=
794
= MovePWalls
795
=
796
=================
797
*/
798
 
799
void MovePWalls (void)
800
{
801
    int oldblock,oldtile;
802
 
803
    if (!pwallstate)
804
        return;
805
 
806
    oldblock = pwallstate/128;
807
 
808
    pwallstate += (word)tics;
809
 
810
    if (pwallstate/128 != oldblock)
811
    {
812
        // block crossed into a new block
813
        oldtile = pwalltile;
814
 
815
        //
816
        // the tile can now be walked into
817
        //
818
        tilemap[pwallx][pwally] = 0;
819
        actorat[pwallx][pwally] = 0;
820
        *(mapsegs[0]+(pwally<areanumber+AREATILE;
821
 
822
        int dx=dirs[pwalldir][0], dy=dirs[pwalldir][1];
823
        //
824
        // see if it should be pushed farther
825
        //
826
        if (pwallstate>=256)            // only move two tiles fix
827
        {
828
            //
829
            // the block has been pushed two tiles
830
            //
831
            pwallstate = 0;
832
            tilemap[pwallx+dx][pwally+dy] = oldtile;
833
            return;
834
        }
835
        else
836
        {
837
            int xl,yl,xh,yh;
838
            xl = (player->x-PLAYERSIZE) >> TILESHIFT;
839
            yl = (player->y-PLAYERSIZE) >> TILESHIFT;
840
            xh = (player->x+PLAYERSIZE) >> TILESHIFT;
841
            yh = (player->y+PLAYERSIZE) >> TILESHIFT;
842
 
843
            pwallx += dx;
844
            pwally += dy;
845
 
846
            if (actorat[pwallx+dx][pwally+dy]
847
                || xl<=pwallx+dx && pwallx+dx<=xh && yl<=pwally+dy && pwally+dy<=yh)
848
            {
849
                pwallstate = 0;
850
                tilemap[pwallx][pwally] = oldtile;
851
                return;
852
            }
853
            actorat[pwallx+dx][pwally+dy] = (objtype *)(uintptr_t) (tilemap[pwallx+dx][pwally+dy] = oldtile);
854
            tilemap[pwallx+dx][pwally+dy] = 64;
855
        }
856
    }
857
 
858
    pwallpos = (pwallstate/2)&63;
859
}