Subversion Repositories eduke32

Rev

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

Rev Author Line No. Line
5 Plagman 1
//-------------------------------------------------------------------------
2
/*
1652 terminx 3
Copyright (C) 2010 EDuke32 developers and contributors
5 Plagman 4
 
1652 terminx 5
This file is part of EDuke32.
5 Plagman 6
 
7
EDuke32 is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 
15
See the GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
*/
21
//-------------------------------------------------------------------------
22
 
110 terminx 23
#include "duke3d.h"
1346 terminx 24
 
3221 hendricks2 25
#include "baselayer.h"
26
#include "renderlayer.h"
3116 hendricks2 27
 
5 Plagman 28
#include "scriplib.h"
29
#include "file_lib.h"
30
#include "mathutil.h"
31
#include "gamedefs.h"
32
#include "keyboard.h"
33
#include "mouse.h"  // JBF 20030809
2728 hendricks2 34
#include "joystick.h"
5 Plagman 35
#include "function.h"
36
#include "control.h"
37
#include "fx_man.h"
38
#include "sounds.h"
39
#include "config.h"
40
#include "osd.h"
41
#include "osdfuncs.h"
42
#include "osdcmds.h"
130 terminx 43
#include "scriptfile.h"
241 terminx 44
#include "grpscan.h"
610 terminx 45
#include "gamedef.h"
640 terminx 46
#include "kplib.h"
1552 terminx 47
#include "crc32.h"
1173 terminx 48
#include "hightile.h"
1632 terminx 49
#include "control.h"
1552 terminx 50
#include "quicklz.h"
1677 terminx 51
#include "net.h"
52
#include "premap.h"
53
#include "gameexec.h"
54
#include "menus.h"
55
#include "savegame.h"
56
#include "anim.h"
57
#include "demo.h"
2542 helixhorne 58
#include "common.h"
2726 hendricks2 59
#include "common_game.h"
2728 hendricks2 60
#include "input.h"
3170 helixhorne 61
#include "compat.h"
1552 terminx 62
 
2721 helixhorne 63
#ifdef LUNATIC
3148 helixhorne 64
# include "lunatic_game.h"
2034 helixhorne 65
#endif
66
 
1595 helixhorne 67
#if KRANDDEBUG
68
# define GAME_INLINE
69
# define GAME_STATIC
70
#else
71
# define GAME_INLINE inline
72
# define GAME_STATIC static
73
#endif
74
 
418 terminx 75
#ifdef _WIN32
3221 hendricks2 76
# include "winlayer.h"
77
# define WIN32_LEAN_AND_MEAN
78
# include <windows.h>
79
# include <shellapi.h>
1205 terminx 80
extern int32_t G_GetVersionFromWebsite(char *buffer);
3221 hendricks2 81
# define UPDATEINTERVAL 604800 // 1w
82
# include "winbits.h"
933 terminx 83
#else
1205 terminx 84
static int32_t usecwd = 0;
3221 hendricks2 85
# ifndef GEKKO
86
#  include <sys/ioctl.h>
87
# endif
1008 hnt_ts 88
#endif /* _WIN32 */
1587 terminx 89
 
90
int32_t g_quitDeadline = 0;
418 terminx 91
 
3405 helixhorne 92
#ifdef LUNATIC
93
camera_t g_camera;
94
#else
1205 terminx 95
int32_t g_cameraDistance = 0, g_cameraClock = 0;
3405 helixhorne 96
#endif
1587 terminx 97
static int32_t g_quickExit;
1205 terminx 98
static int32_t g_commandSetup = 0;
99
int32_t g_noSetup = 0;
100
static int32_t g_noAutoLoad = 0;
101
static int32_t g_noSound = 0;
102
static int32_t g_noMusic = 0;
2561 helixhorne 103
static const char *CommandMap = NULL;
104
static const char *CommandName = NULL;
1587 terminx 105
int32_t g_forceWeaponChoice = 0;
2879 helixhorne 106
int32_t g_fakeMultiMode = 0;
1632 terminx 107
 
1068 terminx 108
char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0};
1587 terminx 109
 
110
static char g_rootDir[BMAX_PATH];
111
char g_modDir[BMAX_PATH] = "/";
112
 
1772 plagman 113
 
2516 helixhorne 114
uint8_t water_pal[768],slime_pal[768],title_pal[768],dre_alms[768],ending_pal[768];
1772 plagman 115
 
2516 helixhorne 116
uint8_t *basepaltable[BASEPALCOUNT] = { palette, water_pal, slime_pal, dre_alms, title_pal, ending_pal, NULL /*anim_pal*/ };
1772 plagman 117
 
2518 helixhorne 118
int8_t g_noFloorPal[MAXPALOOKUPS];  // 1 if sprite pal should not be taken over from floor pal
2517 helixhorne 119
 
1205 terminx 120
int32_t voting = -1;
121
int32_t vote_map = -1, vote_episode = -1;
147 terminx 122
 
1587 terminx 123
static int32_t g_Debug = 0;
1205 terminx 124
static int32_t g_noLogoAnim = 0;
125
static int32_t g_noLogo = 0;
249 terminx 126
 
2726 hendricks2 127
const char *defaultrtsfilename[GAMECOUNT] = { "DUKE.RTS", "NAM.RTS", "NAPALM.RTS", "WW2GI.RTS" };
1205 terminx 128
 
2561 helixhorne 129
// g_gameNamePtr can point to one of: grpfiles[].name (string literal), string
130
// literal, malloc'd block (XXX: possible leak)
131
const char *g_gameNamePtr = NULL;
132
// g_rtsNamePtr can point to an argv[] element
133
const char *g_rtsNamePtr = NULL;
1205 terminx 134
 
1937 hendricks2 135
char **g_scriptModules = NULL;
2495 hendricks2 136
int32_t g_scriptModulesNum = 0;
1937 hendricks2 137
char **g_defModules = NULL;
2495 hendricks2 138
int32_t g_defModulesNum = 0;
3654 terminx 139
int32_t g_dependencyCRC = 0;
140
int32_t g_usingAddon = 0;
1937 hendricks2 141
 
2495 hendricks2 142
#ifdef HAVE_CLIPSHAPE_FEATURE
143
char **g_clipMapFiles = NULL;
144
int32_t g_clipMapFilesNum = 0;
145
#endif
146
 
1205 terminx 147
extern int32_t lastvisinc;
249 terminx 148
 
1205 terminx 149
int32_t g_Shareware = 0;
150
 
1037 terminx 151
#define MAXUSERQUOTES 6
1677 terminx 152
int32_t quotebot, quotebotgoal;
1205 terminx 153
static int32_t user_quote_time[MAXUSERQUOTES];
444 terminx 154
static char user_quote[MAXUSERQUOTES][178];
249 terminx 155
// char typebuflen,typebuf[41];
156
 
1658 terminx 157
// This was 32 for a while, but I think lowering it to 24 will help things like the Dingoo.
158
// Ideally, we would look at our memory usage on our most cramped platform and figure out
159
// how much of that is needed for the underlying OS and things like SDL instead of guessing
2628 helixhorne 160
#ifndef GEKKO
1658 terminx 161
static int32_t MAXCACHE1DSIZE = (24*1048576);
2628 helixhorne 162
#else
163
static int32_t MAXCACHE1DSIZE = (8*1048576);
164
#endif
253 terminx 165
 
1205 terminx 166
int32_t tempwallptr;
249 terminx 167
 
1205 terminx 168
static int32_t nonsharedtimer;
249 terminx 169
 
1552 terminx 170
int32_t ticrandomseed;
171
 
1205 terminx 172
static void G_DrawCameraText(int16_t i);
1595 helixhorne 173
GAME_STATIC GAME_INLINE int32_t G_MoveLoop(void);
1143 terminx 174
static void G_DoOrderScreen(void);
395 terminx 175
 
1552 terminx 176
#define quotepulseshade (sintable[(totalclock<<5)&2047]>>11)
177
 
1205 terminx 178
int32_t althud_numbertile = 2930;
179
int32_t althud_numberpal = 0;
180
int32_t althud_shadows = 1;
181
int32_t althud_flashing = 1;
182
int32_t hud_glowingquotes = 1;
183
int32_t hud_showmapname = 1;
937 terminx 184
 
1205 terminx 185
int32_t g_levelTextTime = 0;
1068 terminx 186
 
1205 terminx 187
int32_t r_maxfps = 0;
188
uint32_t g_frameDelay = 0;
1086 terminx 189
 
1176 terminx 190
#if defined(RENDERTYPEWIN) && defined(USE_OPENGL)
1120 terminx 191
extern char forcegl;
192
#endif
193
 
1652 terminx 194
void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); };  // needed for linking since it's referenced from build/src/osd.c
1649 helixhorne 195
 
1712 helixhorne 196
int32_t kopen4loadfrommod(const char *filename, char searchfirst)
992 terminx 197
{
2703 helixhorne 198
    int32_t r=-1;
992 terminx 199
 
2703 helixhorne 200
    if (g_modDir[0]!='/' || g_modDir[1]!=0)
201
    {
202
        static char fn[BMAX_PATH];
203
 
2836 helixhorne 204
        Bsnprintf(fn, sizeof(fn), "%s/%s",g_modDir,filename);
2703 helixhorne 205
        r = kopen4load(fn,searchfirst);
206
    }
207
 
993 terminx 208
    if (r < 0)
992 terminx 209
        r = kopen4load(filename,searchfirst);
1719 helixhorne 210
 
992 terminx 211
    return r;
212
}
213
 
2726 hendricks2 214
const char *G_DefaultRtsFile(void)
1909 terminx 215
{
2726 hendricks2 216
    if (DUKE)
217
        return defaultrtsfilename[GAME_DUKE];
218
    else if (WW2GI)
219
        return defaultrtsfilename[GAME_WW2GI];
220
    else if (NAPALM)
221
    {
2752 helixhorne 222
        if (!testkopen(defaultrtsfilename[GAME_NAPALM],0) && testkopen(defaultrtsfilename[GAME_NAM],0))
3618 hendricks2 223
            return defaultrtsfilename[GAME_NAM]; // NAM/NAPALM Sharing
2726 hendricks2 224
        else
225
            return defaultrtsfilename[GAME_NAPALM];
226
    }
227
    else if (NAM)
228
    {
2752 helixhorne 229
        if (!testkopen(defaultrtsfilename[GAME_NAM],0) && testkopen(defaultrtsfilename[GAME_NAPALM],0))
3618 hendricks2 230
            return defaultrtsfilename[GAME_NAPALM]; // NAM/NAPALM Sharing
2726 hendricks2 231
        else
232
            return defaultrtsfilename[GAME_NAM];
233
    }
1909 terminx 234
 
2726 hendricks2 235
    return defaultrtsfilename[0];
1909 terminx 236
}
237
 
1677 terminx 238
enum gametokens
335 terminx 239
{
505 terminx 240
    T_INCLUDE = 0,
249 terminx 241
    T_INTERFACE = 0,
505 terminx 242
    T_LOADGRP = 1,
249 terminx 243
    T_MODE = 1,
505 terminx 244
    T_CACHESIZE = 2,
626 terminx 245
    T_ALLOW = 2,
246
    T_NOAUTOLOAD,
1909 terminx 247
    T_INCLUDEDEFAULT,
634 terminx 248
    T_MUSIC,
249
    T_SOUND,
250
    T_FILE,
2242 helixhorne 251
    T_ANIMSOUNDS,
2517 helixhorne 252
    T_NOFLOORPALRANGE,
634 terminx 253
    T_ID
249 terminx 254
};
255
 
256
 
3399 helixhorne 257
static int32_t sbarsc(int32_t sc)
258
{
259
    return scale(sc,ud.statusbarscale,100);
260
}
5 Plagman 261
 
2640 helixhorne 262
static int32_t sbarx(int32_t x)
5 Plagman 263
{
3399 helixhorne 264
    if (ud.screen_size == 4) return sbarsc(x<<16);
265
    return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x<<16);
5 Plagman 266
}
267
 
2640 helixhorne 268
static int32_t sbarxr(int32_t x)
934 terminx 269
{
3399 helixhorne 270
    if (ud.screen_size == 4) return (320<<16) - sbarsc(x<<16);
271
    return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x<<16);
934 terminx 272
}
273
 
2640 helixhorne 274
static int32_t sbary(int32_t y)
5 Plagman 275
{
3399 helixhorne 276
    return (200<<16) - sbarsc(200<<16) + sbarsc(y<<16);
5 Plagman 277
}
278
 
3612 hendricks2 279
static int32_t sbarx16(int32_t x)
280
{
281
    if (ud.screen_size == 4) return sbarsc(x);
282
    return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x);
283
}
284
 
285
#if 0 // enable if ever needed
286
static int32_t sbarxr16(int32_t x)
287
{
288
    if (ud.screen_size == 4) return (320<<16) - sbarsc(x);
289
    return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x);
290
}
291
#endif
292
 
293
static int32_t sbary16(int32_t y)
294
{
295
    return (200<<16) - sbarsc(200<<16) + sbarsc(y);
296
}
297
 
2728 hendricks2 298
int32_t textsc(int32_t sc)
1095 terminx 299
{
1097 terminx 300
    // prevent ridiculousness to a degree
1099 terminx 301
    if (xdim <= 320) return sc;
302
    else if (xdim <= 640) return scale(sc,min(200,ud.textscale),100);
303
    else if (xdim <= 800) return scale(sc,min(300,ud.textscale),100);
304
    else if (xdim <= 1024) return scale(sc,min(350,ud.textscale),100);
1095 terminx 305
    return scale(sc,ud.textscale,100);
306
}
307
 
1205 terminx 308
static void G_PatchStatusBar(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
5 Plagman 309
{
3399 helixhorne 310
    int32_t scl = sbarsc(65536);
3674 hendricks2 311
    int32_t tx = sbarx16((320<<15) - (tilesizx[BOTTOMSTATUSBAR]<<15)); // centered
312
    int32_t ty = sbary(200-tilesizy[BOTTOMSTATUSBAR]);
5 Plagman 313
 
3399 helixhorne 314
    int32_t clx1 = sbarsc(scale(x1,xdim,320)), cly1 = sbarsc(scale(y1,ydim,200));
315
    int32_t clx2 = sbarsc(scale(x2,xdim,320)), cly2 = sbarsc(scale(y2,ydim,200));
316
    int32_t clofx = (xdim - sbarsc(xdim)) >> 1, clofy = (ydim - sbarsc(ydim));
5 Plagman 317
 
508 terminx 318
    rotatesprite(tx,ty,scl,0,BOTTOMSTATUSBAR,4,0,10+16+64,clx1+clofx,cly1+clofy,clx2+clofx-1,cly2+clofy-1);
5 Plagman 319
}
320
 
1772 plagman 321
void P_SetGamePalette(DukePlayer_t *player, uint8_t palid, int32_t set)
5 Plagman 322
{
1772 plagman 323
    if (palid >= BASEPALCOUNT)
324
        palid = BASEPAL;
1604 terminx 325
 
2954 helixhorne 326
    player->palette = palid;
327
 
564 terminx 328
    if (player != g_player[screenpeek].ps)
5 Plagman 329
        return;
1918 terminx 330
 
1781 plagman 331
    setbrightness(ud.brightness>>2, palid, set);
5 Plagman 332
}
333
 
2947 helixhorne 334
 
2961 helixhorne 335
// flags
336
//  4: small font, wrap strings?
1604 terminx 337
int32_t G_PrintGameText(int32_t f,  int32_t tile, int32_t x,  int32_t y,  const char *t,
338
                        int32_t s,  int32_t p,    int32_t o,
339
                        int32_t x1, int32_t y1,   int32_t x2, int32_t y2, int32_t z)
587 terminx 340
{
1604 terminx 341
    int32_t ac;
3608 hendricks2 342
    const int32_t squishtext = (f&2) != 0 ? 1 : 0;
343
    const int32_t widthx = 320<<16;
344
    int32_t origx = x, origy, j = 0;
5 Plagman 345
 
1604 terminx 346
    if (t == NULL)
347
        return -1;
348
 
3608 hendricks2 349
    if (!(o & ROTATESPRITE_FULL16))
966 hnt_ts 350
    {
3608 hendricks2 351
        x <<= 16;
352
        y <<= 16;
966 hnt_ts 353
    }
5 Plagman 354
 
3608 hendricks2 355
    origy = y;
356
 
357
    if (x == (widthx>>1)) // center
1604 terminx 358
    {
359
        const char *oldt = t;
360
        int32_t newx = 0;
102 terminx 361
 
1019 terminx 362
        do
5 Plagman 363
        {
1604 terminx 364
            int32_t i;
365
 
366
            if (*t == 32)
151 terminx 367
            {
3608 hendricks2 368
                newx += ((((f & 8) ? 8 : 5) - squishtext) * z);
266 terminx 369
                continue;
151 terminx 370
            }
1604 terminx 371
 
372
            if (*t == '^' && isdigit(*(t+1)))
335 terminx 373
            {
2380 helixhorne 374
                t++;
375
                if (isdigit(*(t+1)))
376
                    t++;
3499 helixhorne 377
//                t += 1 + isdigit(*(t+2));   // This code is wrong, see C99 6.5 #2
335 terminx 378
                continue;
379
            }
5 Plagman 380
 
1604 terminx 381
            ac = *t - '!' + tile;
5 Plagman 382
 
2947 helixhorne 383
            if (ac < tile || ac > (tile + 93))
384
                break;
1604 terminx 385
 
3608 hendricks2 386
            i = ((((f & 8) ? 8 : tilesizx[ac]) - squishtext) * z);
2380 helixhorne 387
            newx += i;
1604 terminx 388
 
331 terminx 389
            if (*t >= '0' && *t <= '9')
3608 hendricks2 390
                newx -= i - ((8 * z));
5 Plagman 391
        }
1019 terminx 392
        while (*(++t));
5 Plagman 393
 
394
        t = oldt;
1604 terminx 395
 
396
        x = (f & 4) ?
397
            (xres>>1)-textsc(newx>>1) :
3608 hendricks2 398
            (widthx>>1)-(newx>>1);
5 Plagman 399
    }
1604 terminx 400
 
1019 terminx 401
    do
5 Plagman 402
    {
1604 terminx 403
        int32_t i;
404
 
405
        if (*t == 32)
406
        {
3608 hendricks2 407
            j += ((((f & 8) ? 8 : 5) - squishtext) * z);
1604 terminx 408
            continue;
409
        }
410
 
331 terminx 411
        if (*t == '^' && isdigit(*(t+1)))
151 terminx 412
        {
765 terminx 413
            char smallbuf[4];
1604 terminx 414
 
1019 terminx 415
            if (!isdigit(*(++t+1)))
151 terminx 416
            {
1019 terminx 417
                smallbuf[0] = *(t);
151 terminx 418
                smallbuf[1] = '\0';
2374 helixhorne 419
                p = Batoi(smallbuf);
1019 terminx 420
                continue;
151 terminx 421
            }
1604 terminx 422
 
1019 terminx 423
            smallbuf[0] = *(t++);
424
            smallbuf[1] = *(t);
425
            smallbuf[2] = '\0';
2374 helixhorne 426
            p = Batoi(smallbuf);
266 terminx 427
            continue;
151 terminx 428
        }
5 Plagman 429
 
1604 terminx 430
        ac = *t - '!' + tile;
431
 
432
        if (ac < tile || ac > (tile + 93))
5 Plagman 433
            break;
434
 
1604 terminx 435
        if (f&4)
2947 helixhorne 436
        {
3608 hendricks2 437
            rotatesprite(textsc(x+j), (origy)+textsc((y-origy)), textsc(z),
1677 terminx 438
                         0,ac,s,p,(8|16|(o&1)|(o&32)),x1,y1,x2,y2);
2947 helixhorne 439
        }
440
        else
441
        {
442
            const int32_t orient = (f&1) ? (8|16|(o&1)|(o&32)) : (2|o);
3608 hendricks2 443
            rotatesprite(x+j, y, z,
2947 helixhorne 444
                         0,ac,s,p,orient,x1,y1,x2,y2);
445
        }
1095 terminx 446
 
2947 helixhorne 447
        i = (f & 8) ?
3608 hendricks2 448
            ((8 - squishtext) * z):
449
            ((tilesizx[ac] - squishtext) * z);
450
        j += i;
1604 terminx 451
 
2947 helixhorne 452
        if (*t >= '0' && *t <= '9')
3608 hendricks2 453
            j -= i-((8*z));
924 terminx 454
 
2896 helixhorne 455
        // wrapping long strings doesn't work for precise coordinates due to overflow
456
        // XXX: above comment obsolete?
3608 hendricks2 457
        if (!(o&ROTATESPRITE_FULL16))
1095 terminx 458
        {
3608 hendricks2 459
            if (((f&4) ? textsc(x+j) : (x+j)) > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET)<<16)
460
                j = 0, y += z<<3; // z == 65536 --> 8<<16
1095 terminx 461
        }
5 Plagman 462
    }
1019 terminx 463
    while (*(++t));
1604 terminx 464
 
3608 hendricks2 465
    return origx + ((o & ROTATESPRITE_FULL16) ? j : (j>>16));
5 Plagman 466
}
467
 
1205 terminx 468
int32_t G_GameTextLen(int32_t x,const char *t)
877 terminx 469
{
1205 terminx 470
    int32_t ac;
867 terminx 471
 
877 terminx 472
    if (t == NULL)
473
        return -1;
474
 
1019 terminx 475
    do
877 terminx 476
    {
477
        if (*t == 32)
478
        {
479
            x+=5;
480
            continue;
481
        }
482
 
1625 terminx 483
        ac = *t - '!' + STARTALPHANUM;
484
 
877 terminx 485
        if (ac < STARTALPHANUM || ac > (STARTALPHANUM + 93))
486
            break;
487
 
1625 terminx 488
        x += (*t >= '0' && *t <= '9') ? 8 : tilesizx[ac];
877 terminx 489
    }
1019 terminx 490
    while (*(++t));
1625 terminx 491
 
1095 terminx 492
    return (textsc(x));
877 terminx 493
}
494
 
2640 helixhorne 495
int32_t mpgametext(int32_t y,const char *t,int32_t s,int32_t dabits)
78 terminx 496
{
1604 terminx 497
    return(G_PrintGameText(4,STARTALPHANUM, 5,y,t,s,0,dabits,0, 0, xdim-1, ydim-1, 65536));
78 terminx 498
}
499
 
2944 helixhorne 500
// minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords,
501
// (sb&ROTATESPRITE_MAX) only.
502
static int32_t minitext_yofs = 0;
3606 hendricks2 503
static int32_t minitext_lowercase = 0;
1205 terminx 504
int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t sb)
5 Plagman 505
{
3608 hendricks2 506
    int32_t ac, j = 0;
1205 terminx 507
    char ch, cmode;
5 Plagman 508
 
1658 terminx 509
    cmode = (sb&ROTATESPRITE_MAX)!=0;
2935 helixhorne 510
    sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN;
5 Plagman 511
 
1918 terminx 512
    if (t == NULL)
513
    {
514
        OSD_Printf("minitext: NULL text!\n");
515
        return 0;
516
    }
1884 terminx 517
 
3608 hendricks2 518
    if (!(sb&ROTATESPRITE_FULL16))
519
    {
520
        x<<=16;
521
        y<<=16;
522
    }
523
 
1019 terminx 524
    do
5 Plagman 525
    {
921 terminx 526
        if (*t == '^' && isdigit(*(t+1)))
527
        {
528
            char smallbuf[4];
1019 terminx 529
            if (!isdigit(*(++t+1)))
921 terminx 530
            {
1019 terminx 531
                smallbuf[0] = *(t);
921 terminx 532
                smallbuf[1] = '\0';
2374 helixhorne 533
                p = Batoi(smallbuf);
1019 terminx 534
                continue;
921 terminx 535
            }
1019 terminx 536
            smallbuf[0] = *(t++);
537
            smallbuf[1] = *(t);
538
            smallbuf[2] = '\0';
2374 helixhorne 539
            p = Batoi(smallbuf);
921 terminx 540
            continue;
541
        }
3606 hendricks2 542
        if (!minitext_lowercase)
543
            ch = Btoupper(*t);
544
        else
545
            ch = *t;
546
 
335 terminx 547
        if (ch == 32)
548
        {
3608 hendricks2 549
            j+=5;
335 terminx 550
            continue;
551
        }
5 Plagman 552
        else ac = ch - '!' + MINIFONT;
553
 
3612 hendricks2 554
        if (cmode) rotatesprite_fs(sbarx16(x+(j<<16)),minitext_yofs+sbary16(y),sbarsc(65536L),0,ac,s,p,sb);
3608 hendricks2 555
        else rotatesprite_fs(x+(j<<16),y,65536L,0,ac,s,p,sb);
556
        j += (tilesizx[ac] > 0 ? tilesizx[ac] : 3) + 1;
5 Plagman 557
 
558
    }
1019 terminx 559
    while (*(++t));
1625 terminx 560
 
3608 hendricks2 561
    return x+(j<<((sb&ROTATESPRITE_FULL16)?16:0));
5 Plagman 562
}
563
 
1143 terminx 564
void G_AddUserQuote(const char *daquote)
5 Plagman 565
{
1205 terminx 566
    int32_t i;
5 Plagman 567
 
1229 terminx 568
    for (i=MAXUSERQUOTES-1; i>0; i--)
5 Plagman 569
    {
232 terminx 570
        Bstrcpy(user_quote[i],user_quote[i-1]);
5 Plagman 571
        user_quote_time[i] = user_quote_time[i-1];
572
    }
232 terminx 573
    Bstrcpy(user_quote[0],daquote);
864 terminx 574
    OSD_Printf("%s\n",daquote);
87 terminx 575
 
88 terminx 576
    user_quote_time[0] = ud.msgdisptime;
5 Plagman 577
    pub = NUMPAGES;
578
}
579
 
1143 terminx 580
void G_HandleSpecialKeys(void)
5 Plagman 581
{
1552 terminx 582
    // we need CONTROL_GetInput in order to pick up joystick button presses
583
    if (CONTROL_Started && !(g_player[myconnectindex].ps->gm & MODE_GAME))
584
    {
585
        ControlInfo noshareinfo;
586
        CONTROL_GetInput(&noshareinfo);
587
    }
588
 
1632 terminx 589
//    CONTROL_ProcessBinds();
808 terminx 590
 
1802 terminx 591
    if (g_networkMode != NET_DEDICATED_SERVER && ALT_IS_PRESSED && KB_KeyPressed(sc_Enter))
114 terminx 592
    {
563 terminx 593
        if (setgamemode(!ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP))
335 terminx 594
        {
909 terminx 595
            OSD_Printf(OSD_ERROR "Failed setting fullscreen video mode.\n");
563 terminx 596
            if (setgamemode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP))
1143 terminx 597
                G_GameExit("Failed to recover from failure to set fullscreen video mode.\n");
114 terminx 598
        }
563 terminx 599
        else ud.config.ScreenMode = !ud.config.ScreenMode;
114 terminx 600
        KB_ClearKeyDown(sc_Enter);
1143 terminx 601
        g_restorePalette = 1;
602
        G_UpdateScreenArea();
114 terminx 603
    }
604
 
824 terminx 605
    if (KB_UnBoundKeyPressed(sc_F12))
472 terminx 606
    {
1852 helixhorne 607
        char titlebuf[256];
608
        Bsprintf(titlebuf,HEAD2 " %s",s_buildRev);
609
 
472 terminx 610
        KB_ClearKeyDown(sc_F12);
1852 helixhorne 611
        screencapture("duke0000.tga",0,titlebuf);
1802 terminx 612
        P_DoQuote(QUOTE_SCREEN_SAVED,g_player[myconnectindex].ps);
472 terminx 613
    }
614
 
5 Plagman 615
    // only dispatch commands here when not in a game
1574 terminx 616
    if (!(g_player[myconnectindex].ps->gm & MODE_GAME))
335 terminx 617
        OSD_DispatchQueued();
5 Plagman 618
 
1587 terminx 619
    if (g_quickExit == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && (KB_KeyPressed(sc_Delete)||KB_KeyPressed(sc_End)))
5 Plagman 620
    {
1587 terminx 621
        g_quickExit = 1;
1143 terminx 622
        G_GameExit("Quick Exit.");
5 Plagman 623
    }
1143 terminx 624
}
5 Plagman 625
 
1571 terminx 626
void G_GameQuit(void)
1552 terminx 627
{
1574 terminx 628
    if (numplayers < 2)
629
        G_GameExit(" ");
630
 
631
    if (g_gameQuit == 0)
1552 terminx 632
    {
1593 terminx 633
        g_gameQuit = 1;
634
        g_quitDeadline = totalclock+120;
635
        g_netDisconnect = 1;
1552 terminx 636
    }
637
 
1587 terminx 638
    if ((totalclock > g_quitDeadline) && (g_gameQuit == 1))
1552 terminx 639
        G_GameExit("Timed out.");
640
}
641
 
1205 terminx 642
extern int32_t cacnum;
5 Plagman 643
extern cactype cac[];
644
 
1143 terminx 645
static void G_ShowCacheLocks(void)
5 Plagman 646
{
1205 terminx 647
    int16_t i,k;
5 Plagman 648
 
1916 helixhorne 649
    if (offscreenrendering)
650
        return;
651
 
5 Plagman 652
    k = 0;
1229 terminx 653
    for (i=cacnum-1; i>=0; i--)
5 Plagman 654
        if ((*cac[i].lock) >= 200)
655
        {
1916 helixhorne 656
            if (k >= ydim-12)
657
                break;
658
 
584 terminx 659
            Bsprintf(tempbuf,"Locked- %d: Leng:%d, Lock:%d",i,cac[i].leng,*cac[i].lock);
335 terminx 660
            printext256(0L,k,31,-1,tempbuf,1);
661
            k += 6;
5 Plagman 662
        }
663
 
1916 helixhorne 664
    if (k < ydim-12)
665
        k += 6;
5 Plagman 666
 
1229 terminx 667
    for (i=10; i>=0; i--)
1677 terminx 668
        if (rts_lumplockbyte[i] >= 200)
5 Plagman 669
        {
1916 helixhorne 670
            if (k >= ydim-12)
671
                break;
672
 
5 Plagman 673
            Bsprintf(tempbuf,"RTS Locked %d:",i);
2441 helixhorne 674
            printext256(0,k,31,-1,tempbuf,1);
335 terminx 675
            k += 6;
5 Plagman 676
        }
1916 helixhorne 677
 
678
    if (k >= ydim-12 && k<ydim-6)
2441 helixhorne 679
        printext256(0,k,31,-1,"(MORE . . .)",1);
680
 
681
    // sounds
682
    if (xdim < 640)
683
        return;
684
 
685
    k = 18;
686
    for (i=0; i<=g_maxSoundPos; i++)
687
        if (g_sounds[i].num > 0)
688
        {
689
            int32_t j, n=g_sounds[i].num;
690
 
691
            for (j=0; j<n; j++)
692
            {
693
                if (k >= ydim-12)
694
                    break;
695
 
696
                Bsprintf(tempbuf, "snd #%d inst %d: voice %d, ow %d", i, j,
2442 helixhorne 697
                         g_sounds[i].SoundOwner[j].voice, g_sounds[i].SoundOwner[j].ow);
2441 helixhorne 698
                printext256(240,k,31,-1,tempbuf,0);
699
 
700
                k += 9;
701
            }
702
        }
5 Plagman 703
}
704
 
1205 terminx 705
int32_t A_CheckInventorySprite(spritetype *s)
5 Plagman 706
{
2297 helixhorne 707
    switch (DYNAMICTILEMAP(s->picnum))
5 Plagman 708
    {
337 terminx 709
    case FIRSTAID__STATIC:
710
    case STEROIDS__STATIC:
711
    case HEATSENSOR__STATIC:
712
    case BOOTS__STATIC:
713
    case JETPACK__STATIC:
714
    case HOLODUKE__STATIC:
715
    case AIRTANK__STATIC:
716
        return 1;
1672 terminx 717
    default:
718
        return 0;
5 Plagman 719
    }
720
}
721
 
3645 helixhorne 722
// MYOS* CON commands.
723
LUNATIC_EXTERN void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum,
724
                                      int32_t shade, int32_t orientation, int32_t p)
5 Plagman 725
{
2896 helixhorne 726
    int32_t a = 0;
5 Plagman 727
 
3479 helixhorne 728
    orientation &= (ROTATESPRITE_MAX-1);
729
 
331 terminx 730
    if (orientation&4)
5 Plagman 731
        a = 1024;
732
 
3608 hendricks2 733
    if (!(orientation&ROTATESPRITE_FULL16))
734
    {
735
        x<<=16;
736
        y<<=16;
737
    }
738
 
739
    rotatesprite_win(x,y,zoom,a,tilenum,shade,p,2|orientation);
5 Plagman 740
}
741
 
3479 helixhorne 742
#if !defined LUNATIC
2896 helixhorne 743
void G_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation)
5 Plagman 744
{
2896 helixhorne 745
    DukePlayer_t *ps = g_player[screenpeek].ps;
746
    int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0;
5 Plagman 747
 
2896 helixhorne 748
    G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p);
749
}
5 Plagman 750
 
2896 helixhorne 751
void G_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
752
{
753
    G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p);
5 Plagman 754
}
755
 
1205 terminx 756
void G_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation)
5 Plagman 757
{
2896 helixhorne 758
    DukePlayer_t *ps = g_player[screenpeek].ps;
759
    int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0;
5 Plagman 760
 
2896 helixhorne 761
    G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p);
5 Plagman 762
}
763
 
1205 terminx 764
void G_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p)
5 Plagman 765
{
2896 helixhorne 766
    G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p);
5 Plagman 767
}
3479 helixhorne 768
#endif
5 Plagman 769
 
1148 terminx 770
#define POLYMOSTTRANS (1)
771
#define POLYMOSTTRANS2 (1|32)
772
 
2944 helixhorne 773
// Draws inventory numbers in the HUD for both the full and mini status bars.
774
// yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords.
775
static void G_DrawInvNum(int32_t x, int32_t yofs, int32_t y, char num1, char ha, int32_t sbits)
5 Plagman 776
{
2896 helixhorne 777
    char dabuf[16];
2316 helixhorne 778
    int32_t i, shd = (x < 0);
934 terminx 779
 
2896 helixhorne 780
    const int32_t sbscale = sbarsc(65536);
2944 helixhorne 781
    const int32_t sby = yofs+sbary(y), sbyp1 = yofs+sbary(y+1);
2896 helixhorne 782
 
946 terminx 783
    if (shd) x = -x;
934 terminx 784
 
2896 helixhorne 785
    Bsprintf(dabuf, "%d", num1);
786
 
331 terminx 787
    if (num1 > 99)
5 Plagman 788
    {
3346 terminx 789
        if (shd && ud.screen_size == 4 && getrendermode() >= REND_POLYMOST && althud_shadows)
934 terminx 790
        {
2316 helixhorne 791
            for (i=0; i<=2; i++)
2896 helixhorne 792
                rotatesprite_fs(sbarx(x+(-4+4*i)+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[i]-'0',
793
                                ha, 4, POLYMOSTTRANS|sbits);
934 terminx 794
        }
2316 helixhorne 795
 
796
        for (i=0; i<=2; i++)
2896 helixhorne 797
            rotatesprite_fs(sbarx(x+(-4+4*i)),sby,sbscale,0,THREEBYFIVE+dabuf[i]-'0',ha, 0, sbits);
425 terminx 798
        return;
5 Plagman 799
    }
2896 helixhorne 800
 
425 terminx 801
    if (num1 > 9)
5 Plagman 802
    {
3346 terminx 803
        if (shd && ud.screen_size == 4 && getrendermode() >= REND_POLYMOST && althud_shadows)
934 terminx 804
        {
2896 helixhorne 805
            rotatesprite_fs(sbarx(x+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,4,POLYMOSTTRANS|sbits);
806
            rotatesprite_fs(sbarx(x+4+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,4,POLYMOSTTRANS|sbits);
934 terminx 807
        }
808
 
2896 helixhorne 809
        rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits);
810
        rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits);
425 terminx 811
        return;
5 Plagman 812
    }
2896 helixhorne 813
 
814
    rotatesprite_fs(sbarx(x+4+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,4,sbits);
815
    rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits);
5 Plagman 816
}
817
 
1658 terminx 818
static void G_DrawWeapNum(int16_t ind,int32_t x,int32_t y,int32_t num1, int32_t num2,int32_t ha)
5 Plagman 819
{
2896 helixhorne 820
    char dabuf[16];
5 Plagman 821
 
2896 helixhorne 822
    const int32_t sbscale = sbarsc(65536);
823
    const int32_t sby = sbary(y);
425 terminx 824
 
2896 helixhorne 825
    rotatesprite_fs(sbarx(x-7),sby,sbscale,0,THREEBYFIVE+ind+1,ha-10,7,10);
826
    rotatesprite_fs(sbarx(x-3),sby,sbscale,0,THREEBYFIVE+10,ha,0,10);
827
 
425 terminx 828
    if (VOLUMEONE && (ind > HANDBOMB_WEAPON || ind < 0))
829
    {
1658 terminx 830
        minitextshade(x+1,y-4,"ORDER",20,11,2+8+16+ROTATESPRITE_MAX);
425 terminx 831
        return;
832
    }
833
 
2896 helixhorne 834
    rotatesprite_fs(sbarx(x+9),sby,sbscale,0,THREEBYFIVE+11,ha,0,10);
5 Plagman 835
 
331 terminx 836
    if (num1 > 99) num1 = 99;
837
    if (num2 > 99) num2 = 99;
5 Plagman 838
 
584 terminx 839
    Bsprintf(dabuf,"%d",num1);
331 terminx 840
    if (num1 > 9)
5 Plagman 841
    {
2896 helixhorne 842
        rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
843
        rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
5 Plagman 844
    }
2896 helixhorne 845
    else rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
5 Plagman 846
 
584 terminx 847
    Bsprintf(dabuf,"%d",num2);
331 terminx 848
    if (num2 > 9)
5 Plagman 849
    {
2896 helixhorne 850
        rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
851
        rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
425 terminx 852
        return;
5 Plagman 853
    }
2896 helixhorne 854
    rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
5 Plagman 855
}
856
 
1205 terminx 857
static void G_DrawWeapNum2(char ind,int32_t x,int32_t y,int32_t num1, int32_t num2,char ha)
5 Plagman 858
{
2896 helixhorne 859
    char dabuf[16];
5 Plagman 860
 
2896 helixhorne 861
    const int32_t sbscale = sbarsc(65536);
862
    const int32_t sby = sbary(y);
5 Plagman 863
 
2896 helixhorne 864
    rotatesprite_fs(sbarx(x-7),sby,sbscale,0,THREEBYFIVE+ind+1,ha-10,7,10);
865
    rotatesprite_fs(sbarx(x-4),sby,sbscale,0,THREEBYFIVE+10,ha,0,10);
866
    rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+11,ha,0,10);
867
 
584 terminx 868
    Bsprintf(dabuf,"%d",num1);
331 terminx 869
    if (num1 > 99)
5 Plagman 870
    {
2896 helixhorne 871
        rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
872
        rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
873
        rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10);
5 Plagman 874
    }
331 terminx 875
    else if (num1 > 9)
5 Plagman 876
    {
2896 helixhorne 877
        rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
878
        rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
5 Plagman 879
    }
2896 helixhorne 880
    else rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
5 Plagman 881
 
584 terminx 882
    Bsprintf(dabuf,"%d",num2);
331 terminx 883
    if (num2 > 99)
5 Plagman 884
    {
2896 helixhorne 885
        rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
886
        rotatesprite_fs(sbarx(x+21),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
887
        rotatesprite_fs(sbarx(x+25),sby,sbscale,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10);
5 Plagman 888
    }
331 terminx 889
    else if (num2 > 9)
5 Plagman 890
    {
2896 helixhorne 891
        rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
892
        rotatesprite_fs(sbarx(x+21),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10);
425 terminx 893
        return;
5 Plagman 894
    }
587 terminx 895
    else
2896 helixhorne 896
        rotatesprite_fs(sbarx(x+25),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10);
5 Plagman 897
}
898
 
2896 helixhorne 899
static void G_DrawWeapAmounts(const DukePlayer_t *p,int32_t x,int32_t y,int32_t u)
5 Plagman 900
{
1205 terminx 901
    int32_t cw = p->curr_weapon;
5 Plagman 902
 
903
    if (u&4)
904
    {
1144 terminx 905
        if (u != -1) G_PatchStatusBar(88,178,88+37,178+6); //original code: (96,178,96+12,178+6);
1143 terminx 906
        G_DrawWeapNum2(PISTOL_WEAPON,x,y,
907
                       p->ammo_amount[PISTOL_WEAPON],p->max_ammo_amount[PISTOL_WEAPON],
908
                       12-20*(cw == PISTOL_WEAPON));
5 Plagman 909
    }
910
    if (u&8)
911
    {
1144 terminx 912
        if (u != -1) G_PatchStatusBar(88,184,88+37,184+6); //original code: (96,184,96+12,184+6);
1143 terminx 913
        G_DrawWeapNum2(SHOTGUN_WEAPON,x,y+6,
914
                       p->ammo_amount[SHOTGUN_WEAPON],p->max_ammo_amount[SHOTGUN_WEAPON],
1625 terminx 915
                       (((p->gotweapon & (1<<SHOTGUN_WEAPON)) == 0)*9)+12-18*
1143 terminx 916
                       (cw == SHOTGUN_WEAPON));
5 Plagman 917
    }
918
    if (u&16)
919
    {
1144 terminx 920
        if (u != -1) G_PatchStatusBar(88,190,88+37,190+6); //original code: (96,190,96+12,190+6);
1143 terminx 921
        G_DrawWeapNum2(CHAINGUN_WEAPON,x,y+12,
922
                       p->ammo_amount[CHAINGUN_WEAPON],p->max_ammo_amount[CHAINGUN_WEAPON],
1625 terminx 923
                       (((p->gotweapon & (1<<CHAINGUN_WEAPON)) == 0)*9)+12-18*
1143 terminx 924
                       (cw == CHAINGUN_WEAPON));
5 Plagman 925
    }
926
    if (u&32)
927
    {
1144 terminx 928
        if (u != -1) G_PatchStatusBar(127,178,127+29,178+6); //original code: (135,178,135+8,178+6);
1143 terminx 929
        G_DrawWeapNum(RPG_WEAPON,x+39,y,
930
                      p->ammo_amount[RPG_WEAPON],p->max_ammo_amount[RPG_WEAPON],
1625 terminx 931
                      (((p->gotweapon & (1<<RPG_WEAPON)) == 0)*9)+12-19*
1143 terminx 932
                      (cw == RPG_WEAPON));
5 Plagman 933
    }
934
    if (u&64)
935
    {
1144 terminx 936
        if (u != -1) G_PatchStatusBar(127,184,127+29,184+6); //original code: (135,184,135+8,184+6);
1143 terminx 937
        G_DrawWeapNum(HANDBOMB_WEAPON,x+39,y+6,
938
                      p->ammo_amount[HANDBOMB_WEAPON],p->max_ammo_amount[HANDBOMB_WEAPON],
1625 terminx 939
                      (((!p->ammo_amount[HANDBOMB_WEAPON])|((p->gotweapon & (1<<HANDBOMB_WEAPON)) == 0))*9)+12-19*
1143 terminx 940
                      ((cw == HANDBOMB_WEAPON) || (cw == HANDREMOTE_WEAPON)));
5 Plagman 941
    }
942
    if (u&128)
943
    {
1144 terminx 944
        if (u != -1) G_PatchStatusBar(127,190,127+29,190+6); //original code: (135,190,135+8,190+6);
5 Plagman 945
 
425 terminx 946
        if (p->subweapon&(1<<GROW_WEAPON))
1143 terminx 947
            G_DrawWeapNum(SHRINKER_WEAPON,x+39,y+12,
948
                          p->ammo_amount[GROW_WEAPON],p->max_ammo_amount[GROW_WEAPON],
1625 terminx 949
                          (((p->gotweapon & (1<<GROW_WEAPON)) == 0)*9)+12-18*
1143 terminx 950
                          (cw == GROW_WEAPON));
335 terminx 951
        else
1143 terminx 952
            G_DrawWeapNum(SHRINKER_WEAPON,x+39,y+12,
953
                          p->ammo_amount[SHRINKER_WEAPON],p->max_ammo_amount[SHRINKER_WEAPON],
1625 terminx 954
                          (((p->gotweapon & (1<<SHRINKER_WEAPON)) == 0)*9)+12-18*
1143 terminx 955
                          (cw == SHRINKER_WEAPON));
5 Plagman 956
    }
957
    if (u&256)
958
    {
1144 terminx 959
        if (u != -1) G_PatchStatusBar(158,178,162+29,178+6); //original code: (166,178,166+8,178+6);
5 Plagman 960
 
1143 terminx 961
        G_DrawWeapNum(DEVISTATOR_WEAPON,x+70,y,
962
                      p->ammo_amount[DEVISTATOR_WEAPON],p->max_ammo_amount[DEVISTATOR_WEAPON],
1625 terminx 963
                      (((p->gotweapon & (1<<DEVISTATOR_WEAPON)) == 0)*9)+12-18*
1143 terminx 964
                      (cw == DEVISTATOR_WEAPON));
5 Plagman 965
    }
966
    if (u&512)
967
    {
1144 terminx 968
        if (u != -1) G_PatchStatusBar(158,184,162+29,184+6); //original code: (166,184,166+8,184+6);
428 terminx 969
 
1143 terminx 970
        G_DrawWeapNum(TRIPBOMB_WEAPON,x+70,y+6,
971
                      p->ammo_amount[TRIPBOMB_WEAPON],p->max_ammo_amount[TRIPBOMB_WEAPON],
1625 terminx 972
                      (((p->gotweapon & (1<<TRIPBOMB_WEAPON)) == 0)*9)+12-18*
1143 terminx 973
                      (cw == TRIPBOMB_WEAPON));
5 Plagman 974
    }
975
 
976
    if (u&65536L)
977
    {
1144 terminx 978
        if (u != -1) G_PatchStatusBar(158,190,162+29,190+6); //original code: (166,190,166+8,190+6);
425 terminx 979
 
1143 terminx 980
        G_DrawWeapNum(-1,x+70,y+12,
981
                      p->ammo_amount[FREEZE_WEAPON],p->max_ammo_amount[FREEZE_WEAPON],
1625 terminx 982
                      (((p->gotweapon & (1<<FREEZE_WEAPON)) == 0)*9)+12-18*
1143 terminx 983
                      (cw == FREEZE_WEAPON));
5 Plagman 984
    }
985
}
986
 
2944 helixhorne 987
// yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords.
988
static void G_DrawDigiNum_(int32_t x, int32_t yofs, int32_t y, int32_t n, char s, int32_t cs)
5 Plagman 989
{
1205 terminx 990
    int32_t i, j = 0, k, p, c;
2086 helixhorne 991
    char b[12];
5 Plagman 992
 
2086 helixhorne 993
    i = Bsprintf(b,"%d",n);
5 Plagman 994
 
1229 terminx 995
    for (k=i-1; k>=0; k--)
5 Plagman 996
    {
2566 helixhorne 997
        p = DIGITALNUM + b[k]-'0';
5 Plagman 998
        j += tilesizx[p]+1;
999
    }
1000
    c = x-(j>>1);
1001
 
1002
    j = 0;
1229 terminx 1003
    for (k=0; k<i; k++)
5 Plagman 1004
    {
2566 helixhorne 1005
        p = DIGITALNUM + b[k]-'0';
2944 helixhorne 1006
        rotatesprite_fs(sbarx(c+j), yofs+sbary(y), sbarsc(65536), 0, p, s, 0, cs);
5 Plagman 1007
        j += tilesizx[p]+1;
1008
    }
1009
}
1010
 
2944 helixhorne 1011
static inline void G_DrawDigiNum(int32_t x, int32_t y, int32_t n, char s, int32_t cs)
1012
{
1013
    G_DrawDigiNum_(x, 0, y, n, s, cs);
1014
}
1015
 
1658 terminx 1016
void G_DrawTXDigiNumZ(int32_t starttile, int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,
1017
                      int32_t cs,int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z)
5 Plagman 1018
{
1205 terminx 1019
    int32_t i, j = 0, k, p, c;
2086 helixhorne 1020
    char b[12];
3608 hendricks2 1021
    const int32_t shift = (cs&ROTATESPRITE_FULL16)?0:16;
5 Plagman 1022
 
2086 helixhorne 1023
    i = Bsprintf(b,"%d",n);
5 Plagman 1024
 
3608 hendricks2 1025
    // center the number string
1229 terminx 1026
    for (k=i-1; k>=0; k--)
5 Plagman 1027
    {
2086 helixhorne 1028
        p = starttile + b[k]-'0';
3608 hendricks2 1029
        j += ((1+tilesizx[p])*z);
5 Plagman 1030
    }
3608 hendricks2 1031
    c = (x<<shift)-(j>>1);
5 Plagman 1032
 
1033
    j = 0;
1229 terminx 1034
    for (k=0; k<i; k++)
5 Plagman 1035
    {
2086 helixhorne 1036
        p = starttile + b[k]-'0';
3608 hendricks2 1037
        rotatesprite(c+j,y<<shift,z,0,p,s,pal,2|cs,x1,y1,x2,y2);
1038
        j += ((1+tilesizx[p])*z);
5 Plagman 1039
    }
1040
}
1041
 
2566 helixhorne 1042
static void G_DrawAltDigiNum(int32_t x, int32_t y, int32_t n, char s, int32_t cs)
934 terminx 1043
{
1205 terminx 1044
    int32_t i, j = 0, k, p, c;
2086 helixhorne 1045
    char b[12];
1205 terminx 1046
    int32_t rev = (x < 0);
1047
    int32_t shd = (y < 0);
934 terminx 1048
 
2896 helixhorne 1049
    const int32_t sbscale = sbarsc(65536);
1050
 
934 terminx 1051
    if (rev) x = -x;
946 terminx 1052
    if (shd) y = -y;
934 terminx 1053
 
2086 helixhorne 1054
    i = Bsprintf(b,"%d",n);
934 terminx 1055
 
1229 terminx 1056
    for (k=i-1; k>=0; k--)
934 terminx 1057
    {
2566 helixhorne 1058
        p = althud_numbertile + b[k]-'0';
934 terminx 1059
        j += tilesizx[p]+1;
1060
    }
1061
    c = x-(j>>1);
1062
 
1063
    if (rev)
1064
    {
1229 terminx 1065
        for (k=0; k<i; k++)
934 terminx 1066
        {
2566 helixhorne 1067
            p = althud_numbertile + b[k]-'0';
3346 terminx 1068
            if (shd && getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1069
                rotatesprite_fs(sbarxr(c+j-1),sbary(y+1),sbscale,0,p,s,4,cs|POLYMOSTTRANS2);
1070
            rotatesprite_fs(sbarxr(c+j),sbary(y),sbscale,0,p,s,althud_numberpal,cs);
934 terminx 1071
            j -= tilesizx[p]+1;
1072
        }
1073
        return;
1074
    }
2566 helixhorne 1075
 
934 terminx 1076
    j = 0;
1229 terminx 1077
    for (k=0; k<i; k++)
934 terminx 1078
    {
2566 helixhorne 1079
        p = althud_numbertile + b[k]-'0';
3346 terminx 1080
        if (shd && getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1081
            rotatesprite_fs(sbarx(c+j+1),sbary(y+1),sbscale,0,p,s,4,cs|POLYMOSTTRANS2);
1082
        rotatesprite_fs(sbarx(c+j),sbary(y),sbscale,0,p,s,althud_numberpal,cs);
934 terminx 1083
        j += tilesizx[p]+1;
1084
    }
1085
}
1086
 
3676 hendricks2 1087
static int32_t invensc(int32_t maximum) // used to reposition the inventory icon selector as the HUD scales
1088
{
1089
    return scale(maximum << 16, ud.statusbarscale - 36, 100 - 36);
1090
}
1091
 
2896 helixhorne 1092
static void G_DrawInventory(const DukePlayer_t *p)
5 Plagman 1093
{
3676 hendricks2 1094
    int32_t n, j = 0, x = 0, y;
5 Plagman 1095
 
1572 terminx 1096
    n = (p->inv_amount[GET_JETPACK] > 0)<<3;
335 terminx 1097
    if (n&8) j++;
1572 terminx 1098
    n |= (p->inv_amount[GET_SCUBA] > 0)<<5;
335 terminx 1099
    if (n&32) j++;
1572 terminx 1100
    n |= (p->inv_amount[GET_STEROIDS] > 0)<<1;
335 terminx 1101
    if (n&2) j++;
1572 terminx 1102
    n |= (p->inv_amount[GET_HOLODUKE] > 0)<<2;
335 terminx 1103
    if (n&4) j++;
1572 terminx 1104
    n |= (p->inv_amount[GET_FIRSTAID] > 0);
335 terminx 1105
    if (n&1) j++;
1572 terminx 1106
    n |= (p->inv_amount[GET_HEATS] > 0)<<4;
335 terminx 1107
    if (n&16) j++;
1572 terminx 1108
    n |= (p->inv_amount[GET_BOOTS] > 0)<<6;
335 terminx 1109
    if (n&64) j++;
5 Plagman 1110
 
3676 hendricks2 1111
    x = (160-(j*11))<<16; // nearly center
5 Plagman 1112
 
1113
    j = 0;
1114
 
3676 hendricks2 1115
    if (ud.screen_size < 8) // mini-HUDs or no HUD
1116
    {
1117
        y = 172<<16;
5 Plagman 1118
 
3676 hendricks2 1119
        if (ud.screen_size == 4 && ud.althud) // modern mini-HUD
1120
            y -= invensc(tilesizy[BIGALPHANUM]+10); // slide on the y-axis
1121
    }
1122
    else // full HUD
1123
    {
1124
        y = (200<<16) - (sbarsc(tilesizy[BOTTOMSTATUSBAR]<<16) + (12<<16) + (tilesizy[BOTTOMSTATUSBAR]<<(16-1)));
1125
 
1126
        if (!ud.statusbarmode) // original non-overlay mode
1127
            y += sbarsc(tilesizy[BOTTOMSTATUSBAR]<<16)>>1; // account for the viewport y-size as the HUD scales
1128
    }
1129
 
1130
    if (ud.screen_size == 4 && !ud.althud) // classic mini-HUD
1131
        x += invensc(ud.multimode > 1 ? 56 : 65); // slide on the x-axis
1132
 
333 terminx 1133
    while (j <= 9)
5 Plagman 1134
    {
333 terminx 1135
        if (n&(1<<j))
5 Plagman 1136
        {
333 terminx 1137
            switch (n&(1<<j))
5 Plagman 1138
            {
1632 terminx 1139
            case 1:
3676 hendricks2 1140
                rotatesprite_win(x,y,65536L,0,FIRSTAID_ICON,0,0,2+16);
337 terminx 1141
                break;
1632 terminx 1142
            case 2:
3676 hendricks2 1143
                rotatesprite_win(x+(1<<16),y,65536L,0,STEROIDS_ICON,0,0,2+16);
337 terminx 1144
                break;
1632 terminx 1145
            case 4:
3676 hendricks2 1146
                rotatesprite_win(x+(2<<16),y,65536L,0,HOLODUKE_ICON,0,0,2+16);
337 terminx 1147
                break;
1632 terminx 1148
            case 8:
3676 hendricks2 1149
                rotatesprite_win(x,y,65536L,0,JETPACK_ICON,0,0,2+16);
337 terminx 1150
                break;
1632 terminx 1151
            case 16:
3676 hendricks2 1152
                rotatesprite_win(x,y,65536L,0,HEAT_ICON,0,0,2+16);
337 terminx 1153
                break;
1632 terminx 1154
            case 32:
3676 hendricks2 1155
                rotatesprite_win(x,y,65536L,0,AIRTANK_ICON,0,0,2+16);
337 terminx 1156
                break;
1157
            case 64:
3676 hendricks2 1158
                rotatesprite_win(x,y-(1<<16),65536L,0,BOOT_ICON,0,0,2+16);
337 terminx 1159
                break;
5 Plagman 1160
            }
1161
 
3676 hendricks2 1162
            x += 22<<16;
5 Plagman 1163
 
331 terminx 1164
            if (p->inven_icon == j+1)
3676 hendricks2 1165
                rotatesprite_win(x-(2<<16),y+(19<<16),65536L,1024,ARROW,-32,0,2+16);
5 Plagman 1166
        }
1167
 
1168
        j++;
1169
    }
1170
}
1171
 
1143 terminx 1172
void G_DrawFrags(void)
5 Plagman 1173
{
1205 terminx 1174
    int32_t i, j = 0;
2896 helixhorne 1175
    const int32_t orient = 2+8+16+64;
5 Plagman 1176
 
2379 helixhorne 1177
    for (TRAVERSE_CONNECT(i))
2896 helixhorne 1178
        if (i > j)
1179
            j = i;
5 Plagman 1180
 
2896 helixhorne 1181
    for (i=0; i<=(j>>2); i++)
1182
        rotatesprite_fs(0,(8*i)<<16,65600, 0, FRAGBAR, 0,0,orient);
5 Plagman 1183
 
2379 helixhorne 1184
    for (TRAVERSE_CONNECT(i))
5 Plagman 1185
    {
2896 helixhorne 1186
        const DukePlayer_t *ps = g_player[i].ps;
1187
        minitext(21+(73*(i&3)), 2+((i&28)<<1), g_player[i].user_name, ps->palookup, 2+8+16);
1188
        Bsprintf(tempbuf, "%d", ps->frag-ps->fraggedself);
1189
        minitext(17+50+(73*(i&3)), 2+((i&28)<<1), tempbuf, ps->palookup, 2+8+16);
5 Plagman 1190
    }
1191
}
1192
 
2896 helixhorne 1193
static int32_t G_GetInvAmount(const DukePlayer_t *p)
1194
{
1195
    switch (p->inven_icon)
1196
    {
3115 terminx 1197
    case ICON_FIRSTAID:
2896 helixhorne 1198
        return p->inv_amount[GET_FIRSTAID];
3115 terminx 1199
    case ICON_STEROIDS:
2896 helixhorne 1200
        return ((p->inv_amount[GET_STEROIDS]+3)>>2);
3115 terminx 1201
    case ICON_HOLODUKE:
2896 helixhorne 1202
        return ((p->inv_amount[GET_HOLODUKE]+15)/24);
3115 terminx 1203
    case ICON_JETPACK:
2896 helixhorne 1204
        return ((p->inv_amount[GET_JETPACK]+15)>>4);
3115 terminx 1205
    case ICON_HEATS:
2896 helixhorne 1206
        return p->inv_amount[GET_HEATS]/12;
3115 terminx 1207
    case ICON_SCUBA:
2896 helixhorne 1208
        return ((p->inv_amount[GET_SCUBA]+63)>>6);
3115 terminx 1209
    case ICON_BOOTS:
2896 helixhorne 1210
        return (p->inv_amount[GET_BOOTS]>>1);
1211
    }
261 terminx 1212
 
2896 helixhorne 1213
    return -1;
1214
}
1215
 
1216
static int32_t G_GetInvOn(const DukePlayer_t *p)
1217
{
1218
    switch (p->inven_icon)
1219
    {
3115 terminx 1220
    case ICON_HOLODUKE:
2896 helixhorne 1221
        return p->holoduke_on;
3115 terminx 1222
    case ICON_JETPACK:
2896 helixhorne 1223
        return p->jetpack_on;
3115 terminx 1224
    case ICON_HEATS:
2896 helixhorne 1225
        return p->heat_on;
1226
    }
1227
 
1228
    return 0x80000000;
1229
}
1230
 
3556 helixhorne 1231
static int32_t G_GetMorale(int32_t p_i, int32_t snum)
1232
{
1233
#if !defined LUNATIC
1234
    return Gv_GetVarByLabel("PLR_MORALE",-1, p_i, snum);
1235
#else
3557 helixhorne 1236
    UNREFERENCED_PARAMETER(p_i);
1237
    UNREFERENCED_PARAMETER(snum);
3556 helixhorne 1238
    return -1;
1239
#endif
1240
}
1241
 
1205 terminx 1242
static void G_DrawStatusBar(int32_t snum)
5 Plagman 1243
{
2896 helixhorne 1244
    const DukePlayer_t *const p = g_player[snum].ps;
2900 helixhorne 1245
    int32_t i, j, o, u;
1205 terminx 1246
    int32_t permbit = 0;
5 Plagman 1247
 
2944 helixhorne 1248
    const int32_t ss = g_fakeMultiMode ? 4 : ud.screen_size;
2900 helixhorne 1249
    const int32_t althud = g_fakeMultiMode ? 0 : ud.althud;
1250
 
2896 helixhorne 1251
    const int32_t SBY = (200-tilesizy[BOTTOMSTATUSBAR]);
532 terminx 1252
 
2896 helixhorne 1253
    const int32_t sb15 = sbarsc(32768), sb15h = sbarsc(49152);
1254
    const int32_t sb16 = sbarsc(65536);
1255
 
1256
    static int32_t item_icons[8];
1257
 
1258
    if (ss < 4)
1259
        return;
1260
 
1261
    if (item_icons[0] == 0)
1262
    {
1263
        int32_t iicons[8] = { -1, FIRSTAID_ICON, STEROIDS_ICON, HOLODUKE_ICON,
1264
                              JETPACK_ICON, HEAT_ICON, AIRTANK_ICON, BOOT_ICON };
1265
        Bmemcpy(item_icons, iicons, sizeof(item_icons));
1266
    }
1267
 
3346 terminx 1268
    if (getrendermode() >= REND_POLYMOST) pus = NUMPAGES;   // JBF 20040101: always redraw in GL
5 Plagman 1269
 
2901 helixhorne 1270
    if ((g_netServer || ud.multimode > 1) && ((GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR) || g_fakeMultiMode))
5 Plagman 1271
    {
1272
        if (pus)
1143 terminx 1273
            G_DrawFrags();
5 Plagman 1274
        else
1275
        {
2379 helixhorne 1276
            for (TRAVERSE_CONNECT(i))
1277
                if (g_player[i].ps->frag != sbar.frag[i])
1278
                {
1279
                    G_DrawFrags();
1280
                    break;
1281
                }
331 terminx 1282
 
5 Plagman 1283
        }
2379 helixhorne 1284
        for (TRAVERSE_CONNECT(i))
1285
            if (i != myconnectindex)
1286
                sbar.frag[i] = g_player[i].ps->frag;
5 Plagman 1287
    }
1288
 
1289
    if (ss == 4)   //DRAW MINI STATUS BAR:
1290
    {
2900 helixhorne 1291
        if (althud)
934 terminx 1292
        {
2900 helixhorne 1293
            // ALTERNATIVE STATUS BAR
1294
 
1205 terminx 1295
            static int32_t ammo_sprites[MAX_WEAPONS];
934 terminx 1296
 
2896 helixhorne 1297
            if (ammo_sprites[0] == 0)
934 terminx 1298
            {
1299
                /* this looks stupid but it lets us initialize static memory to dynamic values
1300
                   these values can be changed from the CONs with dynamic tile remapping
1301
                   but we don't want to have to recreate the values in memory every time
1302
                   the HUD is drawn */
1303
 
2896 helixhorne 1304
                int32_t asprites[MAX_WEAPONS] = { BOOTS, AMMO, SHOTGUNAMMO, BATTERYAMMO,
1305
                                                  RPGAMMO, HBOMBAMMO, CRYSTALAMMO, DEVISTATORAMMO,
1207 terminx 1306
                                                  TRIPBOMBSPRITE, FREEZEAMMO+1, HBOMBAMMO, GROWAMMO
1307
                                                };
2896 helixhorne 1308
                Bmemcpy(ammo_sprites, asprites, sizeof(ammo_sprites));
934 terminx 1309
            }
1310
 
2896 helixhorne 1311
//            rotatesprite_fs(sbarx(5+1),sbary(200-25+1),sb15h,0,SIXPAK,0,4,10+16+1+32);
1312
//            rotatesprite_fs(sbarx(5),sbary(200-25),sb15h,0,SIXPAK,0,0,10+16);
3346 terminx 1313
            if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1314
                rotatesprite_fs(sbarx(2+1),sbary(200-21+1),sb15h,0,COLA,0,4,10+16+256+POLYMOSTTRANS2);
1315
            rotatesprite_fs(sbarx(2),sbary(200-21),sb15h,0,COLA,0,0,10+16+256);
935 terminx 1316
 
934 terminx 1317
            if (sprite[p->i].pal == 1 && p->last_extra < 2)
1658 terminx 1318
                G_DrawAltDigiNum(40,-(200-22),1,-16,10+16+256);
953 terminx 1319
            else if (!althud_flashing || p->last_extra > (p->max_player_health>>2) || totalclock&32)
1089 terminx 1320
            {
1205 terminx 1321
                int32_t s = -8;
1089 terminx 1322
                if (althud_flashing && p->last_extra > p->max_player_health)
1323
                    s += (sintable[(totalclock<<5)&2047]>>10);
1658 terminx 1324
                G_DrawAltDigiNum(40,-(200-22),p->last_extra,s,10+16+256);
1089 terminx 1325
            }
934 terminx 1326
 
3346 terminx 1327
            if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1328
                rotatesprite_fs(sbarx(62+1),sbary(200-25+1),sb15h,0,SHIELD,0,4,10+16+POLYMOSTTRANS2+256);
1329
            rotatesprite_fs(sbarx(62),sbary(200-25),sb15h,0,SHIELD,0,0,10+16+256);
934 terminx 1330
 
1490 terminx 1331
            {
3556 helixhorne 1332
                int32_t lAmount = G_GetMorale(p->i, snum);
1333
                if (lAmount == -1)
1334
                    lAmount = p->inv_amount[GET_SHIELD];
1658 terminx 1335
                G_DrawAltDigiNum(105,-(200-22),lAmount,-16,10+16+256);
1490 terminx 1336
            }
934 terminx 1337
 
3346 terminx 1338
            if (getrendermode() >= REND_POLYMOST && althud_shadows)
944 terminx 1339
            {
2896 helixhorne 1340
                if (p->got_access&1) rotatesprite_fs(sbarxr(39-1),sbary(200-43+1),sb15,0,ACCESSCARD,0,4,10+16+POLYMOSTTRANS2+512);
1341
                if (p->got_access&4) rotatesprite_fs(sbarxr(34-1),sbary(200-41+1),sb15,0,ACCESSCARD,0,4,10+16+POLYMOSTTRANS2+512);
1342
                if (p->got_access&2) rotatesprite_fs(sbarxr(29-1),sbary(200-39+1),sb15,0,ACCESSCARD,0,4,10+16+POLYMOSTTRANS2+512);
944 terminx 1343
            }
935 terminx 1344
 
2896 helixhorne 1345
            if (p->got_access&1) rotatesprite_fs(sbarxr(39),sbary(200-43),sb15,0,ACCESSCARD,0,0,10+16+512);
1346
            if (p->got_access&4) rotatesprite_fs(sbarxr(34),sbary(200-41),sb15,0,ACCESSCARD,0,23,10+16+512);
1347
            if (p->got_access&2) rotatesprite_fs(sbarxr(29),sbary(200-39),sb15,0,ACCESSCARD,0,21,10+16+512);
935 terminx 1348
 
1658 terminx 1349
            i = (p->curr_weapon == PISTOL_WEAPON) ? 16384 : 32768;
1350
 
3346 terminx 1351
            if (getrendermode() >= REND_POLYMOST && althud_shadows)
2308 helixhorne 1352
                rotatesprite_fs(sbarxr(57-1),sbary(200-15+1),sbarsc(i),0,ammo_sprites[p->curr_weapon],0,4,10+POLYMOSTTRANS2+512);
1353
            rotatesprite_fs(sbarxr(57),sbary(200-15),sbarsc(i),0,ammo_sprites[p->curr_weapon],0,0,10+512);
934 terminx 1354
 
1355
            if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON;
1356
            else i = p->curr_weapon;
1658 terminx 1357
 
952 terminx 1358
            if (p->curr_weapon != KNEE_WEAPON &&
962 terminx 1359
                    (!althud_flashing || totalclock&32 || p->ammo_amount[i] > (p->max_ammo_amount[i]/10)))
1658 terminx 1360
                G_DrawAltDigiNum(-20,-(200-22),p->ammo_amount[i],-16,10+16+512);
934 terminx 1361
 
941 terminx 1362
            o = 102;
934 terminx 1363
            permbit = 0;
1364
 
1365
            if (p->inven_icon)
1366
            {
2896 helixhorne 1367
                const int32_t orient = 10+16+permbit+256;
1368
 
3115 terminx 1369
                i = ((unsigned)p->inven_icon < ICON_MAX) ? item_icons[p->inven_icon] : -1;
934 terminx 1370
                if (i >= 0)
1371
                {
3346 terminx 1372
                    if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1373
                        rotatesprite_fs(sbarx(231-o+1),sbary(200-21-2+1),sb16,0,i,0,4, orient+POLYMOSTTRANS2);
1374
                    rotatesprite_fs(sbarx(231-o),sbary(200-21-2),sb16,0,i,0,0,orient);
934 terminx 1375
                }
1376
 
3346 terminx 1377
                if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1378
                    minitext(292-30-o+1,190-3+1,"%",4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX);
1379
                minitext(292-30-o,190-3,"%",6, orient+ROTATESPRITE_MAX);
934 terminx 1380
 
2896 helixhorne 1381
                i = G_GetInvAmount(p);
1382
                j = G_GetInvOn(p);
1383
 
2944 helixhorne 1384
                G_DrawInvNum(-(284-30-o),0,200-6-3,(uint8_t)i,0,10+permbit+256);
2896 helixhorne 1385
 
934 terminx 1386
                if (j > 0)
1387
                {
3346 terminx 1388
                    if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1389
                        minitext(288-30-o+1,180-3+1,"On",4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX);
1390
                    minitext(288-30-o,180-3,"On",0, orient+ROTATESPRITE_MAX);
934 terminx 1391
                }
1205 terminx 1392
                else if ((uint32_t)j != 0x80000000)
934 terminx 1393
                {
3346 terminx 1394
                    if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1395
                        minitext(284-30-o+1,180-3+1,"Off",4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX);
1396
                    minitext(284-30-o,180-3,"Off",2, orient+ROTATESPRITE_MAX);
934 terminx 1397
                }
1677 terminx 1398
 
3115 terminx 1399
                if (p->inven_icon >= ICON_SCUBA)
934 terminx 1400
                {
3346 terminx 1401
                    if (getrendermode() >= REND_POLYMOST && althud_shadows)
2896 helixhorne 1402
                        minitext(284-35-o+1,180-3+1,"Auto",4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX);
1403
                    minitext(284-35-o,180-3,"Auto",2, orient+ROTATESPRITE_MAX);
934 terminx 1404
                }
1405
            }
1406
        }
2900 helixhorne 1407
        else
1408
        {
1409
            // ORIGINAL MINI STATUS BAR
2944 helixhorne 1410
            int32_t orient = 2+8+16+256, yofs=0, yofssh=0;
1658 terminx 1411
 
2944 helixhorne 1412
            if (g_fakeMultiMode)
1413
            {
1414
                const int32_t sidebyside = (ud.screen_size!=0);
1415
 
1416
                if (sidebyside && snum==1)
1417
                {
1418
                    orient |= RS_CENTERORIGIN;
1419
                }
1420
                else if (!sidebyside && snum==0)
1421
                {
1422
                    yofs = -100;
1423
                    yofssh = yofs<<16;
1424
                }
1425
            }
1426
 
1427
            rotatesprite_fs(sbarx(5), yofssh+sbary(200-28), sb16, 0, HEALTHBOX, 0, 21, orient);
2900 helixhorne 1428
            if (p->inven_icon)
2944 helixhorne 1429
                rotatesprite_fs(sbarx(69), yofssh+sbary(200-30), sb16, 0, INVENTORYBOX, 0, 21, orient);
5 Plagman 1430
 
2902 helixhorne 1431
            // health
2935 helixhorne 1432
            {
1433
                int32_t health = (sprite[p->i].pal == 1 && p->last_extra < 2) ? 1 : p->last_extra;
2944 helixhorne 1434
                G_DrawDigiNum_(20, yofssh, 200-17, health, -16, orient);
2935 helixhorne 1435
            }
5 Plagman 1436
 
2944 helixhorne 1437
            rotatesprite_fs(sbarx(37), yofssh+sbary(200-28), sb16, 0, AMMOBOX, 0, 21, orient);
5 Plagman 1438
 
2944 helixhorne 1439
            if (p->curr_weapon == HANDREMOTE_WEAPON)
1440
                i = HANDBOMB_WEAPON;
1441
            else
1442
                i = p->curr_weapon;
1443
            G_DrawDigiNum_(53, yofssh, 200-17, p->ammo_amount[i], -16, orient);
5 Plagman 1444
 
2900 helixhorne 1445
            o = 158;
1446
            permbit = 0;
1447
            if (p->inven_icon)
1448
            {
2935 helixhorne 1449
//                orient |= permbit;
5 Plagman 1450
 
3115 terminx 1451
                i = ((unsigned)p->inven_icon < ICON_MAX) ? item_icons[p->inven_icon] : -1;
2900 helixhorne 1452
                if (i >= 0)
2944 helixhorne 1453
                    rotatesprite_fs(sbarx(231-o), yofssh+sbary(200-21), sb16, 0, i, 0, 0, orient);
5 Plagman 1454
 
2935 helixhorne 1455
                // scale by status bar size
1456
                orient |= ROTATESPRITE_MAX;
2896 helixhorne 1457
 
2944 helixhorne 1458
                minitext_yofs = yofssh;
1459
                minitext(292-30-o, 190, "%", 6, orient);
2902 helixhorne 1460
 
2900 helixhorne 1461
                i = G_GetInvAmount(p);
1462
                j = G_GetInvOn(p);
2896 helixhorne 1463
 
2944 helixhorne 1464
                G_DrawInvNum(284-30-o, yofssh, 200-6, (uint8_t)i, 0, orient&~16);
2896 helixhorne 1465
 
2900 helixhorne 1466
                if (j > 0)
2944 helixhorne 1467
                    minitext(288-30-o, 180, "On", 0, orient);
2900 helixhorne 1468
                else if ((uint32_t)j != 0x80000000)
2944 helixhorne 1469
                    minitext(284-30-o, 180, "Off", 2, orient);
2896 helixhorne 1470
 
3115 terminx 1471
                if (p->inven_icon >= ICON_SCUBA)
2944 helixhorne 1472
                    minitext(284-35-o, 180, "Auto", 2, orient);
1473
 
1474
                minitext_yofs = 0;
2900 helixhorne 1475
            }
5 Plagman 1476
        }
2900 helixhorne 1477
 
5 Plagman 1478
        return;
1479
    }
1480
 
1481
    //DRAW/UPDATE FULL STATUS BAR:
1482
 
335 terminx 1483
    if (pus)
1484
    {
1485
        pus = 0;
1486
        u = -1;
1487
    }
331 terminx 1488
    else u = 0;
5 Plagman 1489
 
335 terminx 1490
    if (sbar.frag[myconnectindex] != p->frag)
1491
    {
1492
        sbar.frag[myconnectindex] = p->frag;
1493
        u |= 32768;
1494
    }
1495
    if (sbar.got_access != p->got_access)
1496
    {
1497
        sbar.got_access = p->got_access;
1498
        u |= 16384;
1499
    }
261 terminx 1500
 
423 terminx 1501
    if (sbar.last_extra != p->last_extra)
5 Plagman 1502
    {
423 terminx 1503
        sbar.last_extra = p->last_extra;
1504
        u |= 1;
1505
    }
1506
 
1507
    {
3556 helixhorne 1508
        int32_t lAmount = G_GetMorale(p->i, snum);
331 terminx 1509
        if (lAmount == -1)
2896 helixhorne 1510
            lAmount = p->inv_amount[GET_SHIELD];
1511
        if (sbar.inv_amount[GET_SHIELD] != lAmount)
5 Plagman 1512
        {
2896 helixhorne 1513
            sbar.inv_amount[GET_SHIELD] = lAmount;
1514
            u |= 2;
5 Plagman 1515
        }
1516
    }
261 terminx 1517
 
335 terminx 1518
    if (sbar.curr_weapon != p->curr_weapon)
1519
    {
1520
        sbar.curr_weapon = p->curr_weapon;
1521
        u |= (4+8+16+32+64+128+256+512+1024+65536L);
1522
    }
218 terminx 1523
 
1229 terminx 1524
    for (i=1; i<MAX_WEAPONS; i++)
5 Plagman 1525
    {
1526
        if (sbar.ammo_amount[i] != p->ammo_amount[i])
1527
        {
1528
            sbar.ammo_amount[i] = p->ammo_amount[i];
331 terminx 1529
            if (i < 9)
5 Plagman 1530
                u |= ((2<<i)+1024);
218 terminx 1531
            else u |= 65536L+1024;
5 Plagman 1532
        }
218 terminx 1533
 
1625 terminx 1534
        if ((sbar.gotweapon & (1<<i)) != (p->gotweapon & (1<<i)))
5 Plagman 1535
        {
1625 terminx 1536
            if (p->gotweapon & (1<<i))
1537
                sbar.gotweapon |= 1<<i;
1538
            else sbar.gotweapon &= ~(1<<i);
1539
 
333 terminx 1540
            if (i < 9)
5 Plagman 1541
                u |= ((2<<i)+1024);
218 terminx 1542
            else u |= 65536L+1024;
5 Plagman 1543
        }
1544
    }
2896 helixhorne 1545
 
335 terminx 1546
    if (sbar.inven_icon != p->inven_icon)
1547
    {
1548
        sbar.inven_icon = p->inven_icon;
1549
        u |= (2048+4096+8192);
1550
    }
1551
    if (sbar.holoduke_on != p->holoduke_on)
1552
    {
1553
        sbar.holoduke_on = p->holoduke_on;
1554
        u |= (4096+8192);
1555
    }
1556
    if (sbar.jetpack_on != p->jetpack_on)
1557
    {
1558
        sbar.jetpack_on = p->jetpack_on;
1559
        u |= (4096+8192);
1560
    }
1561
    if (sbar.heat_on != p->heat_on)
1562
    {
1563
        sbar.heat_on = p->heat_on;
1564
        u |= (4096+8192);
1565
    }
2896 helixhorne 1566
 
335 terminx 1567
    {
2896 helixhorne 1568
        static const int32_t check_items[] = {
1569
            GET_FIRSTAID, GET_STEROIDS, GET_HOLODUKE, GET_JETPACK,
1570
            GET_HEATS, GET_SCUBA, GET_BOOTS
1571
        };
1572
 
1573
        for (i=0; i<(int32_t)sizeof(check_items)/(int32_t)sizeof(check_items[0]); i++)
1574
        {
1575
            int32_t item = check_items[i];
1576
 
1577
            if (sbar.inv_amount[item] != p->inv_amount[item])
1578
            {
1579
                sbar.inv_amount[item] = p->inv_amount[item];
1580
                u |= 8192;
1581
            }
1582
        }
335 terminx 1583
    }
2926 helixhorne 1584
#if 0
2896 helixhorne 1585
    if (u == 0)
1586
        return;
2926 helixhorne 1587
#else
1588
    // FIXME: full status bar draws rectangles in the wrong places when it's
1589
    // updated partially.
1590
    u = -1;
1591
#endif
2896 helixhorne 1592
 
5 Plagman 1593
    //0 - update health
1594
    //1 - update armor
1595
    //2 - update PISTOL_WEAPON ammo
1596
    //3 - update SHOTGUN_WEAPON ammo
1597
    //4 - update CHAINGUN_WEAPON ammo
1598
    //5 - update RPG_WEAPON ammo
1599
    //6 - update HANDBOMB_WEAPON ammo
1600
    //7 - update SHRINKER_WEAPON ammo
1601
    //8 - update DEVISTATOR_WEAPON ammo
1602
    //9 - update TRIPBOMB_WEAPON ammo
1603
    //10 - update ammo display
1604
    //11 - update inventory icon
1605
    //12 - update inventory on/off
1606
    //13 - update inventory %
1607
    //14 - update keys
1608
    //15 - update kills
1609
    //16 - update FREEZE_WEAPON ammo
261 terminx 1610
 
5 Plagman 1611
    if (u == -1)
1612
    {
1144 terminx 1613
        G_PatchStatusBar(0,0,320,200);
2925 helixhorne 1614
        if ((g_netServer || ud.multimode > 1) && (GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR))
2896 helixhorne 1615
            rotatesprite_fs(sbarx(277+1),sbary(SBY+7-1),sb16,0,KILLSICON,0,0,10+16);
5 Plagman 1616
    }
2925 helixhorne 1617
 
1618
    if ((g_netServer || ud.multimode > 1) && (GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR))
5 Plagman 1619
    {
1620
        if (u&32768)
1621
        {
1144 terminx 1622
            if (u != -1) G_PatchStatusBar(276,SBY+17,299,SBY+17+10);
1143 terminx 1623
            G_DrawDigiNum(287,SBY+17,max(p->frag-p->fraggedself,0),-16,10+16);
5 Plagman 1624
        }
1625
    }
1626
    else
1627
    {
1628
        if (u&16384)
1629
        {
1144 terminx 1630
            if (u != -1) G_PatchStatusBar(275,SBY+18,299,SBY+18+12);
2896 helixhorne 1631
            if (p->got_access&4) rotatesprite_fs(sbarx(275),sbary(SBY+16),sb16,0,ACCESS_ICON,0,23,10+16);
1632
            if (p->got_access&2) rotatesprite_fs(sbarx(288),sbary(SBY+16),sb16,0,ACCESS_ICON,0,21,10+16);
1633
            if (p->got_access&1) rotatesprite_fs(sbarx(281),sbary(SBY+23),sb16,0,ACCESS_ICON,0,0,10+16);
5 Plagman 1634
        }
1635
    }
1636
 
2896 helixhorne 1637
    if (u&(4+8+16+32+64+128+256+512+65536L))
1638
        G_DrawWeapAmounts(p,96,SBY+16,u);
1639
 
5 Plagman 1640
    if (u&1)
1641
    {
1144 terminx 1642
        if (u != -1) G_PatchStatusBar(20,SBY+17,43,SBY+17+11);
5 Plagman 1643
        if (sprite[p->i].pal == 1 && p->last_extra < 2)
1143 terminx 1644
            G_DrawDigiNum(32,SBY+17,1,-16,10+16);
1645
        else G_DrawDigiNum(32,SBY+17,p->last_extra,-16,10+16);
5 Plagman 1646
    }
1647
    if (u&2)
1648
    {
3556 helixhorne 1649
        int32_t lAmount = G_GetMorale(p->i, snum);
1650
 
1651
        if (u != -1)
1652
            G_PatchStatusBar(52,SBY+17,75,SBY+17+11);
1653
 
331 terminx 1654
        if (lAmount == -1)
1572 terminx 1655
            G_DrawDigiNum(64,SBY+17,p->inv_amount[GET_SHIELD],-16,10+16);
5 Plagman 1656
        else
1143 terminx 1657
            G_DrawDigiNum(64,SBY+17,lAmount,-16,10+16);
5 Plagman 1658
    }
1659
 
1660
    if (u&1024)
1661
    {
1144 terminx 1662
        if (u != -1) G_PatchStatusBar(196,SBY+17,219,SBY+17+11);
5 Plagman 1663
        if (p->curr_weapon != KNEE_WEAPON)
1664
        {
335 terminx 1665
            if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON;
1666
            else i = p->curr_weapon;
1143 terminx 1667
            G_DrawDigiNum(230-22,SBY+17,p->ammo_amount[i],-16,10+16);
5 Plagman 1668
        }
1669
    }
1670
 
1671
    if (u&(2048+4096+8192))
1672
    {
1673
        if (u != -1)
1674
        {
335 terminx 1675
            if (u&(2048+4096))
1144 terminx 1676
                G_PatchStatusBar(231,SBY+13,265,SBY+13+18);
335 terminx 1677
            else
1144 terminx 1678
                G_PatchStatusBar(250,SBY+24,261,SBY+24+6);
2896 helixhorne 1679
        }
331 terminx 1680
 
5 Plagman 1681
        if (p->inven_icon)
1682
        {
335 terminx 1683
            o = 0;
500 terminx 1684
//            permbit = 128;
5 Plagman 1685
 
1686
            if (u&(2048+4096))
1687
            {
3115 terminx 1688
                i = ((unsigned)p->inven_icon < ICON_MAX) ? item_icons[p->inven_icon] : -1;
2896 helixhorne 1689
                // XXX: i < 0?
1690
                rotatesprite_fs(sbarx(231-o),sbary(SBY+13),sb16,0,i,0,0,10+16+permbit);
1658 terminx 1691
                minitext(292-30-o,SBY+24,"%",6,10+16+permbit + ROTATESPRITE_MAX);
3115 terminx 1692
                if (p->inven_icon >= ICON_SCUBA) minitext(284-35-o,SBY+14,"Auto",2,10+16+permbit + ROTATESPRITE_MAX);
5 Plagman 1693
            }
2896 helixhorne 1694
 
5 Plagman 1695
            if (u&(2048+4096))
1696
            {
2896 helixhorne 1697
                j = G_GetInvOn(p);
1698
 
2540 hendricks2 1699
                if (j > 0) minitext(288-30-o,SBY+14,"On",0,10+16+permbit  + ROTATESPRITE_MAX);
1700
                else if ((uint32_t)j != 0x80000000) minitext(284-30-o,SBY+14,"Off",2,10+16+permbit + ROTATESPRITE_MAX);
5 Plagman 1701
            }
2896 helixhorne 1702
 
5 Plagman 1703
            if (u&8192)
1704
            {
2896 helixhorne 1705
                i = G_GetInvAmount(p);
2944 helixhorne 1706
                G_DrawInvNum(284-30-o,0,SBY+28,(uint8_t)i,0,10+permbit);
5 Plagman 1707
            }
1708
        }
1709
    }
1710
}
1711
 
932 terminx 1712
#define COLOR_RED 248
1713
#define COLOR_WHITE 31
1120 terminx 1714
#define LOW_FPS 30
926 terminx 1715
 
1179 terminx 1716
static void G_PrintFPS(void)
933 terminx 1717
{
1062 terminx 1718
    // adapted from ZDoom because I like it better than what we had
1719
    // applicable ZDoom code available under GPL from csDoom
1205 terminx 1720
    static int32_t FrameCount = 0;
1721
    static int32_t LastCount = 0;
1722
    static int32_t LastSec = 0;
1723
    static int32_t LastMS = 0;
1724
    int32_t ms = getticks();
1725
    int32_t howlong = ms - LastMS;
1120 terminx 1726
    if (howlong >= 0)
1062 terminx 1727
    {
1205 terminx 1728
        int32_t thisSec = ms/1000;
1729
        int32_t x = (xdim <= 640);
1673 terminx 1730
 
1120 terminx 1731
        if (ud.tickrate)
1062 terminx 1732
        {
1571 terminx 1733
            int32_t chars = Bsprintf(tempbuf, "%d ms (%3u fps)", howlong, LastCount);
5 Plagman 1734
 
1089 terminx 1735
            printext256(windowx2-(chars<<(3-x))+1,windowy1+2,0,-1,tempbuf,x);
1177 terminx 1736
            printext256(windowx2-(chars<<(3-x)),windowy1+1,
1179 terminx 1737
                        (LastCount < LOW_FPS) ? COLOR_RED : COLOR_WHITE,-1,tempbuf,x);
1062 terminx 1738
 
1177 terminx 1739
            // lag meter
1587 terminx 1740
            if (g_netClientPeer)
1062 terminx 1741
            {
1593 terminx 1742
                chars = Bsprintf(tempbuf, "%d +- %d ms", (g_netClientPeer->lastRoundTripTime + g_netClientPeer->roundTripTime)/2,
1743
                                 (g_netClientPeer->lastRoundTripTimeVariance + g_netClientPeer->roundTripTimeVariance)/2);
1571 terminx 1744
 
1745
                printext256(windowx2-(chars<<(3-x))+1,windowy1+10+2,0,-1,tempbuf,x);
1587 terminx 1746
                printext256(windowx2-(chars<<(3-x)),windowy1+10+1,g_netClientPeer->lastRoundTripTime > 200 ? COLOR_RED : COLOR_WHITE,-1,tempbuf,x);
1062 terminx 1747
            }
1748
        }
1749
 
1673 terminx 1750
        if (thisSec - LastSec)
193 terminx 1751
        {
1143 terminx 1752
            g_currentFrameRate = LastCount = FrameCount / (thisSec - LastSec);
1120 terminx 1753
            LastSec = thisSec;
1754
            FrameCount = 0;
193 terminx 1755
        }
1120 terminx 1756
        FrameCount++;
5 Plagman 1757
    }
1120 terminx 1758
    LastMS = ms;
5 Plagman 1759
}
1760
 
2413 helixhorne 1761
// yxaspect and viewingrange just before the 'main' drawrooms call
1762
static int32_t dr_yxaspect, dr_viewingrange;
1763
 
1205 terminx 1764
static void G_PrintCoords(int32_t snum)
5 Plagman 1765
{
2413 helixhorne 1766
    const int32_t x = 250;
1205 terminx 1767
    int32_t y = 16;
5 Plagman 1768
 
3051 helixhorne 1769
    const DukePlayer_t *ps = g_player[snum].ps;
1770
    const int32_t sectnum = ps->cursectnum;
1771
 
1143 terminx 1772
    if ((GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR))
5 Plagman 1773
    {
532 terminx 1774
        if (ud.multimode > 4)
1062 terminx 1775
            y = 32;
2925 helixhorne 1776
        else if (g_netServer || ud.multimode > 1)
532 terminx 1777
            y = 24;
5 Plagman 1778
    }
3051 helixhorne 1779
    Bsprintf(tempbuf,"XYZ= (%d,%d,%d)",ps->pos.x,ps->pos.y,ps->pos.z);
2413 helixhorne 1780
    printext256(x,y,31,-1,tempbuf,0);
3051 helixhorne 1781
    Bsprintf(tempbuf,"A/H/HO= %d,%d,%d",ps->ang,ps->horiz,ps->horizoff);
2413 helixhorne 1782
    printext256(x,y+9,31,-1,tempbuf,0);
3051 helixhorne 1783
    Bsprintf(tempbuf,"ZV= %d",ps->vel.z);
2413 helixhorne 1784
    printext256(x,y+18,31,-1,tempbuf,0);
3051 helixhorne 1785
    Bsprintf(tempbuf,"OG= %d  SBRIDGE=%d SBS=%d",ps->on_ground, ps->spritebridge, ps->sbs);
2413 helixhorne 1786
    printext256(x,y+27,31,-1,tempbuf,0);
1787
    if (sectnum >= 0)
3238 hendricks2 1788
        Bsprintf_nowarn(tempbuf,"SECT= %d (LO=%d EX=%d)",sectnum,TrackerCast(sector[sectnum].lotag),TrackerCast(sector[sectnum].extra));
2413 helixhorne 1789
    else
1790
        Bsprintf(tempbuf,"SECT= %d", sectnum);
1791
    printext256(x,y+36,31,-1,tempbuf,0);
1792
//    Bsprintf(tempbuf,"SEED= %d",randomseed);
1793
//    printext256(x,y+45,31,-1,tempbuf,0);
1794
    y -= 9;
1795
 
1796
    y += 7;
3051 helixhorne 1797
    Bsprintf(tempbuf,"THOLD= %d", ps->transporter_hold);
2413 helixhorne 1798
    printext256(x,y+54,31,-1,tempbuf,0);
1945 helixhorne 1799
    Bsprintf(tempbuf,"GAMETIC= %d",g_moveThingsCount);
2413 helixhorne 1800
    printext256(x,y+63,31,-1,tempbuf,0);
1801
 
1802
    y += 7;
1803
    Bsprintf(tempbuf,"VR=%.03f  YX=%.03f",(double)dr_viewingrange/65536.0,(double)dr_yxaspect/65536.0);
1804
    printext256(x,y+72,31,-1,tempbuf,0);
5 Plagman 1805
}
1806
 
1143 terminx 1807
 
2946 helixhorne 1808
// orientation flags depending on time that a quote has still to be displayed
1809
static inline int32_t texto(int32_t t)
5 Plagman 1810
{
2946 helixhorne 1811
    if (t > 4) return 2+8+16;
1812
    if (t > 2) return 2+8+16+1;
1813
    return 2+8+16+1+32;
1814
}
5 Plagman 1815
 
2946 helixhorne 1816
static int32_t calc_ybase(int32_t begy)
1817
{
1818
    int32_t k = begy;
1819
 
2950 helixhorne 1820
    if (GTFLAGS(GAMETYPE_FRAGBAR) && (ud.screen_size > 0 && !g_fakeMultiMode)
1821
            && (g_netServer || ud.multimode > 1))
1037 terminx 1822
    {
2946 helixhorne 1823
        int32_t i, j = 0;
1824
 
1037 terminx 1825
        k += 8;
2379 helixhorne 1826
        for (TRAVERSE_CONNECT(i))
2946 helixhorne 1827
            if (i > j)
1828
                j = i;
532 terminx 1829
 
1037 terminx 1830
        if (j >= 4 && j <= 8) k += 8;
1831
        else if (j > 8 && j <= 12) k += 16;
1832
        else if (j > 12) k += 24;
1833
    }
1834
 
2946 helixhorne 1835
    return k;
1836
}
1837
 
1838
// this handles both multiplayer and item pickup message type text
1839
// both are passed on to gametext
2948 helixhorne 1840
void G_PrintGameQuotes(int32_t snum)
2946 helixhorne 1841
{
1842
    int32_t i, j, k;
1843
 
2948 helixhorne 1844
    const DukePlayer_t *const ps = g_player[snum].ps;
2950 helixhorne 1845
    const int32_t reserved_quote = (ps->ftq >= QUOTE_RESERVED && ps->ftq <= QUOTE_RESERVED3);
2961 helixhorne 1846
    // NOTE: QUOTE_RESERVED4 is not included.
2946 helixhorne 1847
 
1848
    k = calc_ybase(1);
1849
 
2950 helixhorne 1850
    if (ps->fta > 1 && !reserved_quote)
1037 terminx 1851
    {
2950 helixhorne 1852
        k += min(7, ps->fta);
1037 terminx 1853
    }
1854
 
2946 helixhorne 1855
    j = scale(k, ydim, 200);
1037 terminx 1856
 
1229 terminx 1857
    for (i=MAXUSERQUOTES-1; i>=0; i--)
5 Plagman 1858
    {
2946 helixhorne 1859
        int32_t sh, l;
2316 helixhorne 1860
 
1861
        if (user_quote_time[i] <= 0)
1862
            continue;
2950 helixhorne 1863
 
335 terminx 1864
        k = user_quote_time[i];
2316 helixhorne 1865
 
1866
        sh = hud_glowingquotes ? (sintable[((totalclock+(i<<2))<<5)&2047]>>11) : 0;
1867
 
2946 helixhorne 1868
        mpgametext(j, user_quote[i], sh, texto(k));
1869
        j += textsc(k > 4 ? 8 : (k<<1));
2316 helixhorne 1870
 
2946 helixhorne 1871
        l = G_GameTextLen(USERQUOTE_LEFTOFFSET, OSD_StripColors(tempbuf,user_quote[i]));
867 terminx 1872
        while (l > (ud.config.ScreenWidth - USERQUOTE_RIGHTOFFSET))
85 terminx 1873
        {
867 terminx 1874
            l -= (ud.config.ScreenWidth-USERQUOTE_RIGHTOFFSET);
2946 helixhorne 1875
            j += textsc(k > 4 ? 8 : (k<<1));
85 terminx 1876
        }
5 Plagman 1877
    }
1878
 
2946 helixhorne 1879
    if (klabs(quotebotgoal-quotebot) <= 16 && ud.screen_size <= 8)
87 terminx 1880
        quotebot += ksgn(quotebotgoal-quotebot);
1881
    else
1882
        quotebot = quotebotgoal;
1883
 
2950 helixhorne 1884
    if (ps->fta <= 1)
1885
        return;
5 Plagman 1886
 
2946 helixhorne 1887
    if (ScriptQuotes[ps->ftq] == NULL)
437 terminx 1888
    {
2946 helixhorne 1889
        OSD_Printf(OSD_ERROR "%s %d null quote %d\n",__FILE__,__LINE__,ps->ftq);
437 terminx 1890
        return;
1891
    }
1892
 
2946 helixhorne 1893
    k = calc_ybase(0);
1894
 
1895
    if (k == 0)
1896
    {
2950 helixhorne 1897
        if (reserved_quote)
2946 helixhorne 1898
        {
2950 helixhorne 1899
            if (!g_fakeMultiMode)
1900
                k = 140;//quotebot-8-4;
1901
            else
1902
                k = 50;
2946 helixhorne 1903
        }
1904
        else
1905
        {
2771 terminx 1906
#ifdef GEKKO
2946 helixhorne 1907
            k = 16;
2771 terminx 1908
#else
2946 helixhorne 1909
            k = 0;
2771 terminx 1910
#endif
2946 helixhorne 1911
        }
1037 terminx 1912
    }
5 Plagman 1913
 
2948 helixhorne 1914
    {
1915
        int32_t pal = 0;
1916
 
1917
        if (g_fakeMultiMode)
1918
        {
1919
            pal = g_player[snum].pcolor;
1920
 
1921
            if (snum==1)
1922
            {
1923
                const int32_t sidebyside = (ud.screen_size != 0);
1924
 
1925
                // NOTE: setting gametext's x -= 80 doesn't do the expected thing.
1926
                // Needs looking into.
1927
                if (sidebyside)
1928
                    k += 9;
1929
                else
1930
                    k += 101;
1931
            }
1932
        }
1933
 
1934
        gametextpalbits(160, k, ScriptQuotes[ps->ftq],
1935
                        hud_glowingquotes ? quotepulseshade : 0,
1936
                        pal, texto(ps->fta));
1937
    }
5 Plagman 1938
}
1939
 
1205 terminx 1940
void P_DoQuote(int32_t q, DukePlayer_t *p)
5 Plagman 1941
{
1205 terminx 1942
    int32_t cq = 0;
868 terminx 1943
 
1944
    if (q & MAXQUOTES)
5 Plagman 1945
    {
868 terminx 1946
        cq = 1;
1947
        q &= ~MAXQUOTES;
1948
    }
1949
 
1143 terminx 1950
    if (ScriptQuotes[q] == NULL)
868 terminx 1951
    {
909 terminx 1952
        OSD_Printf(OSD_ERROR "%s %d null quote %d\n",__FILE__,__LINE__,q);
437 terminx 1953
        return;
1954
    }
5 Plagman 1955
 
437 terminx 1956
    if (ud.fta_on == 0)
1957
        return;
465 terminx 1958
 
1802 terminx 1959
    if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2)
1960
        if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
5 Plagman 1961
 
437 terminx 1962
    p->fta = 100;
392 terminx 1963
 
1625 terminx 1964
    if (p->ftq != q)
437 terminx 1965
    {
1989 hendricks2 1966
        if (p == g_player[screenpeek].ps
1967
            && Bstrcmp(ScriptQuotes[q],"")) // avoid printing blank quotes
1625 terminx 1968
        {
1969
            if (cq) OSD_Printf(OSDTEXT_BLUE "%s\n",ScriptQuotes[q]);
1970
            else OSD_Printf("%s\n",ScriptQuotes[q]);
1971
        }
437 terminx 1972
 
1973
        p->ftq = q;
335 terminx 1974
    }
1625 terminx 1975
    pub = NUMPAGES;
1976
    pus = NUMPAGES;
5 Plagman 1977
}
1978
 
2581 helixhorne 1979
 
1980
////////// OFTEN-USED FEW-LINERS //////////
3476 helixhorne 1981
static void G_HandleEventsWhileNoInput(void)
2581 helixhorne 1982
{
2728 hendricks2 1983
    I_ClearInputWaiting();
1984
 
1985
    while (!I_CheckInputWaiting())
2581 helixhorne 1986
        G_HandleAsync();
2728 hendricks2 1987
 
1988
    I_ClearInputWaiting();
2581 helixhorne 1989
}
1990
 
3476 helixhorne 1991
static int32_t G_PlaySoundWhileNoInput(int32_t soundnum)
2581 helixhorne 1992
{
1993
    S_PlaySound(soundnum);
2728 hendricks2 1994
    I_ClearInputWaiting();
2581 helixhorne 1995
    while (S_CheckSoundPlaying(-1, soundnum))
1996
    {
1997
        G_HandleAsync();
2728 hendricks2 1998
        if (I_CheckInputWaiting())
1999
        {
2000
            I_ClearInputWaiting();
2581 helixhorne 2001
            return 1;
2728 hendricks2 2002
        }
2581 helixhorne 2003
    }
2004
 
2005
    return 0;
2006
}
2007
//////////
2008
 
1625 terminx 2009
void G_FadePalette(int32_t r,int32_t g,int32_t b,int32_t e)
2010
{
2011
    setpalettefade(r,g,b,e&63);
2012
 
2013
    if ((e&128) == 0)
2014
    {
2015
        int32_t tc;
1969 helixhorne 2016
 
1625 terminx 2017
        nextpage();
1969 helixhorne 2018
        tc = totalclock;
2019
        while (totalclock < tc + 4)
2581 helixhorne 2020
            G_HandleAsync();
1625 terminx 2021
    }
2022
}
2023
 
2583 helixhorne 2024
// START and END limits are always inclusive!
2025
// STEP must evenly divide END-START, i.e. abs(end-start)%step == 0
1205 terminx 2026
void fadepal(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step)
398 terminx 2027
{
3346 terminx 2028
    if (getrendermode() >= REND_POLYMOST)
1918 terminx 2029
    {
2030
        G_FadePalette(r, g, b, end);
2031
        return;
2032
    }
1909 terminx 2033
 
2583 helixhorne 2034
    // (end-start)/step + 1 iterations
2035
    do
1625 terminx 2036
    {
2583 helixhorne 2037
        if (KB_KeyPressed(sc_Space))
1625 terminx 2038
        {
2583 helixhorne 2039
            KB_ClearKeyDown(sc_Space);
2040
            setpalettefade(r,g,b,end);  // have to set to end fade value if we break!
2041
            return;
2042
        }
2582 helixhorne 2043
 
2583 helixhorne 2044
        G_FadePalette(r,g,b,start);
2045
 
2046
        start += step;
1625 terminx 2047
    }
2583 helixhorne 2048
    while (start != end+step);
398 terminx 2049
}
2050
 
2583 helixhorne 2051
// START and END limits are always inclusive!
2265 helixhorne 2052
static void fadepaltile(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t tile)
1625 terminx 2053
{
2924 helixhorne 2054
    // STEP must evenly divide END-START
2055
    Bassert(klabs(end-start)%step == 0);
2582 helixhorne 2056
 
2924 helixhorne 2057
    clearallviews(0);
2058
 
2583 helixhorne 2059
    // (end-start)/step + 1 iterations
2060
    do
1625 terminx 2061
    {
2583 helixhorne 2062
        if (KB_KeyPressed(sc_Space))
1625 terminx 2063
        {
2583 helixhorne 2064
            KB_ClearKeyDown(sc_Space);
2065
            setpalettefade(r,g,b,end);  // have to set to end fade value if we break!
2066
            return;
1625 terminx 2067
        }