Subversion Repositories eduke32

Rev

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

Rev Author Line No. Line
5 Plagman 1
//-------------------------------------------------------------------------
2
/*
3
Copyright (C) 1996, 2003 - 3D Realms Entertainment
484 terminx 4
Copyright (C) 2004, 2007 - EDuke32 developers
5 Plagman 5
 
484 terminx 6
This file is part of EDuke32
5 Plagman 7
 
484 terminx 8
EDuke32 is free software; you can redistribute it and/or
5 Plagman 9
modify it under the terms of the GNU General Public License version 2
10
as published by the Free Software Foundation.
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
331 terminx 14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 Plagman 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
*/
22
//-------------------------------------------------------------------------
23
 
24
#include "compat.h"
25
#include "build.h"
26
#include "editor.h"
27
#include "pragmas.h"
28
#include "baselayer.h"
29
#include "names.h"
30
#include "osd.h"
31
#include "osdfuncs.h"
32
#include "cache1d.h"
33
 
34
#include "mapster32.h"
35
#include "keys.h"
36
#include "types.h"
37
#include "keyboard.h"
249 terminx 38
#include "scriptfile.h"
534 terminx 39
#include "crc32.h"
5 Plagman 40
 
886 terminx 41
#define VERSION " 1.2.0devel"
5 Plagman 42
 
511 terminx 43
static int floor_over_floor;
5 Plagman 44
 
653 terminx 45
// static char *startwin_labeltext = "Starting Mapster32...";
480 terminx 46
static char setupfilename[BMAX_PATH]= "mapster32.cfg";
464 terminx 47
static char defaultduke3dgrp[BMAX_PATH] = "duke3d.grp";
48
static char *duke3dgrp = defaultduke3dgrp;
480 terminx 49
static int fixmapbeforesaving = 1;
728 terminx 50
static int lastsave = -180*60;
552 terminx 51
static int NoAutoLoad = 0;
744 hnt_ts 52
int spnoclip=1;
5 Plagman 53
 
654 terminx 54
#if !defined(_WIN32)
55
static int usecwd = 0;
56
#endif
57
 
464 terminx 58
static struct strllist
59
{
60
    struct strllist *next;
61
    char *str;
62
}
583 terminx 63
*CommandPaths = NULL, *CommandGrps = NULL;
464 terminx 64
 
5 Plagman 65
#define MAXHELP2D (signed int)(sizeof(Help2d)/sizeof(Help2d[0]))
727 terminx 66
 
67
#define eitherALT   (keystatus[KEYSC_LALT]|  keystatus[KEYSC_RALT])
68
#define eitherCTRL  (keystatus[KEYSC_LCTRL]| keystatus[KEYSC_RCTRL])
69
#define eitherSHIFT (keystatus[KEYSC_LSHIFT]|keystatus[KEYSC_RSHIFT])
70
 
534 terminx 71
static char *Help2d[]=
559 terminx 72
{
73
    " 'A = Autosave toggle",
74
    " 'J = Jump to location",
75
    " 'L = Adjust sprite/wall coords",
76
    " 'S = Sprite size",
77
    " '3 = Caption mode",
78
    " '7 = Swap tags",
79
    " 'F = Special functions",
80
    " X  = Horiz. flip selected sects",
81
    " Y  = Vert. flip selected sects",
82
    " F5 = Item count",
83
    " F6 = Actor count/SE help",
84
    " F7 = Edit sector",
85
    " F8 = Edit wall/sprite",
86
    " F9 = Sector tag help",
87
    " Ctrl-S = Quick save",
88
    " Alt-F7 = Search sector lotag",
89
    " Alt-F8 = Search wall/sprite tags",
90
    " [      = Search forward",
91
    " ]      = Search backward",
92
};
5 Plagman 93
 
534 terminx 94
static char *SpriteMode[]=
559 terminx 95
{
96
    "NONE",
97
    "SECTORS",
98
    "WALLS",
99
    "SPRITES",
100
    "ALL",
101
    "ITEMS ONLY",
102
    "CURRENT SPRITE ONLY",
103
    "ONLY SECTOREFFECTORS AND SECTORS",
104
    "NO SECTOREFFECTORS OR SECTORS"
105
};
5 Plagman 106
 
107
#define MAXSKILL 5
534 terminx 108
static char *SKILLMODE[MAXSKILL]=
559 terminx 109
{
110
    "Actor skill display: PIECE OF CAKE",
111
    "Actor skill display: LET'S ROCK",
112
    "Actor skill display: COME GET SOME",
113
    "Actor skill display: DAMN I'M GOOD",
114
    "Actor skill display: ALL SKILL LEVELS"
115
};
5 Plagman 116
 
117
#define MAXNOSPRITES 4
534 terminx 118
static char *SPRDSPMODE[MAXNOSPRITES]=
559 terminx 119
{
120
    "Sprite display: DISPLAY ALL SPRITES",
121
    "Sprite display: NO EFFECTORS",
122
    "Sprite display: NO ACTORS",
123
    "Sprite display: NO EFFECTORS OR ACTORS"
124
};
5 Plagman 125
 
126
#define MAXHELP3D (signed int)(sizeof(Help3d)/sizeof(Help3d[0]))
534 terminx 127
static char *Help3d[]=
559 terminx 128
{
129
    "Mapster32 3D mode help",
130
    " ",
131
    " F1 = TOGGLE THIS HELP DISPLAY",
132
    " F2 = TOGGLE CLIPBOARD",
133
    " F3 = MOUSELOOK",
134
    " F6 = AUTOMATIC SECTOREFFECTOR HELP",
135
    " F7 = AUTOMATIC SECTOR TAG HELP",
136
    "",
137
    " ' A = TOGGLE AUTOSAVE",
138
    " ' D = CYCLE SPRITE SKILL DISPLAY",
139
    " ' R = TOGGLE FRAMERATE DISPLAY",
140
    " ' W = TOGGLE SPRITE DISPLAY",
763 terminx 141
    " ' X = MAP SHADE PREVIEW",
559 terminx 142
    " ' Y = TOGGLE PURPLE BACKGROUND",
143
    "",
144
    " ' T = CHANGE LOTAG",
145
    " ' H = CHANGE HITAG",
146
    " ' S = CHANGE SHADE",
147
    " ' M = CHANGE EXTRA",
148
    " ' V = CHANGE VISIBILITY",
149
    " ' L = CHANGE OBJECT COORDINATES",
150
    " ' C = CHANGE GLOBAL SHADE",
151
    "",
152
    " ' ENTER = PASTE GRAPHIC ONLY",
153
    " ' P & ; P = PASTE PALETTE TO ALL SELECTED SECTORS",
154
    " ; V = SET VISIBILITY ON ALL SELECTED SECTORS",
155
    " ' DEL = CSTAT=0",
156
    " CTRL-S = SAVE BOARD",
157
    " HOME = PGUP/PGDN MODIFIER (256 UNITS)",
158
    " END = PGUP/PGDN MODIFIER (512 UNITS)",
159
};
782 terminx 160
static char *type2str[]={"Wall","Sector","Sector","Sprite","Wall"};
5 Plagman 161
 
507 terminx 162
static CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL;
163
static int numdirs=0, numfiles=0;
164
static int currentlist=0;
728 terminx 165
static int mouseaction=0, mouseax=0, mouseay=0;
166
static int repeatcountx, repeatcounty;
732 terminx 167
static int infobox=3; // bit0: current window, bit1: mouse pointer, the variable should be renamed
507 terminx 168
 
728 terminx 169
extern char mskip;
782 terminx 170
extern short capturecount;
853 terminx 171
extern int editorgridextent;    // in engine.c
728 terminx 172
 
507 terminx 173
static void clearfilenames(void)
174
{
175
    klistfree(finddirs);
176
    klistfree(findfiles);
177
    finddirs = findfiles = NULL;
178
    numfiles = numdirs = 0;
179
}
180
 
181
static int getfilenames(const char *path, char kind[])
182
{
183
    CACHE1D_FIND_REC *r;
184
 
185
    clearfilenames();
186
    finddirs = klistpath(path,"*",CACHE1D_FIND_DIR);
187
    findfiles = klistpath(path,kind,CACHE1D_FIND_FILE);
188
    for (r = finddirs; r; r=r->next) numdirs++;
189
    for (r = findfiles; r; r=r->next) numfiles++;
190
 
191
    finddirshigh = finddirs;
192
    findfileshigh = findfiles;
193
    currentlist = 0;
194
    if (findfileshigh) currentlist = 1;
195
 
196
    return(0);
197
}
198
 
5 Plagman 199
void ExtLoadMap(const char *mapname)
200
{
584 terminx 201
    int i;
202
    int sky=0;
5 Plagman 203
    int j;
783 terminx 204
 
205
    getmessageleng = 0;
206
    getmessagetimeoff = 0;
207
 
5 Plagman 208
    // PreCache Wall Tiles
209
    /*
210
        for(j=0;j<numwalls;j++)
211
            if(waloff[wall[j].picnum] == 0)
212
            {
213
                loadtile(wall[j].picnum);
214
                if (bpp != 8)
215
                    polymost_precache(wall[j].picnum,wall[j].pal,0);
216
            }
217
 
218
        for(j=0;j<numsectors;j++)
219
            if(waloff[sector[j].floorpicnum] == 0 || waloff[sector[j].ceilingpicnum] == 0)
220
            {
221
                loadtile(sector[j].floorpicnum);
222
                loadtile(sector[j].ceilingpicnum);
223
                if (bpp != 8)
224
                {
225
                    polymost_precache(sector[j].floorpicnum,sector[j].floorpal,0);
226
                    polymost_precache(sector[j].floorpicnum,sector[j].floorpal,0);
559 terminx 227
                }
5 Plagman 228
            }
229
 
230
        for(j=0;j<numsprites;j++)
231
            if(waloff[sprite[j].picnum] == 0)
232
            {
233
                loadtile(sprite[j].picnum);
234
                if (bpp != 8)
235
                    polymost_precache(sprite[j].picnum,sprite[j].pal,1);
236
            }
237
    */
238
    // Presize Sprites
331 terminx 239
    for (j=0;j<MAXSPRITES;j++)
5 Plagman 240
    {
331 terminx 241
        if (tilesizx[sprite[j].picnum]==0 || tilesizy[sprite[j].picnum]==0)
5 Plagman 242
            sprite[j].picnum=0;
243
 
331 terminx 244
        if (sprite[j].picnum>=20 && sprite[j].picnum<=59)
5 Plagman 245
        {
335 terminx 246
            if (sprite[j].picnum==26)
247
            {
248
                sprite[j].xrepeat = 8;
249
                sprite[j].yrepeat = 8;
5 Plagman 250
            }
251
            else
252
            {
335 terminx 253
                sprite[j].xrepeat = 32;
254
                sprite[j].yrepeat = 32;
5 Plagman 255
            }
256
        }
257
 
258
    }
259
 
260
    Bstrcpy(levelname,mapname);
261
    pskyoff[0]=0;
331 terminx 262
    for (i=0;i<8;i++) pskyoff[i]=0;
5 Plagman 263
 
331 terminx 264
    for (i=0;i<numsectors;i++)
5 Plagman 265
    {
331 terminx 266
        switch (sector[i].ceilingpicnum)
5 Plagman 267
        {
337 terminx 268
        case MOONSKY1 :
269
        case BIGORBIT1 : // orbit
270
        case LA : // la city
271
            sky=sector[i].ceilingpicnum;
272
            break;
5 Plagman 273
        }
274
    }
275
 
331 terminx 276
    switch (sky)
5 Plagman 277
    {
337 terminx 278
    case MOONSKY1 :
279
        //        earth          mountian   mountain         sun
280
        pskyoff[6]=1;
281
        pskyoff[1]=2;
282
        pskyoff[4]=2;
283
        pskyoff[2]=3;
284
        break;
5 Plagman 285
 
337 terminx 286
    case BIGORBIT1 : // orbit
287
        //       earth1         2           3           moon/sun
288
        pskyoff[5]=1;
289
        pskyoff[6]=2;
290
        pskyoff[7]=3;
291
        pskyoff[2]=4;
292
        break;
5 Plagman 293
 
337 terminx 294
    case LA : // la city
295
        //       earth1         2           3           moon/sun
296
        pskyoff[0]=1;
297
        pskyoff[1]=2;
298
        pskyoff[2]=1;
299
        pskyoff[3]=3;
300
        pskyoff[4]=4;
301
        pskyoff[5]=0;
302
        pskyoff[6]=2;
303
        pskyoff[7]=3;
304
        break;
5 Plagman 305
    }
306
 
307
    pskybits=3;
308
    parallaxtype=0;
309
    Bsprintf(tempbuf, "Mapster32"VERSION" - %s",mapname);
310
    wm_setapptitle(tempbuf);
311
}
312
 
313
void ExtSaveMap(const char *mapname)
314
{
654 terminx 315
    UNREFERENCED_PARAMETER(mapname);
5 Plagman 316
    saveboard("backup.map",&posx,&posy,&posz,&ang,&cursectnum);
317
}
318
 
858 terminx 319
int getTileGroup(const char *groupName)
320
{
321
    int temp;
322
    for (temp = 0; temp < MAX_TILE_GROUPS; temp++)
323
    {
859 terminx 324
        if (s_TileGroups[temp].szText == NULL)
325
        {
858 terminx 326
            return -1;
327
        }
328
        if (!strcmp(s_TileGroups[temp].szText, groupName))
329
        {
330
            return temp;
331
        }
332
    }
333
    return -1;
334
}
335
 
336
int tileInGroup(int group, int tilenum)
337
{
338
    // @todo Make a bitmap instead of doing this slow search..
339
    int temp;
340
    if (group < 0 || group >= MAX_TILE_GROUPS || s_TileGroups[group].szText == NULL)
341
    {
342
        // group isn't valid.
343
        return 0;
344
    }
345
    for (temp = 0; temp < s_TileGroups[group].nIds; temp++)
346
    {
347
        if (tilenum == s_TileGroups[group].pIds[temp])
348
        {
349
            return 1;
350
        }
351
    }
352
    return 0;
353
}
354
 
5 Plagman 355
const char *ExtGetSectorCaption(short sectnum)
356
{
331 terminx 357
    if (qsetmode != 200 && (!(onnames==1 || onnames==4 || onnames==7) || (onnames==8)))
5 Plagman 358
    {
359
        tempbuf[0] = 0;
360
        return(tempbuf);
361
    }
362
 
363
    if (qsetmode != 200 && (sector[sectnum].lotag|sector[sectnum].hitag) == 0)
364
    {
365
        tempbuf[0] = 0;
366
    }
367
    else
368
    {
331 terminx 369
        switch (sector[sectnum].lotag)
5 Plagman 370
        {
344 terminx 371
        case 1:
337 terminx 372
            Bsprintf(lo,"1 WATER (SE 7)");
373
            break;
344 terminx 374
        case 2:
337 terminx 375
            Bsprintf(lo,"2 UNDERWATER (SE 7)");
376
            break;
344 terminx 377
        case 9:
337 terminx 378
            Bsprintf(lo,"9 STAR TREK DOORS");
379
            break;
344 terminx 380
        case 15:
337 terminx 381
            Bsprintf(lo,"15 ELEVATOR TRANSPORT (SE 17)");
382
            break;
344 terminx 383
        case 16:
337 terminx 384
            Bsprintf(lo,"16 ELEVATOR PLATFORM DOWN");
385
            break;
344 terminx 386
        case 17:
337 terminx 387
            Bsprintf(lo,"17 ELEVATOR PLATFORM UP");
388
            break;
344 terminx 389
        case 18:
337 terminx 390
            Bsprintf(lo,"18 ELEVATOR DOWN");
391
            break;
344 terminx 392
        case 19:
337 terminx 393
            Bsprintf(lo,"19 ELEVATOR UP");
394
            break;
344 terminx 395
        case 20:
337 terminx 396
            Bsprintf(lo,"20 CEILING DOOR");
397
            break;
344 terminx 398
        case 21:
337 terminx 399
            Bsprintf(lo,"21 FLOOR DOOR");
400
            break;
344 terminx 401
        case 22:
337 terminx 402
            Bsprintf(lo,"22 SPLIT DOOR");
403
            break;
344 terminx 404
        case 23:
337 terminx 405
            Bsprintf(lo,"23 SWING DOOR (SE 11)");
406
            break;
344 terminx 407
        case 25:
337 terminx 408
            Bsprintf(lo,"25 SLIDE DOOR (SE 15)");
409
            break;
344 terminx 410
        case 26:
337 terminx 411
            Bsprintf(lo,"26 SPLIT STAR TREK DOOR");
412
            break;
344 terminx 413
        case 27:
337 terminx 414
            Bsprintf(lo,"27 BRIDGE (SE 20)");
415
            break;
344 terminx 416
        case 28:
337 terminx 417
            Bsprintf(lo,"28 DROP FLOOR (SE 21)");
418
            break;
344 terminx 419
        case 29:
337 terminx 420
            Bsprintf(lo,"29 TEETH DOOR (SE 22)");
421
            break;
344 terminx 422
        case 30:
337 terminx 423
            Bsprintf(lo,"30 ROTATE RISE BRIDGE");
424
            break;
344 terminx 425
        case 31:
337 terminx 426
            Bsprintf(lo,"31 2 WAY TRAIN (SE=30)");
427
            break;
344 terminx 428
        case 32767:
337 terminx 429
            Bsprintf(lo,"32767 SECRET ROOM");
430
            break;
344 terminx 431
        case -1:
337 terminx 432
            Bsprintf(lo,"65535 END OF LEVEL");
433
            break;
434
        default :
435
            Bsprintf(lo,"%hu",sector[sectnum].lotag);
436
            break;
5 Plagman 437
        }
438
        if (sector[sectnum].lotag > 10000 && sector[sectnum].lotag < 32767)
439
            Bsprintf(lo,"%d 1 TIME SOUND",sector[sectnum].lotag);
331 terminx 440
        if (qsetmode != 200)
5 Plagman 441
            Bsprintf(tempbuf,"%hu,%s",sector[sectnum].hitag,lo);
442
        else Bstrcpy(tempbuf,lo);
443
    }
444
    return(tempbuf);
445
}
446
 
447
const char *ExtGetWallCaption(short wallnum)
448
{
331 terminx 449
    if (!(onnames==2 || onnames==4))
5 Plagman 450
    {
451
        tempbuf[0] = 0;
452
        return(tempbuf);
453
    }
454
 
455
    // HERE
456
 
457
    if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0)
458
    {
459
        tempbuf[0] = 0;
460
    }
461
    else
462
    {
463
        Bsprintf(tempbuf,"%hu,%hu",wall[wallnum].hitag,wall[wallnum].lotag);
464
    }
465
    return(tempbuf);
466
} //end
467
 
468
const char *SectorEffectorText(short spritenum)
469
{
331 terminx 470
    switch (sprite[spritenum].lotag)
5 Plagman 471
    {
337 terminx 472
    case 0:
473
        Bsprintf(tempbuf,"SE: ROTATED SECTOR");
474
        break;
475
    case 1:
476
        Bsprintf(tempbuf,"SE: PIVOT SPRITE FOR SE 0");
477
        break;
478
    case 2:
479
        Bsprintf(tempbuf,"SE: EARTHQUAKE");
480
        break;
481
    case 3:
482
        Bsprintf(tempbuf,"SE: RANDOM LIGHTS AFTER SHOT OUT");
483
        break;
484
    case 4:
485
        Bsprintf(tempbuf,"SE: RANDOM LIGHTS");
486
        break;
487
    case 6:
488
        Bsprintf(tempbuf,"SE: SUBWAY");
489
        break;
490
    case 7:
491
        Bsprintf(tempbuf,"SE: TRANSPORT");
492
        break;
493
    case 8:
494
        Bsprintf(tempbuf,"SE: UP OPEN DOOR LIGHTS");
495
        break;
496
    case 9:
497
        Bsprintf(tempbuf,"SE: DOWN OPEN DOOR LIGHTS");
498
        break;
499
    case 10:
500
        Bsprintf(tempbuf,"SE: DOOR AUTO CLOSE (H=DELAY)");
501
        break;
502
    case 11:
503
        Bsprintf(tempbuf,"SE: ROTATE SECTOR DOOR");
504
        break;
505
    case 12:
506
        Bsprintf(tempbuf,"SE: LIGHT SWITCH");
507
        break;
508
    case 13:
509
        Bsprintf(tempbuf,"SE: EXPLOSIVE");
510
        break;
511
    case 14:
512
        Bsprintf(tempbuf,"SE: SUBWAY CAR");
513
        break;
514
    case 15:
515
        Bsprintf(tempbuf,"SE: SLIDE DOOR (ST 25)");
516
        break;
517
    case 16:
518
        Bsprintf(tempbuf,"SE: ROTATE REACTOR SECTOR");
519
        break;
520
    case 17:
521
        Bsprintf(tempbuf,"SE: ELEVATOR TRANSPORT (ST 15)");
522
        break;
523
    case 18:
524
        Bsprintf(tempbuf,"SE: INCREMENTAL SECTOR RISE/FALL");
525
        break;
526
    case 19:
527
        Bsprintf(tempbuf,"SE: CEILING FALL ON EXPLOSION");
528
        break;
529
    case 20:
530
        Bsprintf(tempbuf,"SE: BRIDGE (ST 27)");
531
        break;
532
    case 21:
533
        Bsprintf(tempbuf,"SE: DROP FLOOR (ST 28)");
534
        break;
535
    case 22:
536
        Bsprintf(tempbuf,"SE: TEETH DOOR (ST 29)");
537
        break;
538
    case 23:
539
        Bsprintf(tempbuf,"SE: 1-WAY SE7 DESTINATION (H=SE 7)");
540
        break;
541
    case 24:
542
        Bsprintf(tempbuf,"SE: CONVAYER BELT");
543
        break;
544
    case 25:
545
        Bsprintf(tempbuf,"SE: ENGINE");
546
        break;
547
    case 28:
548
        Bsprintf(tempbuf,"SE: LIGHTNING (H= TILE#4890)");
549
        break;
550
    case 27:
551
        Bsprintf(tempbuf,"SE: CAMERA FOR PLAYBACK");
552
        break;
553
    case 29:
554
        Bsprintf(tempbuf,"SE: FLOAT");
555
        break;
556
    case 30:
557
        Bsprintf(tempbuf,"SE: 2 WAY TRAIN (ST=31)");
558
        break;
559
    case 31:
560
        Bsprintf(tempbuf,"SE: FLOOR RISE");
561
        break;
562
    case 32:
563
        Bsprintf(tempbuf,"SE: CEILING FALL");
564
        break;
565
    case 33:
566
        Bsprintf(tempbuf,"SE: SPAWN JIB W/QUAKE");
567
        break;
568
    case 36:
569
        Bsprintf(tempbuf,"SE: SKRINK RAY SHOOTER");
570
        break;
571
    default:
572
        SpriteName(spritenum,tempbuf);
573
        break;
5 Plagman 574
    }
575
    return (tempbuf);
576
}
577
 
578
const char *ExtGetSpriteCaption(short spritenum)
579
{
331 terminx 580
    if ((onnames!=5 && onnames!=6 &&(!(onnames==3 || onnames==4 || onnames==7 || onnames==8))) || (onnames==7 && sprite[spritenum].picnum!=1))
5 Plagman 581
    {
582
        tempbuf[0] = 0;
583
        return(tempbuf);
584
    }
585
 
586
    if (onnames==5)
587
    {
858 terminx 588
        if (!tileInGroup(tilegroupItems, sprite[spritenum].picnum))
5 Plagman 589
        {
337 terminx 590
            tempbuf[0] = 0;
591
            return(tempbuf);
5 Plagman 592
        }
593
    }
594
 
333 terminx 595
    if (onnames==6 && sprite[spritenum].picnum != sprite[cursprite].picnum)
5 Plagman 596
    {
597
        tempbuf[0] = 0;
598
        return(tempbuf);
599
    }
600
 
601
    tempbuf[0] = 0;
602
    if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0)
603
    {
604
        SpriteName(spritenum,lo);
331 terminx 605
        if (lo[0]!=0)
5 Plagman 606
        {
331 terminx 607
            if (sprite[spritenum].pal==1) Bsprintf(tempbuf,"%s (MULTIPLAYER)",lo);
5 Plagman 608
            else Bsprintf(tempbuf,"%s",lo);
609
        }
610
    }
611
    else
331 terminx 612
        if (sprite[spritenum].picnum==SECTOREFFECTOR)
5 Plagman 613
        {
614
            if (onnames==8)
615
                tempbuf[0] = 0;
616
            else
617
            {
618
                Bsprintf(lo,"%s: %hu",SectorEffectorText(spritenum),sprite[spritenum].lotag);
619
                Bsprintf(tempbuf,"%s, %hu",lo,sprite[spritenum].hitag);
620
            }
621
        }
622
        else
623
        {
624
            SpriteName(spritenum,lo);
625
            if (sprite[spritenum].extra != -1)
626
                Bsprintf(tempbuf,"%hu,%hu,%d %s",sprite[spritenum].hitag,sprite[spritenum].lotag,sprite[spritenum].extra,lo);
627
            else
628
                Bsprintf(tempbuf,"%hu,%hu %s",sprite[spritenum].hitag,sprite[spritenum].lotag,lo);
629
        }
630
    return(tempbuf);
631
 
632
} //end
633
 
634
//printext16 parameters:
584 terminx 635
//printext16(int xpos, int ypos, short col, short backcol,
5 Plagman 636
//           char name[82], char fontsize)
637
//  xpos 0-639   (top left)
638
//  ypos 0-479   (top left)
639
//  col 0-15
640
//  backcol 0-15, -1 is transparent background
641
//  name
642
//  fontsize 0=8*8, 1=3*5
643
 
644
//drawline16 parameters:
584 terminx 645
// drawline16(int x1, int y1, int x2, int y2, char col)
5 Plagman 646
//  x1, x2  0-639
647
//  y1, y2  0-143  (status bar is 144 high, origin is top-left of STATUS BAR)
648
//  col     0-15
649
 
650
void ExtShowSectorData(short sectnum)   //F5
651
{
652
    short statnum=0;
653
    int x,x2,y;
91 terminx 654
    int i;
5 Plagman 655
    int secrets=0;
656
    int totalactors1=0,totalactors2=0,totalactors3=0,totalactors4=0;
657
    int totalrespawn=0;
658
 
654 terminx 659
    UNREFERENCED_PARAMETER(sectnum);
331 terminx 660
    if (qsetmode==200)
5 Plagman 661
        return;
662
 
331 terminx 663
    for (i=0;i<numsectors;i++)
5 Plagman 664
    {
331 terminx 665
        if (sector[i].lotag==32767) secrets++;
5 Plagman 666
    }
667
 
668
    statnum=0;
669
    i = headspritestat[statnum];
670
    while (i != -1)
671
    {
858 terminx 672
        // Count all non-player actors.
673
        if (tileInGroup(tilegroupActors, sprite[i].picnum))
5 Plagman 674
        {
808 terminx 675
            if (sprite[i].lotag<=1) totalactors1++;
676
            if (sprite[i].lotag<=2) totalactors2++;
677
            if (sprite[i].lotag<=3) totalactors3++;
678
            if (sprite[i].lotag<=4) totalactors4++;
858 terminx 679
        }
680
        if (sprite[i].picnum == RESPAWN) totalrespawn++;
5 Plagman 681
 
808 terminx 682
        i = nextspritestat[i];
5 Plagman 683
    }
684
 
331 terminx 685
    for (i=0;i<MAXSPRITES;i++) numsprite[i]=0;
686
    for (i=0;i<MAXSPRITES;i++) multisprite[i]=0;
687
    for (i=0;i<MAXSPRITES;i++)
5 Plagman 688
    {
331 terminx 689
        if (sprite[i].statnum==0)
5 Plagman 690
        {
331 terminx 691
            if (sprite[i].pal!=0) multisprite[sprite[i].picnum]++;
5 Plagman 692
            else numsprite[sprite[i].picnum]++;
693
        }
694
    }
695
 
696
    clearmidstatbar16();             //Clear middle of status bar
697
    Bsprintf(tempbuf,"Level %s",levelname);
698
    printmessage16(tempbuf);
699
 
335 terminx 700
    x=1;
701
    x2=14;
702
    y=4;
5 Plagman 703
    begindrawing();
704
    printext16(x*8,ydim16+y*8,11,-1,"Item Count",0);
705
    enddrawing();
706
    PrintStatus("10%health=",numsprite[COLA],x,y+2,11);
726 terminx 707
    PrintStatus("",multisprite[COLA],x2,y+2,9);
5 Plagman 708
    PrintStatus("30%health=",numsprite[SIXPAK],x,y+3,11);
726 terminx 709
    PrintStatus("",multisprite[SIXPAK],x2,y+3,9);
5 Plagman 710
    PrintStatus("Med-Kit  =",numsprite[FIRSTAID],x,y+4,11);
726 terminx 711
    PrintStatus("",multisprite[FIRSTAID],x2,y+4,9);
5 Plagman 712
    PrintStatus("Atom     =",numsprite[ATOMICHEALTH],x,y+5,11);
726 terminx 713
    PrintStatus("",multisprite[ATOMICHEALTH],x2,y+5,9);
5 Plagman 714
    PrintStatus("Shields  =",numsprite[SHIELD],x,y+6,11);
726 terminx 715
    PrintStatus("",multisprite[SHIELD],x2,y+6,9);
5 Plagman 716
 
335 terminx 717
    x=17;
718
    x2=30;
719
    y=4;
5 Plagman 720
    begindrawing();
721
    printext16(x*8,ydim16+y*8,11,-1,"Inventory",0);
722
    enddrawing();
723
    PrintStatus("Steroids =",numsprite[STEROIDS],x,y+2,11);
726 terminx 724
    PrintStatus("",multisprite[STEROIDS],x2,y+2,9);
5 Plagman 725
    PrintStatus("Airtank  =",numsprite[AIRTANK],x,y+3,11);
726 terminx 726
    PrintStatus("",multisprite[AIRTANK],x2,y+3,9);
5 Plagman 727
    PrintStatus("Jetpack  =",numsprite[JETPACK],x,y+4,11);
726 terminx 728
    PrintStatus("",multisprite[JETPACK],x2,y+4,9);
5 Plagman 729
    PrintStatus("Goggles  =",numsprite[HEATSENSOR],x,y+5,11);
726 terminx 730
    PrintStatus("",multisprite[HEATSENSOR],x2,y+5,9);
5 Plagman 731
    PrintStatus("Boots    =",numsprite[BOOTS],x,y+6,11);
726 terminx 732
    PrintStatus("",multisprite[BOOTS],x2,y+6,9);
5 Plagman 733
    PrintStatus("HoloDuke =",numsprite[HOLODUKE],x,y+7,11);
726 terminx 734
    PrintStatus("",multisprite[HOLODUKE],x2,y+7,9);
5 Plagman 735
    PrintStatus("Multi D  =",numsprite[APLAYER],x,y+8,11);
736
 
335 terminx 737
    x=33;
738
    x2=46;
739
    y=4;
5 Plagman 740
    begindrawing();
741
    printext16(x*8,ydim16+y*8,11,-1,"Weapon Count",0);
742
    enddrawing();
743
    PrintStatus("Pistol   =",numsprite[FIRSTGUNSPRITE],x,y+2,11);
726 terminx 744
    PrintStatus("",multisprite[FIRSTGUNSPRITE],x2,y+2,9);
5 Plagman 745
    PrintStatus("Shotgun  =",numsprite[SHOTGUNSPRITE],x,y+3,11);
726 terminx 746
    PrintStatus("",multisprite[SHOTGUNSPRITE],x2,y+3,9);
5 Plagman 747
    PrintStatus("Chaingun =",numsprite[CHAINGUNSPRITE],x,y+4,11);
726 terminx 748
    PrintStatus("",multisprite[CHAINGUNSPRITE],x2,y+4,9);
5 Plagman 749
    PrintStatus("RPG      =",numsprite[RPGSPRITE],x,y+5,11);
726 terminx 750
    PrintStatus("",multisprite[RPGSPRITE],x2,y+5,9);
5 Plagman 751
    PrintStatus("Pipe Bomb=",numsprite[HEAVYHBOMB],x,y+6,11);
726 terminx 752
    PrintStatus("",multisprite[HEAVYHBOMB],x2,y+6,9);
5 Plagman 753
    PrintStatus("Shrinker =",numsprite[SHRINKERSPRITE],x,y+7,11);
726 terminx 754
    PrintStatus("",multisprite[SHRINKERSPRITE],x2,y+7,9);
5 Plagman 755
    PrintStatus("Devastatr=",numsprite[DEVISTATORSPRITE],x,y+8,11);
726 terminx 756
    PrintStatus("",multisprite[DEVISTATORSPRITE],x2,y+8,9);
5 Plagman 757
    PrintStatus("Trip mine=",numsprite[TRIPBOMBSPRITE],x,y+9,11);
726 terminx 758
    PrintStatus("",multisprite[TRIPBOMBSPRITE],x2,y+9,9);
5 Plagman 759
    PrintStatus("Freezeray=",numsprite[FREEZESPRITE],x,y+10,11);
726 terminx 760
    PrintStatus("",multisprite[FREEZESPRITE],x2,y+10,9);
5 Plagman 761
 
335 terminx 762
    x=49;
763
    x2=62;
764
    y=4;
5 Plagman 765
    begindrawing();
766
    printext16(x*8,ydim16+y*8,11,-1,"Ammo Count",0);
767
    enddrawing();
768
    PrintStatus("Pistol   =",numsprite[AMMO],x,y+2,11);
726 terminx 769
    PrintStatus("",multisprite[AMMO],x2,y+2,9);
5 Plagman 770
    PrintStatus("Shot     =",numsprite[SHOTGUNAMMO],x,y+3,11);
726 terminx 771
    PrintStatus("",multisprite[SHOTGUNAMMO],x2,y+3,9);
5 Plagman 772
    PrintStatus("Chain    =",numsprite[BATTERYAMMO],x,y+4,11);
726 terminx 773
    PrintStatus("",multisprite[BATTERYAMMO],x2,y+4,9);
5 Plagman 774
    PrintStatus("RPG Box  =",numsprite[RPGAMMO],x,y+5,11);
726 terminx 775
    PrintStatus("",multisprite[RPGAMMO],x2,y+5,9);
5 Plagman 776
    PrintStatus("Pipe Bomb=",numsprite[HBOMBAMMO],x,y+6,11);
726 terminx 777
    PrintStatus("",multisprite[HBOMBAMMO],x2,y+6,9);
5 Plagman 778
    PrintStatus("Shrinker =",numsprite[CRYSTALAMMO],x,y+7,11);
726 terminx 779
    PrintStatus("",multisprite[CRYSTALAMMO],x2,y+7,9);
5 Plagman 780
    PrintStatus("Devastatr=",numsprite[DEVISTATORAMMO],x,y+8,11);
726 terminx 781
    PrintStatus("",multisprite[DEVISTATORAMMO],x2,y+8,9);
5 Plagman 782
    PrintStatus("Expander =",numsprite[GROWAMMO],x,y+9,11);
726 terminx 783
    PrintStatus("",multisprite[GROWAMMO],x2,y+9,9);
5 Plagman 784
    PrintStatus("Freezeray=",numsprite[FREEZEAMMO],x,y+10,11);
726 terminx 785
    PrintStatus("",multisprite[FREEZEAMMO],x2,y+10,9);
5 Plagman 786
 
787
    begindrawing();
788
    printext16(65*8,ydim16+4*8,11,-1,"MISC",0);
789
    enddrawing();
790
    PrintStatus("Secrets =",secrets,65,6,11);
791
    begindrawing();
792
    printext16(65*8,ydim16+8*8,11,-1,"ACTORS",0);
793
    enddrawing();
794
    PrintStatus("Skill 1 =",totalactors1,65,10,11);
795
    PrintStatus("Skill 2 =",totalactors2,65,11,11);
796
    PrintStatus("Skill 3 =",totalactors3,65,12,11);
797
    PrintStatus("Skill 4 =",totalactors4,65,13,11);
798
    PrintStatus("Respawn =",totalrespawn,65,14,11);
799
 
800
}// end ExtShowSectorData
801
 
802
void ExtShowWallData(short wallnum)       //F6
803
{
804
    int i,nextfreetag=0,total=0;
805
    char x,y;
806
 
654 terminx 807
    UNREFERENCED_PARAMETER(wallnum);
649 terminx 808
 
331 terminx 809
    if (qsetmode==200)
5 Plagman 810
        return;
811
 
331 terminx 812
    for (i=0;i<MAXSPRITES;i++)
5 Plagman 813
    {
331 terminx 814
        if (sprite[i].statnum==0)
815
            switch (sprite[i].picnum)
5 Plagman 816
            {
337 terminx 817
                //LOTAG
818
            case ACTIVATOR:
819
            case ACTIVATORLOCKED:
820
            case TOUCHPLATE:
821
            case MASTERSWITCH:
822
            case RESPAWN:
823
            case ACCESSSWITCH:
824
            case SLOTDOOR:
825
            case LIGHTSWITCH:
826
            case SPACEDOORSWITCH:
827
            case SPACELIGHTSWITCH:
828
            case FRANKENSTINESWITCH:
829
            case MULTISWITCH:
830
            case DIPSWITCH:
831
            case DIPSWITCH2:
832
            case TECHSWITCH:
833
            case DIPSWITCH3:
834
            case ACCESSSWITCH2:
835
            case POWERSWITCH1:
836
            case LOCKSWITCH1:
837
            case POWERSWITCH2:
838
            case PULLSWITCH:
839
            case ALIENSWITCH:
840
                if (sprite[i].lotag>nextfreetag) nextfreetag=1+sprite[i].lotag;
841
                break;
5 Plagman 842
 
337 terminx 843
                //HITAG
844
            case SEENINE:
845
            case OOZFILTER:
846
            case SECTOREFFECTOR:
847
                if (sprite[i].lotag==10 || sprite[i].lotag==27 || sprite[i].lotag==28 || sprite[i].lotag==29)
5 Plagman 848
                    break;
337 terminx 849
                else
850
                    if (sprite[i].hitag>nextfreetag) nextfreetag=1+sprite[i].hitag;
851
                break;
852
            default:
853
                break;
5 Plagman 854
 
855
            }
856
 
857
    } // end sprite loop
858
 
859
    //Count Normal Actors
331 terminx 860
    for (i=0;i<MAXSPRITES;i++) numsprite[i]=0;
861
    for (i=0;i<MAXSPRITES;i++) multisprite[i]=0;
862
    for (i=0;i<MAXSPRITES;i++)
5 Plagman 863
    {
331 terminx 864
        if (sprite[i].statnum==0)
5 Plagman 865
        {
331 terminx 866
            if (sprite[i].pal!=0)
867
                switch (sprite[i].picnum)
5 Plagman 868
                {
337 terminx 869
                case LIZTROOP :
870
                case LIZTROOPRUNNING :
871
                case LIZTROOPSTAYPUT :
872
                case LIZTROOPSHOOT :
873
                case LIZTROOPJETPACK :
874
                case LIZTROOPONTOILET :
875
                case LIZTROOPDUCKING :
876
                    numsprite[LIZTROOP]++;
877
                    break;
878
                case BOSS1:
879
                case BOSS1STAYPUT:
880
                case BOSS1SHOOT:
881
                case BOSS1LOB:
882
                case BOSSTOP:
883
                    multisprite[BOSS1]++;
884
                    break;
885
                case BOSS2:
886
                    multisprite[BOSS2]++;
887
                    break;
888
                case BOSS3:
889
                    multisprite[BOSS3]++;
890
                    break;
5 Plagman 891
 
337 terminx 892
                default:
893
                    break;
5 Plagman 894
                }
895
            else
331 terminx 896
                switch (sprite[i].picnum)
5 Plagman 897
                {
335 terminx 898
                case LIZTROOP :
899
                case LIZTROOPRUNNING :
900
                case LIZTROOPSTAYPUT :
901
                case LIZTROOPSHOOT :
902
                case LIZTROOPJETPACK :
903
                case LIZTROOPONTOILET :
904
                case LIZTROOPDUCKING :
905
                    numsprite[LIZTROOP]++;
906
                    break;
907
                case PIGCOP:
908
                case PIGCOPSTAYPUT:
909
                case PIGCOPDIVE:
910
                    numsprite[PIGCOP]++;
911
                    break;
912
                case LIZMAN:
913
                case LIZMANSTAYPUT:
914
                case LIZMANSPITTING:
915
                case LIZMANFEEDING:
916
                case LIZMANJUMP:
917
                    numsprite[LIZMAN]++;
918
                    break;
919
                case BOSS1:
920
                case BOSS1STAYPUT:
921
                case BOSS1SHOOT:
922
                case BOSS1LOB:
923
                case BOSSTOP:
337 terminx 924
                    numsprite[BOSS1]++;
335 terminx 925
                    break;
926
                case COMMANDER:
927
                case COMMANDERSTAYPUT:
928
                    numsprite[COMMANDER]++;
929
                    break;
930
                case OCTABRAIN:
931
                case OCTABRAINSTAYPUT:
932
                    numsprite[OCTABRAIN]++;
933
                    break;
934
                case RECON:
935
                case DRONE:
936
                case ROTATEGUN:
937
                case EGG:
938
                case ORGANTIC:
939
                case GREENSLIME:
940
                case BOSS2:
941
                case BOSS3:
942
                case TANK:
943
                case NEWBEAST:
944
                case BOSS4:
337 terminx 945
 
946
                    numsprite[sprite[i].picnum]++;
335 terminx 947
                default:
948
                    break;
337 terminx 949
 
950
                }// end switch
951
        }// end if
952
    }//end for
953
    total=0;
954
    for (i=0;i<MAXSPRITES;i++) if (numsprite[i]!=0) total+=numsprite[i];
955
    for (i=0;i<MAXSPRITES;i++) if (multisprite[i]!=0) total+=multisprite[i];
956
 
957
    clearmidstatbar16();
958
 
959
    Bsprintf(tempbuf,"Level %s next tag %d",levelname,nextfreetag);
960
    printmessage16(tempbuf);
961
 
962
    x=2;
963
    y=4;
964
    PrintStatus("Normal Actors =",total,x,y,11);
965
 
966
    PrintStatus(" Liztroop  =",numsprite[LIZTROOP],x,y+1,11);
967
    PrintStatus(" Lizman    =",numsprite[LIZMAN],x,y+2,11);
968
    PrintStatus(" Commander =",numsprite[COMMANDER],x,y+3,11);
969
    PrintStatus(" Octabrain =",numsprite[OCTABRAIN],x,y+4,11);
970
    PrintStatus(" PigCop    =",numsprite[PIGCOP],x,y+5,11);
971
    PrintStatus(" Recon Car =",numsprite[RECON],x,y+6,11);
972
    PrintStatus(" Drone     =",numsprite[DRONE],x,y+7,11);
973
    PrintStatus(" Turret    =",numsprite[ROTATEGUN],x,y+8,11);
974
    PrintStatus(" Egg       =",numsprite[EGG],x,y+9,11);
975
    x+=17;
976
    PrintStatus("Slimer    =",numsprite[GREENSLIME],x,y+1,11);
977
    PrintStatus("Boss1     =",numsprite[BOSS1],x,y+2,11);
978
    PrintStatus("MiniBoss1 =",multisprite[BOSS1],x,y+3,11);
979
    PrintStatus("Boss2     =",numsprite[BOSS2],x,y+4,11);
980
    PrintStatus("Boss3     =",numsprite[BOSS3],x,y+5,11);
981
    PrintStatus("Riot Tank =",numsprite[TANK],x,y+6,11);
982
    PrintStatus("Newbeast  =",numsprite[NEWBEAST],x,y+7,11);
983
    PrintStatus("Boss4     =",numsprite[BOSS4],x,y+8,11);
984
 
985
    //Count Respawn Actors
986
    for (i=0;i<MAXSPRITES;i++) numsprite[i]=0;
987
    for (i=0;i<MAXSPRITES;i++) multisprite[i]=0;
988
    for (i=0;i<MAXSPRITES;i++)
989
    {
990
        if (sprite[i].statnum==0 && sprite[i].picnum==RESPAWN)
991
        {
992
            switch (sprite[i].hitag)
993
            {
994
            case LIZTROOP :
995
            case LIZTROOPRUNNING :
996
            case LIZTROOPSTAYPUT :
997
            case LIZTROOPSHOOT :
998
            case LIZTROOPJETPACK :
999
            case LIZTROOPONTOILET :
1000
            case LIZTROOPDUCKING :
1001
                numsprite[LIZTROOP]++;
1002
                break;
1003
            case PIGCOP:
1004
            case PIGCOPSTAYPUT:
1005
            case PIGCOPDIVE:
1006
                numsprite[PIGCOP]++;
1007
                break;
1008
            case LIZMAN:
1009
            case LIZMANSTAYPUT:
1010
            case LIZMANSPITTING:
1011
            case LIZMANFEEDING:
1012
            case LIZMANJUMP:
1013
                numsprite[LIZMAN]++;
1014
                break;
1015
            case BOSS1:
1016
            case BOSS1STAYPUT:
1017
            case BOSS1SHOOT:
1018
            case BOSS1LOB:
1019
            case BOSSTOP:
1020
                if (sprite[i].pal!=0) multisprite[BOSS1]++;
1021
                else numsprite[BOSS1]++;
1022
                break;
1023
            case COMMANDER:
1024
            case COMMANDERSTAYPUT:
1025
                numsprite[COMMANDER]++;
1026
                break;
1027
            case OCTABRAIN:
1028
            case OCTABRAINSTAYPUT:
1029
                numsprite[OCTABRAIN]++;
1030
                break;
1031
            case RECON:
1032
            case DRONE:
1033
            case ROTATEGUN:
1034
            case EGG:
1035
            case ORGANTIC:
1036
            case GREENSLIME:
1037
            case BOSS2:
1038
            case BOSS3:
1039
            case TANK:
1040
            case NEWBEAST:
1041
            case BOSS4:
1042
                numsprite[sprite[i].hitag]++;
1043
            default:
1044
                break;
5 Plagman 1045
            }//end switch
1046
        }// end if
1047
    }// end for
1048
    total=0;
331 terminx 1049
    for (i=0;i<MAXSPRITES;i++) if (numsprite[i]!=0) total+=numsprite[i];
1050
    for (i=0;i<MAXSPRITES;i++) if (multisprite[i]!=0) total+=multisprite[i];
5 Plagman 1051
 
1052
 
335 terminx 1053
    x=36;
1054
    y=4;
5 Plagman 1055
    PrintStatus("Respawn",total,x,y,11);
1056
 
1057
    PrintStatus(" Liztroop  =",numsprite[LIZTROOP],x,y+1,11);
1058
    PrintStatus(" Lizman    =",numsprite[LIZMAN],x,y+2,11);
1059
    PrintStatus(" Commander =",numsprite[COMMANDER],x,y+3,11);
1060
    PrintStatus(" Octabrain =",numsprite[OCTABRAIN],x,y+4,11);
1061
    PrintStatus(" PigCop    =",numsprite[PIGCOP],x,y+5,11);
1062
    PrintStatus(" Recon Car =",numsprite[RECON],x,y+6,11);
1063
    PrintStatus(" Drone     =",numsprite[DRONE],x,y+7,11);
1064
    PrintStatus(" Turret    =",numsprite[ROTATEGUN],x,y+8,11);
1065
    PrintStatus(" Egg       =",numsprite[EGG],x,y+9,11);
1066
    x+=17;
1067
    PrintStatus("Slimer    =",numsprite[GREENSLIME],x,y+1,11);
1068
    PrintStatus("Boss1     =",numsprite[BOSS1],x,y+2,11);
1069
    PrintStatus("MiniBoss1 =",multisprite[BOSS1],x,y+3,11);
1070
    PrintStatus("Boss2     =",numsprite[BOSS2],x,y+4,11);
1071
    PrintStatus("Boss3     =",numsprite[BOSS3],x,y+5,11);
1072
    PrintStatus("Riot Tank =",numsprite[TANK],x,y+6,11);
1073
    PrintStatus("Newbeast  =",numsprite[NEWBEAST],x,y+7,11);
1074
    PrintStatus("Boss4     =",numsprite[BOSS4],x,y+8,11);
1075
}// end ExtShowWallData
1076
 
398 terminx 1077
static void Show2dText(char *name)
5 Plagman 1078
{
91 terminx 1079
    int fp,t;
352 terminx 1080
    unsigned char x=0,y=4,xmax=0,xx=0,col=0;
5 Plagman 1081
    clearmidstatbar16();
331 terminx 1082
    if ((fp=kopen4load(name,0)) == -1)
5 Plagman 1083
    {
1084
        begindrawing();
1085
        printext16(1*4,ydim16+4*8,11,-1,"ERROR: file not found.",0);
1086
        enddrawing();
1087
        return;
1088
    }
1089
 
1090
    t=65;
1091
    begindrawing();
331 terminx 1092
    while (t!=EOF && col<5)
5 Plagman 1093
    {
1094
        t = 0;
1095
        if (kread(fp,&t,1)<=0)
1096
            t = EOF;
331 terminx 1097
        while (t!=EOF && t!='\n' && x<250)
5 Plagman 1098
        {
1099
            tempbuf[x]=t;
335 terminx 1100
            t = 0;
1101
            if (kread(fp,&t,1)<=0) t = EOF;
1102
            x++;
1103
            if (x>xmax) xmax=x;
5 Plagman 1104
        }
1105
        tempbuf[x]=0;
1106
        printext16(xx*4,ydim16+(y*6)+2,11,-1,tempbuf,1);
335 terminx 1107
        x=0;
1108
        y++;
1109
        if (y>18)
1110
        {
1111
            col++;
1112
            y=6;
1113
            xx+=xmax;
1114
            xmax=0;
5 Plagman 1115
        }
1116
    }
1117
    enddrawing();
1118
 
1119
    kclose(fp);
1120
 
1121
}// end Show2dText
1122
 
764 terminx 1123
// PK_ vvvv
1124
typedef struct helppage_
1125
{
1126
    int numlines;
1127
    char line[][80];  // C99 flexible array member
1128
} helppage_t;
1129
 
1130
helppage_t **helppage=NULL;
1131
int numhelppages=0;
1132
 
784 terminx 1133
static int newpage(const char *start)
764 terminx 1134
{
1135
    int i;
1136
    for (i=0; i<80; i++)
1137
    {
784 terminx 1138
//        if (start[i]=='\n' || !start[i]) break;
1139
//        if (start[i]!=' ' && start[i]!='\t' && start[i]!='\r')
1140
//            return 0;
1141
        if (start[i] == '^' && start[i+1] == 'P')
1142
            return 1;
764 terminx 1143
    }
784 terminx 1144
    return 0;
764 terminx 1145
}
1146
 
1147
#define IHELP_INITPAGES 32
1148
#define IHELP_INITLINES 16
1149
 
1150
static void ReadHelpFile(const char *name)
1151
{
1152
    BFILE *fp;
1153
    int i, j, k, numallocpages;
1154
    long int pos, charsread=0;
1155
    helppage_t *hp;
1156
    char skip=0;
1157
 
1158
    if ((fp=fopenfrompath(name,"rb")) == NULL)
1159
    {
1160
        initprintf("Error initializing integrated help: file \"%s\" not found.\n", name);
1161
        return;
1162
    }
1163
 
1164
    helppage=malloc(IHELP_INITPAGES * sizeof(helppage_t *));
1165
    numallocpages=IHELP_INITPAGES;
1166
    if (!helppage) goto ERROR;
1167
 
1168
    i=0;
1169
    while (!Bfeof(fp) && !ferror(fp))
1170
    {
1171
        while (!Bfeof(fp))    // skip empty lines
1172
        {
1173
            pos = ftell(fp);
1174
            Bfgets(tempbuf, 80, fp);
1175
            charsread = ftell(fp)-pos;
784 terminx 1176
            if (!newpage(tempbuf))
764 terminx 1177
            {
1178
                break;
1179
            }
1180
        }
1181
 
1182
        if (Bfeof(fp) || charsread<=0) break;
1183
 
1184
        hp=Bcalloc(1,sizeof(helppage_t) + IHELP_INITLINES*80);
1185
        if (!hp) goto ERROR;
1186
        hp->numlines = IHELP_INITLINES;
1187
 
1188
        if (charsread == 79 && tempbuf[78]!='\n') skip=1;
1189
        j=0;
1190
 
1191
        do
1192
        {
1193
            if (j >= hp->numlines)
1194
            {
1195
                hp=realloc(hp, sizeof(helppage_t) + 2*hp->numlines*80);
1196
                if (!hp) goto ERROR;
1197
                hp->numlines *= 2;
1198
            }
1199
 
1200
            // limit the line length to 78 chars and probably get rid of the CR
1201
            if (charsread>0)
1202
            {
1203
                tempbuf[charsread-1]=0;
1204
                if (tempbuf[charsread-2]==0x0d) tempbuf[charsread-2]=0;
1205
            }
1206
 
1207
            memcpy(hp->line[j], tempbuf, 80);
1208
 
1209
            for (k=charsread; k<80; k++) hp->line[j][k]=0;
1210
 
1211
            if (skip)
1212
            {
1213
                while (fgetc(fp)!='\n' && !Bfeof(fp)) /*skip rest of line*/;
1214
                skip=0;
1215
            }
1216
 
1217
            pos = ftell(fp);
1218
            Bfgets(tempbuf, 80, fp);
1219
            charsread = ftell(fp)-pos;
1220
            if (charsread == 79 && tempbuf[78]!='\n') skip=1;
1221
 
1222
            j++;
1223
 
1224
        }
784 terminx 1225
        while (!newpage(tempbuf) && !Bfeof(fp) && charsread>0);
764 terminx 1226
 
1227
        hp=realloc(hp, sizeof(helppage_t) + j*80);
1228
        if (!hp) goto ERROR;
1229
        hp->numlines=j;
1230
 
1231
        if (i >= numallocpages)
1232
        {
1233
            helppage = realloc(helppage, 2*numallocpages*sizeof(helppage_t *));
1234
            numallocpages *= 2;
1235
            if (!helppage) goto ERROR;
1236
        }
1237
        helppage[i] = hp;
1238
        i++;
1239
    }
1240
 
1241
    helppage = realloc(helppage, i*sizeof(helppage_t *));
1242
    if (!helppage) goto ERROR;
1243
    numhelppages = i;
1244
 
1245
    Bfclose(fp);
1246
    return;
1247
 
1248
ERROR:
1249
 
1250
    Bfclose(fp);
1251
    initprintf("ReadHelpFile(): ERROR allocating memory.\n");
1252
    return;
1253
}
1254
 
1255
#define IHELP_NUMDISPLINES 10
1256
#define IHELP_PATLEN 45
1257
 
1258
static void IntegratedHelp()
1259
{
1260
    int i, j;
1261
    int curhp=0, curline=0;
1262
    int highlighthp=-1, highlightline=-1, lasthighlighttime=0;
1263
    char disptext[IHELP_NUMDISPLINES][80];
1264
    char oldpattern[IHELP_PATLEN+1];
1265
 
1266
    if (!helppage) return;
1267
 
1268
    memset(oldpattern, 0, sizeof(char));
1269
    clearmidstatbar16();
1270
 
1271
    while (keystatus[KEYSC_ESC]==0 && keystatus[KEYSC_Q]==0)
1272
    {
1273
        if (handleevents())
1274
        {
1275
            if (quitevent) quitevent = 0;
1276
        }
1277
        idle();
1278
//        printmessage16("Help mode, press <Esc> to exit");
1279
 
1280
        if (keystatus[KEYSC_T])    // goto table of contents
1281
        {
1282
            keystatus[KEYSC_T]=0;
1283
            curhp=0;
1284
            curline=0;
1285
        }
1286
        else if (keystatus[KEYSC_G])    // goto arbitrary page
1287
        {
1288
            keystatus[KEYSC_G]=0;
1289
            Bsprintf(tempbuf, "Goto page: ");
1290
            curhp=getnumber16(tempbuf, 0, numhelppages-1, 0);
1291
            curline=0;
1292
        }
1293
        else if (keystatus[KEYSC_UP])    // scroll up
1294
        {
1295
            keystatus[KEYSC_UP]=0;
1296
            if (curline>0) curline--;
1297
        }
1298
        else if (keystatus[KEYSC_DOWN])    // scroll down
1299
        {
1300
            keystatus[KEYSC_DOWN]=0;
1301
            if (curline+IHELP_NUMDISPLINES < helppage[curhp]->numlines) curline++;
1302
        }
1303
        else if (keystatus[KEYSC_PGUP])    // scroll one page up
1304
        {
1305
            keystatus[KEYSC_PGUP]=0;
1306
            i=IHELP_NUMDISPLINES;
1307
            while (i>0 && curline>0) i--, curline--;
1308
        }
1309
        else if (keystatus[KEYSC_PGDN])    // scroll one page down
1310
        {
1311
            keystatus[KEYSC_PGDN]=0;
1312
            i=IHELP_NUMDISPLINES;
1313
            while (i>0 && curline+IHELP_NUMDISPLINES < helppage[curhp]->numlines) i--, curline++;
1314
        }
1315
        else if (keystatus[KEYSC_HOME])    // goto beginning of page
1316
        {
1317
            keystatus[KEYSC_HOME]=0;
1318
            curline=0;
1319
        }
1320
        else if (keystatus[KEYSC_END])    // goto end of page
1321
        {
1322
            keystatus[KEYSC_END]=0;
1323
            if ((curline=helppage[curhp]->numlines-IHELP_NUMDISPLINES) >= 0) /**/;
1324
            else curline=0;
1325
        }
1326
        else if (keystatus[KEYSC_LEFT])    // prev page
1327
        {
1328
            keystatus[KEYSC_LEFT]=0;
1329
            if (curhp>0)
1330
            {
1331
                curhp--;
1332
                curline=0;
1333
            }
1334
        }
1335
        else if (keystatus[KEYSC_RIGHT])    // next page
1336
        {
1337
            keystatus[KEYSC_RIGHT]=0;
1338
            if (curhp<numhelppages-1)
1339
            {
1340
                curhp++;
1341
                curline=0;
1342
            }
1343
        }
1344
 
1345
        // based on 'save as' dialog in overheadeditor()
1346
        else if (keystatus[KEYSC_S])    // text search
1347
        {
1348
 
1349
            char ch, bad=0, pattern[IHELP_PATLEN+1];
1350
 
1351
            for (i=0; i<IHELP_PATLEN+1; i++) pattern[i]=0;
1352
 
1353
            i=0;
1354
            bflushchars();
1355
            while (bad == 0)
1356
            {
1357
                Bsprintf(tempbuf,"Search: %s_", pattern);
1358
                printmessage16(tempbuf);
1359
                showframe(1);
1360
 
1361
                if (handleevents())
1362
                {
1363
                    if (quitevent) quitevent = 0;
1364
                }
1365
                idle();
1366
 
1367
                ch = bgetchar();
1368
 
1369
                if (keystatus[1]) bad = 1;
1370
                else if (ch == 13) bad = 2;
1371
                else if (ch > 0)
1372
                {
1373
                    if (i > 0 && (ch == 8 || ch == 127))
1374
                    {
1375
                        i--;
1376
                        pattern[i] = 0;
1377
                    }
1378
                    else if (i < IHELP_PATLEN && ch >= 32 && ch < 128)
1379
                    {
1380
                        pattern[i++] = ch;
1381
                        pattern[i] = 0;
1382
                    }
1383
                }
1384
            }
1385
 
1386
            if (bad==1)
1387
            {
1388
                keystatus[KEYSC_ESC] = 0;
1389
            }
1390
 
1391
            if (bad==2)
1392
            {
1393
                keystatus[KEYSC_ENTER] = 0;
1394
 
1395
                for (i=curhp; i<numhelppages; i++)
1396
                {
1397
                    for (j = (i==curhp)?(curline+1):0; j<helppage[i]->numlines; j++)
1398
                    {
1399
                        // entering an empty pattern will search with the last used pattern
1400
                        if (strstr(helppage[i]->line[j], pattern[0]?pattern:oldpattern))
1401
                        {
1402
                            curhp = i;
1403
 
1404
                            if ((curline=j) <= helppage[i]->numlines-IHELP_NUMDISPLINES) /**/;
1405
                            else if ((curline=helppage[i]->numlines-IHELP_NUMDISPLINES) >= 0) /**/;
1406
                            else curline=0;
1407
 
1408
                            highlighthp = i;
1409
                            highlightline = j;
1410
                            lasthighlighttime = totalclock;
1411
                            goto ENDFOR1;
1412
                        }
1413
                    }
1414
                }
1415
ENDFOR1:
1416
                if (pattern[0])
1417
                    memcpy(oldpattern, pattern, IHELP_PATLEN+1);
1418
            }
1419
        }
1420
        else    // '1'-'0' on the upper row
1421
        {
1422
            for (i=2; i<=11; i++)
1423
                if (keystatus[i]) break;
1424
            if (i--<12 && i<numhelppages)
1425
            {
1426
                curhp=i;
1427
            }
1428
        }
1429
 
1430
        clearmidstatbar16();
1431
        if (curhp < helppage[0]->numlines)
1432
        {
1433
            printmessage16(helppage[0]->line[curhp]);
1434
        }
1435
        else
1436
        {
1437
            for (i=Bsprintf(tempbuf, "%d. (Untitled page)", curhp); i<80; i++)
1438
                tempbuf[i]=0;
1439
            printmessage16(tempbuf);
1440
        }
1441
 
1442
        for (i=0; j=(curhp==0)?(i+curline+1):(i+curline),
1443
                i<IHELP_NUMDISPLINES && j<helppage[curhp]->numlines; i++)
1444
        {
1445
            Bmemcpy(disptext[i], helppage[curhp]->line[j], 80);
1446
            printext16(8,ydim-STATUS2DSIZ+32+i*9,11,
1447
                       (j==highlightline && curhp==highlighthp
1448
                        && totalclock-lasthighlighttime<120*5)?1:-1,
1449
                       disptext[i],0);
1450
        }
1451
 
1452
        showframe(1);
1453
    }
1454
 
1455
    printmessage16("");
1456
    showframe(1);
1457
 
1458
    keystatus[KEYSC_ESC] = keystatus[KEYSC_Q] = 0;
1459
}
1460
// PK_ ^^^^
1461
 
398 terminx 1462
static void Show3dText(char *name)
5 Plagman 1463
{
91 terminx 1464
    int fp,t;
352 terminx 1465
    unsigned char x=0,y=4,xmax=0,xx=0,col=0;
91 terminx 1466
 
331 terminx 1467
    if ((fp=kopen4load(name,0)) == -1)
5 Plagman 1468
    {
1469
        begindrawing();
1470
        printext256(1*4,4*8,whitecol,-1,"ERROR: file not found.",0);
1471
        enddrawing();
1472
        return;
1473
    }
1474
    t=65;
1475
    begindrawing();
331 terminx 1476
    while (t!=EOF && col<5)
5 Plagman 1477
    {
1478
        t = 0;
1479
        if (kread(fp,&t,1)<=0)
1480
            t = EOF;
331 terminx 1481
        while (t!=EOF && t!='\n' && x<250)
5 Plagman 1482
        {
1483
            tempbuf[x]=t;
335 terminx 1484
            t = 0;
1485
            if (kread(fp,&t,1)<=0) t = EOF;
1486
            x++;
1487
            if (x>xmax) xmax=x;
5 Plagman 1488
        }
1489
        tempbuf[x]=0;
1490
        printext256(xx*4,(y*6)+2,whitecol,-1,tempbuf,1);
335 terminx 1491
        x=0;
1492
        y++;
1493
        if (y>18)
1494
        {
1495
            col++;
1496
            y=6;
1497
            xx+=xmax;
1498
            xmax=0;
5 Plagman 1499
        }
1500
    }
1501
    enddrawing();
1502
 
1503
    kclose(fp);
1504
}// end Show3dText
1505
 
649 terminx 1506
#if 0
398 terminx 1507
static void ShowHelpText(char *name)
5 Plagman 1508
{
1509
    BFILE *fp;
91 terminx 1510
    char x=0,y=4;
654 terminx 1511
    UNREFERENCED_PARAMETER(name);
331 terminx 1512
    if ((fp=fopenfrompath("helpdoc.txt","rb")) == NULL)
5 Plagman 1513
    {
1514
        begindrawing();
1515
        printext256(1*4,4*8,whitecol,-1,"ERROR: file not found.",0);
1516
        enddrawing();
1517
        return;
1518
    }
1519
    /*
1520
        Bfgets(tempbuf,80,fp);
1521
        while(!Bfeof(fp) && Bstrcmp(tempbuf,"SectorEffector"))
1522
        {
1523
            Bfgets(tempbuf,80,fp);
1524
        }
1525
    */
1526
    y=2;
1527
    Bfgets(tempbuf,80,fp);
1528
    Bstrcat(tempbuf,"\n");
1529
    begindrawing();
331 terminx 1530
    while (!Bfeof(fp) && !(Bstrcmp(tempbuf,"SectorEffector")==0))
5 Plagman 1531
    {
1532
        Bfgets(tempbuf,80,fp);
1533
        Bstrcat(tempbuf,"\n");
1534
        printext256(x*4,(y*6)+2,whitecol,-1,tempbuf,1);
1535
        y++;
1536
    }
1537
    enddrawing();
1538
 
1539
    Bfclose(fp);
1540
}// end ShowHelpText
649 terminx 1541
#endif
5 Plagman 1542
void ExtShowSpriteData(short spritenum)   //F6
1543
{
654 terminx 1544
    UNREFERENCED_PARAMETER(spritenum);
5 Plagman 1545
    if (qsetmode != 200)
1546
        Show2dText("sehelp.hlp");
1547
    /*    if (qsetmode == 200)                // In 3D mode
1548
            return;
1549
 
1550
        while (KEY_PRESSED(KEYSC_F6));
1551
        ResetKeys();
1552
        ContextHelp(spritenum);             // Get context sensitive help */
1553
}// end ExtShowSpriteData
1554
 
1555
// Floor Over Floor (duke3d)
1556
 
1557
// If standing in sector with SE42 or SE44
1558
// then draw viewing to SE41 and raise all =hi SE43 cielings.
1559
 
1560
// If standing in sector with SE43 or SE45
1561
// then draw viewing to SE40 and lower all =hi SE42 floors.
1562
 
1563
int fofsizex = -1;
1564
int fofsizey = -1;
649 terminx 1565
#if 0
398 terminx 1566
static void ResetFOFSize()
5 Plagman 1567
{
1568
    if (fofsizex != -1) tilesizx[FOF] = fofsizex;
1569
    if (fofsizey != -1) tilesizy[FOF] = fofsizey;
1570
}
649 terminx 1571
#endif
584 terminx 1572
static void ExtSE40Draw(int spnum,int x,int y,int z,short a,short h)
5 Plagman 1573
{
584 terminx 1574
    static int tempsectorz[MAXSECTORS];
1575
    static int tempsectorpicnum[MAXSECTORS];
5 Plagman 1576
 
1577
    int i=0,j=0,k=0;
1578
    int floor1=0,floor2=0,ok=0,fofmode=0,draw_both=0;
584 terminx 1579
    int offx,offy,offz;
5 Plagman 1580
 
331 terminx 1581
    if (sprite[spnum].ang!=512) return;
5 Plagman 1582
 
1583
    // Things are a little different now, as we allow for masked transparent
1584
    // floors and ceilings. So the FOF textures is no longer required
1585
    //  if (!(gotpic[FOF>>3]&(1<<(FOF&7))))
1586
    //          return;
1587
    //  gotpic[FOF>>3] &= ~(1<<(FOF&7));
1588
 
1589
    if (tilesizx[562])
1590
    {
1591
        fofsizex = tilesizx[562];
1592
        tilesizx[562] = 0;
1593
    }
1594
    if (tilesizy[562])
1595
    {
1596
        fofsizey = tilesizy[562];
1597
        tilesizy[562] = 0;
1598
    }
1599
 
1600
    floor1=spnum;
1601
 
331 terminx 1602
    if (sprite[spnum].lotag==42) fofmode=40;
1603
    if (sprite[spnum].lotag==43) fofmode=41;
1604
    if (sprite[spnum].lotag==44) fofmode=40;
1605
    if (sprite[spnum].lotag==45) fofmode=41;
5 Plagman 1606
 
1607
    // fofmode=sprite[spnum].lotag-2;
1608
 
1609
    // sectnum=sprite[j].sectnum;
1610
    // sectnum=cursectnum;
1611
    ok++;
1612
 
1613
    /*  recursive?
1614
    for(j=0;j<MAXSPRITES;j++)
1615
    {
1616
    if(
1617
    sprite[j].sectnum==sectnum &&
1618
    sprite[j].picnum==1 &&
1619
    sprite[j].lotag==110
1620
       ) { DrawFloorOverFloor(j); break;}
1621
    }
1622
    */
1623
 
1624
    // if(ok==0) { Message("no fof",RED); return; }
1625
 
331 terminx 1626
    for (j=0;j<MAXSPRITES;j++)
5 Plagman 1627
    {
333 terminx 1628
        if (sprite[j].picnum==1 && sprite[j].lotag==fofmode && sprite[j].hitag==sprite[floor1].hitag)
5 Plagman 1629
        {
1630
            floor1=j;
1631
            fofmode=sprite[j].lotag;
1632
            ok++;
1633
            break;
1634
        }
1635
    }
1636
    // if(ok==1) { Message("no floor1",RED); return; }
1637
 
335 terminx 1638
    if (fofmode==40) k=41;
1639
    else k=40;
5 Plagman 1640
 
331 terminx 1641
    for (j=0;j<MAXSPRITES;j++)
5 Plagman 1642
    {
333 terminx 1643
        if (sprite[j].picnum==1 && sprite[j].lotag==k && sprite[j].hitag==sprite[floor1].hitag)
5 Plagman 1644
        {
335 terminx 1645
            floor2=j;
1646
            ok++;
1647
            break;
5 Plagman 1648
        }
1649
    }
1650
 
1651
    i=floor1;
1652
    offx=sprite[floor2].x-sprite[floor1].x;
1653
    offy=sprite[floor2].y-sprite[floor1].y;
1654
    offz=0;
1655
 
1656
    if (sprite[floor2].ang >= 1024)
1657
        offz = sprite[floor2].z;
1658
    else if (fofmode==41)
1659
        offz = sector[sprite[floor2].sectnum].floorz;
1660
    else
1661
        offz = sector[sprite[floor2].sectnum].ceilingz;
1662
 
1663
    if (sprite[floor1].ang >= 1024)
1664
        offz -= sprite[floor1].z;
1665
    else if (fofmode==40)
1666
        offz -= sector[sprite[floor1].sectnum].floorz;
1667
    else
1668
        offz -= sector[sprite[floor1].sectnum].ceilingz;
1669
 
1670
    // if(ok==2) { Message("no floor2",RED); return; }
1671
 
331 terminx 1672
    for (j=0;j<MAXSPRITES;j++) // raise ceiling or floor
5 Plagman 1673
    {
333 terminx 1674
        if (sprite[j].picnum==1 && sprite[j].lotag==k+2 && sprite[j].hitag==sprite[floor1].hitag)
5 Plagman 1675
        {
331 terminx 1676
            if (k==40)
5 Plagman 1677
            {
1678
                tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].floorz;
1679
                sector[sprite[j].sectnum].floorz+=(((z-sector[sprite[j].sectnum].floorz)/32768)+1)*32768;
1680
                tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].floorpicnum;
1681
                sector[sprite[j].sectnum].floorpicnum=562;
1682
            }
1683
            else
1684
            {
1685
                tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingz;
1686
                sector[sprite[j].sectnum].ceilingz+=(((z-sector[sprite[j].sectnum].ceilingz)/32768)-1)*32768;
1687
                tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingpicnum;
1688
                sector[sprite[j].sectnum].ceilingpicnum=562;
1689
            }
1690
            draw_both = 1;
1691
        }
1692
    }
1693
 
1694
    drawrooms(x+offx,y+offy,z+offz,a,h,sprite[floor2].sectnum);
1695
    ExtAnalyzeSprites();
1696
    drawmasks();
1697
 
1698
    if (draw_both)
1699
    {
331 terminx 1700
        for (j=0;j<MAXSPRITES;j++) // restore ceiling or floor for the draw both sectors
5 Plagman 1701
        {
331 terminx 1702
            if (sprite[j].picnum==1 &&
5 Plagman 1703
                    sprite[j].lotag==k+2 &&
1704
                    sprite[j].hitag==sprite[floor1].hitag)
1705
            {
331 terminx 1706
                if (k==40)
5 Plagman 1707
                {
1708
                    sector[sprite[j].sectnum].floorz=tempsectorz[sprite[j].sectnum];
1709
                    sector[sprite[j].sectnum].floorpicnum=tempsectorpicnum[sprite[j].sectnum];
1710
                }
1711
                else
1712
                {
1713
                    sector[sprite[j].sectnum].ceilingz=tempsectorz[sprite[j].sectnum];
1714
                    sector[sprite[j].sectnum].ceilingpicnum=tempsectorpicnum[sprite[j].sectnum];
1715
                }
1716
            }// end if
1717
        }// end for
1718
 
1719
        // Now re-draw
1720
        drawrooms(x+offx,y+offy,z+offz,a,h,sprite[floor2].sectnum);
1721
        ExtAnalyzeSprites();
1722
        drawmasks();
1723
    }
1724
 
1725
} // end SE40
1726
 
584 terminx 1727
static void SE40Code(int x,int y,int z,int a,int h)
5 Plagman 1728
{
1729
    int i;
1730
 
1731
    i = 0;
331 terminx 1732
    while (i<MAXSPRITES)
5 Plagman 1733
    {
1734
        int t = sprite[i].lotag;
331 terminx 1735
        switch (t)
5 Plagman 1736
        {
337 terminx 1737
            //            case 40:
1738
            //            case 41:
1739
            //                ExtSE40Draw(i,x,y,z,a,h);
1740
            //                break;
1741
        case 42:
1742
        case 43:
1743
        case 44:
1744
        case 45:
1745
            if (cursectnum == sprite[i].sectnum)
1746
                ExtSE40Draw(i,x,y,z,a,h);
1747
            break;
5 Plagman 1748
        }
1749
        i++;
1750
    }
1751
}
1752
 
1753
void ExtEditSectorData(short sectnum)    //F7
1754
{
1755
    //    if (qsetmode != 200) Show2dText("sthelp.hlp");
1756
    if (qsetmode == 200)
1757
        return;
727 terminx 1758
    if (eitherALT)  //ALT
5 Plagman 1759
    {
727 terminx 1760
        keystatus[KEYSC_F7] = 0;
5 Plagman 1761
        wallsprite=0;
1762
        curwall = 0;
1763
        curwallnum = 0;
1764
        cursearchspritenum = 0;
1765
        cursectornum=0;
1766
        cursector_lotag = sector[sectnum].lotag;
1767
        cursector_lotag=getnumber16("Enter search sector lotag : ", cursector_lotag, 65536L,0);
1768
        Bsprintf(tempbuf,"Search sector lotag %d",cursector_lotag);
1769
        printmessage16(tempbuf);
1770
    }
1771
    else EditSectorData(sectnum);
1772
}// end ExtEditSectorData
1773
 
1774
void ExtEditWallData(short wallnum)       //F8
1775
{
331 terminx 1776
    if (qsetmode==200)
5 Plagman 1777
        return;
727 terminx 1778
    if (eitherALT)  //ALT
5 Plagman 1779
    {
1780
        wallsprite=1;
1781
        curwall = wallnum;
1782
        curwallnum = 0;
1783
        cursearchspritenum = 0;
1784
        cursectornum = 0;
1785
        search_lotag = wall[curwall].lotag;
1786
        search_hitag = wall[curwall].hitag;
1787
        search_lotag=getnumber16("Enter wall search lotag : ", search_lotag, 65536L,0);
1788
        search_hitag=getnumber16("Enter wall search hitag : ", search_hitag, 65536L,0);
1789
        //    Bsprintf(tempbuf,"Current wall %d lo=%d hi=%d",
1790
        //             curwall,wall[curwall].lotag,wall[curwall].hitag);
1791
        Bsprintf(tempbuf,"Search wall lo=%d hi=%d",search_lotag,search_hitag);
1792
        printmessage16(tempbuf);
1793
    }
1794
    else EditWallData(wallnum);
1795
}
1796
 
1797
void ExtEditSpriteData(short spritenum)   //F8
1798
{
331 terminx 1799
    if (qsetmode==200)
5 Plagman 1800
        return;
727 terminx 1801
    if (eitherALT)  //ALT
5 Plagman 1802
    {
1803
        wallsprite=2;
1804
        cursearchsprite = spritenum;
1805
        curwallnum = 0;
1806
        cursearchspritenum = 0;
1807
        cursectornum = 0;
1808
        search_lotag = sprite[cursearchsprite].lotag;
1809
        search_hitag = sprite[cursearchsprite].hitag;
1810
        search_lotag=getnumber16("Enter sprite search lotag : ", search_lotag, 65536L,0);
1811
        search_hitag=getnumber16("Enter sprite search hitag : ", search_hitag, 65536L,0);
1812
        Bsprintf(tempbuf,"Search sprite lo=%d hi=%d",search_lotag,search_hitag);
1813
        printmessage16(tempbuf);
1814
    }
1815
    else EditSpriteData(spritenum);
1816
}
1817
 
398 terminx 1818
static void PrintStatus(char *string,int num,char x,char y,char color)
5 Plagman 1819
{
1820
    Bsprintf(tempbuf,"%s %d",string,num);
1821
    begindrawing();
1822
    printext16(x*8,ydim16+y*8,color,-1,tempbuf,0);
1823
    enddrawing();
1824
}
1825
 
398 terminx 1826
static inline void SpriteName(short spritenum, char *lo2)
5 Plagman 1827
{
1828
    Bsprintf(lo2,names[sprite[spritenum].picnum]);
1829
}// end SpriteName
1830
 
398 terminx 1831
static void ReadPaletteTable()
5 Plagman 1832
{
1833
    int i,j,fp;
1834
    char lookup_num;
331 terminx 1835
    if ((fp=kopen4load("lookup.dat",0)) == -1)
5 Plagman 1836
    {
331 terminx 1837
        if ((fp=kopen4load("lookup.dat",1)) == -1)
5 Plagman 1838
        {
1839
            initprintf("LOOKUP.DAT not found, creating dummy palette lookups\n");
331 terminx 1840
            for (i=0;i<256;i++)
5 Plagman 1841
                tempbuf[i] = ((i+32)&255);  //remap colors for screwy palette sectors
1842
            makepalookup(MAXPALOOKUPS,tempbuf,0,0,0,1);
1843
            return;
1844
        }
1845
    }
848 terminx 1846
//    initprintf("Loading palette lookups... ");
5 Plagman 1847
    kread(fp,&num_tables,1);
331 terminx 1848
    for (j=0;j<num_tables;j++)
5 Plagman 1849
    {
1850
        kread(fp,&lookup_num,1);
1851
        kread(fp,tempbuf,256);
1852
        makepalookup(lookup_num,tempbuf,0,0,0,1);
1853
    }
1854
    for (j = 0; j < 256; j++)
1855
        tempbuf[j] = j;
1856
    num_tables++;
1857
    makepalookup(num_tables, tempbuf, 15, 15, 15, 1);
398 terminx 1858
    makepalookup(num_tables + 1, tempbuf, 15, 0, 0, 1);
1859
    makepalookup(num_tables + 2, tempbuf, 0, 15, 0, 1);
1860
    makepalookup(num_tables + 3, tempbuf, 0, 0, 15, 1);
5 Plagman 1861
 
1862
    kread(fp,WATERpalette,768);
1863
    kread(fp,SLIMEpalette,768);
1864
    kread(fp,TITLEpalette,768);
1865
    kread(fp,REALMSpalette,768);
1866
    kread(fp,BOSS1palette,768);
1867
    kclose(fp);
849 terminx 1868
//    initprintf("success.\n");
5 Plagman 1869
}// end ReadPaletteTable
1870
 
398 terminx 1871
static void ReadGamePalette()
5 Plagman 1872
{
1873
    int i,fp;
331 terminx 1874
    if ((fp=kopen4load("palette.dat",0)) == -1)
1875
        if ((fp=kopen4load("palette.dat",1)) == -1)
5 Plagman 1876
        {
1877
            initprintf("!!! PALETTE.DAT NOT FOUND !!!\n");
1878
            Bstrcpy(tempbuf, "Mapster32"VERSION"");
1879
            wm_msgbox(tempbuf,"palette.dat not found");
1880
            exit(0);
1881
        }
849 terminx 1882
//    initprintf("Loading game palette... ");
5 Plagman 1883
    kread(fp,GAMEpalette,768);
331 terminx 1884
    for (i=0;i<768;++i) GAMEpalette[i]=GAMEpalette[i];
5 Plagman 1885
    kclose(fp);
849 terminx 1886
//    initprintf("success.\n");
5 Plagman 1887
    ReadPaletteTable();
1888
}
1889
 
782 terminx 1890
void message(const char *fmt, ...)
5 Plagman 1891
{
782 terminx 1892
    char tmpstr[256];
1893
    va_list va;
1894
 
1895
    va_start(va, fmt);
1896
    Bvsnprintf(tmpstr, 256, fmt, va);
1897
    va_end(va);
1898
 
1899
    Bstrcpy(getmessage,tmpstr);
5 Plagman 1900
    getmessageleng = strlen(getmessage);
747 terminx 1901
    getmessagetimeoff = totalclock+120*3;
728 terminx 1902
    lastmessagetime = totalclock;
782 terminx 1903
    if (!mouseaction)
1904
    {
1905
        Bstrcat(tmpstr,"\n");
1906
        OSD_Printf(tmpstr);
1907
    }
5 Plagman 1908
}
1909
 
1910
static char lockbyte4094;
1911
 
584 terminx 1912
static int lastupdate, mousecol, mouseadd = 1, bstatus;
5 Plagman 1913
 
398 terminx 1914
static void m32_showmouse(void)
5 Plagman 1915
{
508 terminx 1916
    int i, col;
5 Plagman 1917
 
331 terminx 1918
    if (totalclock > lastupdate)
5 Plagman 1919
    {
1920
        mousecol += mouseadd;
331 terminx 1921
        if (mousecol >= 30 || mousecol <= 0)
5 Plagman 1922
        {
1923
            mouseadd = -mouseadd;
1924
            mousecol += mouseadd;
1925
        }
1926
        lastupdate = totalclock + 3;
1927
    }
1928
 
331 terminx 1929
    switch (whitecol)
5 Plagman 1930
    {
337 terminx 1931
    case 1:  // Shadow Warrior
1932
        col = whitecol+mousecol;
1933
        break;
1934
    case 31: // Duke Nukem 3D
1935
        col = whitecol-mousecol;
1936
        break;
1937
    default:
1938
        col = whitecol;
1939
        break;
5 Plagman 1940
    }
1941
 
331 terminx 1942
    if (col != whitecol)
5 Plagman 1943
    {
508 terminx 1944
        for (i=((xdim > 640)?3:2);i<=((xdim > 640)?7:3);i++)
5 Plagman 1945
        {
1946
            plotpixel(searchx+i,searchy,col);
1947
            plotpixel(searchx-i,searchy,col);
1948
            plotpixel(searchx,searchy-i,col);
1949
            plotpixel(searchx,searchy+i,col);
1950
        }
508 terminx 1951
        for (i=1;i<=((xdim > 640)?2:1);i++)
5 Plagman 1952
        {
1953
            plotpixel(searchx+i,searchy,whitecol);
1954
            plotpixel(searchx-i,searchy,whitecol);
1955
            plotpixel(searchx,searchy-i,whitecol);
1956
            plotpixel(searchx,searchy+i,whitecol);
1957
        }
508 terminx 1958
        i=((xdim > 640)?8:4);
5 Plagman 1959
        plotpixel(searchx+i,searchy,0);
1960
        plotpixel(searchx-i,searchy,0);
1961
        plotpixel(searchx,searchy-i,0);
1962
        plotpixel(searchx,searchy+i,0);
1963
    }
522 terminx 1964
 
508 terminx 1965
    if (xdim > 640)
1966
    {
1967
        for (i=1;i<=4;i++)
1968
        {
1969
            plotpixel(searchx+i,searchy,whitecol);
1970
            plotpixel(searchx-i,searchy,whitecol);
1971
            plotpixel(searchx,searchy-i,whitecol);
1972
            plotpixel(searchx,searchy+i,whitecol);
1973
        }
522 terminx 1974
    }
5 Plagman 1975
}
1976
 
728 terminx 1977
static int AskIfSure(char *text)
5 Plagman 1978
{
377 terminx 1979
    int retval=1;
5 Plagman 1980
 
728 terminx 1981
    if (qsetmode == 200)
1982
    {
1983
        begindrawing(); //{{{
1984
        printext256(0,0,whitecol,0,text?text:"Are you sure you want to proceed?",0);
1985
        enddrawing();   //}}}
1986
    }
1987
    else
1988
    {
1989
        printmessage16(text?text:"Are you sure you want to proceed?");
1990
    }
5 Plagman 1991
 
1992
    showframe(1);
1993
 
727 terminx 1994
    while ((keystatus[KEYSC_ESC]|keystatus[KEYSC_ENTER]|keystatus[KEYSC_SPACE]|keystatus[KEYSC_N]) == 0)
5 Plagman 1995
    {
335 terminx 1996
        if (handleevents())
1997
        {
1998
            if (quitevent)
1999
            {
377 terminx 2000
                retval = 1;
5 Plagman 2001
                break;
2002
            }
451 terminx 2003
        }
2004
        idle();
734 terminx 2005
        if (keystatus[KEYSC_Y]||keystatus[KEYSC_ENTER])
335 terminx 2006
        {
727 terminx 2007
            keystatus[KEYSC_Y] = 0;
734 terminx 2008
            keystatus[KEYSC_ENTER] = 0;
335 terminx 2009
            retval = 0;
2010
            break;
5 Plagman 2011
        }
2012
    }
727 terminx 2013
    while (keystatus[KEYSC_ESC])
5 Plagman 2014
    {
727 terminx 2015
        keystatus[KEYSC_ESC] = 0;
5 Plagman 2016
        retval = 1;
2017
        break;
2018
    }
2019
    return(retval);
2020
}
2021
 
584 terminx 2022
static int IsValidTile(const int idTile)
534 terminx 2023
{
584 terminx 2024
    int bValid = 0;
534 terminx 2025
 
2026
    if ((idTile >= 0) && (idTile < MAXTILES))
2027
    {
2028
        if ((tilesizx[idTile] != 0) && (tilesizy[idTile] != 0))
2029
        {
2030
            bValid = 1;
2031
        }
2032
    }
2033
 
2034
    return bValid;
2035
}
2036
 
584 terminx 2037
static int SelectAllTiles(int iCurrentTile)
534 terminx 2038
{
584 terminx 2039
    int i;
534 terminx 2040
 
2041
    if (iCurrentTile < localartlookupnum)
2042
    {
2043
        iCurrentTile = localartlookup[iCurrentTile];
2044
    }
2045
    else
2046
    {
2047
        iCurrentTile = 0;
2048
    }
2049
 
2050
    localartlookupnum = MAXTILES;
2051
 
2052
    for (i = 0; i < MAXTILES; i++)
2053
    {
2054
        localartlookup[i] = i;
2055
        localartfreq[i] = 0;
2056
    }
2057
 
2058
    return iCurrentTile;
2059
}
2060
 
584 terminx 2061
static int OnGotoTile(int iTile);
2062
static int OnSelectTile(int iTile);
2063
static int s_Zoom = INITIAL_ZOOM;
2064
static int s_TileZoom = 1;
534 terminx 2065
 
728 terminx 2066
static int DrawTiles(int iTopLeft, int iSelected, int nXTiles, int nYTiles, int TileDim, int offset);
534 terminx 2067
 
2068
 
584 terminx 2069
static int m32gettile(int idInitialTile)
534 terminx 2070
{
584 terminx 2071
    int gap, temp;
2072
    int nXTiles, nYTiles, nDisplayedTiles;
2073
    int i;
2074
    int iTile, iTopLeftTile;
2075
    int idSelectedTile;
734 terminx 2076
    int scrollmode;
728 terminx 2077
    int mousedx, mousedy, mtile, omousex=searchx, omousey=searchy, moffset=0;
534 terminx 2078
 
2079
// Enable following line for testing. I couldn't work out how to change vidmode on the fly
2080
// s_Zoom = NUM_ZOOMS - 1;
2081
 
2082
    if (idInitialTile < 0)
2083
    {
2084
        idInitialTile = 0;
2085
    }
2086
    else if (idInitialTile >= MAXTILES)
2087
    {
2088
        idInitialTile = MAXTILES - 1;
2089
    }
2090
 
2091
    // Ensure zoom not to big (which can happen if display size
2092
    //   changes whilst Mapster is running)
2093
    do
2094
    {
2095
        nXTiles = xdim / ZoomToThumbSize[s_Zoom];
2096
        nYTiles = ydim / ZoomToThumbSize[s_Zoom];
858 terminx 2097
        // Refuse to draw less than half of a row.
2098
        if (ZoomToThumbSize[s_Zoom]/2 < 12) nYTiles--;
534 terminx 2099
        nDisplayedTiles  = nXTiles * nYTiles;
2100
 
536 terminx 2101
        if (!nDisplayedTiles)
534 terminx 2102
        {
2103
            // Eh-up, resolution changed since we were last displaying tiles.
2104
            s_Zoom--;
2105
        }
2106
    }
536 terminx 2107
    while (!nDisplayedTiles);
534 terminx 2108
 
727 terminx 2109
    keystatus[KEYSC_V] = 0;
534 terminx 2110
 
2111
    for (i = 0; i < MAXTILES; i++)
2112
    {
2113
        localartfreq[i] = 0;
2114
 
2115
        localartlookup[i] = i;
2116
    }
2117
 
2118
    iTile = idSelectedTile = idInitialTile;
2119
 
2120
    switch (searchstat)
2121
    {
2122
    case 0 :
2123
        for (i = 0; i < numwalls; i++)
2124
        {
2125
            localartfreq[ wall[i].picnum ]++;
2126
        }
2127
        break;
2128
 
2129
    case 1 :
2130
    case 2 :
2131
        for (i = 0; i < numsectors; i++)
2132
        {
2133
            localartfreq[ sector[i].ceilingpicnum ]++;
2134
            localartfreq[ sector[i].floorpicnum ]++;
2135
        }
2136
        break;
2137
 
2138
    case 3 :
2139
        for (i=0;i<MAXSPRITES;i++)
2140
        {
2141
            if (sprite[i].statnum < MAXSTATUS)
2142
            {
2143
                localartfreq[ sprite[i].picnum ]++;
2144
            }
2145
        }
2146
        break;
2147
 
2148
    case 4 :
2149
        for (i = 0; i < numwalls; i++)
2150
        {
2151
            localartfreq[ wall[i].overpicnum ]++;
2152
        }
2153
        break;
2154
 
2155
    default :
2156
        break;
2157
    }
2158
 
2159
 
2160
    //
2161
    //  Sort tiles into frequency order
2162
    //
2163
 
2164
    gap = MAXTILES / 2;
2165
 
2166
    do
2167
    {
2168
        for (i = 0; i < MAXTILES-gap; i++)
2169
        {
2170
            temp = i;
2171
 
2172
            while ((localartfreq[temp] < localartfreq[temp+gap]) && (temp >= 0))
2173
            {
584 terminx 2174
                int tempint;
534 terminx 2175
 
584 terminx 2176
                tempint = localartfreq[temp];
534 terminx 2177
                localartfreq[temp] = localartfreq[temp+gap];
584 terminx 2178
                localartfreq[temp+gap] = tempint;
534 terminx 2179
 
584 terminx 2180
                tempint = localartlookup[temp];
534 terminx 2181
                localartlookup[temp] = localartlookup[temp+gap];
584 terminx 2182
                localartlookup[temp+gap] = tempint;
534 terminx 2183
 
2184
                if (iTile == temp)
2185
                {
2186
                    iTile = temp + gap;
2187
                }
2188
                else if (iTile == temp + gap)
2189
                {
2190
                    iTile = temp;
2191
                }
2192
 
2193
                temp -= gap;
2194
            }
2195
        }
2196
        gap >>= 1;
2197
    }
2198
    while (gap > 0);
2199
 
2200
    //
2201
    // Set up count of number of used tiles
2202
    //
2203
 
2204
    localartlookupnum = 0;
2205
    while (localartfreq[localartlookupnum] > 0)
2206
    {
2207
        localartlookupnum++;
2208
    }
2209
 
2210
    //
2211
    // Check : If no tiles used at all then switch to displaying all tiles
2212
    //
2213
 
536 terminx 2214
    if (!localartfreq[0])
534 terminx 2215
    {
2216
        localartlookupnum = MAXTILES;
2217
 
2218
        for (i = 0; i < MAXTILES; i++)
2219
        {
2220
            localartlookup[i] = i;
2221
            localartfreq[i] = 0; // Terrible bodge : zero tilefreq's not displayed in tile view. Still, when in Rome ... :-)
2222
        }
2223
 
2224
        iTile = idInitialTile;
2225
    }
2226
 
2227
    //
2228
    //
2229
    //
2230
 
2231
    iTopLeftTile = iTile - (iTile % nXTiles);
2232
 
2233
    if (iTopLeftTile < 0)
2234
    {
2235
        iTopLeftTile = 0;
2236
    }
2237
 
2238
    if (iTopLeftTile > MAXTILES-nDisplayedTiles)
2239
    {
2240
        iTopLeftTile = MAXTILES-nDisplayedTiles;
2241
    }
2242
 
728 terminx 2243
    searchx=((iTile-iTopLeftTile)%nXTiles)*ZoomToThumbSize[s_Zoom]+ZoomToThumbSize[s_Zoom]/2;
2244
    searchy=((iTile-iTopLeftTile)/nXTiles)*ZoomToThumbSize[s_Zoom]+ZoomToThumbSize[s_Zoom]/2;
534 terminx 2245
 
2246
    ////////////////////////////////
2247
    // Start of key handling code //
2248
    ////////////////////////////////
2249
 
728 terminx 2250
    while ((keystatus[KEYSC_ENTER]|keystatus[KEYSC_ESC]|(bstatus&1)) == 0) // <- Presumably one of these is escape key ???
534 terminx 2251
    {
732 terminx 2252
        DrawTiles(iTopLeftTile, (iTile >= localartlookupnum)?localartlookupnum-1:iTile, nXTiles, nYTiles, ZoomToThumbSize[s_Zoom],moffset);
534 terminx 2253
 
728 terminx 2254
        getmousevalues(&mousedx,&mousedy,&bstatus);
2255
        searchx += mousedx;
2256
        searchy += mousedy;
732 terminx 2257
        if (bstatus&2)
728 terminx 2258
        {
732 terminx 2259
            moffset+=mousedy*2;
2260
            searchy += mousedy;
2261
            searchx -= mousedx;
734 terminx 2262
            if ((moffset < 0 && iTopLeftTile > localartlookupnum-nDisplayedTiles-1)
2263
                    || (moffset > 0 && iTopLeftTile==0))
2264
            {
2265
                moffset=0;
2266
                searchy -= mousedy*2;
2267
            }
728 terminx 2268
            while (moffset>ZoomToThumbSize[s_Zoom])
2269
            {
2270
                iTopLeftTile-=nXTiles;
2271
                moffset-=ZoomToThumbSize[s_Zoom];
2272
            }
2273
            while (moffset<-ZoomToThumbSize[s_Zoom])
2274
            {
2275
                iTopLeftTile+=nXTiles;
2276
                moffset+=ZoomToThumbSize[s_Zoom];
2277
            }
2278
        }
729 terminx 2279
 
858 terminx 2280
        // Keep the pointer visible at all times.
2281
        temp = min((ZoomToThumbSize[s_Zoom] / 2), 12);
2282
        if (searchx < temp) searchx = temp;
2283
        if (searchy < temp) searchy = temp;
2284
        if (searchx > xdim - temp) searchx = xdim - temp;
2285
        if (searchy > ydim - temp) searchy = ydim - temp;
2286
 
734 terminx 2287
        scrollmode=!(eitherCTRL^revertCTRL);
2288
        if (bstatus&16 && scrollmode && iTopLeftTile > 0)
732 terminx 2289
        {
2290
            mouseb &= ~16;
734 terminx 2291
            iTopLeftTile -= (nXTiles*scrollamount);
732 terminx 2292
        }
734 terminx 2293
        if (bstatus&32 && scrollmode && iTopLeftTile < localartlookupnum-nDisplayedTiles-1)
732 terminx 2294
        {
2295
            mouseb &= ~32;
734 terminx 2296
            iTopLeftTile += (nXTiles*scrollamount);
732 terminx 2297
        }
728 terminx 2298
        mtile=iTile=(searchx/ZoomToThumbSize[s_Zoom])+((searchy-moffset)/ZoomToThumbSize[s_Zoom])*nXTiles+iTopLeftTile;
2299
        while (iTile >= iTopLeftTile + nDisplayedTiles)
2300
        {
2301
            iTile-=nXTiles;
2302
            mtile=iTile;
2303
        }
2304
 
534 terminx 2305
        if (handleevents())
2306
        {
2307
            if (quitevent) quitevent = 0;
2308
        }
536 terminx 2309
        idle();
534 terminx 2310
 
2311
        // These two lines are so obvious I don't need to comment them ...;-)
2312
        synctics = totalclock-lockclock;
2313
        lockclock += synctics;
2314
 
2315
        // Zoom in / out using numeric key pad's / and * keys
734 terminx 2316
        if (((keystatus[KEYSC_gSLASH] || (!scrollmode && bstatus&16)) && s_Zoom<(signed)(NUM_ZOOMS-1))
2317
                || ((keystatus[KEYSC_gSTAR]  || (!scrollmode && bstatus&32)) && s_Zoom>0))
534 terminx 2318
        {
734 terminx 2319
            if (keystatus[KEYSC_gSLASH] || (!scrollmode && bstatus&16))
534 terminx 2320
            {
727 terminx 2321
                keystatus[KEYSC_gSLASH] = 0;
728 terminx 2322
                mouseb &= ~16;
2323
                bstatus &= ~16;
534 terminx 2324
 
2325
                // Watch out : If editor window is small, then the next zoom level
2326
                //  might get so large that even one tile might not fit !
2327
                if ((ZoomToThumbSize[s_Zoom+1] <= xdim)
2328
                        && (ZoomToThumbSize[s_Zoom+1] <= ydim))
2329
                {
2330
                    // Phew, plenty of room.
2331
                    s_Zoom++;
2332
                }
2333
            }
2334
            else
2335
            {
727 terminx 2336
                keystatus[KEYSC_gSTAR] = 0;
728 terminx 2337
                mouseb &= ~32;
2338
                bstatus &= ~32;
534 terminx 2339
                s_Zoom--;
2340
            }
2341
 
732 terminx 2342
            if (iTile >= localartlookupnum)iTile = localartlookupnum-1;
2343
 
534 terminx 2344
            // Calculate new num of tiles to display
2345
            nXTiles = xdim / ZoomToThumbSize[s_Zoom];
2346
            nYTiles = ydim / ZoomToThumbSize[s_Zoom];
858 terminx 2347
            // Refuse to draw less than half of a row.
2348
            if (ZoomToThumbSize[s_Zoom]/2 < 12) nYTiles--;
534 terminx 2349
            nDisplayedTiles  = nXTiles * nYTiles;
2350
 
2351
            // Determine if the top-left displayed tile needs to
2352
            //   alter in order to display selected tile
2353
            iTopLeftTile = iTile - (iTile % nXTiles);
2354
 
2355
            if (iTopLeftTile < 0)
2356
            {
2357
                iTopLeftTile = 0;
2358
            }
2359
            else if (iTopLeftTile > MAXTILES - nDisplayedTiles)
2360
            {
2361
                iTopLeftTile = MAXTILES - nDisplayedTiles;
2362
            }
728 terminx 2363
            // scroll window so mouse points the same tile as it was before zooming
2364
            iTopLeftTile-=(searchx/ZoomToThumbSize[s_Zoom])+((searchy-moffset)/ZoomToThumbSize[s_Zoom])*nXTiles+iTopLeftTile-iTile;
534 terminx 2365
        }
2366
 
727 terminx 2367
        if (keystatus[KEYSC_LEFT])
534 terminx 2368
        {
2369
            iTile -= (iTile > 0);
727 terminx 2370
            keystatus[KEYSC_LEFT] = 0;
534 terminx 2371
        }
2372
 
727 terminx 2373
        if (keystatus[KEYSC_RIGHT])
534 terminx 2374
        {
2375
            iTile += (iTile < MAXTILES);
727 terminx 2376
            keystatus[KEYSC_RIGHT] = 0;
534 terminx 2377
        }
2378
 
727 terminx 2379
        if (keystatus[KEYSC_UP])
534 terminx 2380
        {
2381
            iTile -= nXTiles;
727 terminx 2382
            keystatus[KEYSC_UP] = 0;
534 terminx 2383
        }
2384
 
727 terminx 2385
        if (keystatus[KEYSC_DOWN])
534 terminx 2386
        {
2387
            iTile += nXTiles;
727 terminx 2388
            keystatus[KEYSC_DOWN] = 0;
534 terminx 2389
        }
2390
 
727 terminx 2391
        if (keystatus[KEYSC_PGUP])
534 terminx 2392
        {
2393
            iTile -= nDisplayedTiles;
727 terminx 2394
            keystatus[KEYSC_PGUP] = 0;
534 terminx 2395
        }
2396
 
727 terminx 2397
        if (keystatus[KEYSC_PGDN])
534 terminx 2398
        {
2399
            iTile += nDisplayedTiles;
727 terminx 2400
            keystatus[KEYSC_PGDN] = 0;
534 terminx 2401
        }
2402
 
2403
        //
2404
        // Ensure tilenum is within valid range
2405
        //
2406
 
536 terminx 2407
        if (iTile < 0)
534 terminx 2408
        {
536 terminx 2409
            iTile = 0;
534 terminx 2410
        }
2411
 
536 terminx 2412
        if (iTile >= MAXTILES)  // shouldn't this be the count of num tiles ???
534 terminx 2413
        {
536 terminx 2414
            iTile = MAXTILES-1;
534 terminx 2415
        }
2416
 
2417
        // 'V'  KEYPRESS
727 terminx 2418
        if (keystatus[KEYSC_V])
534 terminx 2419
        {
541 terminx 2420
            keystatus[KEYSC_V] = 0;
534 terminx 2421
 
2422
            iTile = SelectAllTiles(iTile);
2423
        }
2424
 
2425
        // 'G'  KEYPRESS - Goto frame
727 terminx 2426
        if (keystatus[KEYSC_G])
534 terminx 2427
        {
541 terminx 2428
            keystatus[KEYSC_G] = 0;
534 terminx 2429
 
2430
            iTile = OnGotoTile(iTile);
2431
        }
2432
 
2433
        // 'U'  KEYPRESS : go straight to user defined art
541 terminx 2434
        if (keystatus[KEYSC_U])
534 terminx 2435
        {
2436
            SelectAllTiles(iTile);
2437
 
2438
            iTile = FIRST_USER_ART_TILE;
541 terminx 2439
            keystatus[KEYSC_U] = 0;
534 terminx 2440
        }
2441
 
2442
        // 'A'  KEYPRESS : Go straight to start of Atomic edition's art
541 terminx 2443
        if (keystatus[KEYSC_A])
534 terminx 2444
        {
2445
            SelectAllTiles(iTile);
2446
 
2447
            iTile = FIRST_ATOMIC_TILE;
541 terminx 2448
            keystatus[KEYSC_A] = 0;
534 terminx 2449
        }
2450
 
2451
        // 'T' KEYPRESS = Select from pre-defined tileset
541 terminx 2452
        if (keystatus[KEYSC_T])
534 terminx 2453
        {
541 terminx 2454
            keystatus[KEYSC_T] = 0;
534 terminx 2455
 
2456
            iTile = OnSelectTile(iTile);
2457
        }
2458
 
536 terminx 2459
        // 'E'  KEYPRESS : Go straight to start of extended art
541 terminx 2460
        if (keystatus[KEYSC_E])
536 terminx 2461
        {
2462
            SelectAllTiles(iTile);
2463
 
2464
            if (iTile == FIRST_EXTENDED_TILE)
2465
                iTile = SECOND_EXTENDED_TILE;
2466
            else iTile = FIRST_EXTENDED_TILE;
2467
 
541 terminx 2468
            keystatus[KEYSC_E] = 0;
536 terminx 2469
        }
2470
 
541 terminx 2471
        if (keystatus[KEYSC_Z])
2472
        {
2473
            s_TileZoom = !s_TileZoom;
2474
            keystatus[KEYSC_Z] = 0;
2475
        }
2476
 
534 terminx 2477
        //
2478
        //      Adjust top-left to ensure tilenum is within displayed range of tiles
2479
        //
2480
 
728 terminx 2481
        while (iTile < iTopLeftTile - (moffset<0)?nXTiles:0)
534 terminx 2482
        {
2483
            iTopLeftTile -= nXTiles;
2484
        }
2485
 
2486
        while (iTile >= iTopLeftTile + nDisplayedTiles)
2487
        {
2488
            iTopLeftTile += nXTiles;
2489
        }
2490
 
2491
        if (iTopLeftTile < 0)
2492
        {
2493
            iTopLeftTile = 0;
2494
        }
2495
 
2496
        if (iTopLeftTile > MAXTILES - nDisplayedTiles)
2497
        {
2498
            iTopLeftTile = MAXTILES - nDisplayedTiles;
2499
        }
2500
 
728 terminx 2501
        if ((keystatus[KEYSC_ENTER] || (bstatus&1)) == 0)   // uh ? Not escape key ?
534 terminx 2502
        {
2503
            idSelectedTile = idInitialTile;
2504
        }
2505
        else
2506
        {
2507
            if (iTile < localartlookupnum)
2508
            {
2509
                // Convert tile num from index to actual tile num
2510
                idSelectedTile = localartlookup[iTile];
2511
 
2512
                // Check : if invalid tile selected, return original tile num
2513
                if (!IsValidTile(idSelectedTile))
2514
                {
2515
                    idSelectedTile = idInitialTile;
2516
                }
2517
            }
2518
            else
2519
            {
2520
                idSelectedTile = idInitialTile;
2521
            }
2522
        }
728 terminx 2523
        if (mtile!=iTile) // if changed by keyboard, update mouse cursor
2524
        {
2525
            searchx=((iTile-iTopLeftTile)%nXTiles)*ZoomToThumbSize[s_Zoom]+ZoomToThumbSize[s_Zoom]/2;
2526
            searchy=((iTile-iTopLeftTile)/nXTiles)*ZoomToThumbSize[s_Zoom]+ZoomToThumbSize[s_Zoom]/2+moffset;
2527
        }
534 terminx 2528
    }
728 terminx 2529
    searchx=omousex;searchy=omousey;
534 terminx 2530
 
727 terminx 2531
    keystatus[KEYSC_ESC] = 0;
2532
    keystatus[KEYSC_ENTER] = 0;
534 terminx 2533
 
2534
    return(idSelectedTile);
2535
 
2536
}
2537
 
2538
// Dir = 0 (zoom out) or 1 (zoom in)
584 terminx 2539
//void OnZoomInOut( int *pZoom, int Dir /*0*/ )
534 terminx 2540
//{
2541
//}
2542
 
584 terminx 2543
static int OnGotoTile(int iTile)
534 terminx 2544
{
584 terminx 2545
    int iTemp, iNewTile;