Subversion Repositories eduke32

Rev

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

Rev Author Line No. Line
5618 terminx 1
//-------------------------------------------------------------------------
2
/*
3
Copyright (C) 2016 EDuke32 developers and contributors
4
 
5
This file is part of EDuke32.
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
*/
21
//-------------------------------------------------------------------------
22
 
7186 terminx 23
#ifdef __ANDROID__
24
#include "android.h"
25
#endif
26
 
27
#include "anim.h"
28
#include "colmatch.h"
29
#include "compat.h"
30
#include "demo.h"
5618 terminx 31
#include "duke3d.h"
32
#include "input.h"
7186 terminx 33
#include "mdsprite.h"
5618 terminx 34
#include "sbar.h"
7186 terminx 35
#include "screens.h"
5618 terminx 36
 
37
#define COLOR_RED redcol
38
#define COLOR_WHITE whitecol
39
 
40
#define quotepulseshade (sintable[((uint32_t)totalclock<<5)&2047]>>11)
41
 
6061 hendricks2 42
palette_t CrosshairColors = { 255, 255, 255, 0 };
43
palette_t DefaultCrosshairColors = { 0, 0, 0, 0 };
5950 hendricks2 44
int32_t g_crosshairSum = -1;
5618 terminx 45
// yxaspect and viewingrange just before the 'main' drawrooms call
46
int32_t dr_yxaspect, dr_viewingrange;
6736 terminx 47
double g_moveActorsTime, g_moveWorldTime;  // in ms, smoothed
5618 terminx 48
int32_t g_noLogoAnim = 0;
49
int32_t g_noLogo = 0;
50
 
51
////////// OFTEN-USED FEW-LINERS //////////
6271 terminx 52
#ifndef EDUKE32_STANDALONE
5618 terminx 53
static void G_HandleEventsWhileNoInput(void)
54
{
55
    I_ClearAllInput();
56
 
7894 hendricks2 57
    while (!I_GeneralTrigger())
8140 terminx 58
        gameHandleEvents();
5618 terminx 59
 
60
    I_ClearAllInput();
61
}
62
 
63
static int32_t G_PlaySoundWhileNoInput(int32_t soundnum)
64
{
65
    S_PlaySound(soundnum);
66
    I_ClearAllInput();
7279 terminx 67
    while (S_CheckSoundPlaying(soundnum))
5618 terminx 68
    {
8140 terminx 69
        gameHandleEvents();
7894 hendricks2 70
        if (I_GeneralTrigger())
5618 terminx 71
        {
72
            I_ClearAllInput();
73
            return 1;
74
        }
75
    }
76
 
77
    return 0;
78
}
6271 terminx 79
#endif
5618 terminx 80
//////////
81
 
82
void P_SetGamePalette(DukePlayer_t *player, uint32_t palid, int32_t set)
83
{
84
    if (palid >= MAXBASEPALS)
85
        palid = 0;
86
 
87
    player->palette = palid;
88
 
89
    if (player != g_player[screenpeek].ps)
90
        return;
91
 
6829 terminx 92
    videoSetPalette(ud.brightness>>2, palid, set);
5618 terminx 93
}
94
 
95
void G_GetCrosshairColor(void)
96
{
7808 terminx 97
    if (FURY)
6995 terminx 98
        return;
5618 terminx 99
 
100
    if (DefaultCrosshairColors.f)
101
        return;
102
 
6995 terminx 103
    tileLoad(CROSSHAIR);
5618 terminx 104
 
6995 terminx 105
    if (!waloff[CROSSHAIR])
106
        return;
5618 terminx 107
 
6995 terminx 108
    char const *ptr = (char const *) waloff[CROSSHAIR];
5618 terminx 109
 
6995 terminx 110
    // find the brightest color in the original 8-bit tile
111
    int32_t ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y;
112
    int32_t bri = 0, j = 0, i;
113
 
114
    Bassert(ii > 0);
115
 
5618 terminx 116
    do
117
    {
118
        if (*ptr != 255)
119
        {
120
            i = curpalette[(int32_t) *ptr].r+curpalette[(int32_t) *ptr].g+curpalette[(int32_t) *ptr].b;
121
            if (i > j) { j = i; bri = *ptr; }
122
        }
123
        ptr++;
124
    } while (--ii);
125
 
126
    Bmemcpy(&CrosshairColors, &curpalette[bri], sizeof(palette_t));
127
    Bmemcpy(&DefaultCrosshairColors, &curpalette[bri], sizeof(palette_t));
128
    DefaultCrosshairColors.f = 1; // this flag signifies that the color has been detected
129
}
130
 
131
void G_SetCrosshairColor(int32_t r, int32_t g, int32_t b)
132
{
7808 terminx 133
    if (FURY)
6650 hendricks2 134
        return;
135
 
6995 terminx 136
    if (g_crosshairSum == r+(g<<8)+(b<<16))
137
        return;
5618 terminx 138
 
6995 terminx 139
    tileLoad(CROSSHAIR);
5618 terminx 140
 
6995 terminx 141
    if (!waloff[CROSSHAIR])
142
        return;
143
 
5618 terminx 144
    if (!DefaultCrosshairColors.f)
145
        G_GetCrosshairColor();
146
 
147
    g_crosshairSum = r+(g<<8)+(b<<16);
148
    CrosshairColors.r = r;
149
    CrosshairColors.g = g;
150
    CrosshairColors.b = b;
151
 
152
    char *ptr = (char *) waloff[CROSSHAIR];
153
 
6995 terminx 154
    int32_t ii = tilesiz[CROSSHAIR].x * tilesiz[CROSSHAIR].y;
5618 terminx 155
 
6995 terminx 156
    Bassert(ii > 0);
5618 terminx 157
 
6995 terminx 158
    int32_t i = (videoGetRenderMode() == REND_CLASSIC)
159
                ? paletteGetClosestColor(CrosshairColors.r, CrosshairColors.g, CrosshairColors.b)
160
                : paletteGetClosestColor(255, 255, 255);  // use white in GL so we can tint it to the right color
5618 terminx 161
 
162
    do
163
    {
164
        if (*ptr != 255)
165
            *ptr = i;
166
        ptr++;
167
    } while (--ii);
168
 
6829 terminx 169
    paletteMakeLookupTable(CROSSHAIR_PAL, NULL, CrosshairColors.r, CrosshairColors.g, CrosshairColors.b, 1);
5618 terminx 170
 
171
#ifdef USE_OPENGL
172
    // XXX: this makes us also load all hightile textures tinted with the crosshair color!
6215 hendricks2 173
    polytint_t & crosshairtint = hictinting[CROSSHAIR_PAL];
174
    crosshairtint.r = CrosshairColors.r;
175
    crosshairtint.g = CrosshairColors.g;
176
    crosshairtint.b = CrosshairColors.b;
177
    crosshairtint.f = HICTINT_USEONART | HICTINT_GRAYSCALE;
5618 terminx 178
#endif
6831 terminx 179
    tileInvalidate(CROSSHAIR, -1, -1);
5618 terminx 180
}
181
 
182
#define SCORESHEETOFFSET -20
183
static void G_ShowScores(void)
184
{
185
    int32_t t, i;
186
 
5835 terminx 187
    if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET))
5618 terminx 188
    {
6210 hendricks2 189
        gametext_center(SCORESHEETOFFSET+58+2, "Multiplayer Totals");
190
        gametext_center(SCORESHEETOFFSET+58+10, g_mapInfo[G_LastMapInfoIndex()].name);
5618 terminx 191
 
192
        t = 0;
193
        minitext(70, SCORESHEETOFFSET+80, "Name", 8, 2+8+16+ROTATESPRITE_MAX);
194
        minitext(170, SCORESHEETOFFSET+80, "Frags", 8, 2+8+16+ROTATESPRITE_MAX);
195
        minitext(200, SCORESHEETOFFSET+80, "Deaths", 8, 2+8+16+ROTATESPRITE_MAX);
196
        minitext(235, SCORESHEETOFFSET+80, "Ping", 8, 2+8+16+ROTATESPRITE_MAX);
197
 
5835 terminx 198
        for (i=g_mostConcurrentPlayers-1; i>=0; i--)
5618 terminx 199
        {
200
            if (!g_player[i].playerquitflag)
201
                continue;
202
 
203
            minitext(70, SCORESHEETOFFSET+90+t, g_player[i].user_name, g_player[i].ps->palookup, 2+8+16+ROTATESPRITE_MAX);
204
 
205
            Bsprintf(tempbuf, "%-4d", g_player[i].ps->frag);
206
            minitext(170, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX);
207
 
208
            Bsprintf(tempbuf, "%-4d", g_player[i].frags[i] + g_player[i].ps->fraggedself);
209
            minitext(200, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX);
210
 
211
            Bsprintf(tempbuf, "%-4d", g_player[i].ping);
212
            minitext(235, SCORESHEETOFFSET+90+t, tempbuf, 2, 2+8+16+ROTATESPRITE_MAX);
213
 
214
            t += 7;
215
        }
216
    }
217
}
218
#undef SCORESHEETOFFSET
219
 
220
////////// TINT ACCUMULATOR //////////
221
 
222
typedef struct {
223
    int32_t r, g, b;
224
    // f: 0-63 scale
225
    int32_t maxf, sumf;
226
} palaccum_t;
227
 
228
#define PALACCUM_INITIALIZER { 0, 0, 0, 0, 0 }
229
 
230
/* For a picture frame F and n tints C_1, C_2, ... C_n weighted a_1, a_2,
231
* ... a_n (on a 0-1 scale), the faded frame is calculated as
232
*
233
*    F_new := (1-max_i(a_i))*F + d*sum_i(a_i), where
234
*
235
*    d := max_i(a_i)/sum_i(a_i).
236
*
237
* This means that
238
*  1) tint application is independent of their order.
239
*  2) going from n+1 to n tints is continuous when the leaving one has faded.
240
*
241
* But note that for more than one tint, the composite tint will in general
242
* change its hue as the ratio of the weights of the individual ones changes.
243
*/
244
static void palaccum_add(palaccum_t *pa, const palette_t *pal, int32_t f)
245
{
246
    f = clamp(f, 0, 63);
247
    if (f == 0)
248
        return;
249
 
250
    pa->maxf = max(pa->maxf, f);
251
    pa->sumf += f;
252
 
253
    pa->r += f*clamp(pal->r, 0, 63);
254
    pa->g += f*clamp(pal->g, 0, 63);
255
    pa->b += f*clamp(pal->b, 0, 63);
256
}
257
 
258
static void G_FadePalaccum(const palaccum_t *pa)
259
{
6829 terminx 260
    videoFadePalette(tabledivide32_noinline(pa->r, pa->sumf)<<2,
5618 terminx 261
        tabledivide32_noinline(pa->g, pa->sumf)<<2,
262
        tabledivide32_noinline(pa->b, pa->sumf)<<2, pa->maxf<<2);
263
}
264
 
265
 
266
static int32_t gtextsc(int32_t sc)
267
{
268
    return scale(sc, ud.textscale, 400);
269
}
270
 
271
////////// DISPLAYREST //////////
272
 
273
static void G_DrawCameraText(int16_t i)
274
{
275
    if (VM_OnEvent(EVENT_DISPLAYCAMERAOSD, i, screenpeek) != 0)
276
        return;
277
 
5825 terminx 278
    if (!T1(i))
5618 terminx 279
    {
280
        rotatesprite_win(24<<16, 33<<16, 65536L, 0, CAMCORNER, 0, 0, 2);
281
        rotatesprite_win((320-26)<<16, 34<<16, 65536L, 0, CAMCORNER+1, 0, 0, 2);
282
        rotatesprite_win(22<<16, 163<<16, 65536L, 512, CAMCORNER+1, 0, 0, 2+4);
283
        rotatesprite_win((310-10)<<16, 163<<16, 65536L, 512, CAMCORNER+1, 0, 0, 2);
284
 
8050 pogokeen 285
        if ((int32_t) totalclock&16)
5618 terminx 286
            rotatesprite_win(46<<16, 32<<16, 65536L, 0, CAMLIGHT, 0, 0, 2);
287
    }
288
    else
289
    {
8050 pogokeen 290
        int32_t flipbits = ((int32_t) totalclock<<1)&48;
5618 terminx 291
 
5829 terminx 292
        for (bssize_t x=-64; x<394; x+=64)
293
            for (bssize_t y=0; y<200; y+=64)
5618 terminx 294
                rotatesprite_win(x<<16, y<<16, 65536L, 0, STATIC, 0, 0, 2+flipbits);
295
    }
296
}
297
 
298
static inline void G_MoveClouds(void)
299
{
300
    int32_t i;
301
 
5835 terminx 302
    if (totalclock <= g_cloudClock && totalclock >= (g_cloudClock-7))
5618 terminx 303
        return;
304
 
5835 terminx 305
    g_cloudClock = totalclock+6;
5618 terminx 306
 
6725 terminx 307
    g_cloudX += sintable[(fix16_to_int(g_player[screenpeek].ps->q16ang)+512)&2047]>>9;
308
    g_cloudY += sintable[fix16_to_int(g_player[screenpeek].ps->q16ang)&2047]>>9;
5618 terminx 309
 
5835 terminx 310
    for (i=g_cloudCnt-1; i>=0; i--)
5618 terminx 311
    {
5835 terminx 312
        sector[g_cloudSect[i]].ceilingxpanning = g_cloudX>>6;
313
        sector[g_cloudSect[i]].ceilingypanning = g_cloudY>>6;
5618 terminx 314
    }
315
}
316
 
317
static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16_t cang)
318
{
319
    int32_t i, j, k, l, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff;
320
    int32_t dax, day, cosang, sinang, xspan, yspan, sprx, spry;
321
    int32_t xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
322
    int32_t xvect, yvect, xvect2, yvect2;
323
    int16_t p;
324
    char col;
7603 terminx 325
    uwallptr_t wal, wal2;
5618 terminx 326
    spritetype *spr;
327
 
328
    int32_t tmpydim = (xdim*5)/8;
329
 
6831 terminx 330
    renderSetAspect(65536, divscale16(tmpydim*320, xdim*200));
5618 terminx 331
 
332
    xvect = sintable[(-cang)&2047] * czoom;
333
    yvect = sintable[(1536-cang)&2047] * czoom;
334
    xvect2 = mulscale16(xvect, yxaspect);
335
    yvect2 = mulscale16(yvect, yxaspect);
336
 
6832 terminx 337
    renderDisableFog();
5618 terminx 338
 
339
    //Draw red lines
340
    for (i=numsectors-1; i>=0; i--)
341
    {
7876 terminx 342
        if (!(show2dsector[i>>3]&pow2char[i&7])) continue;
5618 terminx 343
 
344
        startwall = sector[i].wallptr;
345
        endwall = sector[i].wallptr + sector[i].wallnum;
346
 
347
        z1 = sector[i].ceilingz;
348
        z2 = sector[i].floorz;
349
 
7603 terminx 350
        for (j=startwall, wal=(uwallptr_t)&wall[startwall]; j<endwall; j++, wal++)
5618 terminx 351
        {
352
            k = wal->nextwall;
353
            if (k < 0) continue;
354
 
7086 terminx 355
            if (sector[wal->nextsector].ceilingz == z1 && sector[wal->nextsector].floorz == z2)
5618 terminx 356
                    if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue;
357
 
7876 terminx 358
            if (!(show2dsector[wal->nextsector>>3]&pow2char[wal->nextsector&7]))
6461 terminx 359
                col = editorcolors[7];
5618 terminx 360
            else continue;
361
 
362
            ox = wal->x-cposx;
363
            oy = wal->y-cposy;
364
            x1 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11);
365
            y1 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11);
366
 
7603 terminx 367
            wal2 = (uwallptr_t)&wall[wal->point2];
5618 terminx 368
            ox = wal2->x-cposx;
369
            oy = wal2->y-cposy;
370
            x2 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11);
371
            y2 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11);
372
 
6832 terminx 373
            renderDrawLine(x1, y1, x2, y2, col);
5618 terminx 374
        }
375
    }
376
 
6832 terminx 377
    renderEnableFog();
5618 terminx 378
 
379
    //Draw sprites
380
    k = g_player[screenpeek].ps->i;
7989 hendricks2 381
    if (!FURY) for (i=numsectors-1; i>=0; i--)
5618 terminx 382
    {
7876 terminx 383
        if (!(show2dsector[i>>3]&pow2char[i&7])) continue;
5618 terminx 384
        for (j=headspritesect[i]; j>=0; j=nextspritesect[j])
385
        {
386
            spr = &sprite[j];
387
 
388
            if (j == k || (spr->cstat&0x8000) || spr->cstat == 257 || spr->xrepeat == 0) continue;
389
 
6461 terminx 390
            col = editorcolors[6]; //cyan
391
            if (spr->cstat&1) col = editorcolors[5]; //magenta
5618 terminx 392
 
393
            sprx = spr->x;
394
            spry = spr->y;
395
 
396
            if ((spr->cstat&257) != 0) switch (spr->cstat&48)
397
            {
398
            case 0:
399
                //                    break;
400
 
401
                ox = sprx-cposx;
402
                oy = spry-cposy;
403
                x1 = dmulscale16(ox, xvect, -oy, yvect);
404
                y1 = dmulscale16(oy, xvect2, ox, yvect2);
405
 
406
                ox = (sintable[(spr->ang+512)&2047]>>7);
407
                oy = (sintable[(spr->ang)&2047]>>7);
408
                x2 = dmulscale16(ox, xvect, -oy, yvect);
409
                y2 = dmulscale16(oy, xvect, ox, yvect);
410
 
411
                x3 = mulscale16(x2, yxaspect);
412
                y3 = mulscale16(y2, yxaspect);
413
 
6832 terminx 414
                renderDrawLine(x1-x2+(xdim<<11), y1-y3+(ydim<<11),
5618 terminx 415
                    x1+x2+(xdim<<11), y1+y3+(ydim<<11), col);
6832 terminx 416
                renderDrawLine(x1-y2+(xdim<<11), y1+x3+(ydim<<11),
5618 terminx 417
                    x1+x2+(xdim<<11), y1+y3+(ydim<<11), col);
6832 terminx 418
                renderDrawLine(x1+y2+(xdim<<11), y1-x3+(ydim<<11),
5618 terminx 419
                    x1+x2+(xdim<<11), y1+y3+(ydim<<11), col);
420
                break;
421
 
422
            case 16:
423
                if (spr->picnum == LASERLINE)
424
                {
425
                    x1 = sprx;
426
                    y1 = spry;
427
                    tilenum = spr->picnum;
428
                    xoff = picanm[tilenum].xofs + spr->xoffset;
429
                    if ((spr->cstat&4) > 0) xoff = -xoff;
430
                    k = spr->ang;
431
                    l = spr->xrepeat;
432
                    dax = sintable[k&2047]*l;
433
                    day = sintable[(k+1536)&2047]*l;
434
                    l = tilesiz[tilenum].x;
435
                    k = (l>>1)+xoff;
436
                    x1 -= mulscale16(dax, k);
437
                    x2 = x1+mulscale16(dax, l);
438
                    y1 -= mulscale16(day, k);
439
                    y2 = y1+mulscale16(day, l);
440
 
441
                    ox = x1-cposx;
442
                    oy = y1-cposy;
443
                    x1 = dmulscale16(ox, xvect, -oy, yvect);
444
                    y1 = dmulscale16(oy, xvect2, ox, yvect2);
445
 
446
                    ox = x2-cposx;
447
                    oy = y2-cposy;
448
                    x2 = dmulscale16(ox, xvect, -oy, yvect);
449
                    y2 = dmulscale16(oy, xvect2, ox, yvect2);
450
 
6832 terminx 451
                    renderDrawLine(x1+(xdim<<11), y1+(ydim<<11),
5618 terminx 452
                        x2+(xdim<<11), y2+(ydim<<11), col);
453
                }
454
 
455
                break;
456
 
457
            case 32:
458
                tilenum = spr->picnum;
459
                xoff = picanm[tilenum].xofs + spr->xoffset;
460
                yoff = picanm[tilenum].yofs + spr->yoffset;
461
                if ((spr->cstat&4) > 0) xoff = -xoff;
462
                if ((spr->cstat&8) > 0) yoff = -yoff;
463
 
464
                k = spr->ang;
465
                cosang = sintable[(k+512)&2047];
466
                sinang = sintable[k&2047];
467
                xspan = tilesiz[tilenum].x;
468
                xrepeat = spr->xrepeat;
469
                yspan = tilesiz[tilenum].y;
470
                yrepeat = spr->yrepeat;
471
 
472
                dax = ((xspan>>1)+xoff)*xrepeat;
473
                day = ((yspan>>1)+yoff)*yrepeat;
474
                x1 = sprx + dmulscale16(sinang, dax, cosang, day);
475
                y1 = spry + dmulscale16(sinang, day, -cosang, dax);
476
                l = xspan*xrepeat;
477
                x2 = x1 - mulscale16(sinang, l);
478
                y2 = y1 + mulscale16(cosang, l);
479
                l = yspan*yrepeat;
480
                k = -mulscale16(cosang, l);
481
                x3 = x2+k;
482
                x4 = x1+k;
483
                k = -mulscale16(sinang, l);
484
                y3 = y2+k;
485
                y4 = y1+k;
486
 
487
                ox = x1-cposx;
488
                oy = y1-cposy;
489
                x1 = dmulscale16(ox, xvect, -oy, yvect);
490
                y1 = dmulscale16(oy, xvect2, ox, yvect2);
491
 
492
                ox = x2-cposx;
493
                oy = y2-cposy;
494
                x2 = dmulscale16(ox, xvect, -oy, yvect);
495
                y2 = dmulscale16(oy, xvect2, ox, yvect2);
496
 
497
                ox = x3-cposx;
498
                oy = y3-cposy;
499
                x3 = dmulscale16(ox, xvect, -oy, yvect);
500
                y3 = dmulscale16(oy, xvect2, ox, yvect2);
501
 
502
                ox = x4-cposx;
503
                oy = y4-cposy;
504
                x4 = dmulscale16(ox, xvect, -oy, yvect);
505
                y4 = dmulscale16(oy, xvect2, ox, yvect2);
506
 
6832 terminx 507
                renderDrawLine(x1+(xdim<<11), y1+(ydim<<11),
5618 terminx 508
                    x2+(xdim<<11), y2+(ydim<<11), col);
509
 
6832 terminx 510
                renderDrawLine(x2+(xdim<<11), y2+(ydim<<11),
5618 terminx 511
                    x3+(xdim<<11), y3+(ydim<<11), col);
512
 
6832 terminx 513
                renderDrawLine(x3+(xdim<<11), y3+(ydim<<11),
5618 terminx 514
                    x4+(xdim<<11), y4+(ydim<<11), col);
515
 
6832 terminx 516
                renderDrawLine(x4+(xdim<<11), y4+(ydim<<11),
5618 terminx 517
                    x1+(xdim<<11), y1+(ydim<<11), col);
518
 
519
                break;
520
            }
521
        }
522
    }
523
 
6832 terminx 524
    renderDisableFog();
5618 terminx 525
 
526
    //Draw white lines
527
    for (i=numsectors-1; i>=0; i--)
528
    {
7876 terminx 529
        if (!(show2dsector[i>>3]&pow2char[i&7])) continue;
5618 terminx 530
 
531
        startwall = sector[i].wallptr;
532
        endwall = sector[i].wallptr + sector[i].wallnum;
533
 
534
        k = -1;
7603 terminx 535
        for (j=startwall, wal=(uwallptr_t)&wall[startwall]; j<endwall; j++, wal++)
5618 terminx 536
        {
537
            if (wal->nextwall >= 0) continue;
538
 
539
            if (tilesiz[wal->picnum].x == 0) continue;
540
            if (tilesiz[wal->picnum].y == 0) continue;
541
 
542
            if (j == k)
543
            {
544
                x1 = x2;
545
                y1 = y2;
546
            }
547
            else
548
            {
549
                ox = wal->x-cposx;
550
                oy = wal->y-cposy;
551
                x1 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11);
552
                y1 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11);
553
            }
554
 
555
            k = wal->point2;
7603 terminx 556
            wal2 = (uwallptr_t)&wall[k];
5618 terminx 557
            ox = wal2->x-cposx;
558
            oy = wal2->y-cposy;
559
            x2 = dmulscale16(ox, xvect, -oy, yvect)+(xdim<<11);
560
            y2 = dmulscale16(oy, xvect2, ox, yvect2)+(ydim<<11);
561
 
6832 terminx 562
            renderDrawLine(x1, y1, x2, y2, editorcolors[7]);
5618 terminx 563
        }
564
    }
565
 
6832 terminx 566
    renderEnableFog();
5618 terminx 567
 
6828 terminx 568
    videoSetCorrectedAspect();
5618 terminx 569
 
570
    for (TRAVERSE_CONNECT(p))
571
    {
572
        if (ud.scrollmode && p == screenpeek) continue;
573
 
7776 terminx 574
        auto const pPlayer = g_player[p].ps;
7603 terminx 575
        auto const pSprite = (uspriteptr_t)&sprite[pPlayer->i];
6953 hendricks2 576
 
577
        ox = pSprite->x - cposx;
578
        oy = pSprite->y - cposy;
579
        daang = (pSprite->ang - cang) & 2047;
5618 terminx 580
        if (p == screenpeek)
581
        {
582
            ox = 0;
583
            oy = 0;
584
            daang = 0;
585
        }
6254 hendricks2 586
        x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
587
        y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
5618 terminx 588
 
589
        if (p == screenpeek || GTFLAGS(GAMETYPE_OTHERPLAYERSINMAP))
590
        {
6953 hendricks2 591
            if (pSprite->xvel > 16 && pPlayer->on_ground)
8050 pogokeen 592
                i = APLAYERTOP+(((int32_t) totalclock>>4)&3);
5618 terminx 593
            else
594
                i = APLAYERTOP;
595
 
6953 hendricks2 596
            i = VM_OnEventWithReturn(EVENT_DISPLAYOVERHEADMAPPLAYER, pPlayer->i, p, i);
6608 hendricks2 597
 
598
            if (i < 0)
599
                continue;
600
 
6953 hendricks2 601
            j = klabs(pPlayer->truefz - pPlayer->pos.z) >> 8;
602
            j = mulscale16(czoom * (pSprite->yrepeat + j), yxaspect);
5618 terminx 603
 
604
            if (j < 22000) j = 22000;
6953 hendricks2 605
            else if (j > (65536<<1)) j = (65536<<1);
5618 terminx 606
 
6953 hendricks2 607
            rotatesprite_win((x1<<4)+(xdim<<15), (y1<<4)+(ydim<<15), j, daang, i, pSprite->shade,
6955 hendricks2 608
                P_GetOverheadPal(pPlayer), 0);
5618 terminx 609
        }
610
    }
611
}
612
 
613
#define printcoordsline(fmt, ...) do { \
614
    Bsprintf(tempbuf, fmt, ## __VA_ARGS__); \
615
    printext256(20, y+=9, COLOR_WHITE, -1, tempbuf, 0); \
616
} while (0)
617
 
5621 terminx 618
#ifdef DEBUGGINGAIDS
619
sprstat_t g_spriteStat;
620
#endif
621
 
5618 terminx 622
static void G_PrintCoords(int32_t snum)
623
{
7278 terminx 624
    const int32_t x = g_Debug ? 288 : 0;
625
    int32_t y = 0;
5618 terminx 626
 
7776 terminx 627
    auto const ps = g_player[snum].ps;
5618 terminx 628
    const int32_t sectnum = ps->cursectnum;
629
 
5835 terminx 630
    if ((g_gametypeFlags[ud.coop] & GAMETYPE_FRAGBAR))
5618 terminx 631
    {
632
        if (ud.multimode > 4)
633
            y = 32;
634
        else if (g_netServer || ud.multimode > 1)
635
            y = 24;
636
    }
637
    Bsprintf(tempbuf, "XYZ= (%d, %d, %d)", ps->pos.x, ps->pos.y, ps->pos.z);
638
    printext256(x, y, COLOR_WHITE, -1, tempbuf, 0);
6725 terminx 639
    char ang[16], horiz[16], horizoff[16];
640
    fix16_to_str(ps->q16ang, ang, 2);
641
    fix16_to_str(ps->q16horiz, horiz, 2);
642
    fix16_to_str(ps->q16horizoff, horizoff, 2);
643
    Bsprintf(tempbuf, "A/H/HO= %s, %s, %s", ang, horiz, horizoff);
5618 terminx 644
    printext256(x, y+9, COLOR_WHITE, -1, tempbuf, 0);
645
    Bsprintf(tempbuf, "VEL= (%d, %d, %d) + (%d, %d, 0)",
646
        ps->vel.x>>14, ps->vel.y>>14, ps->vel.z, ps->fric.x>>5, ps->fric.y>>5);
647
    printext256(x, y+18, COLOR_WHITE, -1, tempbuf, 0);
648
    Bsprintf(tempbuf, "OG= %d  SBRIDGE=%d SBS=%d", ps->on_ground, ps->spritebridge, ps->sbs);
649
    printext256(x, y+27, COLOR_WHITE, -1, tempbuf, 0);
650
    if (sectnum >= 0)
651
        Bsprintf(tempbuf, "SECT= %d (LO=%d EX=%d)", sectnum,
652
            TrackerCast(sector[sectnum].lotag), TrackerCast(sector[sectnum].extra));
653
    else
654
        Bsprintf(tempbuf, "SECT= %d", sectnum);
655
    printext256(x, y+36, COLOR_WHITE, -1, tempbuf, 0);
656
    //    Bsprintf(tempbuf,"SEED= %d",randomseed);
657
    //    printext256(x,y+45,COLOR_WHITE,-1,tempbuf,0);
658
    y -= 9;
659
 
660
    y += 7;
661
    Bsprintf(tempbuf, "THOLD= %d", ps->transporter_hold);
662
    printext256(x, y+54, COLOR_WHITE, -1, tempbuf, 0);
8050 pogokeen 663
    Bsprintf(tempbuf, "GAMETIC= %u, TOTALCLOCK=%d", g_moveThingsCount, (int32_t) totalclock);
5618 terminx 664
    printext256(x, y+63, COLOR_WHITE, -1, tempbuf, 0);
665
#ifdef DEBUGGINGAIDS
666
    Bsprintf(tempbuf, "NUMSPRITES= %d", Numsprites);
667
    printext256(x, y+72, COLOR_WHITE, -1, tempbuf, 0);
668
    if (g_moveThingsCount > g_spriteStat.lastgtic + REALGAMETICSPERSEC)
669
    {
670
        g_spriteStat.lastgtic = g_moveThingsCount;
671
        g_spriteStat.lastnumins = g_spriteStat.numins;
672
        g_spriteStat.numins = 0;
673
    }
674
    Bsprintf(tempbuf, "INSERTIONS/s= %u", g_spriteStat.lastnumins);
675
    printext256(x, y+81, COLOR_WHITE, -1, tempbuf, 0);
676
    Bsprintf(tempbuf, "ONSCREEN= %d", g_spriteStat.numonscreen);
677
    printext256(x, y+90, COLOR_WHITE, -1, tempbuf, 0);
678
    y += 3*9;
679
#endif
680
    y += 7;
681
    Bsprintf(tempbuf, "VR=%.03f  YX=%.03f", (double) dr_viewingrange/65536.0, (double) dr_yxaspect/65536.0);
682
    printext256(x, y+72, COLOR_WHITE, -1, tempbuf, 0);
683
 
684
#ifdef USE_OPENGL
685
    if (ud.coords == 2)
686
    {
687
        y=16;
688
 
6829 terminx 689
        printcoordsline("rendmode = %d", videoGetRenderMode());
5618 terminx 690
        printcoordsline("r_ambientlight = %.03f", r_ambientlight);
691
 
692
        if (rendmode >= 3)
693
        {
694
            if (rendmode==3)
695
                printcoordsline("r_usenewshading = %d", r_usenewshading);
696
# ifdef POLYMER
697
            else
698
                printcoordsline("r_pr_artmapping = %d", pr_artmapping);
699
#endif
8360 hendricks2 700
            printcoordsline("r_usetileshades = %d", r_usetileshades);
5618 terminx 701
        }
702
    }
703
#endif
704
}
705
 
706
static void G_ShowCacheLocks(void)
707
{
708
    if (offscreenrendering)
709
        return;
710
 
7278 terminx 711
    int k = 0;
712
 
5618 terminx 713
#if !defined DEBUG_ALLOCACHE_AS_MALLOC
8204 terminx 714
    auto indexes = g_cache.getIndex();
715
 
716
    for (int i=g_cache.numBlocks()-1; i>=0; i--)
7278 terminx 717
    {
8204 terminx 718
        if ((*indexes[i].lock) != CACHE1D_LOCKED && (*indexes[i].lock) != 1)
5618 terminx 719
        {
720
            if (k >= ydim-12)
721
                break;
722
 
8204 terminx 723
            Bsprintf(tempbuf, "Locked- %d: Leng:%d, Lock:%d", i, indexes[i].leng, *indexes[i].lock);
5618 terminx 724
            printext256(0L, k, COLOR_WHITE, -1, tempbuf, 1);
725
            k += 6;
726
        }
7278 terminx 727
    }
5618 terminx 728
#endif
7278 terminx 729
 
5618 terminx 730
    if (k < ydim-12)
731
        k += 6;
732
 
7278 terminx 733
    for (int i=10; i>=0; i--)
734
    {
8201 terminx 735
        if (rts_lumplockbyte[i] >= CACHE1D_LOCKED)
5618 terminx 736
        {
737
            if (k >= ydim-12)
738
                break;
739
 
740
            Bsprintf(tempbuf, "RTS Locked %d:", i);
741
            printext256(0, k, COLOR_WHITE, -1, tempbuf, 1);
742
            k += 6;
743
        }
7278 terminx 744
    }
5618 terminx 745
 
746
    if (k >= ydim-12 && k<ydim-6)
747
        printext256(0, k, COLOR_WHITE, -1, "(MORE . . .)", 1);
748
 
749
    // sounds
750
    if (xdim < 640)
751
        return;
752
 
7278 terminx 753
    k = 0;
754
 
755
    for (int i=0; i<=g_highestSoundIdx; i++)
756
    {
5618 terminx 757
        if (g_sounds[i].num > 0)
758
        {
7278 terminx 759
            for (int j = 0, n = g_sounds[i].num; j < n; j++)
5618 terminx 760
            {
761
                if (k >= ydim-12)
7278 terminx 762
                    return;
5618 terminx 763
 
7278 terminx 764
                Bsprintf(tempbuf, "snd %d_%d: voice %d, ow %d", i, j, g_sounds[i].voices[j].id, g_sounds[i].voices[j].owner);
765
                printext256(160, k, COLOR_WHITE, -1, tempbuf, 1);
5618 terminx 766
 
7278 terminx 767
                k += 6;
5618 terminx 768
            }
769
        }
7278 terminx 770
    }
5618 terminx 771
}
772
 
7304 terminx 773
#define LOW_FPS ((videoGetRenderMode() == REND_CLASSIC) ? 35 : 50)
7278 terminx 774
#define SLOW_FRAME_TIME 20
5618 terminx 775
 
776
#if defined GEKKO
777
# define FPS_YOFFSET 16
778
#else
779
# define FPS_YOFFSET 0
780
#endif
781
 
6019 terminx 782
#define FPS_COLOR(x) ((x) ? COLOR_RED : COLOR_WHITE)
783
 
5618 terminx 784
static void G_PrintFPS(void)
785
{
7304 terminx 786
    static int32_t frameCount;
787
    static double cumulativeFrameDelay;
788
    static double lastFrameTime;
7799 hendricks2 789
    static float lastFPS, minFPS = std::numeric_limits<float>::max(), maxFPS;
790
    static double minGameUpdate = std::numeric_limits<double>::max(), maxGameUpdate;
5618 terminx 791
 
7304 terminx 792
    double frameTime = timerGetHiTicks();
793
    double frameDelay = frameTime - lastFrameTime;
6660 pogokeen 794
    cumulativeFrameDelay += frameDelay;
5618 terminx 795
 
6238 terminx 796
    if (frameDelay >= 0)
5618 terminx 797
    {
798
        int32_t x = (xdim <= 640);
799
 
6021 terminx 800
        if (ud.showfps)
5618 terminx 801
        {
7304 terminx 802
            int32_t chars = Bsprintf(tempbuf, "%.1f ms, %5.1f fps", frameDelay, lastFPS);
5618 terminx 803
 
5800 terminx 804
            printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+2+FPS_YOFFSET, 0, -1, tempbuf, x);
805
            printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+1+FPS_YOFFSET,
6238 terminx 806
                FPS_COLOR(lastFPS < LOW_FPS), -1, tempbuf, x);
5618 terminx 807
 
6021 terminx 808
            if (ud.showfps > 1)
5618 terminx 809
            {
7304 terminx 810
                chars = Bsprintf(tempbuf, "max: %5.1f fps", maxFPS);
5618 terminx 811
 
5800 terminx 812
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+10+2+FPS_YOFFSET, 0, -1, tempbuf, x);
813
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+10+FPS_YOFFSET,
6238 terminx 814
                    FPS_COLOR(maxFPS < LOW_FPS), -1, tempbuf, x);
5618 terminx 815
 
7304 terminx 816
                chars = Bsprintf(tempbuf, "min: %5.1f fps", minFPS);
5618 terminx 817
 
5800 terminx 818
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+20+2+FPS_YOFFSET, 0, -1, tempbuf, x);
819
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+20+FPS_YOFFSET,
6238 terminx 820
                    FPS_COLOR(minFPS < LOW_FPS), -1, tempbuf, x);
5618 terminx 821
            }
6882 pogokeen 822
            if (ud.showfps > 2)
823
            {
824
                if (g_gameUpdateTime > maxGameUpdate) maxGameUpdate = g_gameUpdateTime;
825
                if (g_gameUpdateTime < minGameUpdate) minGameUpdate = g_gameUpdateTime;
5618 terminx 826
 
7304 terminx 827
                chars = Bsprintf(tempbuf, "Game Update: %2.2f ms + draw: %2.2f ms", g_gameUpdateTime, g_gameUpdateAndDrawTime);
6882 pogokeen 828
 
829
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+30+2+FPS_YOFFSET, 0, -1, tempbuf, x);
830
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+30+FPS_YOFFSET,
831
                    FPS_COLOR(g_gameUpdateAndDrawTime >= SLOW_FRAME_TIME), -1, tempbuf, x);
832
 
7304 terminx 833
                chars = Bsprintf(tempbuf, "GU min/max/avg: %5.2f/%5.2f/%5.2f ms", minGameUpdate, maxGameUpdate, g_gameUpdateAvgTime);
6882 pogokeen 834
 
835
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+40+2+FPS_YOFFSET, 0, -1, tempbuf, x);
836
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+40+FPS_YOFFSET,
837
                    FPS_COLOR(maxGameUpdate >= SLOW_FRAME_TIME), -1, tempbuf, x);
7278 terminx 838
 
839
                chars = Bsprintf(tempbuf, "G_MoveActors(): %.3e ms", g_moveActorsTime);
840
 
841
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+50+2+FPS_YOFFSET, 0, -1, tempbuf, x);
842
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+50+FPS_YOFFSET,
843
                    COLOR_WHITE, -1, tempbuf, x);
844
 
845
                chars = Bsprintf(tempbuf, "G_MoveWorld(): %.3e ms", g_moveWorldTime);
846
 
847
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+60+2+FPS_YOFFSET, 0, -1, tempbuf, x);
848
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+60+FPS_YOFFSET,
849
                    COLOR_WHITE, -1, tempbuf, x);
6882 pogokeen 850
            }
851
 
5618 terminx 852
            // lag meter
853
            if (g_netClientPeer)
854
            {
855
                chars = Bsprintf(tempbuf, "%d +- %d ms", (g_netClientPeer->lastRoundTripTime + g_netClientPeer->roundTripTime)/2,
856
                    (g_netClientPeer->lastRoundTripTimeVariance + g_netClientPeer->roundTripTimeVariance)/2);
857
 
5800 terminx 858
                printext256(windowxy2.x-(chars<<(3-x))+1, windowxy1.y+30+2+FPS_YOFFSET, 0, -1, tempbuf, x);
6019 terminx 859
                printext256(windowxy2.x-(chars<<(3-x)), windowxy1.y+30+1+FPS_YOFFSET, FPS_COLOR(g_netClientPeer->lastRoundTripTime > 200), -1, tempbuf, x);
5618 terminx 860
            }
861
        }
862
 
7304 terminx 863
        if (cumulativeFrameDelay >= 1000.0)
5618 terminx 864
        {
7304 terminx 865
            lastFPS = 1000.f * frameCount / cumulativeFrameDelay;
866
            g_frameRate = Blrintf(lastFPS);
6238 terminx 867
            frameCount = 0;
7304 terminx 868
            cumulativeFrameDelay = 0.0;
5618 terminx 869
 
6238 terminx 870
            if (ud.showfps > 1)
5618 terminx 871
            {
6238 terminx 872
                if (lastFPS > maxFPS) maxFPS = lastFPS;
7304 terminx 873
                if (lastFPS < minFPS) minFPS = lastFPS;
874
 
6238 terminx 875
                static int secondCounter;
876
 
7308 terminx 877
                if (++secondCounter >= ud.frameperiod)
6238 terminx 878
                {
7304 terminx 879
                    maxFPS = (lastFPS + maxFPS) * .5f;
880
                    minFPS = (lastFPS + minFPS) * .5f;
881
                    maxGameUpdate = (g_gameUpdateTime + maxGameUpdate) * 0.5;
882
                    minGameUpdate = (g_gameUpdateTime + minGameUpdate) * 0.5;
6238 terminx 883
                    secondCounter = 0;
884
                }
5618 terminx 885
            }
886
        }
6238 terminx 887
        frameCount++;
5618 terminx 888
    }
6238 terminx 889
    lastFrameTime = frameTime;
5618 terminx 890
}
891
 
6019 terminx 892
#undef FPS_COLOR
893
 
5618 terminx 894
void G_DisplayRest(int32_t smoothratio)
895
{
896
    int32_t i, j;
897
    palaccum_t tint = PALACCUM_INITIALIZER;
898
 
7776 terminx 899
    auto const pp = g_player[screenpeek].ps;
5618 terminx 900
#ifdef SPLITSCREEN_MOD_HACKS
7776 terminx 901
    auto const pp2 = g_fakeMultiMode==2 ? g_player[1].ps : NULL;
5618 terminx 902
#endif
903
    int32_t cposx, cposy, cang;
904
 
905
#ifdef USE_OPENGL
906
    // this takes care of fullscreen tint for OpenGL
6829 terminx 907
    if (videoGetRenderMode() >= REND_POLYMOST)
5618 terminx 908
    {
6215 hendricks2 909
        polytint_t & fstint = hictinting[MAXPALOOKUPS-1];
910
 
5618 terminx 911
        if (pp->palette == WATERPAL)
912
        {
6215 hendricks2 913
            fstint.r = 224;
914
            fstint.g = 192;
915
            fstint.b = 255;
916
            fstint.f = 0;
5618 terminx 917
        }
918
        else if (pp->palette == SLIMEPAL)
919
        {
6215 hendricks2 920
            fstint.r = 208;
921
            fstint.g = 255;
922
            fstint.b = 192;
923
            fstint.f = 0;
5618 terminx 924
        }
925
        else
926
        {
6215 hendricks2 927
            fstint.r = 255;
928
            fstint.g = 255;
929
            fstint.b = 255;
930
            fstint.f = 0;
5618 terminx 931
        }
932
    }
933
#endif  // USE_OPENGL
934
 
935
    palaccum_add(&tint, &pp->pals, pp->pals.f);
936
#ifdef SPLITSCREEN_MOD_HACKS
937
    if (pp2)
938
        palaccum_add(&tint, &pp2->pals, pp2->pals.f);
939
#endif
940
    {
6061 hendricks2 941
        static const palette_t loogiepal = { 0, 63, 0, 0 };
5618 terminx 942
 
943
        palaccum_add(&tint, &loogiepal, pp->loogcnt>>1);
944
#ifdef SPLITSCREEN_MOD_HACKS
945
        if (pp2)
946
            palaccum_add(&tint, &loogiepal, pp2->loogcnt>>1);
947
#endif
948
    }
949
 
950
    if (g_restorePalette)
951
    {
952
        // reset a normal palette
953
        static uint32_t omovethingscnt;
954
 
955
        if (g_restorePalette < 2 || omovethingscnt+1 == g_moveThingsCount)
956
        {
957
            int32_t pal = pp->palette;
958
#ifdef SPLITSCREEN_MOD_HACKS
959
            const int32_t opal = pal;
960
 
961
            if (pp2)  // splitscreen HACK: BASEPAL trumps all, then it's arbitrary.
962
                pal = min(pal, pp2->palette);
963
#endif
964
 
965
            // g_restorePalette < 0: reset tinting, too (e.g. when loading new game)
966
            P_SetGamePalette(pp, pal, 2 + (g_restorePalette>0)*16);
967
 
968
#ifdef SPLITSCREEN_MOD_HACKS
969
            if (pp2)  // keep first player's pal as its member!
970
                pp->palette = opal;
971
#endif
972
 
973
            g_restorePalette = 0;
974
        }
975
        else
976
        {
977
            // delay setting the palette by one game tic
978
            omovethingscnt = g_moveThingsCount;
979
        }
980
    }
981
 
982
    if (ud.show_help)
983
    {
984
        switch (ud.show_help)
985
        {
986
        case 1:
987
            rotatesprite_fs(160<<16, 100<<16, 65536L, 0, TEXTSTORY, 0, 0, 10+64);
988
            break;
989
        case 2:
990
            rotatesprite_fs(160<<16, 100<<16, 65536L, 0, F1HELP, 0, 0, 10+64);
991
            break;
992
        }
993
 
994
        if (I_ReturnTrigger())
995
        {
996
            I_ReturnTriggerClear();
997
            ud.show_help = 0;
998
            if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
999
            {
1000
                ready2send = 1;
1001
                totalclock = ototalclock;
1002
            }
1003
            G_UpdateScreenArea();
1004
        }
1005
 
1006
        return;
1007
    }
1008
 
1009
    i = pp->cursectnum;
1010
    if (i > -1)
1011
    {
1012
        const walltype *wal = &wall[sector[i].wallptr];
1013
 
7876 terminx 1014
        show2dsector[i>>3] |= pow2char[i&7];
5618 terminx 1015
        for (j=sector[i].wallnum; j>0; j--, wal++)
1016
        {
1017
            i = wal->nextsector;
1018
            if (i < 0) continue;
1019
            if (wal->cstat&0x0071) continue;
1020
            if (wall[wal->nextwall].cstat&0x0071) continue;
1021
            if (sector[i].lotag == 32767) continue;
1022
            if (sector[i].ceilingz >= sector[i].floorz) continue;
7876 terminx 1023
            show2dsector[i>>3] |= pow2char[i&7];
5618 terminx 1024
        }
1025
    }
1026
 
1027
    if (ud.camerasprite == -1)
1028
    {
1029
        if (ud.overhead_on != 2)
1030
        {
1031
            if (pp->newowner >= 0)
1032
                G_DrawCameraText(pp->newowner);
1033
            else
1034
            {
1035
                P_DisplayWeapon();
1036
#ifdef SPLITSCREEN_MOD_HACKS
1037
                if (pp2)  // HACK
1038
                {
1039
                    const int32_t oscreenpeek = screenpeek;
1040
                    screenpeek = 1;
1041
                    P_DisplayWeapon();
1042
                    screenpeek = oscreenpeek;
1043
                }
1044
#endif
1045
 
1046
                if (pp->over_shoulder_on == 0)
1047
                    P_DisplayScuba();
1048
#ifdef SPLITSCREEN_MOD_HACKS
1049
                if (pp2 && pp2->over_shoulder_on == 0)  // HACK
1050
                {
1051
                    const int32_t oscreenpeek = screenpeek;
1052
                    screenpeek = 1;
1053
                    P_DisplayScuba();
1054
                    screenpeek = oscreenpeek;
1055
                }
1056
#endif
1057
            }
1058
            G_MoveClouds();
1059
        }
1060
 
1061
        if (ud.overhead_on > 0)
1062
        {
1063
            // smoothratio = min(max(smoothratio,0),65536);
1064
            smoothratio = calc_smoothratio(totalclock, ototalclock);
1065
            G_DoInterpolations(smoothratio);
1066
 
1067
            if (ud.scrollmode == 0)
1068
            {
1069
                if (pp->newowner == -1 && !ud.pause_on)
1070
                {
1071
                    cposx = pp->opos.x + mulscale16(pp->pos.x-pp->opos.x, smoothratio);
1072
                    cposy = pp->opos.y + mulscale16(pp->pos.y-pp->opos.y, smoothratio);
6725 terminx 1073
                    cang = fix16_to_int(pp->oq16ang) + mulscale16((fix16_to_int(pp->q16ang+F16(1024)-pp->oq16ang)&2047)-1024, smoothratio);
5618 terminx 1074
                }
1075
                else
1076
                {
1077
                    cposx = pp->opos.x;
1078
                    cposy = pp->opos.y;
6725 terminx 1079
                    cang = fix16_to_int(pp->oq16ang);
5618 terminx 1080
                }
1081
            }
1082
            else
1083
            {
1084
#ifdef __ANDROID__
1085
                CONTROL_Android_ScrollMap(&ud.fola, &ud.folx, &ud.foly, &pp->zoom);
1086
#else
1087
                if (!ud.pause_on)
1088
                {
1089
                    ud.fola += ud.folavel>>3;
1090
                    ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14;
1091
                    ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14;
1092
                }
1093
#endif
1094
                cposx = ud.folx;
1095
                cposy = ud.foly;
1096
                cang = ud.fola;
1097
            }
1098
 
1099
            if (ud.overhead_on == 2)
1100
            {
6828 terminx 1101
                videoClearViewableArea(0L);
7331 terminx 1102
#ifdef USE_OPENGL
1103
                if (videoGetRenderMode() >= REND_POLYMOST)
1104
                {
1105
                    G_DrawBackground(); // Necessary GL fills the entire screen with black
1106
                }
1107
#endif
6831 terminx 1108
                renderDrawMapView(cposx, cposy, pp->zoom, cang);
5618 terminx 1109
            }
1110
            G_DrawOverheadMap(cposx, cposy, pp->zoom, cang);
1111
 
1112
            G_RestoreInterpolations();
1113
 
6258 hendricks2 1114
            int32_t const textret = VM_OnEvent(EVENT_DISPLAYOVERHEADMAPTEXT, g_player[screenpeek].ps->i, screenpeek);
1115
 
1116
            if (textret == 0 && ud.overhead_on == 2)
5618 terminx 1117
            {
1118
                const int32_t a = (ud.screen_size > 0) ? 147 : 179;
8016 hendricks2 1119
                char const * levelname = g_mapInfo[ud.volume_number*MAXLEVELS + ud.level_number].name;
1120
                if (G_HaveUserMap())
1121
                    levelname = boardfilename;
1122
                else if (!(G_GetLogoFlags() & LOGO_HIDEEPISODE))
6597 hendricks2 1123
                    minitext(5, a+6, g_volumeNames[ud.volume_number], 0, 2+8+16+256);
8016 hendricks2 1124
                minitext(5, a+6+6, levelname, 0, 2+8+16+256);
5618 terminx 1125
            }
1126
        }
1127
    }
1128
 
1129
    if (pp->invdisptime > 0) G_DrawInventory(pp);
1130
 
1131
    if (VM_OnEvent(EVENT_DISPLAYSBAR, g_player[screenpeek].ps->i, screenpeek) == 0)
1132
        G_DrawStatusBar(screenpeek);
1133
 
1134
#ifdef SPLITSCREEN_MOD_HACKS
1135
    // HACK
1136
    if (g_fakeMultiMode==2)
1137
    {
1138
        G_DrawStatusBar(1);
1139
        G_PrintGameQuotes(1);
1140
    }
1141
#endif
1142
 
1143
    G_PrintGameQuotes(screenpeek);
1144
 
1145
    if (ud.show_level_text && hud_showmapname && g_levelTextTime > 1)
1146
    {
6208 hendricks2 1147
        int32_t o = 10|16;
5618 terminx 1148
 
1149
        if (g_levelTextTime < 3)
6208 hendricks2 1150
            o |= 1|32;
5618 terminx 1151
        else if (g_levelTextTime < 5)
6208 hendricks2 1152
            o |= 1;
5618 terminx 1153
 
5835 terminx 1154
        if (g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name != NULL)
5618 terminx 1155
        {
6208 hendricks2 1156
            char const * const fn = currentboardfilename[0] != 0 &&
1157
                ud.volume_number == 0 && ud.level_number == 7
1158
                    ? currentboardfilename
1159
                    : g_mapInfo[(ud.volume_number*MAXLEVELS) + ud.level_number].name;
1160
 
1161
            menutext_(160<<16, (90+16+8)<<16, -g_levelTextTime+22/*quotepulseshade*/, fn, o, TEXT_XCENTER);
5618 terminx 1162
        }
1163
    }
1164
 
1165
    if (I_EscapeTrigger() && ud.overhead_on == 0
1166
        && ud.show_help == 0
1167
        && g_player[myconnectindex].ps->newowner == -1)
1168
    {
1169
        if ((g_player[myconnectindex].ps->gm&MODE_MENU) == MODE_MENU && g_currentMenu <= MENU_MAIN_INGAME)
1170
        {
1171
            I_EscapeTriggerClear();
1172
            S_PlaySound(EXITMENUSOUND);
5923 terminx 1173
            Menu_Change(MENU_CLOSE);
5880 hendricks2 1174
            if (!ud.pause_on)
7119 terminx 1175
                S_PauseSounds(false);
5618 terminx 1176
        }
1177
        else if ((g_player[myconnectindex].ps->gm&MODE_MENU) != MODE_MENU &&
1178
            g_player[myconnectindex].ps->newowner == -1 &&
1179
            (g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE)
1180
        {
1181
            I_EscapeTriggerClear();
7119 terminx 1182
            S_PauseSounds(true);
5618 terminx 1183
 
5923 terminx 1184
            Menu_Open(myconnectindex);
5618 terminx 1185
 
1186
            if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2) ready2send = 0;
1187
 
5923 terminx 1188
            if (g_player[myconnectindex].ps->gm&MODE_GAME) Menu_Change(MENU_MAIN_INGAME);
1189
            else Menu_Change(MENU_MAIN);
5618 terminx 1190
            screenpeek = myconnectindex;
5875 terminx 1191
 
1192
            S_MenuSound();
5618 terminx 1193
        }
1194
    }
1195
 
1196
    if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1)
1197
    {
6714 hendricks2 1198
        ud.returnvar[0] = (160<<16) - (g_player[myconnectindex].ps->look_ang<<15);
1199
        ud.returnvar[1] = 100<<16;
1200
        int32_t a = VM_OnEventWithReturn(EVENT_DISPLAYCROSSHAIR, g_player[screenpeek].ps->i, screenpeek, CROSSHAIR);
5618 terminx 1201
        if ((unsigned) a < MAXTILES)
1202
        {
6714 hendricks2 1203
            vec2_t crosshairpos = { ud.returnvar[0], ud.returnvar[1] };
6568 hendricks2 1204
            uint8_t crosshair_pal = CROSSHAIR_PAL;
1205
            uint32_t crosshair_o = 1|2;
6606 hendricks2 1206
            uint32_t crosshair_scale = divscale16(ud.crosshairscale, 100);
6568 hendricks2 1207
 
1208
            auto const oyxaspect = yxaspect;
7808 terminx 1209
            if (FURY)
6568 hendricks2 1210
            {
6650 hendricks2 1211
                crosshairpos.x = scale(crosshairpos.x - (320<<15), ydim << 2, xdim * 3) + (320<<15);
6714 hendricks2 1212
                crosshairpos.y = scale(crosshairpos.y - (200<<15), (ydim << 2) * 6, (xdim * 3) * 5) + (200<<15);
6650 hendricks2 1213
                crosshair_scale = scale(crosshair_scale, ydim << 2, xdim * 3) >> 1;
6568 hendricks2 1214
                crosshair_pal = 0;
1215
                crosshair_o |= 1024;
6831 terminx 1216
                renderSetAspect(viewingrange, 65536);
6568 hendricks2 1217
            }
1218
 
6650 hendricks2 1219
            rotatesprite_win(crosshairpos.x, crosshairpos.y, crosshair_scale, 0, a, 0, crosshair_pal, crosshair_o);
5618 terminx 1220
 
7808 terminx 1221
            if (FURY)
6831 terminx 1222
                renderSetAspect(viewingrange, oyxaspect);
6714 hendricks2 1223
        }
1224
    }
1225
 
5618 terminx 1226
#ifdef GEKKO
6714 hendricks2 1227
    // like the mouse cursor, the pointer doesn't use the crosshair enabled / scale options
1228
    if (g_player[myconnectindex].ps->newowner == -1 && ud.overhead_on == 0 && ud.camerasprite == -1 &&
6827 terminx 1229
        (g_player[myconnectindex].ps->gm&MODE_MENU) == 0 && mouseReadAbs((vec2_t *)&ud.returnvar[0], &g_mouseAbs))
6714 hendricks2 1230
    {
1231
        int32_t a = VM_OnEventWithReturn(EVENT_DISPLAYPOINTER, g_player[screenpeek].ps->i, screenpeek, CROSSHAIR);
1232
        if ((unsigned) a < MAXTILES)
1233
        {
6939 pogokeen 1234
            vec2_t pointerpos = { tabledivide32(ud.returnvar[0], upscalefactor), tabledivide32(ud.returnvar[1], upscalefactor) };
6714 hendricks2 1235
            uint8_t pointer_pal = CROSSHAIR_PAL;
1236
            uint32_t pointer_o = 1|2;
1237
            uint32_t pointer_scale = 65536;
1238
 
1239
            auto const oyxaspect = yxaspect;
7808 terminx 1240
            if (FURY)
6650 hendricks2 1241
            {
6714 hendricks2 1242
                pointerpos.x = scale(pointerpos.x - (320<<15), ydim << 2, xdim * 3) + (320<<15);
1243
                pointerpos.y = scale(pointerpos.y - (200<<15), (ydim << 2) * 6, (xdim * 3) * 5) + (200<<15);
1244
                pointer_scale = scale(pointer_scale, ydim << 2, xdim * 3) >> 1;
1245
                pointer_pal = 0;
1246
                pointer_o |= 1024;
6831 terminx 1247
                renderSetAspect(viewingrange, 65536);
6650 hendricks2 1248
            }
6568 hendricks2 1249
 
6714 hendricks2 1250
            rotatesprite_win(pointerpos.x, pointerpos.y, pointer_scale, 0, a, 0, pointer_pal, pointer_o);
1251
 
7808 terminx 1252
            if (FURY)
6831 terminx 1253
                renderSetAspect(viewingrange, oyxaspect);
5618 terminx 1254
        }
1255
    }
6714 hendricks2 1256
#endif
5618 terminx 1257
#if 0
6481 hendricks2 1258
    if (g_gametypeFlags[ud.coop] & GAMETYPE_TDM)
5618 terminx 1259
    {
1260
        for (i=0; i<ud.multimode; i++)
1261
        {
1262
            if (g_player[i].ps->team == g_player[myconnectindex].ps->team)
1263
            {
1264
                j = min(max((G_GetAngleDelta(getangle(g_player[i].ps->pos.x-g_player[myconnectindex].ps->pos.x,
1265
                    g_player[i].ps->pos.y-g_player[myconnectindex].ps->pos.y), g_player[myconnectindex].ps->ang))>>1, -160), 160);
1266
                rotatesprite_win((160-j)<<16, 100L<<16, 65536L, 0, DUKEICON, 0, 0, 2+1);
1267
            }
1268
        }
1269
    }
1270
#endif
1271
 
6715 hendricks2 1272
    if (VM_HaveEvent(EVENT_DISPLAYREST))
1273
    {
1274
        int32_t vr=viewingrange, asp=yxaspect;
7636 terminx 1275
        VM_ExecuteEvent(EVENT_DISPLAYREST, g_player[screenpeek].ps->i, screenpeek);
6831 terminx 1276
        renderSetAspect(vr, asp);
6715 hendricks2 1277
    }
1278
 
5618 terminx 1279
    if (ud.pause_on==1 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
6208 hendricks2 1280
        menutext_center(100, "Game Paused");
5618 terminx 1281
 
1282
    if (ud.coords)
1283
        G_PrintCoords(screenpeek);
1284
 
1285
#ifdef YAX_DEBUG
1286
    M32_drawdebug();
1287
#endif
1288
 
1289
#ifdef USE_OPENGL
1290
    mdpause = (ud.pause_on || (ud.recstat==2 && (g_demo_paused && g_demo_goalCnt==0)) || (g_player[myconnectindex].ps->gm&MODE_MENU && numplayers < 2));
1291
#endif
1292
 
1293
    G_PrintFPS();
1294
 
1295
    // JBF 20040124: display level stats in screen corner
6537 terminx 1296
    if (ud.overhead_on != 2 && ud.levelstats && VM_OnEvent(EVENT_DISPLAYLEVELSTATS, g_player[screenpeek].ps->i, screenpeek) == 0)
5618 terminx 1297
    {
7776 terminx 1298
        auto const myps = g_player[myconnectindex].ps;
5618 terminx 1299
 
1300
        i = 198<<16;
1301
 
1302
        if (ud.screen_size == 4)
1303
        {
6897 hendricks2 1304
            if (ud.althud == 0 || ud.hudontop == 0)
5618 terminx 1305
                i -= sbarsc(ud.althud ? (tilesiz[BIGALPHANUM].y+8)<<16 : tilesiz[INVENTORYBOX].y<<16);
1306
        }
1307
        else if (ud.screen_size > 2)
8789 hendricks2 1308
            i -= sbarsc(tilesiz[sbartile()].y<<16);
5618 terminx 1309
 
6458 hendricks2 1310
        int32_t const xbetween = (tilesiz[MF_Bluefont.tilenum + 'A' - '!'].x<<16) + MF_Bluefont.between.x;
1311
 
5618 terminx 1312
        Bsprintf(tempbuf, "T:^15%d:%02d.%02d",
1313
            (myps->player_par/(REALGAMETICSPERSEC*60)),
1314
            (myps->player_par/REALGAMETICSPERSEC)%60,
1315
            ((myps->player_par%REALGAMETICSPERSEC)*33)/10
1316
            );
8653 hendricks2 1317
        G_ScreenText(MF_Bluefont.tilenum, 2<<16, i-gtextsc(21<<16), gtextsc(MF_Bluefont.zoom), 0, 0, tempbuf, 0, 10, 2|8|16|256, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, xbetween, MF_Bluefont.between.y, MF_Bluefont.textflags|TEXT_XOFFSETZERO|TEXT_CONSTWIDTHNUMS, 0, 0, xdim-1, ydim-1);
5618 terminx 1318
 
1319
        if (ud.player_skill > 3 || ((g_netServer || ud.multimode > 1) && !GTFLAGS(GAMETYPE_PLAYERSFRIENDLY)))
1320
            Bsprintf(tempbuf, "K:^15%d", (ud.multimode>1 &&!GTFLAGS(GAMETYPE_PLAYERSFRIENDLY)) ?
1321
                myps->frag-myps->fraggedself : myps->actors_killed);
1322
        else
1323
        {
1324
            if (myps->actors_killed >= myps->max_actors_killed)
7011 terminx 1325
                Bsprintf(tempbuf, "K:%d/%d", myps->actors_killed, myps->actors_killed);
5618 terminx 1326
            else
7011 terminx 1327
                Bsprintf(tempbuf, "K:^15%d/%d", myps->actors_killed, myps->max_actors_killed);
5618 terminx 1328
        }
8653 hendricks2 1329
        G_ScreenText(MF_Bluefont.tilenum, 2<<16, i-gtextsc(14<<16), gtextsc(MF_Bluefont.zoom), 0, 0, tempbuf, 0, 10, 2|8|16|256, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, xbetween, MF_Bluefont.between.y, MF_Bluefont.textflags|TEXT_XOFFSETZERO|TEXT_CONSTWIDTHNUMS, 0, 0, xdim-1, ydim-1);
5618 terminx 1330
 
1331
        if (myps->secret_rooms == myps->max_secret_rooms)
1332
            Bsprintf(tempbuf, "S:%d/%d", myps->secret_rooms, myps->max_secret_rooms);
1333
        else Bsprintf(tempbuf, "S:^15%d/%d", myps->secret_rooms, myps->max_secret_rooms);
8653 hendricks2 1334
        G_ScreenText(MF_Bluefont.tilenum, 2<<16, i-gtextsc(7<<16), gtextsc(MF_Bluefont.zoom), 0, 0, tempbuf, 0, 10, 2|8|16|256, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, xbetween, MF_Bluefont.between.y, MF_Bluefont.textflags|TEXT_XOFFSETZERO|TEXT_CONSTWIDTHNUMS, 0, 0, xdim-1, ydim-1);
5618 terminx 1335
    }
1336
 
1337
    if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
1338
    {
1339
        Bsprintf(tempbuf, "%s^00 has called a vote for map", g_player[voting].user_name);
6210 hendricks2 1340
        gametext_center(40, tempbuf);
5835 terminx 1341
        Bsprintf(tempbuf, "%s (E%dL%d)", g_mapInfo[vote_episode*MAXLEVELS + vote_map].name, vote_episode+1, vote_map+1);
6210 hendricks2 1342
        gametext_center(48, tempbuf);
1343
        gametext_center(70, "Press F1 to Accept, F2 to Decline");
5618 terminx 1344
    }
1345
 
1346
    if (BUTTON(gamefunc_Show_DukeMatch_Scores))
1347
        G_ShowScores();
1348
 
1349
    if (g_Debug)
1350
        G_ShowCacheLocks();
1351
 
1352
#ifdef LUNATIC
1353
    El_DisplayErrors();
1354
#endif
1355
 
1356
#ifndef EDUKE32_TOUCH_DEVICES
1357
    if (VOLUMEONE)
1358
    {
1359
        if (ud.show_help == 0 && g_showShareware > 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
1360
            rotatesprite_fs((320-50)<<16, 9<<16, 65536L, 0, BETAVERSION, 0, 0, 2+8+16+128);
1361
    }
1362
#endif
1363
 
1364
    if (!Demo_IsProfiling())
1365
    {
1366
        if (g_player[myconnectindex].ps->gm&MODE_TYPE)
1367
            Net_SendMessage();
1368
        else
1369
            M_DisplayMenus();
1370
    }
1371
 
1372
    {
1373
        static int32_t applied = 0;
1374
 
1375
        if (tint.maxf)
1376
        {
1377
            G_FadePalaccum(&tint);
1378
            applied = 1;
1379
        }
1380
        else if (applied)
1381
        {
1382
            // be sure to always un-apply a tint.
6829 terminx 1383
            videoFadePalette(0, 0, 0, 0);
5618 terminx 1384
            applied = 0;
1385
        }
1386
    }
6512 hendricks2 1387
 
1388
    VM_OnEvent(EVENT_DISPLAYEND, g_player[screenpeek].ps->i, screenpeek);
5618 terminx 1389
}
1390
 
1391
void G_FadePalette(int32_t r, int32_t g, int32_t b, int32_t e)
1392
{
6556 hendricks2 1393
    if (ud.screenfade == 0)
1394
      return;
6829 terminx 1395
    videoFadePalette(r, g, b, e);
6828 terminx 1396
    videoNextPage();
5618 terminx 1397
 
8050 pogokeen 1398
    int32_t tc = (int32_t) totalclock;
5618 terminx 1399
    while (totalclock < tc + 4)
8140 terminx 1400
        gameHandleEvents();
5618 terminx 1401
}
1402
 
1403
// START and END limits are always inclusive!
1404
// STEP must evenly divide END-START, i.e. abs(end-start)%step == 0
1405
void fadepal(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step)
1406
{
6556 hendricks2 1407
    if (ud.screenfade == 0)
1408
      return;
7855 terminx 1409
 
6829 terminx 1410
    if (videoGetRenderMode() >= REND_POLYMOST)
5618 terminx 1411
    {
1412
        G_FadePalette(r, g, b, end);
1413
        return;
1414
    }
1415
 
1416
    // (end-start)/step + 1 iterations
1417
    do
1418
    {
7894 hendricks2 1419
        if (I_GeneralTrigger())
5618 terminx 1420
        {
7855 terminx 1421
            I_ClearAllInput();
6829 terminx 1422
            videoFadePalette(r, g, b, end);  // have to set to end fade value if we break!
5618 terminx 1423
            return;
1424
        }
1425
 
1426
        G_FadePalette(r, g, b, start);
1427
        start += step;
1428
    } while (start != end+step);
1429
}
1430
 
1431
// START and END limits are always inclusive!
1432
static void fadepaltile(int32_t r, int32_t g, int32_t b, int32_t start, int32_t end, int32_t step, int32_t tile)
1433
{
6556 hendricks2 1434
    if (ud.screenfade == 0)
1435
      return;
7855 terminx 1436
 
5618 terminx 1437
    // STEP must evenly divide END-START
1438
    Bassert(klabs(end-start)%step == 0);
1439
 
6828 terminx 1440
    videoClearScreen(0);
5618 terminx 1441
 
1442
    // (end-start)/step + 1 iterations
1443
    do
1444
    {
7894 hendricks2 1445
        if (I_GeneralTrigger())
5618 terminx 1446
        {
7855 terminx 1447
            I_ClearAllInput();
6829 terminx 1448
            videoFadePalette(r, g, b, end);  // have to set to end fade value if we break!
5618 terminx 1449
            return;
1450
        }
7855 terminx 1451
 
5708 hendricks2 1452
        rotatesprite_fs(160<<16, 100<<16, 65536L, 0, tile, 0, 0, 2+8+64+BGSTRETCH);
5618 terminx 1453
        G_FadePalette(r, g, b, start);
1454
        start += step;
1455
    } while (start != end+step);
1456
}
1457
 
1458
#ifdef LUNATIC
1459
int32_t g_logoFlags = 255;
1460
#endif
1461
 
1462
#ifdef __ANDROID__
1463
int inExtraScreens = 0;
1464
#endif
1465
 
7176 terminx 1466
void gameDisplayTENScreen()
5618 terminx 1467
{
7176 terminx 1468
#ifdef __ANDROID__
1469
    inExtraScreens = 1;
1470
#endif
1471
    videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
1472
    renderFlushPerms();
1473
    // g_player[myconnectindex].ps->palette = palette;
1474
    P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1);  // JBF 20040308
1475
    fadepal(0, 0, 0, 0, 252, 28);
1476
    I_ClearAllInput();
1477
    totalclock = 0;
1478
    rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, TENSCREEN, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1479
    fadepaltile(0, 0, 0, 252, 0, -28, TENSCREEN);
7894 hendricks2 1480
    while (!I_GeneralTrigger() && totalclock < 2400)
8140 terminx 1481
        gameHandleEvents();
5618 terminx 1482
 
7176 terminx 1483
    fadepaltile(0, 0, 0, 0, 252, 28, TENSCREEN);
1484
    I_ClearAllInput();
1485
#ifdef __ANDROID__
1486
    inExtraScreens = 0;
1487
#endif
1488
}
5618 terminx 1489
 
7176 terminx 1490
void gameDisplaySharewareScreens()
1491
{
5618 terminx 1492
#ifdef __ANDROID__
7176 terminx 1493
    inExtraScreens = 1;
5618 terminx 1494
#endif
7176 terminx 1495
    videoSetViewableArea(0, 0, xdim - 1, ydim - 1);
1496
    renderFlushPerms();
1497
    // g_player[myconnectindex].ps->palette = palette;
1498
    P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1);  // JBF 20040308
1499
    fadepal(0, 0, 0, 0, 252, 28);
1500
    I_ClearAllInput();
1501
    rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, 3291, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1502
    fadepaltile(0, 0, 0, 252, 0, -28, 3291);
7894 hendricks2 1503
    while (!I_GeneralTrigger())
8140 terminx 1504
        gameHandleEvents();
5618 terminx 1505
 
7176 terminx 1506
    fadepaltile(0, 0, 0, 0, 252, 28, 3291);
1507
    I_ClearAllInput();
1508
    rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, 3290, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1509
    fadepaltile(0, 0, 0, 252, 0, -28, 3290);
7894 hendricks2 1510
    while (!I_GeneralTrigger())
8140 terminx 1511
        gameHandleEvents();
5618 terminx 1512
 
1513
#ifdef __ANDROID__
7176 terminx 1514
    inExtraScreens = 0;
5618 terminx 1515
#endif
7176 terminx 1516
}
1517
 
1518
void G_DisplayExtraScreens(void)
1519
{
1520
    S_StopMusic();
1521
    FX_StopAllSounds();
1522
 
1523
    if (!DUKEBETA && (!VOLUMEALL || G_GetLogoFlags() & LOGO_SHAREWARESCREENS))
1524
        gameDisplaySharewareScreens();
1525
 
1526
    if (G_GetLogoFlags() & LOGO_TENSCREEN)
1527
        gameDisplayTENScreen();
1528
}
1529
 
1530
void gameDisplay3DRScreen()
1531
{
7894 hendricks2 1532
    if (!I_GeneralTrigger() && g_noLogoAnim == 0)
7176 terminx 1533
    {
7359 hendricks2 1534
        buildvfs_kfd i;
7176 terminx 1535
        Net_GetPackets();
1536
 
1537
        i = kopen4loadfrommod("3dr.ivf", 0);
1538
 
7359 hendricks2 1539
        if (i == buildvfs_kfd_invalid)
7176 terminx 1540
            i = kopen4loadfrommod("3dr.anm", 0);
1541
 
7359 hendricks2 1542
        if (i != buildvfs_kfd_invalid)
7176 terminx 1543
        {
1544
            kclose(i);
1545
            Anim_Play("3dr.anm");
1546
            G_FadePalette(0, 0, 0, 252);
1547
            I_ClearAllInput();
1548
        }
1549
        else
1550
        {
1551
            videoClearScreen(0);
1552
 
1553
            P_SetGamePalette(g_player[myconnectindex].ps, DREALMSPAL, 8 + 2 + 1);  // JBF 20040308
1554
            fadepal(0, 0, 0, 0, 252, 28);
1555
            renderFlushPerms();
1556
            rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1557
            videoNextPage();
1558
            fadepaltile(0, 0, 0, 252, 0, -28, DREALMS);
1559
            totalclock = 0;
1560
 
7894 hendricks2 1561
            while (totalclock < (120 * 7) && !I_GeneralTrigger())
7176 terminx 1562
            {
8716 terminx 1563
                if (engineFPSLimit())
7176 terminx 1564
                {
1565
                    videoClearScreen(0);
1566
                    rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, DREALMS, 0, 0, 2 + 8 + 64 + BGSTRETCH);
8140 terminx 1567
                    gameHandleEvents();
7176 terminx 1568
 
1569
                    if (g_restorePalette)
1570
                    {
1571
                        P_SetGamePalette(g_player[myconnectindex].ps, g_player[myconnectindex].ps->palette, 0);
1572
                        g_restorePalette = 0;
1573
                    }
7730 pogokeen 1574
                    videoNextPage();
7176 terminx 1575
                }
1576
            }
1577
 
1578
            fadepaltile(0, 0, 0, 0, 252, 28, DREALMS);
1579
        }
5618 terminx 1580
    }
7176 terminx 1581
}
5618 terminx 1582
 
7176 terminx 1583
void gameDisplayTitleScreen(void)
1584
{
1585
    int titlesound  = 0;
1586
    int32_t const logoflags = G_GetLogoFlags();
1587
 
1588
    videoClearScreen(0);
1589
 
1590
    // g_player[myconnectindex].ps->palette = titlepal;
1591
    P_SetGamePalette(g_player[myconnectindex].ps, TITLEPAL, 8 + 2 + 1);  // JBF 20040308
1592
    renderFlushPerms();
1593
    rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, BETASCREEN, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1594
    KB_FlushKeyboardQueue();
1595
    fadepaltile(0, 0, 0, 252, 0, -28, BETASCREEN);
1596
    totalclock = 0;
1597
 
1598
    while (
8569 terminx 1599
#ifndef EDUKE32_RETAIL_MENU
7176 terminx 1600
    totalclock < (860 + 120) &&
1601
#endif
7894 hendricks2 1602
    !I_GeneralTrigger())
5618 terminx 1603
    {
8716 terminx 1604
        if (engineFPSLimit())
7176 terminx 1605
        {
1606
            videoClearScreen(0);
1607
            rotatesprite_fs(160 << 16, 100 << 16, 65536L, 0, BETASCREEN, 0, 0, 2 + 8 + 64 + BGSTRETCH);
1608
            if (logoflags & LOGO_DUKENUKEM)
1609
            {
1610
                if (totalclock > 120 && totalclock < (120 + 60))
1611
                {
1612
                    if (titlesound == 0)
1613
                    {
1614
                        titlesound++;
1615
                        S_PlaySound(PIPEBOMB_EXPLODE);
1616
                    }
8050 pogokeen 1617
                    rotatesprite_fs(160 << 16, 104 << 16, ((int32_t) totalclock - 120) << 10, 0, DUKENUKEM, 0, 0, 2 + 8);
7176 terminx 1618
                }
1619
                else if (totalclock >= (120 + 60))
1620
                    rotatesprite_fs(160 << 16, (104) << 16, 60 << 10, 0, DUKENUKEM, 0, 0, 2 + 8);
1621
            }
1622
            else
1623
                titlesound++;
1624
 
1625
            if (logoflags & LOGO_THREEDEE)
1626
            {
1627
                if (totalclock > 220 && totalclock < (220 + 30))
1628
                {
1629
                    if (titlesound == 1)
1630
                    {
1631
                        titlesound++;
1632
                        S_PlaySound(PIPEBOMB_EXPLODE);
1633
                    }
1634
 
1635
                    rotatesprite_fs(160 << 16, (104) << 16, 60 << 10, 0, DUKENUKEM, 0, 0, 2 + 8);
8050 pogokeen 1636
                    rotatesprite_fs(160 << 16, (129) << 16, ((int32_t) totalclock - 220) << 11, 0, THREEDEE, 0, 0, 2 + 8);
7176 terminx 1637
                }
1638
                else if (totalclock >= (220 + 30))
1639
                    rotatesprite_fs(160 << 16, (129) << 16, 30 << 11, 0, THREEDEE, 0, 0, 2 + 8);
1640
            }
1641
            else
1642
                titlesound++;
1643
 
1644
            if (PLUTOPAK && (logoflags & LOGO_PLUTOPAKSPRITE))
1645
            {
1646
                // JBF 20030804
1647
                if (totalclock >= 280 && totalclock < 395)
1648
                {
8050 pogokeen 1649
                    rotatesprite_fs(160 << 16, (151) << 16, (410 - (int32_t) totalclock) << 12, 0, PLUTOPAKSPRITE + 1,
1650
                                    (sintable[((int32_t) totalclock << 4) & 2047] >> 11), 0, 2 + 8);
7176 terminx 1651
                    if (titlesound == 2)
1652
                    {
1653
                        titlesound++;
1654
                        S_PlaySound(FLY_BY);
1655
                    }
1656
                }
1657
                else if (totalclock >= 395)
1658
                {
1659
                    if (titlesound == 3)
1660
                    {
1661
                        titlesound++;
1662
                        S_PlaySound(PIPEBOMB_EXPLODE);
1663
                    }
8050 pogokeen 1664
                    rotatesprite_fs(160 << 16, (151) << 16, 30 << 11, 0, PLUTOPAKSPRITE + 1, (sintable[((int32_t) totalclock << 4) & 2047] >> 11), 0,
7176 terminx 1665
                                    2 + 8);
1666
                }
1667
            }
1668
 
1669
#ifdef LUNATIC
1670
            g_elEventError = 0;
5618 terminx 1671
#endif
7176 terminx 1672
            VM_OnEvent(EVENT_LOGO, -1, screenpeek);
5618 terminx 1673
 
7176 terminx 1674
            if (g_restorePalette)
1675
            {
1676
                P_SetGamePalette(g_player[myconnectindex].ps, g_player[myconnectindex].ps->palette, 0);
1677
                g_restorePalette = 0;
1678
            }
7730 pogokeen 1679
 
1680
            videoNextPage();
1681
 
7176 terminx 1682
#ifdef LUNATIC
1683
            if (g_elEventError)
1684
                break;
5618 terminx 1685
#endif
7176 terminx 1686
        }
1687
 
8140 terminx 1688
        gameHandleEvents();
5618 terminx 1689
    }
1690
}
1691
 
1692
void G_DisplayLogo(void)
1693
{
7176 terminx 1694
    int32_t const logoflags = G_GetLogoFlags();
5618 terminx 1695
 
1696
    ready2send = 0;
1697
 
1698
    I_ClearAllInput();
1699
 
6828 terminx 1700
    videoSetViewableArea(0, 0, xdim-1, ydim-1);
1701
    videoClearScreen(0L);
5618 terminx 1702
    G_FadePalette(0, 0, 0, 252);
1703
 
6832 terminx 1704
    renderFlushPerms();
6828 terminx 1705
    videoNextPage();
5618 terminx 1706
 
1707
    G_UpdateAppTitle();
1708
 
1709
    S_StopMusic();
1710
    FX_StopAllSounds(); // JBF 20031228
1711
    S_ClearSoundLocks();  // JBF 20031228
7176 terminx 1712
 
6584 hendricks2 1713
    if (!g_noLogo /* && (!g_netServer && ud.multimode < 2) */ &&
1714
        VM_OnEventWithReturn(EVENT_MAINMENUSCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0) == 0 &&
1715
        (logoflags & LOGO_ENABLED))
5618 terminx 1716
    {
1717
        if (
1718
#ifndef EDUKE32_TOUCH_DEVICES
1719
            VOLUMEALL &&
1720
#endif
1721
            (logoflags & LOGO_PLAYANIM))
1722
        {
7894 hendricks2 1723
            if (!I_GeneralTrigger() && g_noLogoAnim == 0)
5618 terminx 1724
            {
1725
                Net_GetPackets();
1726
                Anim_Play("logo.anm");
1727
                G_FadePalette(0, 0, 0, 252);
1728
                I_ClearAllInput();
1729
            }
1730
 
6828 terminx 1731
            videoClearScreen(0L);
1732
            videoNextPage();
5618 terminx 1733
 
1734
            if (logoflags & LOGO_STOPANIMSOUNDS)
1735
            {
1736
                FX_StopAllSounds();
1737
                S_ClearSoundLocks();
1738
            }
1739
        }
1740
 
1741
        if (logoflags & LOGO_PLAYMUSIC)
6619 hendricks2 1742
            S_PlaySpecialMusicOrNothing(MUS_INTRO);
5618 terminx 1743
 
1744
        if (!NAM)
1745
        {
1746
            //g_player[myconnectindex].ps->palette = drealms;
1747
            //G_FadePalette(0,0,0,252);
1748
 
1749
            if (logoflags & LOGO_3DRSCREEN)
1750
            {
7176 terminx 1751
                gameDisplay3DRScreen();
5618 terminx 1752
 
6828 terminx 1753
                videoClearScreen(0L);
1754
                videoNextPage();
5618 terminx 1755
            }
1756
 
1757
            I_ClearAllInput();
1758
        }
1759
 
6828 terminx 1760
        videoClearScreen(0L);
1761
        videoNextPage();
5618 terminx 1762
 
1763
        if (logoflags & LOGO_TITLESCREEN)
7176 terminx 1764
            gameDisplayTitleScreen();
5618 terminx 1765
 
1766
        I_ClearAllInput();
1767
    }
1768
 
6832 terminx 1769
    renderFlushPerms();
6828 terminx 1770
    videoClearScreen(0L);
1771
    videoNextPage();
5618 terminx 1772
 
7176 terminx 1773
    P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0);
1774
 
6555 hendricks2 1775
    if ((G_GetLogoFlags() & LOGO_STOPMISCSOUNDS) == 0)
1776
        S_PlaySound(NITEVISION_ONOFF);
5618 terminx 1777
 
1778
    //G_FadePalette(0,0,0,0);
6828 terminx 1779
    videoClearScreen(0L);
5618 terminx 1780
}
1781
 
6271 terminx 1782
#ifndef EDUKE32_STANDALONE
5618 terminx 1783
void G_DoOrderScreen(void)
1784
{
6828 terminx 1785
    videoSetViewableArea(0, 0, xdim-1, ydim-1);
5618 terminx 1786
    P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 1);    // JBF 20040308
1787
 
7176 terminx 1788
    for (int i=0; i<4; i++)
5618 terminx 1789
    {
1790
        fadepal(0, 0, 0, 0, 252, 28);
1791
        I_ClearAllInput();
1792
        rotatesprite_fs(160<<16, 100<<16, 65536L, 0, ORDERING+i, 0, 0, 2+8+64+BGSTRETCH);
1793
        fadepal(0, 0, 0, 252, 0, -28);
1794
        while (!I_CheckAllInput())
8140 terminx 1795
            gameHandleEvents();
5618 terminx 1796
    }
1797
 
1798
    I_ClearAllInput();
1799
}
1800
 
1801
 
1802
static void G_BonusCutscenes(void)
1803
{
1804
    if (!(numplayers < 2 && ud.eog && ud.from_bonus == 0))
1805
        return;
1806
 
1807
    switch (ud.volume_number)
1808
    {
1809
    case 0:
1810
        if ((G_GetLogoFlags() & LOGO_NOE1BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN))
1811
            return;
1812
 
1813
        if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE1BONUSSCENE))
1814
        {
7176 terminx 1815
            int bonuscnt=0;
1816
            int const bossmove [] =
5668 terminx 1817
            {
1818
                0, 120, VICTORY1+3, 86, 59,
1819
                220, 260, VICTORY1+4, 86, 59,
1820
                260, 290, VICTORY1+5, 86, 59,
1821
                290, 320, VICTORY1+6, 86, 59,
1822
                320, 350, VICTORY1+7, 86, 59,
1823
                350, 380, VICTORY1+8, 86, 59,
1824
                350, 380, VICTORY1+8, 86, 59 // duplicate row to alleviate overflow in the for loop below "boss"
1825
            };
1826
 
5618 terminx 1827
            P_SetGamePalette(g_player[myconnectindex].ps, ENDINGPAL, 8+2+1); // JBF 20040308
6828 terminx 1828
            videoClearScreen(0L);
5618 terminx 1829
            rotatesprite_fs(0, 50<<16, 65536L, 0, VICTORY1, 0, 0, 2+8+16+64+128+BGSTRETCH);
6828 terminx 1830
            videoNextPage();
5618 terminx 1831
            fadepal(0, 0, 0, 252, 0, -4);
1832
 
1833
            I_ClearAllInput();
1834
            totalclock = 0;
1835
 
7176 terminx 1836
            do
5618 terminx 1837
            {
8716 terminx 1838
                if (engineFPSLimit())
6237 terminx 1839
                {
6828 terminx 1840
                    videoClearScreen(0L);
6237 terminx 1841
                    rotatesprite_fs(0, 50<<16, 65536L, 0, VICTORY1, 0, 0, 2+8+16+64+128+BGSTRETCH);
5618 terminx 1842
 
6237 terminx 1843
                    // boss
1844
                    if (totalclock > 390 && totalclock < 780)
1845
                        for (bssize_t t=0; t<35; t+=5) if (bossmove[t+2] && (totalclock%390) > bossmove[t] && (totalclock%390) <= bossmove[t+1])
5618 terminx 1846
                        {
6237 terminx 1847
                            if (t==10 && bonuscnt == 1)
1848
                            {
1849
                                S_PlaySound(SHOTGUN_FIRE);
1850
                                S_PlaySound(SQUISHED);
1851
                                bonuscnt++;
1852
                            }
1853
                            rotatesprite_fs(bossmove[t+3]<<16, bossmove[t+4]<<16, 65536L, 0, bossmove[t+2], 0, 0, 2+8+16+64+128+BGSTRETCH);
5618 terminx 1854
                        }
1855
 
6237 terminx 1856
                    // Breathe
1857
                    if (totalclock < 450 || totalclock >= 750)
5668 terminx 1858
                    {
6237 terminx 1859
                        int32_t const breathe [] =
5618 terminx 1860
                        {
6237 terminx 1861
                            0,  30, VICTORY1+1, 176, 59,
1862
                            30,  60, VICTORY1+2, 176, 59,
1863
                            60,  90, VICTORY1+1, 176, 59,
1864
                            90, 120,          0, 176, 59
1865
                        };
5618 terminx 1866
 
6237 terminx 1867
                        if (totalclock >= 750)
5618 terminx 1868
                        {
6237 terminx 1869
                            rotatesprite_fs(86<<16, 59<<16, 65536L, 0, VICTORY1+8, 0, 0, 2+8+16+64+128+BGSTRETCH);
1870
                            if (totalclock >= 750 && bonuscnt == 2)
5618 terminx 1871
                            {
6237 terminx 1872
                                S_PlaySound(DUKETALKTOBOSS);
5618 terminx 1873
                                bonuscnt++;
1874
                            }
6237 terminx 1875
 
5618 terminx 1876
                        }
6237 terminx 1877
                        for (bssize_t t=0; t<20; t+=5)
1878
                            if (breathe[t+2] && (totalclock%120) > breathe[t] && (totalclock%120) <= breathe[t+1])
1879
                            {
1880
                                if (t==5 && bonuscnt == 0)
1881
                                {
1882
                                    S_PlaySound(BOSSTALKTODUKE);
1883
                                    bonuscnt++;
1884
                                }
1885
                                rotatesprite_fs(breathe[t+3]<<16, breathe[t+4]<<16, 65536L, 0, breathe[t+2], 0, 0, 2+8+16+64+128+BGSTRETCH);
1886
                            }
1887
                    }
7730 pogokeen 1888
                    videoNextPage();
5618 terminx 1889
                }
1890
 
8140 terminx 1891
                gameHandleEvents();
5618 terminx 1892
 
7894 hendricks2 1893
                if (I_GeneralTrigger()) break;
7176 terminx 1894
            } while (1);
5618 terminx 1895
 
1896
            fadepal(0, 0, 0, 0, 252, 4);
1897
        }
1898
 
1899
        if (G_GetLogoFlags() & LOGO_NOE1ENDSCREEN)
1900
            goto VOL1_END;
1901
 
1902
        I_ClearAllInput();
1903
        P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1);   // JBF 20040308
1904
 
1905
        rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3292, 0, 0, 2+8+64+BGSTRETCH);
1906
        fadepal(0, 0, 0, 252, 0, -4);
1907
        G_HandleEventsWhileNoInput();
1908
        fadepal(0, 0, 0, 0, 252, 4);
1909
 
1910
    VOL1_END:
1911
        S_StopMusic();
1912
        FX_StopAllSounds();
1913
        S_ClearSoundLocks();
1914
        break;
1915
 
1916
    case 1:
1917
        if ((G_GetLogoFlags() & LOGO_NOE2BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN))
1918
            return;
1919
 
6828 terminx 1920
        videoSetViewableArea(0, 0, xdim-1, ydim-1);
5618 terminx 1921
 
1922
        S_StopMusic();
6828 terminx 1923
        videoClearScreen(0L);
1924
        videoNextPage();
5618 terminx 1925
 
1926
        if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE2BONUSSCENE))
1927
        {
1928
            fadepal(0, 0, 0, 252, 0, -4);
1929
            Anim_Play("cineov2.anm");
1930
            I_ClearAllInput();
6828 terminx 1931
            videoClearScreen(0L);
1932
            videoNextPage();
5618 terminx 1933
 
1934
            S_PlaySound(PIPEBOMB_EXPLODE);
1935
            fadepal(0, 0, 0, 0, 252, 4);
1936
        }
1937
 
1938
        if (G_GetLogoFlags() & LOGO_NOE2ENDSCREEN)
1939
            return;
1940
 
1941
        I_ClearAllInput();
1942
        P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1);   // JBF 20040308
1943
        rotatesprite_fs(160<<16, 100<<16, 65536L, 0, 3293, 0, 0, 2+8+64+BGSTRETCH);
1944
        fadepal(0, 0, 0, 252, 0, -4);
1945
        G_HandleEventsWhileNoInput();
1946
        fadepal(0, 0, 0, 0, 252, 4);
1947
 
1948
        break;
1949
 
1950
    case 3:
1951
        if ((G_GetLogoFlags() & LOGO_NOE4BONUSSCENE) && (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))
1952
            return;
1953
 
6828 terminx 1954
        videoSetViewableArea(0, 0, xdim-1, ydim-1);
5618 terminx 1955
 
1956
        S_StopMusic();
6828 terminx 1957
        videoClearScreen(0L);
1958
        videoNextPage();
5618 terminx 1959
 
1960
        if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE4BONUSSCENE))
1961
        {
1962
            fadepal(0, 0, 0, 252, 0, -4);
1963
 
1964
            I_ClearAllInput();
5668 terminx 1965
            int t = Anim_Play("vol4e1.anm");
6828 terminx 1966
            videoClearScreen(0L);
1967
            videoNextPage();
5618 terminx 1968
            if (t)
1969
                goto end_vol4e;
1970
 
1971
            t = Anim_Play("vol4e2.anm");
6828 terminx 1972
            videoClearScreen(0L);
1973
            videoNextPage();
5618 terminx 1974
            if (t)
1975
                goto end_vol4e;
1976
 
1977
            Anim_Play("vol4e3.anm");
6828 terminx 1978
            videoClearScreen(0L);
1979
            videoNextPage();
5618 terminx 1980
        }
1981
 
1982
    end_vol4e:
1983
        if ((G_GetLogoFlags() & LOGO_NODUKETEAMTEXT) && (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))
1984
            goto VOL4_END;
1985
 
1986
        FX_StopAllSounds();
1987
        S_ClearSoundLocks();
1988
        S_PlaySound(ENDSEQVOL3SND4);
1989
        I_ClearAllInput();
1990
 
1991
        if (G_GetLogoFlags() & LOGO_NODUKETEAMTEXT)
1992
            goto VOL4_DUKETEAM;
1993
 
1994
        G_FadePalette(0, 0, 0, 0);
1995
        P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1);   // JBF 20040308
1996
                                                                         //        G_FadePalette(0,0,0,252);
6828 terminx 1997
        videoClearScreen(0L);
6208 hendricks2 1998
        menutext_center(60, "Thanks to all our");
1999
        menutext_center(60+16, "fans for giving");
2000
        menutext_center(60+16+16, "us big heads.");
2001
        menutext_center(70+16+16+16, "Look for a Duke Nukem 3D");
2002
        menutext_center(70+16+16+16+16, "sequel soon.");
6828 terminx 2003
        videoNextPage();
5618 terminx 2004
 
2005
        fadepal(0, 0, 0, 252, 0, -12);
6828 terminx 2006
        videoNextPage();
5618 terminx 2007
        I_ClearAllInput();
2008
        G_HandleEventsWhileNoInput();
2009
        fadepal(0, 0, 0, 0, 252, 12);
2010
 
2011
        if (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)
2012
            goto VOL4_END;
2013
 
2014
    VOL4_DUKETEAM:
6828 terminx 2015
        videoClearScreen(0L);
2016
        videoNextPage();
5618 terminx 2017
 
2018
        Anim_Play("DUKETEAM.ANM");
2019
 
2020
        I_ClearAllInput();
2021
        G_HandleEventsWhileNoInput();
2022
 
6828 terminx 2023
        videoClearScreen(0L);
2024
        videoNextPage();
5618 terminx 2025
        G_FadePalette(0, 0, 0, 252);
2026
 
2027
    VOL4_END:
2028
        FX_StopAllSounds();
2029
        S_ClearSoundLocks();
2030
        I_ClearAllInput();
2031
 
2032
        break;
2033
 
2034
    case 2:
2035
        if ((G_GetLogoFlags() & LOGO_NOE3BONUSSCENE) && (G_GetLogoFlags() & LOGO_NOE3RADLOGO) && (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC)))
2036
            return;
2037
 
2038
        S_StopMusic();
6828 terminx 2039
        videoClearScreen(0L);
2040
        videoNextPage();
5618 terminx 2041
        if (ud.lockout == 0 && !(G_GetLogoFlags() & LOGO_NOE3BONUSSCENE))
2042
        {
2043
            fadepal(0, 0, 0, 252, 0, -4);
2044
            Anim_Play("cineov3.anm");
2045
            I_ClearAllInput();
2046
            ototalclock = totalclock+200;
2047
            while (totalclock < ototalclock)
8140 terminx 2048
                gameHandleEvents();
6828 terminx 2049
            videoClearScreen(0L);
2050
            videoNextPage();
5618 terminx 2051
 
2052
            FX_StopAllSounds();
2053
            S_ClearSoundLocks();
2054
        }
2055
 
2056
        if (G_GetLogoFlags() & LOGO_NOE3RADLOGO)
2057
            goto ENDANM;
2058
 
2059
        Anim_Play("RADLOGO.ANM");
2060
 
7894 hendricks2 2061
        if (ud.lockout == 0 && !I_GeneralTrigger())
5618 terminx 2062
        {
2063
            if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND5)) goto ENDANM;
2064
            if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND6)) goto ENDANM;
2065
            if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND7)) goto ENDANM;
2066
            if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND8)) goto ENDANM;
2067
            if (G_PlaySoundWhileNoInput(ENDSEQVOL3SND9)) goto ENDANM;
2068
        }
2069
 
2070
        I_ClearAllInput();
2071
 
2072
        totalclock = 0;
2073
        if (PLUTOPAK || (G_GetLogoFlags() & LOGO_NODUKETEAMPIC))
2074
        {
7894 hendricks2 2075
            while (totalclock < 120 && !I_GeneralTrigger())
8140 terminx 2076
                gameHandleEvents();
5618 terminx 2077
 
2078
            I_ClearAllInput();
2079
        }
2080
        else
2081
        {
2082
            G_HandleEventsWhileNoInput();
2083
        }
2084
 
2085
    ENDANM:
2086
        if (!PLUTOPAK && !(G_GetLogoFlags() & LOGO_NODUKETEAMPIC))
2087
        {
2088
            FX_StopAllSounds();
2089
            S_ClearSoundLocks();
2090
            S_PlaySound(ENDSEQVOL3SND4);
2091
 
6828 terminx 2092
            videoClearScreen(0L);
2093
            videoNextPage();
5618 terminx 2094
 
2095
            Anim_Play("DUKETEAM.ANM");
2096
 
2097
            I_ClearAllInput();
2098
            G_HandleEventsWhileNoInput();
2099
 
6828 terminx 2100
            videoClearScreen(0L);
2101
            videoNextPage();
5618 terminx 2102
            G_FadePalette(0, 0, 0, 252);
2103
        }
2104
 
2105
        I_ClearAllInput();
2106
        FX_StopAllSounds();
2107
        S_ClearSoundLocks();
2108
 
6828 terminx 2109
        videoClearScreen(0L);
5618 terminx 2110
 
2111
        break;
8790 hendricks2 2112
 
2113
    case 4:
2114
        if (!WORLDTOUR)
2115
            return;
2116
 
2117
        if (ud.lockout == 0)
2118
        {
2119
            S_StopMusic();
2120
            totalclocklock = totalclock = 0;
2121
 
2122
            videoClearScreen(0L);
2123
            rotatesprite_fs(160<<16, 100<<16, 65536L, 0, FIREFLYGROWEFFECT, 0, 0, 2+8+64+BGSTRETCH);
2124
            videoNextPage();
2125
 
2126
            fadepal(0, 0, 0, 252, 0, -4);
2127
 
2128
            I_ClearAllInput();
2129
 
2130
            S_PlaySound(E5L7_DUKE_QUIT_YOU);
2131
 
2132
            do
2133
            {
2134
                if (engineFPSLimit())
2135
                {
2136
                    totalclocklock = totalclock;
2137
 
2138
                    videoClearScreen(0L);
2139
                    rotatesprite_fs(160<<16, 100<<16, 65536L, 0, FIREFLYGROWEFFECT, 0, 0, 2+8+64+BGSTRETCH);
2140
                    videoNextPage();
2141
                }
2142
 
2143
                gameHandleEvents();
2144
 
2145
                if (I_GeneralTrigger()) break;
2146
            } while (1);
2147
 
2148
            fadepal(0, 0, 0, 0, 252, 4);
2149
        }
2150
 
2151
        S_StopMusic();
2152
        FX_StopAllSounds();
2153
        S_ClearSoundLocks();
2154
        break;
5618 terminx 2155
    }
2156
}
6271 terminx 2157
#endif
5618 terminx 2158
 
2159
static void G_DisplayMPResultsScreen(void)
2160
{
2161
    int32_t i, y, t = 0;
2162
 
2163
    rotatesprite_fs(160<<16, 100<<16, 65536L, 0, MENUSCREEN, 16, 0, 2+8+64+BGSTRETCH);
2164
    rotatesprite_fs(160<<16, 34<<16, 65536L, 0, INGAMEDUKETHREEDEE, 0, 0, 10);
2165
    if (PLUTOPAK)   // JBF 20030804
2166
        rotatesprite_fs((260)<<16, 36<<16, 65536L, 0, PLUTOPAKSPRITE+2, 0, 0, 2+8);
6210 hendricks2 2167
    gametext_center(58+2, "Multiplayer Totals");
2168
    gametext_center(58+10, g_mapInfo[G_LastMapInfoIndex()].name);
5618 terminx 2169
 
6210 hendricks2 2170
    gametext_center_shade(165, "Press any key or button to continue", quotepulseshade);
5618 terminx 2171
 
6562 hendricks2 2172
    minitext(38, 80, "Name", 8, 2+8+16+128);
2173
    minitext(269, 80, "Kills", 8, 2+8+16+128);
5835 terminx 2174
    for (i=0; i<g_mostConcurrentPlayers; i++)
5618 terminx 2175
    {
2176
        Bsprintf(tempbuf, "%-4d", i+1);
2177
        minitext(92+(i*23), 80, tempbuf, 3, 2+8+16+128);
2178
    }
2179
 
5835 terminx 2180
    for (i=0; i<g_mostConcurrentPlayers; i++)
5618 terminx 2181
    {
2182
        int32_t xfragtotal = 0;
2183
        Bsprintf(tempbuf, "%d", i+1);
2184
 
2185
        minitext(30, 90+t, tempbuf, 0, 2+8+16+128);
2186
        minitext(38, 90+t, g_player[i].user_name, g_player[i].ps->palookup, 2+8+16+128);
2187
 
5835 terminx 2188
        for (y=0; y<g_mostConcurrentPlayers; y++)
5618 terminx 2189
        {
2190
            if (i == y)
2191
            {
2192
                Bsprintf(tempbuf, "%-4d", g_player[y].ps->fraggedself);
2193
                minitext(92+(y*23), 90+t, tempbuf, 2, 2+8+16+128);
2194
                xfragtotal -= g_player[y].ps->fraggedself;
2195
            }
2196
            else
2197
            {
2198
                Bsprintf(tempbuf, "%-4d", g_player[i].frags[y]);
2199
                minitext(92+(y*23), 90+t, tempbuf, 0, 2+8+16+128);
2200
                xfragtotal += g_player[i].frags[y];
2201
            }
2202
        }
2203
 
2204
        Bsprintf(tempbuf, "%-4d", xfragtotal);
2205
        minitext(101+(8*23), 90+t, tempbuf, 2, 2+8+16+128);
2206
 
2207
        t += 7;
2208
    }
2209
 
5835 terminx 2210
    for (y=0; y<g_mostConcurrentPlayers; y++)
5618 terminx 2211
    {
2212
        int32_t yfragtotal = 0;
5835 terminx 2213
        for (i=0; i<g_mostConcurrentPlayers; i++)
5618 terminx 2214
        {
2215
            if (i == y)
2216
                yfragtotal += g_player[i].ps->fraggedself;
6562 hendricks2 2217
            else
2218
                yfragtotal += g_player[i].frags[y];
5618 terminx 2219
        }
2220
        Bsprintf(tempbuf, "%-4d", yfragtotal);
2221
        minitext(92+(y*23), 96+(8*7), tempbuf, 2, 2+8+16+128);
2222
    }
2223
 
2224
    minitext(45, 96+(8*7), "Deaths", 8, 2+8+16+128);
2225
}
2226
 
2227
static int32_t G_PrintTime_ClockPad(void)
2228
{
2229
    int32_t clockpad = 2;
2230
    int32_t ii, ij;
2231
 
5635 hendricks2 2232
    for (ii=g_player[myconnectindex].ps->player_par/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { }
5618 terminx 2233
    clockpad = max(clockpad, ij);
2234
    if (!(ud.volume_number == 0 && ud.last_level-1 == 7 && boardfilename[0]))
2235
    {
5835 terminx 2236
        for (ii=g_mapInfo[G_LastMapInfoIndex()].partime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { }
5618 terminx 2237
        clockpad = max(clockpad, ij);
5835 terminx 2238
        if (!NAM_WW2GI && g_mapInfo[G_LastMapInfoIndex()].designertime)
5618 terminx 2239
        {
5835 terminx 2240
            for (ii=g_mapInfo[G_LastMapInfoIndex()].designertime/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { }
5618 terminx 2241
            clockpad = max(clockpad, ij);
2242
        }
2243
    }
5635 hendricks2 2244
    if (ud.playerbest > 0) for (ii=ud.playerbest/(REALGAMETICSPERSEC*60), ij=1; ii>9; ii/=10, ij++) { }
5618 terminx 2245
    clockpad = max(clockpad, ij);
2246
 
2247
    return clockpad;
2248
}
2249
 
2250
static const char* G_PrintTime2(int32_t time)
2251
{
2252
    Bsprintf(tempbuf, "%0*d:%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60);
2253
    return tempbuf;
2254
}
2255
static const char* G_PrintTime3(int32_t time)
2256
{
2257
    Bsprintf(tempbuf, "%0*d:%02d.%02d", G_PrintTime_ClockPad(), time/(REALGAMETICSPERSEC*60), (time/REALGAMETICSPERSEC)%60, ((time%REALGAMETICSPERSEC)*33)/10);
2258
    return tempbuf;
2259
}
2260
 
2261
const char* G_PrintYourTime(void)
2262
{
2263
    return G_PrintTime3(g_player[myconnectindex].ps->player_par);
2264
}
2265
const char* G_PrintParTime(void)
2266
{
2267
    if (ud.last_level < 1)
2268
        return "<invalid>";
5835 terminx 2269
    return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].partime);
5618 terminx 2270
}
2271
const char* G_PrintDesignerTime(void)
2272
{
2273
    if (ud.last_level < 1)
2274
        return "<invalid>";
5835 terminx 2275
    return G_PrintTime2(g_mapInfo[G_LastMapInfoIndex()].designertime);
5618 terminx 2276
}
2277
const char* G_PrintBestTime(void)
2278
{
2279
    return G_PrintTime3(ud.playerbest);
2280
}
2281
 
2282
void G_BonusScreen(int32_t bonusonly)
2283
{
2284
    int32_t gfx_offset;
2285
    int32_t bonuscnt;
2286
    int32_t clockpad = 2;
2287
    char *lastmapname;
2288
 
2289
    if (g_networkMode == NET_DEDICATED_SERVER)
2290
        return;
2291
 
2292
    G_UpdateAppTitle();
2293
 
2294
    if (ud.volume_number == 0 && ud.last_level == 8 && boardfilename[0])
2295
    {
2296
        lastmapname = Bstrrchr(boardfilename, '\\');
2297
        if (!lastmapname) lastmapname = Bstrrchr(boardfilename, '/');
2298
        if (!lastmapname) lastmapname = boardfilename;
2299
    }
2300
    else
2301
    {
5835 terminx 2302
        lastmapname = g_mapInfo[G_LastMapInfoIndex()].name;
5618 terminx 2303
        if (!lastmapname) // this isn't right but it's better than no name at all
5835 terminx 2304
            lastmapname = g_mapInfo[G_LastMapInfoIndex()].name;
5618 terminx 2305
    }
2306
 
2307
 
2308
    fadepal(0, 0, 0, 0, 252, 28);
6828 terminx 2309
    videoSetViewableArea(0, 0, xdim-1, ydim-1);
2310
    videoClearScreen(0L);
2311
    videoNextPage();
6832 terminx 2312
    renderFlushPerms();
5618 terminx 2313
 
2314
    FX_StopAllSounds();
2315
    S_ClearSoundLocks();
2316
    FX_SetReverb(0L);
2317
    CONTROL_BindsEnabled = 1; // so you can use your screenshot bind on the score screens
2318
 
6271 terminx 2319
#ifndef EDUKE32_STANDALONE
5618 terminx 2320
    if (!bonusonly)
2321
        G_BonusCutscenes();
6271 terminx 2322
#endif
5618 terminx 2323
 
2324
    P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 8+2+1);   // JBF 20040308
2325
    G_FadePalette(0, 0, 0, 252);   // JBF 20031228
2326
    KB_FlushKeyboardQueue();
2327
    totalclock = 0;
2328
    bonuscnt = 0;
2329
 
2330
    S_StopMusic();
2331
    FX_StopAllSounds();
2332
    S_ClearSoundLocks();
2333
 
5835 terminx 2334
    if (g_mostConcurrentPlayers > 1 && (g_gametypeFlags[ud.coop]&GAMETYPE_SCORESHEET))
5618 terminx 2335
    {
6828 terminx 2336
        videoClearScreen(0);
5618 terminx 2337
        G_DisplayMPResultsScreen();
2338
 
2339
        if (ud.config.MusicToggle)
2340
            S_PlaySound(BONUSMUSIC);
2341
 
6828 terminx 2342
        videoNextPage();
5618 terminx 2343
        I_ClearAllInput();
2344
        fadepal(0, 0, 0, 252, 0, -28);
2345
        totalclock = 0;
2346
 
2347
        while (totalclock < TICRATE*10)
2348
        {
8140 terminx 2349
            gameHandleEvents();
5618 terminx 2350
            MUSIC_Update();
2351
 
8716 terminx 2352
            if (engineFPSLimit())
6237 terminx 2353
            {
6828 terminx 2354
                videoClearScreen(0);
6237 terminx 2355
                G_DisplayMPResultsScreen();
7730 pogokeen 2356
                videoNextPage();
6237 terminx 2357
            }
5618 terminx 2358
 
2359
            if (I_CheckAllInput())
2360
            {
2361
                I_ClearAllInput();
2362
                break;
2363
            }
2364
        }
2365
 
2366
        fadepal(0, 0, 0, 0, 252, 28);
2367
    }
2368
 
2369
    if (bonusonly || (g_netServer || ud.multimode > 1)) return;
2370
 
2371
    gfx_offset = (ud.volume_number==1) ? 5 : 0;
2372
    rotatesprite_fs(160<<16, 100<<16, 65536L, 0, BONUSSCREEN+gfx_offset, 0, 0, 2+8+64+128+BGSTRETCH);
2373
 
2374
    if (lastmapname)
6208 hendricks2 2375
        menutext_center(20-6, lastmapname);
2376
    menutext_center(36-6, "Completed");
5618 terminx 2377
 
6210 hendricks2 2378
    gametext_center_shade(192, "Press any key or button to continue", quotepulseshade);
5618 terminx 2379
 
2380
    if (ud.config.MusicToggle)
2381
        S_PlaySound(BONUSMUSIC);