Rev 5054 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5 | Plagman | 1 | //------------------------------------------------------------------------- |
2 | /* |
||
1652 | terminx | 3 | Copyright (C) 2010 EDuke32 developers and contributors |
5 | Plagman | 4 | |
1652 | terminx | 5 | This file is part of EDuke32. |
5 | Plagman | 6 | |
7 | EDuke32 is free software; you can redistribute it and/or |
||
8 | modify it under the terms of the GNU General Public License version 2 |
||
9 | as published by the Free Software Foundation. |
||
10 | |||
11 | This program is distributed in the hope that it will be useful, |
||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
14 | |||
15 | See the GNU General Public License for more details. |
||
16 | |||
17 | You should have received a copy of the GNU General Public License |
||
18 | along with this program; if not, write to the Free Software |
||
4541 | hendricks2 | 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
5 | Plagman | 20 | */ |
21 | //------------------------------------------------------------------------- |
||
22 | |||
110 | terminx | 23 | #include "duke3d.h" |
1346 | terminx | 24 | |
3221 | hendricks2 | 25 | #include "baselayer.h" |
26 | #include "renderlayer.h" |
||
3116 | hendricks2 | 27 | |
5 | Plagman | 28 | #include "scriplib.h" |
29 | #include "file_lib.h" |
||
30 | #include "mathutil.h" |
||
31 | #include "gamedefs.h" |
||
32 | #include "keyboard.h" |
||
33 | #include "mouse.h" // JBF 20030809 |
||
2728 | hendricks2 | 34 | #include "joystick.h" |
5 | Plagman | 35 | #include "function.h" |
36 | #include "control.h" |
||
37 | #include "fx_man.h" |
||
38 | #include "sounds.h" |
||
39 | #include "config.h" |
||
40 | #include "osd.h" |
||
41 | #include "osdfuncs.h" |
||
42 | #include "osdcmds.h" |
||
130 | terminx | 43 | #include "scriptfile.h" |
241 | terminx | 44 | #include "grpscan.h" |
610 | terminx | 45 | #include "gamedef.h" |
640 | terminx | 46 | #include "kplib.h" |
1552 | terminx | 47 | #include "crc32.h" |
1173 | terminx | 48 | #include "hightile.h" |
1632 | terminx | 49 | #include "control.h" |
4316 | hendricks2 | 50 | #include "lz4.h" |
1677 | terminx | 51 | #include "net.h" |
52 | #include "premap.h" |
||
53 | #include "gameexec.h" |
||
54 | #include "menus.h" |
||
55 | #include "savegame.h" |
||
56 | #include "anim.h" |
||
57 | #include "demo.h" |
||
2542 | helixhorne | 58 | #include "common.h" |
2726 | hendricks2 | 59 | #include "common_game.h" |
2728 | hendricks2 | 60 | #include "input.h" |
3170 | helixhorne | 61 | #include "compat.h" |
1552 | terminx | 62 | |
4989 | terminx | 63 | #ifdef __ANDROID__ |
64 | #include "android.h" |
||
65 | #endif |
||
66 | |||
2721 | helixhorne | 67 | #ifdef LUNATIC |
3148 | helixhorne | 68 | # include "lunatic_game.h" |
2034 | helixhorne | 69 | #endif |
70 | |||
3726 | helixhorne | 71 | // Uncomment to prevent anything except mirrors from drawing. It is sensible to |
4875 | helixhorne | 72 | // also uncomment ENGINE_CLEAR_SCREEN in build/src/engine_priv.h. |
3726 | helixhorne | 73 | //#define DEBUG_MIRRORS_ONLY |
74 | |||
1595 | helixhorne | 75 | #if KRANDDEBUG |
76 | # define GAME_INLINE |
||
77 | # define GAME_STATIC |
||
78 | #else |
||
79 | # define GAME_INLINE inline |
||
80 | # define GAME_STATIC static |
||
81 | #endif |
||
82 | |||
418 | terminx | 83 | #ifdef _WIN32 |
3221 | hendricks2 | 84 | # include "winlayer.h" |
85 | # define WIN32_LEAN_AND_MEAN |
||
86 | # include <windows.h> |
||
87 | # include <shellapi.h> |
||
88 | # define UPDATEINTERVAL 604800 // 1w |
||
89 | # include "winbits.h" |
||
933 | terminx | 90 | #else |
3221 | hendricks2 | 91 | # ifndef GEKKO |
92 | # include <sys/ioctl.h> |
||
93 | # endif |
||
1008 | hnt_ts | 94 | #endif /* _WIN32 */ |
1587 | terminx | 95 | |
4538 | hendricks2 | 96 | const char* AppProperName = "EDuke32"; |
97 | const char* AppTechnicalName = "eduke32"; |
||
98 | |||
1587 | terminx | 99 | int32_t g_quitDeadline = 0; |
418 | terminx | 100 | |
3405 | helixhorne | 101 | #ifdef LUNATIC |
102 | camera_t g_camera; |
||
103 | #else |
||
1205 | terminx | 104 | int32_t g_cameraDistance = 0, g_cameraClock = 0; |
3405 | helixhorne | 105 | #endif |
1587 | terminx | 106 | static int32_t g_quickExit; |
1205 | terminx | 107 | static int32_t g_commandSetup = 0; |
108 | int32_t g_noSetup = 0; |
||
109 | static int32_t g_noAutoLoad = 0; |
||
110 | static int32_t g_noSound = 0; |
||
111 | static int32_t g_noMusic = 0; |
||
2561 | helixhorne | 112 | static const char *CommandMap = NULL; |
113 | static const char *CommandName = NULL; |
||
1587 | terminx | 114 | int32_t g_forceWeaponChoice = 0; |
2879 | helixhorne | 115 | int32_t g_fakeMultiMode = 0; |
1632 | terminx | 116 | |
3947 | helixhorne | 117 | double g_moveActorsTime = 0; // in ms, smoothed |
118 | |||
1068 | terminx | 119 | char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0}; |
1587 | terminx | 120 | |
1205 | terminx | 121 | int32_t voting = -1; |
122 | int32_t vote_map = -1, vote_episode = -1; |
||
147 | terminx | 123 | |
1587 | terminx | 124 | static int32_t g_Debug = 0; |
1205 | terminx | 125 | static int32_t g_noLogoAnim = 0; |
126 | static int32_t g_noLogo = 0; |
||
249 | terminx | 127 | |
2726 | hendricks2 | 128 | const char *defaultrtsfilename[GAMECOUNT] = { "DUKE.RTS", "NAM.RTS", "NAPALM.RTS", "WW2GI.RTS" }; |
1205 | terminx | 129 | |
2561 | helixhorne | 130 | // g_rtsNamePtr can point to an argv[] element |
131 | const char *g_rtsNamePtr = NULL; |
||
1205 | terminx | 132 | |
133 | int32_t g_Shareware = 0; |
||
134 | |||
1037 | terminx | 135 | #define MAXUSERQUOTES 6 |
1677 | terminx | 136 | int32_t quotebot, quotebotgoal; |
1205 | terminx | 137 | static int32_t user_quote_time[MAXUSERQUOTES]; |
444 | terminx | 138 | static char user_quote[MAXUSERQUOTES][178]; |
249 | terminx | 139 | |
1658 | terminx | 140 | // This was 32 for a while, but I think lowering it to 24 will help things like the Dingoo. |
141 | // Ideally, we would look at our memory usage on our most cramped platform and figure out |
||
142 | // how much of that is needed for the underlying OS and things like SDL instead of guessing |
||
2628 | helixhorne | 143 | #ifndef GEKKO |
1658 | terminx | 144 | static int32_t MAXCACHE1DSIZE = (24*1048576); |
2628 | helixhorne | 145 | #else |
146 | static int32_t MAXCACHE1DSIZE = (8*1048576); |
||
147 | #endif |
||
253 | terminx | 148 | |
1205 | terminx | 149 | int32_t tempwallptr; |
249 | terminx | 150 | |
1205 | terminx | 151 | static int32_t nonsharedtimer; |
249 | terminx | 152 | |
1552 | terminx | 153 | int32_t ticrandomseed; |
154 | |||
1205 | terminx | 155 | static void G_DrawCameraText(int16_t i); |
1595 | helixhorne | 156 | GAME_STATIC GAME_INLINE int32_t G_MoveLoop(void); |
1143 | terminx | 157 | static void G_DoOrderScreen(void); |
395 | terminx | 158 | |
4919 | terminx | 159 | #define FTAOPAQUETIME 30 |
160 | |||
161 | #define ftapulseshade \ |
||
162 | ((hud_glowingquotes && (getrendermode() == REND_CLASSIC || ps->fta >= FTAOPAQUETIME)) ? \ |
||
163 | (sintable[((uint32_t)ps->fta << 7) & 2047] >> 11) : \ |
||
164 | (sintable[((uint32_t)FTAOPAQUETIME << 7) & 2047] >> 11)) |
||
165 | |||
3773 | helixhorne | 166 | #define quotepulseshade (sintable[((uint32_t)totalclock<<5)&2047]>>11) |
1552 | terminx | 167 | |
1205 | terminx | 168 | int32_t althud_numbertile = 2930; |
169 | int32_t althud_numberpal = 0; |
||
4595 | terminx | 170 | |
4852 | hendricks2 | 171 | #ifdef EDUKE32_TOUCH_DEVICES |
4595 | terminx | 172 | int32_t althud_shadows = 0; |
173 | #else |
||
1205 | terminx | 174 | int32_t althud_shadows = 1; |
4595 | terminx | 175 | #endif |
176 | |||
1205 | terminx | 177 | int32_t althud_flashing = 1; |
178 | int32_t hud_glowingquotes = 1; |
||
179 | int32_t hud_showmapname = 1; |
||
937 | terminx | 180 | |
1205 | terminx | 181 | int32_t g_levelTextTime = 0; |
1068 | terminx | 182 | |
1205 | terminx | 183 | int32_t r_maxfps = 0; |
184 | uint32_t g_frameDelay = 0; |
||
1086 | terminx | 185 | |
1176 | terminx | 186 | #if defined(RENDERTYPEWIN) && defined(USE_OPENGL) |
1120 | terminx | 187 | extern char forcegl; |
188 | #endif |
||
189 | |||
1652 | terminx | 190 | void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); }; // needed for linking since it's referenced from build/src/osd.c |
1649 | helixhorne | 191 | |
2726 | hendricks2 | 192 | const char *G_DefaultRtsFile(void) |
1909 | terminx | 193 | { |
2726 | hendricks2 | 194 | if (DUKE) |
195 | return defaultrtsfilename[GAME_DUKE]; |
||
196 | else if (WW2GI) |
||
197 | return defaultrtsfilename[GAME_WW2GI]; |
||
198 | else if (NAPALM) |
||
199 | { |
||
2752 | helixhorne | 200 | if (!testkopen(defaultrtsfilename[GAME_NAPALM],0) && testkopen(defaultrtsfilename[GAME_NAM],0)) |
3618 | hendricks2 | 201 | return defaultrtsfilename[GAME_NAM]; // NAM/NAPALM Sharing |
2726 | hendricks2 | 202 | else |
203 | return defaultrtsfilename[GAME_NAPALM]; |
||
204 | } |
||
205 | else if (NAM) |
||
206 | { |
||
2752 | helixhorne | 207 | if (!testkopen(defaultrtsfilename[GAME_NAM],0) && testkopen(defaultrtsfilename[GAME_NAPALM],0)) |
3618 | hendricks2 | 208 | return defaultrtsfilename[GAME_NAPALM]; // NAM/NAPALM Sharing |
2726 | hendricks2 | 209 | else |
210 | return defaultrtsfilename[GAME_NAM]; |
||
211 | } |
||
1909 | terminx | 212 | |
2726 | hendricks2 | 213 | return defaultrtsfilename[0]; |
1909 | terminx | 214 | } |
215 | |||
1677 | terminx | 216 | enum gametokens |
335 | terminx | 217 | { |
505 | terminx | 218 | T_INCLUDE = 0, |
249 | terminx | 219 | T_INTERFACE = 0, |
505 | terminx | 220 | T_LOADGRP = 1, |
249 | terminx | 221 | T_MODE = 1, |
505 | terminx | 222 | T_CACHESIZE = 2, |
626 | terminx | 223 | T_ALLOW = 2, |
224 | T_NOAUTOLOAD, |
||
1909 | terminx | 225 | T_INCLUDEDEFAULT, |
634 | terminx | 226 | T_MUSIC, |
227 | T_SOUND, |
||
228 | T_FILE, |
||
4987 | terminx | 229 | T_CUTSCENE, |
2242 | helixhorne | 230 | T_ANIMSOUNDS, |
2517 | helixhorne | 231 | T_NOFLOORPALRANGE, |
4987 | terminx | 232 | T_ID, |
233 | T_DELAY |
||
249 | terminx | 234 | }; |
235 | |||
236 | |||
3399 | helixhorne | 237 | static int32_t sbarsc(int32_t sc) |
238 | { |
||
239 | return scale(sc,ud.statusbarscale,100); |
||
240 | } |
||
5 | Plagman | 241 | |
2640 | helixhorne | 242 | static int32_t sbarx(int32_t x) |
5 | Plagman | 243 | { |
3399 | helixhorne | 244 | if (ud.screen_size == 4) return sbarsc(x<<16); |
245 | return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x<<16); |
||
5 | Plagman | 246 | } |
247 | |||
2640 | helixhorne | 248 | static int32_t sbarxr(int32_t x) |
934 | terminx | 249 | { |
3399 | helixhorne | 250 | if (ud.screen_size == 4) return (320<<16) - sbarsc(x<<16); |
251 | return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x<<16); |
||
934 | terminx | 252 | } |
253 | |||
2640 | helixhorne | 254 | static int32_t sbary(int32_t y) |
5 | Plagman | 255 | { |
4602 | terminx | 256 | if (ud.althud == 2 && ud.screen_size == 4) return sbarsc(y << 16); |
257 | else return (200<<16) - sbarsc(200<<16) + sbarsc(y<<16); |
||
5 | Plagman | 258 | } |
259 | |||
3612 | hendricks2 | 260 | static int32_t sbarx16(int32_t x) |
261 | { |
||
262 | if (ud.screen_size == 4) return sbarsc(x); |
||
263 | return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x); |
||
264 | } |
||
265 | |||
266 | #if 0 // enable if ever needed |
||
267 | static int32_t sbarxr16(int32_t x) |
||
268 | { |
||
269 | if (ud.screen_size == 4) return (320<<16) - sbarsc(x); |
||
270 | return (((320<<16) - sbarsc(320<<16)) >> 1) + sbarsc(x); |
||
271 | } |
||
272 | #endif |
||
273 | |||
274 | static int32_t sbary16(int32_t y) |
||
275 | { |
||
276 | return (200<<16) - sbarsc(200<<16) + sbarsc(y); |
||
277 | } |
||
278 | |||
2728 | hendricks2 | 279 | int32_t textsc(int32_t sc) |
1095 | terminx | 280 | { |
1097 | terminx | 281 | // prevent ridiculousness to a degree |
1099 | terminx | 282 | if (xdim <= 320) return sc; |
283 | else if (xdim <= 640) return scale(sc,min(200,ud.textscale),100); |
||
284 | else if (xdim <= 800) return scale(sc,min(300,ud.textscale),100); |
||
285 | else if (xdim <= 1024) return scale(sc,min(350,ud.textscale),100); |
||
1095 | terminx | 286 | return scale(sc,ud.textscale,100); |
287 | } |
||
5054 | hendricks2 | 288 | static int32_t gtextsc(int32_t sc) |
289 | { |
||
290 | return scale(sc,ud.textscale,400); |
||
291 | } |
||
1095 | terminx | 292 | |
1205 | terminx | 293 | static void G_PatchStatusBar(int32_t x1, int32_t y1, int32_t x2, int32_t y2) |
5 | Plagman | 294 | { |
3399 | helixhorne | 295 | int32_t scl = sbarsc(65536); |
4623 | terminx | 296 | int32_t tx = sbarx16((160<<16) - (tilesiz[BOTTOMSTATUSBAR].x<<15)); // centered |
297 | int32_t ty = sbary(200-tilesiz[BOTTOMSTATUSBAR].y); |
||
5 | Plagman | 298 | |
3399 | helixhorne | 299 | int32_t clx1 = sbarsc(scale(x1,xdim,320)), cly1 = sbarsc(scale(y1,ydim,200)); |
300 | int32_t clx2 = sbarsc(scale(x2,xdim,320)), cly2 = sbarsc(scale(y2,ydim,200)); |
||
301 | int32_t clofx = (xdim - sbarsc(xdim)) >> 1, clofy = (ydim - sbarsc(ydim)); |
||
5 | Plagman | 302 | |
508 | terminx | 303 | rotatesprite(tx,ty,scl,0,BOTTOMSTATUSBAR,4,0,10+16+64,clx1+clofx,cly1+clofy,clx2+clofx-1,cly2+clofy-1); |
5 | Plagman | 304 | } |
305 | |||
1772 | plagman | 306 | void P_SetGamePalette(DukePlayer_t *player, uint8_t palid, int32_t set) |
5 | Plagman | 307 | { |
1772 | plagman | 308 | if (palid >= BASEPALCOUNT) |
309 | palid = BASEPAL; |
||
1604 | terminx | 310 | |
2954 | helixhorne | 311 | player->palette = palid; |
312 | |||
564 | terminx | 313 | if (player != g_player[screenpeek].ps) |
5 | Plagman | 314 | return; |
1918 | terminx | 315 | |
1781 | plagman | 316 | setbrightness(ud.brightness>>2, palid, set); |
5 | Plagman | 317 | } |
318 | |||
3833 | hendricks2 | 319 | // get the string length until the next '\n' |
320 | int32_t G_GetStringLineLength(const char *text, const char *end, const int32_t iter) |
||
321 | { |
||
322 | int32_t length = 0; |
||
2947 | helixhorne | 323 | |
3833 | hendricks2 | 324 | while (*text != '\n' && text != end) |
325 | { |
||
326 | ++length; |
||
327 | |||
328 | text += iter; |
||
329 | } |
||
330 | |||
331 | return length; |
||
332 | } |
||
333 | |||
334 | int32_t G_GetStringNumLines(const char *text, const char *end, const int32_t iter) |
||
335 | { |
||
336 | int32_t count = 1; |
||
337 | |||
338 | while (text != end) |
||
339 | { |
||
340 | if (*text == '\n') |
||
341 | ++count; |
||
342 | text += iter; |
||
343 | } |
||
344 | |||
345 | return count; |
||
346 | } |
||
347 | // Note: Neither of these care about TEXT_LINEWRAP. This is intended. |
||
348 | |||
349 | // This function requires you to Bfree() the returned char*. |
||
350 | char* G_GetSubString(const char *text, const char *end, const int32_t iter, const int32_t length) |
||
351 | { |
||
4491 | helixhorne | 352 | char *line = (char*)Xmalloc((length+1) * sizeof(char)); |
3833 | hendricks2 | 353 | int32_t counter = 0; |
354 | |||
355 | while (counter < length && text != end) |
||
356 | { |
||
357 | line[counter] = *text; |
||
358 | |||
359 | text += iter; |
||
360 | ++counter; |
||
361 | } |
||
362 | |||
3852 | helixhorne | 363 | line[counter] = '\0'; |
3833 | hendricks2 | 364 | |
365 | return line; |
||
366 | } |
||
367 | |||
368 | // assign the character's tilenum |
||
369 | int32_t G_GetStringTile(int32_t font, char *t, int32_t f) |
||
370 | { |
||
371 | if (f & TEXT_DIGITALNUMBER) |
||
372 | return *t - '0' + font; // copied from digitalnumber |
||
373 | else if (f & (TEXT_BIGALPHANUM|TEXT_GRAYFONT)) |
||
374 | { |
||
375 | int32_t offset = (f & TEXT_GRAYFONT) ? 26 : 0; |
||
376 | |||
377 | if (*t >= '0' && *t <= '9') |
||
378 | return *t - '0' + font + ((f & TEXT_GRAYFONT) ? 26 : -10); |
||
379 | else if (*t >= 'a' && *t <= 'z') |
||
380 | return *t - 'a' + font + ((f & TEXT_GRAYFONT) ? -26 : 26); |
||
381 | else if (*t >= 'A' && *t <= 'Z') |
||
382 | return *t - 'A' + font; |
||
383 | else switch (*t) |
||
384 | { |
||
385 | case '_': |
||
386 | case '-': |
||
387 | return font - (11 + offset); |
||
388 | break; |
||
389 | case '.': |
||
390 | return font + (BIGPERIOD - (BIGALPHANUM + offset)); |
||
391 | break; |
||
392 | case ',': |
||
393 | return font + (BIGCOMMA - (BIGALPHANUM + offset)); |
||
394 | break; |
||
395 | case '!': |
||
396 | return font + (BIGX_ - (BIGALPHANUM + offset)); |
||
397 | break; |
||
398 | case '?': |
||
399 | return font + (BIGQ - (BIGALPHANUM + offset)); |
||
400 | break; |
||
401 | case ';': |
||
402 | return font + (BIGSEMI - (BIGALPHANUM + offset)); |
||
403 | break; |
||
404 | case ':': |
||
405 | return font + (BIGCOLIN - (BIGALPHANUM + offset)); |
||
406 | break; |
||
407 | case '\\': |
||
408 | case '/': |
||
409 | return font + (68 - offset); // 3008-2940 |
||
410 | break; |
||
411 | case '%': |
||
412 | return font + (69 - offset); // 3009-2940 |
||
413 | break; |
||
414 | case '`': |
||
415 | case '\"': // could be better hacked in |
||
416 | case '\'': |
||
417 | return font + (BIGAPPOS - (BIGALPHANUM + offset)); |
||
418 | break; |
||
419 | default: // unknown character |
||
420 | *t = ' '; // whitespace-ize |
||
4856 | hendricks2 | 421 | case '\n': |
3833 | hendricks2 | 422 | return font; |
423 | break; |
||
424 | } |
||
425 | } |
||
426 | else |
||
427 | return *t - '!' + font; // uses ASCII order |
||
428 | } |
||
429 | |||
3850 | hendricks2 | 430 | #define NUMHACKACTIVE ((f & TEXT_GAMETEXTNUMHACK) && t >= '0' && t <= '9') |
431 | |||
3833 | hendricks2 | 432 | // qstrdim |
433 | vec2_t G_ScreenTextSize(const int32_t font, |
||
434 | int32_t x, int32_t y, const int32_t z, const int32_t blockangle, |
||
435 | const char *str, const int32_t o, |
||
436 | int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, |
||
437 | const int32_t f, |
||
438 | int32_t x1, int32_t y1, int32_t x2, int32_t y2) |
||
439 | { |
||
440 | vec2_t size = { 0, 0, }; // eventually the return value |
||
441 | vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string |
||
442 | vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line |
||
443 | vec2_t offset = { 0, 0, }; // temporary; holds the last movement made in both directions |
||
444 | |||
445 | int32_t tile; |
||
446 | char t; |
||
447 | |||
448 | // set the start and end points depending on direction |
||
449 | int32_t iter = (f & TEXT_BACKWARDS) ? -1 : 1; // iteration direction |
||
450 | |||
451 | const char *end; |
||
452 | const char *text; |
||
453 | |||
454 | if (str == NULL) |
||
455 | return size; |
||
456 | |||
457 | end = (f & TEXT_BACKWARDS) ? str-1 : Bstrchr(str,'\0'); |
||
458 | text = (f & TEXT_BACKWARDS) ? Bstrchr(str,'\0')-1 : str; |
||
459 | |||
460 | // optimization: justification in both directions |
||
461 | if ((f & TEXT_XJUSTIFY) && (f & TEXT_YJUSTIFY)) |
||
462 | { |
||
463 | size.x = xbetween; |
||
464 | size.y = ybetween; |
||
465 | return size; |
||
466 | } |
||
467 | |||
468 | // for best results, we promote 320x200 coordinates to full precision before any math |
||
469 | if (!(o & ROTATESPRITE_FULL16)) |
||
470 | { |
||
471 | x <<= 16; |
||
472 | y <<= 16; |
||
473 | xspace <<= 16; |
||
474 | yline <<= 16; |
||
475 | xbetween <<= 16; |
||
476 | ybetween <<= 16; |
||
477 | } |
||
478 | // coordinate values should be shifted left by 16 |
||
479 | |||
480 | // handle zooming where applicable |
||
481 | xspace = scale(xspace, z, 65536); |
||
482 | yline = scale(yline, z, 65536); |
||
483 | xbetween = scale(xbetween, z, 65536); |
||
484 | ybetween = scale(ybetween, z, 65536); |
||
485 | // size/width/height/spacing/offset values should be multiplied or scaled by $z, zoom (since 100% is 65536, the same as 1<<16) |
||
486 | |||
487 | // loop through the string |
||
488 | while ((t = *text) && text != end) |
||
489 | { |
||
490 | // handle escape sequences |
||
491 | if (t == '^' && Bisdigit(*(text+iter)) && !(f & TEXT_LITERALESCAPE)) |
||
492 | { |
||
493 | text += iter + iter; |
||
494 | if (Bisdigit(*text)) |
||
495 | text += iter; |
||
496 | continue; |
||
497 | } |
||
498 | |||
499 | // handle case bits |
||
500 | if (f & TEXT_UPPERCASE) |
||
501 | { |
||
502 | if (f & TEXT_INVERTCASE) // optimization...? |
||
503 | { // v^ important that these two ifs remain separate due to the else below |
||
504 | if (Bisupper(t)) |
||
505 | t = Btolower(t); |
||
506 | } |
||
507 | else if (Bislower(t)) |
||
508 | t = Btoupper(t); |
||
509 | } |
||
510 | else if (f & TEXT_INVERTCASE) |
||
511 | { |
||
512 | if (Bisupper(t)) |
||
513 | t = Btolower(t); |
||
514 | else if (Bislower(t)) |
||
515 | t = Btoupper(t); |
||
516 | } |
||
517 | |||
518 | // translate the character to a tilenum |
||
519 | tile = G_GetStringTile(font, &t, f); |
||
520 | |||
521 | // reset this here because we haven't printed anything yet this loop |
||
522 | extent.x = 0; |
||
523 | |||
524 | // reset this here because the act of printing something on this line means that we include the margin above in the total size |
||
525 | offset.y = 0; |
||
526 | |||
527 | // handle each character itself in the context of screen drawing |
||
528 | switch (t) |
||
529 | { |
||
530 | case '\t': |
||
531 | case ' ': |
||
532 | // width |
||
533 | extent.x = xspace; |
||
534 | |||
535 | if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE)) |
||
536 | { |
||
537 | char space = '.'; // this is subject to change as an implementation detail |
||
538 | if (f & TEXT_TILESPACE) |
||
539 | space = '\x7F'; // tile after '~' |
||
540 | tile = G_GetStringTile(font, &space, f); |
||
541 | |||
4623 | terminx | 542 | extent.x += (tilesiz[tile].x * z); |
3833 | hendricks2 | 543 | } |
544 | |||
545 | // prepare the height // near-CODEDUP the other two near-CODEDUPs for this section |
||
546 | { |
||
547 | int32_t tempyextent = yline; |
||
548 | |||
549 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
550 | { |
||
551 | char line = 'A'; // this is subject to change as an implementation detail |
||
552 | if (f & TEXT_TILELINE) |
||
553 | line = '\x7F'; // tile after '~' |
||
554 | tile = G_GetStringTile(font, &line, f); |
||
555 | |||
4623 | terminx | 556 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 557 | } |
558 | |||
559 | SetIfGreater(&extent.y, tempyextent); |
||
560 | } |
||
561 | |||
562 | if (t == '\t') |
||
563 | extent.x <<= 2; // *= 4 |
||
564 | |||
565 | break; |
||
566 | |||
567 | case '\n': // near-CODEDUP "if (wrap)" |
||
4913 | hendricks2 | 568 | extent.x = 0; |
569 | |||
3833 | hendricks2 | 570 | // save the position |
3850 | hendricks2 | 571 | if (!(f & TEXT_XOFFSETZERO)) // we want the entire offset to count as the character width |
572 | pos.x -= offset.x; |
||
3833 | hendricks2 | 573 | SetIfGreater(&size.x, pos.x); |
574 | |||
575 | // reset the position |
||
576 | pos.x = 0; |
||
577 | |||
578 | // prepare the height |
||
579 | { |
||
580 | int32_t tempyextent = yline; |
||
581 | |||
582 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
583 | { |
||
584 | char line = 'A'; // this is subject to change as an implementation detail |
||
585 | if (f & TEXT_TILELINE) |
||
586 | line = '\x7F'; // tile after '~' |
||
587 | tile = G_GetStringTile(font, &line, f); |
||
588 | |||
4623 | terminx | 589 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 590 | } |
591 | |||
592 | SetIfGreater(&extent.y, tempyextent); |
||
593 | } |
||
594 | |||
595 | // move down the line height |
||
596 | if (!(f & TEXT_YOFFSETZERO)) |
||
597 | pos.y += extent.y; |
||
598 | |||
599 | // reset the current height |
||
600 | extent.y = 0; |
||
601 | |||
602 | // line spacing |
||
603 | offset.y = (f & TEXT_YJUSTIFY) ? 0 : ybetween; // ternary to prevent overflow |
||
604 | pos.y += offset.y; |
||
605 | |||
606 | break; |
||
607 | |||
608 | default: |
||
609 | // width |
||
4623 | terminx | 610 | extent.x = tilesiz[tile].x * z; |
3833 | hendricks2 | 611 | |
612 | // obnoxious hardcoded functionality from gametext |
||
3850 | hendricks2 | 613 | if (NUMHACKACTIVE) |
3833 | hendricks2 | 614 | { |
615 | char numeral = '0'; // this is subject to change as an implementation detail |
||
4623 | terminx | 616 | extent.x = (tilesiz[G_GetStringTile(font, &numeral, f)].x-1) * z; |
3833 | hendricks2 | 617 | } |
618 | |||
619 | // height |
||
4623 | terminx | 620 | SetIfGreater(&extent.y, (tilesiz[tile].y * z)); |
3833 | hendricks2 | 621 | |
622 | break; |
||
623 | } |
||
624 | |||
625 | // incrementing the coordinate counters |
||
626 | offset.x = 0; |
||
627 | |||
628 | // advance the x coordinate |
||
3850 | hendricks2 | 629 | if (!(f & TEXT_XOFFSETZERO) || NUMHACKACTIVE) |
3833 | hendricks2 | 630 | offset.x += extent.x; |
631 | |||
632 | // account for text spacing |
||
3850 | hendricks2 | 633 | if (!NUMHACKACTIVE // this "if" line ONLY == replicating hardcoded stuff |
634 | && t != '\n' |
||
3833 | hendricks2 | 635 | && !(f & TEXT_XJUSTIFY)) // to prevent overflow |
636 | offset.x += xbetween; |
||
637 | |||
638 | // line wrapping |
||
639 | if ((f & TEXT_LINEWRAP) && !(f & TEXT_XRIGHT) && !(f & TEXT_XCENTER) && blockangle % 512 == 0) |
||
640 | { |
||
641 | int32_t wrap = 0; |
||
642 | const int32_t ang = blockangle % 2048; |
||
643 | |||
644 | // this is the only place in qstrdim where angle actually affects direction, but only in the wrapping measurement |
||
645 | switch (ang) |
||
646 | { |
||
647 | case 0: |
||
3849 | hendricks2 | 648 | wrap = (x + (pos.x + offset.x) > ((o & 2) ? (320<<16) : ((x2 - USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 649 | break; |
650 | case 512: |
||
3849 | hendricks2 | 651 | wrap = (y + (pos.x + offset.x) > ((o & 2) ? (200<<16) : ((y2 - USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 652 | break; |
653 | case 1024: |
||
3849 | hendricks2 | 654 | wrap = (x - (pos.x + offset.x) < ((o & 2) ? 0 : ((x1 + USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 655 | break; |
656 | case 1536: |
||
3849 | hendricks2 | 657 | wrap = (y - (pos.x + offset.x) < ((o & 2) ? 0 : ((y1 + USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 658 | break; |
659 | } |
||
660 | if (wrap) // near-CODEDUP "case '\n':" |
||
661 | { |
||
662 | // save the position |
||
663 | SetIfGreater(&size.x, pos.x); |
||
664 | |||
665 | // reset the position |
||
666 | pos.x = 0; |
||
667 | |||
668 | // prepare the height |
||
669 | { |
||
670 | int32_t tempyextent = yline; |
||
671 | |||
672 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
673 | { |
||
674 | char line = 'A'; // this is subject to change as an implementation detail |
||
675 | if (f & TEXT_TILELINE) |
||
676 | line = '\x7F'; // tile after '~' |
||
677 | tile = G_GetStringTile(font, &line, f); |
||
678 | |||
4623 | terminx | 679 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 680 | } |
681 | |||
682 | SetIfGreater(&extent.y, tempyextent); |
||
683 | } |
||
684 | |||
685 | // move down the line height |
||
686 | if (!(f & TEXT_YOFFSETZERO)) |
||
687 | pos.y += extent.y; |
||
688 | |||
689 | // reset the current height |
||
690 | extent.y = 0; |
||
691 | |||
692 | // line spacing |
||
693 | offset.y = (f & TEXT_YJUSTIFY) ? 0 : ybetween; // ternary to prevent overflow |
||
694 | pos.y += offset.y; |
||
695 | } |
||
696 | else |
||
697 | pos.x += offset.x; |
||
698 | } |
||
699 | else |
||
700 | pos.x += offset.x; |
||
701 | |||
3850 | hendricks2 | 702 | // save some trouble with calculation in case the line breaks |
703 | if (!(f & TEXT_XOFFSETZERO) || NUMHACKACTIVE) |
||
3833 | hendricks2 | 704 | offset.x -= extent.x; |
705 | |||
706 | // iterate to the next character in the string |
||
707 | text += iter; |
||
708 | } |
||
709 | |||
710 | // calculate final size |
||
3850 | hendricks2 | 711 | if (!(f & TEXT_XOFFSETZERO)) |
712 | pos.x -= offset.x; |
||
3833 | hendricks2 | 713 | |
3850 | hendricks2 | 714 | if (!(f & TEXT_YOFFSETZERO)) |
715 | { |
||
716 | pos.y -= offset.y; |
||
717 | pos.y += extent.y; |
||
718 | } |
||
719 | else |
||
720 | pos.y += ybetween; |
||
721 | |||
3833 | hendricks2 | 722 | SetIfGreater(&size.x, pos.x); |
723 | SetIfGreater(&size.y, pos.y); |
||
724 | |||
725 | // justification where only one of the two directions is set, so we have to iterate |
||
726 | if (f & TEXT_XJUSTIFY) |
||
727 | size.x = xbetween; |
||
728 | if (f & TEXT_YJUSTIFY) |
||
729 | size.y = ybetween; |
||
730 | |||
731 | // return values in the same manner we receive them |
||
732 | if (!(o & ROTATESPRITE_FULL16)) |
||
733 | { |
||
734 | size.x >>= 16; |
||
735 | size.y >>= 16; |
||
736 | } |
||
737 | |||
738 | return size; |
||
739 | } |
||
740 | |||
741 | void G_AddCoordsFromRotation(vec2_t *coords, const vec2_t *unitDirection, const int32_t magnitude) |
||
742 | { |
||
743 | coords->x += scale(magnitude, unitDirection->x, 16384); |
||
744 | coords->y += scale(magnitude, unitDirection->y, 16384); |
||
745 | } |
||
746 | |||
747 | // screentext |
||
748 | vec2_t G_ScreenText(const int32_t font, |
||
749 | int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const int32_t charangle, |
||
4428 | helixhorne | 750 | const char *str, const int32_t shade, int32_t pal, int32_t o, int32_t alpha, |
3833 | hendricks2 | 751 | int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, |
752 | const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) |
||
753 | { |
||
754 | vec2_t size = { 0, 0, }; // eventually the return value |
||
755 | vec2_t origin = { 0, 0, }; // where to start, depending on the alignment |
||
756 | vec2_t pos = { 0, 0, }; // holds the coordinate position as we draw each character tile of the string |
||
757 | vec2_t extent = { 0, 0, }; // holds the x-width of each character and the greatest y-height of each line |
||
758 | const vec2_t Xdirection = { sintable[(blockangle+512)&2047], sintable[blockangle&2047], }; |
||
759 | const vec2_t Ydirection = { sintable[(blockangle+1024)&2047], sintable[(blockangle+512)&2047], }; |
||
760 | |||
4428 | helixhorne | 761 | int32_t blendidx=0, tile; |
3833 | hendricks2 | 762 | char t; |
763 | |||
764 | // set the start and end points depending on direction |
||
765 | int32_t iter = (f & TEXT_BACKWARDS) ? -1 : 1; // iteration direction |
||
766 | |||
767 | const char *end; |
||
768 | const char *text; |
||
769 | |||
770 | if (str == NULL) |
||
771 | return size; |
||
772 | |||
4428 | helixhorne | 773 | NEG_ALPHA_TO_BLEND(alpha, blendidx, o); |
774 | |||
3833 | hendricks2 | 775 | end = (f & TEXT_BACKWARDS) ? str-1 : Bstrchr(str,'\0'); |
776 | text = (f & TEXT_BACKWARDS) ? Bstrchr(str,'\0')-1 : str; |
||
777 | |||
778 | // for best results, we promote 320x200 coordinates to full precision before any math |
||
779 | if (!(o & ROTATESPRITE_FULL16)) |
||
780 | { |
||
781 | x <<= 16; |
||
782 | y <<= 16; |
||
783 | xspace <<= 16; |
||
784 | yline <<= 16; |
||
785 | xbetween <<= 16; |
||
786 | ybetween <<= 16; |
||
787 | } |
||
788 | // coordinate values should be shifted left by 16 |
||
789 | |||
790 | // eliminate conflicts, necessary here to get the correct size value |
||
791 | // especially given justification's special handling in G_ScreenTextSize() |
||
792 | if ((f & TEXT_XRIGHT) || (f & TEXT_XCENTER) || (f & TEXT_XJUSTIFY) || (f & TEXT_YJUSTIFY) || blockangle % 512 != 0) |
||
793 | o &= ~TEXT_LINEWRAP; |
||
794 | |||
795 | // size is the return value, and we need it for alignment |
||
796 | size = G_ScreenTextSize(font, x, y, z, blockangle, str, o | ROTATESPRITE_FULL16, xspace, yline, (f & TEXT_XJUSTIFY) ? 0 : xbetween, (f & TEXT_YJUSTIFY) ? 0 : ybetween, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY), x1, y1, x2, y2); |
||
797 | |||
798 | // handle zooming where applicable |
||
799 | xspace = scale(xspace, z, 65536); |
||
800 | yline = scale(yline, z, 65536); |
||
801 | xbetween = scale(xbetween, z, 65536); |
||
802 | ybetween = scale(ybetween, z, 65536); |
||
803 | // size/width/height/spacing/offset values should be multiplied or scaled by $z, zoom (since 100% is 65536, the same as 1<<16) |
||
804 | |||
805 | // alignment |
||
806 | // near-CODEDUP "case '\n':" |
||
807 | { |
||
808 | int32_t lines = G_GetStringNumLines(text, end, iter); |
||
809 | |||
810 | if ((f & TEXT_XJUSTIFY) || (f & TEXT_XRIGHT) || (f & TEXT_XCENTER)) |
||
811 | { |
||
812 | const int32_t length = G_GetStringLineLength(text, end, iter); |
||
813 | |||
814 | int32_t linewidth = size.x; |
||
815 | |||
816 | if (lines != 1) |
||
817 | { |
||
818 | char *line = G_GetSubString(text, end, iter, length); |
||
819 | |||
4913 | hendricks2 | 820 | linewidth = G_ScreenTextSize(font, x, y, z, blockangle, line, o | ROTATESPRITE_FULL16, xspace, yline, (f & TEXT_XJUSTIFY) ? 0 : xbetween, (f & TEXT_YJUSTIFY) ? 0 : ybetween, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY|TEXT_BACKWARDS), x1, y1, x2, y2).x; |
3833 | hendricks2 | 821 | |
822 | Bfree(line); |
||
823 | } |
||
824 | |||
825 | if (f & TEXT_XJUSTIFY) |
||
826 | { |
||
827 | size.x = xbetween; |
||
828 | |||
4658 | terminx | 829 | xbetween = (length == 1) ? 0 : tabledivide32_noinline((xbetween - linewidth), (length - 1)); |
3833 | hendricks2 | 830 | |
831 | linewidth = size.x; |
||
832 | } |
||
833 | |||
834 | if (f & TEXT_XRIGHT) |
||
835 | origin.x = -linewidth; |
||
836 | else if (f & TEXT_XCENTER) |
||
837 | origin.x = -(linewidth / 2); |
||
838 | } |
||
839 | |||
840 | if (f & TEXT_YJUSTIFY) |
||
841 | { |
||
842 | const int32_t tempswap = ybetween; |
||
4658 | terminx | 843 | ybetween = (lines == 1) ? 0 : tabledivide32_noinline(ybetween - size.y, lines - 1); |
3833 | hendricks2 | 844 | size.y = tempswap; |
845 | } |
||
846 | |||
847 | if (f & TEXT_YBOTTOM) |
||
848 | origin.y = -size.y; |
||
849 | else if (f & TEXT_YCENTER) |
||
850 | origin.y = -(size.y / 2); |
||
851 | } |
||
852 | |||
853 | // loop through the string |
||
854 | while ((t = *text) && text != end) |
||
855 | { |
||
856 | int32_t orientation = o; |
||
857 | int32_t angle = blockangle + charangle; |
||
858 | |||
859 | // handle escape sequences |
||
860 | if (t == '^' && Bisdigit(*(text+iter)) && !(f & TEXT_LITERALESCAPE)) |
||
861 | { |
||
862 | char smallbuf[4]; |
||
863 | |||
864 | text += iter; |
||
865 | smallbuf[0] = *text; |
||
866 | |||
867 | text += iter; |
||
868 | if (Bisdigit(*text)) |
||
869 | { |
||
870 | smallbuf[1] = *text; |
||
871 | smallbuf[2] = '\0'; |
||
872 | text += iter; |
||
873 | } |
||
874 | else |
||
875 | smallbuf[1] = '\0'; |
||
876 | |||
877 | if (!(f & TEXT_IGNOREESCAPE)) |
||
878 | pal = Batoi(smallbuf); |
||
879 | |||
880 | continue; |
||
881 | } |
||
882 | |||
883 | // handle case bits |
||
884 | if (f & TEXT_UPPERCASE) |
||
885 | { |
||
886 | if (f & TEXT_INVERTCASE) // optimization...? |
||
887 | { // v^ important that these two ifs remain separate due to the else below |
||
888 | if (Bisupper(t)) |
||
889 | t = Btolower(t); |
||
890 | } |
||
891 | else if (Bislower(t)) |
||
892 | t = Btoupper(t); |
||
893 | } |
||
894 | else if (f & TEXT_INVERTCASE) |
||
895 | { |
||
896 | if (Bisupper(t)) |
||
897 | t = Btolower(t); |
||
898 | else if (Bislower(t)) |
||
899 | t = Btoupper(t); |
||
900 | } |
||
901 | |||
902 | // translate the character to a tilenum |
||
903 | tile = G_GetStringTile(font, &t, f); |
||
904 | |||
905 | switch (t) |
||
906 | { |
||
907 | case '\t': |
||
908 | case ' ': |
||
909 | case '\n': |
||
910 | case '\x7F': |
||
911 | break; |
||
912 | |||
913 | default: |
||
914 | { |
||
915 | vec2_t location = { x, y, }; |
||
916 | |||
917 | G_AddCoordsFromRotation(&location, &Xdirection, origin.x); |
||
918 | G_AddCoordsFromRotation(&location, &Ydirection, origin.y); |
||
919 | |||
920 | G_AddCoordsFromRotation(&location, &Xdirection, pos.x); |
||
921 | G_AddCoordsFromRotation(&location, &Ydirection, pos.y); |
||
922 | |||
4428 | helixhorne | 923 | rotatesprite_(location.x, location.y, z, angle, tile, shade, pal, orientation, alpha, blendidx, x1, y1, x2, y2); |
3833 | hendricks2 | 924 | |
925 | break; |
||
926 | } |
||
927 | } |
||
928 | |||
929 | // reset this here because we haven't printed anything yet this loop |
||
930 | extent.x = 0; |
||
931 | |||
932 | // handle each character itself in the context of screen drawing |
||
933 | switch (t) |
||
934 | { |
||
935 | case '\t': |
||
936 | case ' ': |
||
937 | // width |
||
938 | extent.x = xspace; |
||
939 | |||
940 | if (f & (TEXT_INTERNALSPACE|TEXT_TILESPACE)) |
||
941 | { |
||
942 | char space = '.'; // this is subject to change as an implementation detail |
||
943 | if (f & TEXT_TILESPACE) |
||
944 | space = '\x7F'; // tile after '~' |
||
945 | tile = G_GetStringTile(font, &space, f); |
||
946 | |||
4623 | terminx | 947 | extent.x += (tilesiz[tile].x * z); |
3833 | hendricks2 | 948 | } |
949 | |||
950 | // prepare the height // near-CODEDUP the other two near-CODEDUPs for this section |
||
951 | { |
||
952 | int32_t tempyextent = yline; |
||
953 | |||
954 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
955 | { |
||
956 | char line = 'A'; // this is subject to change as an implementation detail |
||
957 | if (f & TEXT_TILELINE) |
||
958 | line = '\x7F'; // tile after '~' |
||
959 | tile = G_GetStringTile(font, &line, f); |
||
960 | |||
4623 | terminx | 961 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 962 | } |
963 | |||
964 | SetIfGreater(&extent.y, tempyextent); |
||
965 | } |
||
966 | |||
967 | if (t == '\t') |
||
968 | extent.x <<= 2; // *= 4 |
||
969 | |||
970 | break; |
||
971 | |||
972 | case '\n': // near-CODEDUP "if (wrap)" |
||
4913 | hendricks2 | 973 | extent.x = 0; |
974 | |||
3833 | hendricks2 | 975 | // reset the position |
976 | pos.x = 0; |
||
977 | |||
978 | // prepare the height |
||
979 | { |
||
980 | int32_t tempyextent = yline; |
||
981 | |||
982 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
983 | { |
||
984 | char line = 'A'; // this is subject to change as an implementation detail |
||
985 | if (f & TEXT_TILELINE) |
||
986 | line = '\x7F'; // tile after '~' |
||
987 | tile = G_GetStringTile(font, &line, f); |
||
988 | |||
4623 | terminx | 989 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 990 | } |
991 | |||
992 | SetIfGreater(&extent.y, tempyextent); |
||
993 | } |
||
994 | |||
995 | // move down the line height |
||
996 | if (!(f & TEXT_YOFFSETZERO)) |
||
997 | pos.y += extent.y; |
||
998 | |||
999 | // reset the current height |
||
1000 | extent.y = 0; |
||
1001 | |||
1002 | // line spacing |
||
1003 | pos.y += ybetween; |
||
1004 | |||
1005 | // near-CODEDUP "alignments" |
||
1006 | if ((f & TEXT_XJUSTIFY) || (f & TEXT_XRIGHT) || (f & TEXT_XCENTER)) |
||
1007 | { |
||
4913 | hendricks2 | 1008 | const int32_t length = G_GetStringLineLength(text+1, end, iter); |
3833 | hendricks2 | 1009 | |
4913 | hendricks2 | 1010 | char *line = G_GetSubString(text+1, end, iter, length); |
3833 | hendricks2 | 1011 | |
4913 | hendricks2 | 1012 | int32_t linewidth = G_ScreenTextSize(font, x, y, z, blockangle, line, o | ROTATESPRITE_FULL16, xspace, yline, (f & TEXT_XJUSTIFY) ? 0 : xbetween, (f & TEXT_YJUSTIFY) ? 0 : ybetween, f & ~(TEXT_XJUSTIFY|TEXT_YJUSTIFY|TEXT_BACKWARDS), x1, y1, x2, y2).x; |
3833 | hendricks2 | 1013 | |
1014 | Bfree(line); |
||
1015 | |||
1016 | if (f & TEXT_XJUSTIFY) |
||
1017 | { |
||
4658 | terminx | 1018 | xbetween = (length == 1) ? 0 : tabledivide32_noinline(xbetween - linewidth, length - 1); |
3833 | hendricks2 | 1019 | |
1020 | linewidth = size.x; |
||
1021 | } |
||
1022 | |||
1023 | if (f & TEXT_XRIGHT) |
||
1024 | origin.x = -linewidth; |
||
1025 | else if (f & TEXT_XCENTER) |
||
1026 | origin.x = -(linewidth / 2); |
||
1027 | } |
||
1028 | |||
1029 | break; |
||
1030 | |||
1031 | default: |
||
1032 | // width |
||
4623 | terminx | 1033 | extent.x = tilesiz[tile].x * z; |
3833 | hendricks2 | 1034 | |
1035 | // obnoxious hardcoded functionality from gametext |
||
3850 | hendricks2 | 1036 | if (NUMHACKACTIVE) |
3833 | hendricks2 | 1037 | { |
1038 | char numeral = '0'; // this is subject to change as an implementation detail |
||
4623 | terminx | 1039 | extent.x = (tilesiz[G_GetStringTile(font, &numeral, f)].x-1) * z; |
3833 | hendricks2 | 1040 | } |
1041 | |||
1042 | // height |
||
4623 | terminx | 1043 | SetIfGreater(&extent.y, (tilesiz[tile].y * z)); |
3833 | hendricks2 | 1044 | |
1045 | break; |
||
1046 | } |
||
1047 | |||
1048 | // incrementing the coordinate counters |
||
1049 | { |
||
1050 | int32_t xoffset = 0; |
||
1051 | |||
1052 | // advance the x coordinate |
||
3850 | hendricks2 | 1053 | if (!(f & TEXT_XOFFSETZERO) || NUMHACKACTIVE) |
3833 | hendricks2 | 1054 | xoffset += extent.x; |
1055 | |||
1056 | // account for text spacing |
||
3850 | hendricks2 | 1057 | if (!NUMHACKACTIVE // this "if" line ONLY == replicating hardcoded stuff |
1058 | && t != '\n') |
||
3833 | hendricks2 | 1059 | xoffset += xbetween; |
1060 | |||
1061 | // line wrapping |
||
1062 | if (f & TEXT_LINEWRAP) |
||
1063 | { |
||
1064 | int32_t wrap = 0; |
||
1065 | const int32_t ang = blockangle % 2048; |
||
1066 | |||
1067 | // it's safe to make some assumptions and not go through G_AddCoordsFromRotation() since we limit to four directions |
||
1068 | switch (ang) |
||
1069 | { |
||
1070 | case 0: |
||
3849 | hendricks2 | 1071 | wrap = (x + (pos.x + xoffset) > ((orientation & 2) ? (320<<16) : ((x2 - USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 1072 | break; |
1073 | case 512: |
||
3849 | hendricks2 | 1074 | wrap = (y + (pos.x + xoffset) > ((orientation & 2) ? (200<<16) : ((y2 - USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 1075 | break; |
1076 | case 1024: |
||
3849 | hendricks2 | 1077 | wrap = (x - (pos.x + xoffset) < ((orientation & 2) ? 0 : ((x1 + USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 1078 | break; |
1079 | case 1536: |
||
3849 | hendricks2 | 1080 | wrap = (y - (pos.x + xoffset) < ((orientation & 2) ? 0 : ((y1 + USERQUOTE_RIGHTOFFSET)<<16))); |
3833 | hendricks2 | 1081 | break; |
1082 | } |
||
1083 | if (wrap) // near-CODEDUP "case '\n':" |
||
1084 | { |
||
1085 | // reset the position |
||
1086 | pos.x = 0; |
||
1087 | |||
1088 | // prepare the height |
||
1089 | { |
||
1090 | int32_t tempyextent = yline; |
||
1091 | |||
1092 | if (f & (TEXT_INTERNALLINE|TEXT_TILELINE)) |
||
1093 | { |
||
1094 | char line = 'A'; // this is subject to change as an implementation detail |
||
1095 | if (f & TEXT_TILELINE) |
||
1096 | line = '\x7F'; // tile after '~' |
||
1097 | tile = G_GetStringTile(font, &line, f); |
||
1098 | |||
4623 | terminx | 1099 | tempyextent += tilesiz[tile].y * z; |
3833 | hendricks2 | 1100 | } |
1101 | |||
1102 | SetIfGreater(&extent.y, tempyextent); |
||
1103 | } |
||
1104 | |||
1105 | // move down the line height |
||
1106 | if (!(f & TEXT_YOFFSETZERO)) |
||
1107 | pos.y += extent.y; |
||
1108 | |||
1109 | // reset the current height |
||
1110 | extent.y = 0; |
||
1111 | |||
1112 | // line spacing |
||
1113 | pos.y += ybetween; |
||
1114 | } |
||
1115 | else |
||
1116 | pos.x += xoffset; |
||
1117 | } |
||
1118 | else |
||
1119 | pos.x += xoffset; |
||
1120 | } |
||
1121 | |||
1122 | // iterate to the next character in the string |
||
1123 | text += iter; |
||
1124 | } |
||
1125 | |||
1126 | // return values in the same manner we receive them |
||
1127 | if (!(o & ROTATESPRITE_FULL16)) |
||
1128 | { |
||
1129 | size.x >>= 16; |
||
1130 | size.y >>= 16; |
||
1131 | } |
||
1132 | |||
1133 | return size; |
||
1134 | } |
||
1135 | |||
3838 | hendricks2 | 1136 | vec2_t G_ScreenTextShadow(int32_t sx, int32_t sy, |
1137 | const int32_t font, |
||
1138 | int32_t x, int32_t y, const int32_t z, const int32_t blockangle, const int32_t charangle, |
||
1139 | const char *str, const int32_t shade, int32_t pal, int32_t o, const int32_t alpha, |
||
1140 | int32_t xspace, int32_t yline, int32_t xbetween, int32_t ybetween, const int32_t f, |
||
1141 | const int32_t x1, const int32_t y1, const int32_t x2, const int32_t y2) |
||
1142 | { |
||
1143 | vec2_t size = { 0, 0, }; // eventually the return value |
||
1144 | |||
1145 | if (!(o & ROTATESPRITE_FULL16)) |
||
1146 | { |
||
1147 | sx <<= 16; |
||
1148 | sy <<= 16; |
||
1149 | x <<= 16; |
||
1150 | y <<= 16; |
||
1151 | xspace <<= 16; |
||
1152 | yline <<= 16; |
||
1153 | xbetween <<= 16; |
||
1154 | ybetween <<= 16; |
||
1155 | } |
||
1156 | |||
1157 | G_ScreenText(font, x + scale(sx,z,65536), y + scale(sy,z,65536), z, blockangle, charangle, str, 127, 4, o|ROTATESPRITE_FULL16, alpha, xspace, yline, xbetween, ybetween, f, x1, y1, x2, y2); |
||
1158 | |||
1159 | size = G_ScreenText(font, x, y, z, blockangle, charangle, str, shade, pal, o|ROTATESPRITE_FULL16, alpha, xspace, yline, xbetween, ybetween, f, x1, y1, x2, y2); |
||
1160 | |||
1161 | // return values in the same manner we receive them |
||
1162 | if (!(o & ROTATESPRITE_FULL16)) |
||
1163 | { |
||
1164 | size.x >>= 16; |
||
1165 | size.y >>= 16; |
||
1166 | } |
||
1167 | |||
1168 | return size; |
||
1169 | } |
||
1170 | |||
2961 | helixhorne | 1171 | // flags |
1172 | // 4: small font, wrap strings? |
||
3836 | hendricks2 | 1173 | int32_t G_PrintGameText(int32_t hack, int32_t tile, int32_t x, int32_t y, const char *t, |
1174 | int32_t s, int32_t p, int32_t o, |
||
4919 | terminx | 1175 | int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z, int32_t a) |
587 | terminx | 1176 | { |
3836 | hendricks2 | 1177 | vec2_t dim; |
1178 | int32_t f = TEXT_GAMETEXTNUMHACK; |
||
1179 | int32_t xbetween = 0; |
||
3849 | hendricks2 | 1180 | const int32_t orient = (hack & 4) || (hack & 1) ? (8|16|(o&1)|(o&32)) : (2|o); |
5 | Plagman | 1181 | |
1604 | terminx | 1182 | if (t == NULL) |
1183 | return -1; |
||
1184 | |||
3608 | hendricks2 | 1185 | if (!(o & ROTATESPRITE_FULL16)) |
966 | hnt_ts | 1186 | { |
3608 | hendricks2 | 1187 | x <<= 16; |
1188 | y <<= 16; |
||
966 | hnt_ts | 1189 | } |
5 | Plagman | 1190 | |
3836 | hendricks2 | 1191 | if (hack & 4) |
1604 | terminx | 1192 | { |
3836 | hendricks2 | 1193 | x = textsc(x); |
1194 | z = textsc(z); |
||
1195 | f |= TEXT_LINEWRAP; |
||
5 | Plagman | 1196 | } |
1604 | terminx | 1197 | |
3836 | hendricks2 | 1198 | if (hack & 8) |
5 | Plagman | 1199 | { |
3836 | hendricks2 | 1200 | f |= TEXT_XOFFSETZERO; |
1201 | xbetween = 8; |
||
1202 | } |
||
1604 | terminx | 1203 | |
3836 | hendricks2 | 1204 | // order is important, this bit comes after the rest |
3838 | hendricks2 | 1205 | if ((hack & 2) && !NAM) // squishtext |
3836 | hendricks2 | 1206 | --xbetween; |
1604 | terminx | 1207 | |
3836 | hendricks2 | 1208 | if (x == (160<<16)) |
1209 | f |= TEXT_XCENTER; |
||
1604 | terminx | 1210 | |
4919 | terminx | 1211 | dim = G_ScreenText(tile, x, y, z, 0, 0, t, s, p, orient|ROTATESPRITE_FULL16, a, (5<<16), (8<<16), (xbetween<<16), 0, f, x1, y1, x2, y2); |
1604 | terminx | 1212 | |
3836 | hendricks2 | 1213 | x += dim.x; |
5 | Plagman | 1214 | |
3836 | hendricks2 | 1215 | if (!(o & ROTATESPRITE_FULL16)) |
1216 | x >>= 16; |
||
1604 | terminx | 1217 | |
3836 | hendricks2 | 1218 | return x; |
5 | Plagman | 1219 | } |
1220 | |||
1205 | terminx | 1221 | int32_t G_GameTextLen(int32_t x,const char *t) |
877 | terminx | 1222 | { |
3836 | hendricks2 | 1223 | vec2_t dim; |
867 | terminx | 1224 | |
877 | terminx | 1225 | if (t == NULL) |
1226 | return -1; |
||
1227 | |||
3836 | hendricks2 | 1228 | dim = G_ScreenTextSize(STARTALPHANUM, x, 0, textsc(65536L), 0, t, 2, 5, 8, 0, 0, TEXT_GAMETEXTNUMHACK, 0, 0, xdim-1, ydim-1); |
877 | terminx | 1229 | |
3836 | hendricks2 | 1230 | x += dim.x; |
1625 | terminx | 1231 | |
3836 | hendricks2 | 1232 | return x; |
877 | terminx | 1233 | } |
1234 | |||
2944 | helixhorne | 1235 | // minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords, |
1236 | // (sb&ROTATESPRITE_MAX) only. |
||
1237 | static int32_t minitext_yofs = 0; |
||
4496 | hendricks2 | 1238 | int32_t minitext_lowercase = 0; |
1205 | terminx | 1239 | int32_t minitext_(int32_t x,int32_t y,const char *t,int32_t s,int32_t p,int32_t sb) |
5 | Plagman | 1240 | { |
3836 | hendricks2 | 1241 | vec2_t dim; |
1242 | int32_t z = 65536L; |
||
1243 | int32_t f = 0; |
||
5 | Plagman | 1244 | |
1918 | terminx | 1245 | if (t == NULL) |
1246 | { |
||
1247 | OSD_Printf("minitext: NULL text!\n"); |
||
1248 | return 0; |
||
1249 | } |
||
1884 | terminx | 1250 | |
3836 | hendricks2 | 1251 | if (!(sb & ROTATESPRITE_FULL16)) |
3608 | hendricks2 | 1252 | { |
1253 | x<<=16; |
||
1254 | y<<=16; |
||
1255 | } |
||
1256 | |||
3836 | hendricks2 | 1257 | if (!minitext_lowercase) |
1258 | f |= TEXT_UPPERCASE; |
||
1259 | |||
1260 | if (sb & ROTATESPRITE_MAX) |
||
5 | Plagman | 1261 | { |
3836 | hendricks2 | 1262 | x = sbarx16(x); |
1263 | y = minitext_yofs+sbary16(y); |
||
1264 | z = sbarsc(z); |
||
1265 | } |
||
3606 | hendricks2 | 1266 | |
3836 | hendricks2 | 1267 | sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN; |
5 | Plagman | 1268 | |
3836 | hendricks2 | 1269 | dim = G_ScreenText(MINIFONT, x, y, z, 0, 0, t, s, p, sb|ROTATESPRITE_FULL16, 0, (4<<16), (8<<16), (1<<16), 0, f, 0, 0, xdim-1, ydim-1); |
5 | Plagman | 1270 | |
3836 | hendricks2 | 1271 | x += dim.x; |
1625 | terminx | 1272 | |
3836 | hendricks2 | 1273 | if (!(sb & ROTATESPRITE_FULL16)) |
1274 | x >>= 16; |
||
1275 | |||
1276 | return x; |
||
5 | Plagman | 1277 | } |
4496 | hendricks2 | 1278 | |
1143 | terminx | 1279 | void G_AddUserQuote(const char *daquote) |
5 | Plagman | 1280 | { |
1205 | terminx | 1281 | int32_t i; |
5 | Plagman | 1282 | |
1229 | terminx | 1283 | for (i=MAXUSERQUOTES-1; i>0; i--) |
5 | Plagman | 1284 | { |
232 | terminx | 1285 | Bstrcpy(user_quote[i],user_quote[i-1]); |
5 | Plagman | 1286 | user_quote_time[i] = user_quote_time[i-1]; |
1287 | } |
||
232 | terminx | 1288 | Bstrcpy(user_quote[0],daquote); |
864 | terminx | 1289 | OSD_Printf("%s\n",daquote); |
87 | terminx | 1290 | |
88 | terminx | 1291 | user_quote_time[0] = ud.msgdisptime; |
5 | Plagman | 1292 | pub = NUMPAGES; |
1293 | } |
||
1294 | |||
1143 | terminx | 1295 | void G_HandleSpecialKeys(void) |
5 | Plagman | 1296 | { |
1552 | terminx | 1297 | // we need CONTROL_GetInput in order to pick up joystick button presses |
1298 | if (CONTROL_Started && !(g_player[myconnectindex].ps->gm & MODE_GAME)) |
||
1299 | { |
||
1300 | ControlInfo noshareinfo; |
||
1301 | CONTROL_GetInput(&noshareinfo); |
||
1302 | } |
||
1303 | |||
1632 | terminx | 1304 | // CONTROL_ProcessBinds(); |
808 | terminx | 1305 | |
1802 | terminx | 1306 | if (g_networkMode != NET_DEDICATED_SERVER && ALT_IS_PRESSED && KB_KeyPressed(sc_Enter)) |
114 | terminx | 1307 | { |
563 | terminx | 1308 | if (setgamemode(!ud.config.ScreenMode,ud.config.ScreenWidth,ud.config.ScreenHeight,ud.config.ScreenBPP)) |
335 | terminx | 1309 | { |
909 | terminx | 1310 | OSD_Printf(OSD_ERROR "Failed setting fullscreen video mode.\n"); |
563 | terminx | 1311 | if (setgamemode(ud.config.ScreenMode, ud.config.ScreenWidth, ud.config.ScreenHeight, ud.config.ScreenBPP)) |
1143 | terminx | 1312 | G_GameExit("Failed to recover from failure to set fullscreen video mode.\n"); |
114 | terminx | 1313 | } |
563 | terminx | 1314 | else ud.config.ScreenMode = !ud.config.ScreenMode; |
114 | terminx | 1315 | KB_ClearKeyDown(sc_Enter); |
1143 | terminx | 1316 | g_restorePalette = 1; |
1317 | G_UpdateScreenArea(); |
||
114 | terminx | 1318 | } |
1319 | |||
824 | terminx | 1320 | if (KB_UnBoundKeyPressed(sc_F12)) |
472 | terminx | 1321 | { |
1852 | helixhorne | 1322 | char titlebuf[256]; |
1323 | Bsprintf(titlebuf,HEAD2 " %s",s_buildRev); |
||
1324 | |||
472 | terminx | 1325 | KB_ClearKeyDown(sc_F12); |
1852 | helixhorne | 1326 | screencapture("duke0000.tga",0,titlebuf); |
1802 | terminx | 1327 | P_DoQuote(QUOTE_SCREEN_SAVED,g_player[myconnectindex].ps); |
472 | terminx | 1328 | } |
1329 | |||
5 | Plagman | 1330 | // only dispatch commands here when not in a game |
1574 | terminx | 1331 | if (!(g_player[myconnectindex].ps->gm & MODE_GAME)) |
335 | terminx | 1332 | OSD_DispatchQueued(); |
5 | Plagman | 1333 | |
1587 | terminx | 1334 | if (g_quickExit == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && (KB_KeyPressed(sc_Delete)||KB_KeyPressed(sc_End))) |
5 | Plagman | 1335 | { |
1587 | terminx | 1336 | g_quickExit = 1; |
1143 | terminx | 1337 | G_GameExit("Quick Exit."); |
5 | Plagman | 1338 | } |
1143 | terminx | 1339 | } |
5 | Plagman | 1340 | |
1571 | terminx | 1341 | void G_GameQuit(void) |
1552 | terminx | 1342 | { |
1574 | terminx | 1343 | if (numplayers < 2) |
1344 | G_GameExit(" "); |
||
1345 | |||
1346 | if (g_gameQuit == 0) |
||
1552 | terminx | 1347 | { |
1593 | terminx | 1348 | g_gameQuit = 1; |
1349 | g_quitDeadline = totalclock+120; |
||
1350 | g_netDisconnect = 1; |
||
1552 | terminx | 1351 | } |
1352 | |||
1587 | terminx | 1353 | if ((totalclock > g_quitDeadline) && (g_gameQuit == 1)) |
1552 | terminx | 1354 | G_GameExit("Timed out."); |
1355 | } |
||
1356 | |||
4255 | helixhorne | 1357 | #if !defined DEBUG_ALLOCACHE_AS_MALLOC |
1205 | terminx | 1358 | extern int32_t cacnum; |
5 | Plagman | 1359 | extern cactype cac[]; |
4255 | helixhorne | 1360 | #endif |
5 | Plagman | 1361 | |
1143 | terminx | 1362 | static void G_ShowCacheLocks(void) |
5 | Plagman | 1363 | { |
1205 | terminx | 1364 | int16_t i,k; |
5 | Plagman | 1365 | |
1916 | helixhorne | 1366 | if (offscreenrendering) |
1367 | return; |
||
1368 | |||
5 | Plagman | 1369 | k = 0; |
4255 | helixhorne | 1370 | #if !defined DEBUG_ALLOCACHE_AS_MALLOC |
1229 | terminx | 1371 | for (i=cacnum-1; i>=0; i--) |
5 | Plagman | 1372 | if ((*cac[i].lock) >= 200) |
1373 | { |
||
1916 | helixhorne | 1374 | if (k >= ydim-12) |
1375 | break; |
||
1376 | |||
584 | terminx | 1377 | Bsprintf(tempbuf,"Locked- %d: Leng:%d, Lock:%d",i,cac[i].leng,*cac[i].lock); |
335 | terminx | 1378 | printext256(0L,k,31,-1,tempbuf,1); |
1379 | k += 6; |
||
5 | Plagman | 1380 | } |
4255 | helixhorne | 1381 | #endif |
1916 | helixhorne | 1382 | if (k < ydim-12) |
1383 | k += 6; |
||
5 | Plagman | 1384 | |
1229 | terminx | 1385 | for (i=10; i>=0; i--) |
1677 | terminx | 1386 | if (rts_lumplockbyte[i] >= 200) |
5 | Plagman | 1387 | { |
1916 | helixhorne | 1388 | if (k >= ydim-12) |
1389 | break; |
||
1390 | |||
5 | Plagman | 1391 | Bsprintf(tempbuf,"RTS Locked %d:",i); |
2441 | helixhorne | 1392 | printext256(0,k,31,-1,tempbuf,1); |
335 | terminx | 1393 | k += 6; |
5 | Plagman | 1394 | } |
1916 | helixhorne | 1395 | |
1396 | if (k >= ydim-12 && k<ydim-6) |
||
2441 | helixhorne | 1397 | printext256(0,k,31,-1,"(MORE . . .)",1); |
1398 | |||
1399 | // sounds |
||
1400 | if (xdim < 640) |
||
1401 | return; |
||
1402 | |||
1403 | k = 18; |
||
1404 | for (i=0; i<=g_maxSoundPos; i++) |
||
1405 | if (g_sounds[i].num > 0) |
||
1406 | { |
||
1407 | int32_t j, n=g_sounds[i].num; |
||
1408 | |||
1409 | for (j=0; j<n; j++) |
||
1410 | { |
||
1411 | if (k >= ydim-12) |
||
1412 | break; |
||
1413 | |||
1414 | Bsprintf(tempbuf, "snd #%d inst %d: voice %d, ow %d", i, j, |
||
2442 | helixhorne | 1415 | g_sounds[i].SoundOwner[j].voice, g_sounds[i].SoundOwner[j].ow); |
2441 | helixhorne | 1416 | printext256(240,k,31,-1,tempbuf,0); |
1417 | |||
1418 | k += 9; |
||
1419 | } |
||
1420 | } |
||
5 | Plagman | 1421 | } |
1422 | |||
1205 | terminx | 1423 | int32_t A_CheckInventorySprite(spritetype *s) |
5 | Plagman | 1424 | { |
2297 | helixhorne | 1425 | switch (DYNAMICTILEMAP(s->picnum)) |
5 | Plagman | 1426 | { |
337 | terminx | 1427 | case FIRSTAID__STATIC: |
1428 | case STEROIDS__STATIC: |
||
1429 | case HEATSENSOR__STATIC: |
||
1430 | case BOOTS__STATIC: |
||
1431 | case JETPACK__STATIC: |
||
1432 | case HOLODUKE__STATIC: |
||
1433 | case AIRTANK__STATIC: |
||
1434 | return 1; |
||
1672 | terminx | 1435 | default: |
1436 | return 0; |
||
5 | Plagman | 1437 | } |
1438 | } |
||
1439 | |||
3645 | helixhorne | 1440 | // MYOS* CON commands. |
1441 | LUNATIC_EXTERN void G_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, |
||
1442 | int32_t shade, int32_t orientation, int32_t p) |
||
5 | Plagman | 1443 | { |
2896 | helixhorne | 1444 | int32_t a = 0; |
5 | Plagman | 1445 | |
3479 | helixhorne | 1446 | orientation &= (ROTATESPRITE_MAX-1); |
1447 | |||
331 | terminx | 1448 | if (orientation&4) |
5 | Plagman | 1449 | a = 1024; |
1450 | |||
3608 | hendricks2 | 1451 | if (!(orientation&ROTATESPRITE_FULL16)) |
1452 | { |
||
1453 | x<<=16; |
||
1454 | y<<=16; |
||
1455 | } |
||
1456 | |||
1457 | rotatesprite_win(x,y,zoom,a,tilenum,shade,p,2|orientation); |
||
5 | Plagman | 1458 | } |
1459 | |||
3479 | helixhorne | 1460 | #if !defined LUNATIC |
2896 | helixhorne | 1461 | void G_DrawTile(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) |
5 | Plagman | 1462 | { |
2896 | helixhorne | 1463 | DukePlayer_t *ps = g_player[screenpeek].ps; |
1464 | int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; |
||
5 | Plagman | 1465 | |
2896 | helixhorne | 1466 | G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p); |
1467 | } |
||
5 | Plagman | 1468 | |
2896 | helixhorne | 1469 | void G_DrawTilePal(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) |
1470 | { |
||
1471 | G_DrawTileGeneric(x,y,65536, tilenum,shade,orientation, p); |
||
5 | Plagman | 1472 | } |
1473 | |||
1205 | terminx | 1474 | void G_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation) |
5 | Plagman | 1475 | { |
2896 | helixhorne | 1476 | DukePlayer_t *ps = g_player[screenpeek].ps; |
1477 | int32_t p = ps->cursectnum >= 0 ? sector[ps->cursectnum].floorpal : 0; |
||
5 | Plagman | 1478 | |
2896 | helixhorne | 1479 | G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p); |
5 | Plagman | 1480 | } |
1481 | |||
1205 | terminx | 1482 | void G_DrawTilePalSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) |
5 | Plagman | 1483 | { |
2896 | helixhorne | 1484 | G_DrawTileGeneric(x,y,32768, tilenum,shade,orientation, p); |
5 | Plagman | 1485 | } |
3479 | helixhorne | 1486 | #endif |
5 | Plagman | 1487 | |
1148 | terminx | 1488 | #define POLYMOSTTRANS (1) |
1489 | #define POLYMOSTTRANS2 (1|32) |
||
1490 | |||
2944 | helixhorne | 1491 | // Draws inventory numbers in the HUD for both the full and mini status bars. |
1492 | // yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords. |
||
1493 | static void G_DrawInvNum(int32_t x, int32_t yofs, int32_t y, char num1, char ha, int32_t sbits) |
||
5 | Plagman | 1494 | { |
2896 | helixhorne | 1495 | char dabuf[16]; |
2316 | helixhorne | 1496 | int32_t i, shd = (x < 0); |
934 | terminx | 1497 | |
2896 | helixhorne | 1498 | const int32_t sbscale = sbarsc(65536); |
2944 | helixhorne | 1499 | const int32_t sby = yofs+sbary(y), sbyp1 = yofs+sbary(y+1); |
2896 | helixhorne | 1500 | |
946 | terminx | 1501 | if (shd) x = -x; |
934 | terminx | 1502 | |
2896 | helixhorne | 1503 | Bsprintf(dabuf, "%d", num1); |
1504 | |||
331 | terminx | 1505 | if (num1 > 99) |
5 | Plagman | 1506 | { |
3346 | terminx | 1507 | if (shd && ud.screen_size == 4 && getrendermode() >= REND_POLYMOST && althud_shadows) |
934 | terminx | 1508 | { |
2316 | helixhorne | 1509 | for (i=0; i<=2; i++) |
2896 | helixhorne | 1510 | rotatesprite_fs(sbarx(x+(-4+4*i)+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[i]-'0', |
3837 | hendricks2 | 1511 | 127, 4, POLYMOSTTRANS|sbits); |
934 | terminx | 1512 | } |
2316 | helixhorne | 1513 | |
1514 | for (i=0; i<=2; i++) |
||
2896 | helixhorne | 1515 | rotatesprite_fs(sbarx(x+(-4+4*i)),sby,sbscale,0,THREEBYFIVE+dabuf[i]-'0',ha, 0, sbits); |
425 | terminx | 1516 | return; |
5 | Plagman | 1517 | } |
2896 | helixhorne | 1518 | |
425 | terminx | 1519 | if (num1 > 9) |
5 | Plagman | 1520 | { |
3346 | terminx | 1521 | if (shd && ud.screen_size == 4 && getrendermode() >= REND_POLYMOST && althud_shadows) |
934 | terminx | 1522 | { |
3837 | hendricks2 | 1523 | rotatesprite_fs(sbarx(x+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[0]-'0',127,4,POLYMOSTTRANS|sbits); |
1524 | rotatesprite_fs(sbarx(x+4+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[1]-'0',127,4,POLYMOSTTRANS|sbits); |
||
934 | terminx | 1525 | } |
1526 | |||
2896 | helixhorne | 1527 | rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits); |
1528 | rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits); |
||
425 | terminx | 1529 | return; |
5 | Plagman | 1530 | } |
2896 | helixhorne | 1531 | |
1532 | rotatesprite_fs(sbarx(x+4+1),sbyp1,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,4,sbits); |
||
1533 | rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits); |
||
5 | Plagman | 1534 | } |
1535 | |||
1658 | terminx | 1536 | static void G_DrawWeapNum(int16_t ind,int32_t x,int32_t y,int32_t num1, int32_t num2,int32_t ha) |
5 | Plagman | 1537 | { |
2896 | helixhorne | 1538 | char dabuf[16]; |
5 | Plagman | 1539 | |
2896 | helixhorne | 1540 | const int32_t sbscale = sbarsc(65536); |
1541 | const int32_t sby = sbary(y); |
||
425 | terminx | 1542 | |
2896 | helixhorne | 1543 | rotatesprite_fs(sbarx(x-7),sby,sbscale,0,THREEBYFIVE+ind+1,ha-10,7,10); |
1544 | rotatesprite_fs(sbarx(x-3),sby,sbscale,0,THREEBYFIVE+10,ha,0,10); |
||
1545 | |||
425 | terminx | 1546 | if (VOLUMEONE && (ind > HANDBOMB_WEAPON || ind < 0)) |
1547 | { |
||
1658 | terminx | 1548 | minitextshade(x+1,y-4,"ORDER",20,11,2+8+16+ROTATESPRITE_MAX); |
425 | terminx | 1549 | return; |
1550 | } |
||
1551 | |||
2896 | helixhorne | 1552 | rotatesprite_fs(sbarx(x+9),sby,sbscale,0,THREEBYFIVE+11,ha,0,10); |
5 | Plagman | 1553 | |
331 | terminx | 1554 | if (num1 > 99) num1 = 99; |
1555 | if (num2 > 99) num2 = 99; |
||
5 | Plagman | 1556 | |
584 | terminx | 1557 | Bsprintf(dabuf,"%d",num1); |
331 | terminx | 1558 | if (num1 > 9) |
5 | Plagman | 1559 | { |
2896 | helixhorne | 1560 | rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1561 | rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
5 | Plagman | 1562 | } |
2896 | helixhorne | 1563 | else rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
5 | Plagman | 1564 | |
584 | terminx | 1565 | Bsprintf(dabuf,"%d",num2); |
331 | terminx | 1566 | if (num2 > 9) |
5 | Plagman | 1567 | { |
2896 | helixhorne | 1568 | rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1569 | rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
425 | terminx | 1570 | return; |
5 | Plagman | 1571 | } |
2896 | helixhorne | 1572 | rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
5 | Plagman | 1573 | } |
1574 | |||
1205 | terminx | 1575 | static void G_DrawWeapNum2(char ind,int32_t x,int32_t y,int32_t num1, int32_t num2,char ha) |
5 | Plagman | 1576 | { |
2896 | helixhorne | 1577 | char dabuf[16]; |
5 | Plagman | 1578 | |
2896 | helixhorne | 1579 | const int32_t sbscale = sbarsc(65536); |
1580 | const int32_t sby = sbary(y); |
||
5 | Plagman | 1581 | |
2896 | helixhorne | 1582 | rotatesprite_fs(sbarx(x-7),sby,sbscale,0,THREEBYFIVE+ind+1,ha-10,7,10); |
1583 | rotatesprite_fs(sbarx(x-4),sby,sbscale,0,THREEBYFIVE+10,ha,0,10); |
||
1584 | rotatesprite_fs(sbarx(x+13),sby,sbscale,0,THREEBYFIVE+11,ha,0,10); |
||
1585 | |||
584 | terminx | 1586 | Bsprintf(dabuf,"%d",num1); |
331 | terminx | 1587 | if (num1 > 99) |
5 | Plagman | 1588 | { |
2896 | helixhorne | 1589 | rotatesprite_fs(sbarx(x),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1590 | rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
1591 | rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10); |
||
5 | Plagman | 1592 | } |
331 | terminx | 1593 | else if (num1 > 9) |
5 | Plagman | 1594 | { |
2896 | helixhorne | 1595 | rotatesprite_fs(sbarx(x+4),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1596 | rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
5 | Plagman | 1597 | } |
2896 | helixhorne | 1598 | else rotatesprite_fs(sbarx(x+8),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
5 | Plagman | 1599 | |
584 | terminx | 1600 | Bsprintf(dabuf,"%d",num2); |
331 | terminx | 1601 | if (num2 > 99) |
5 | Plagman | 1602 | { |
2896 | helixhorne | 1603 | rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1604 | rotatesprite_fs(sbarx(x+21),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
1605 | rotatesprite_fs(sbarx(x+25),sby,sbscale,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10); |
||
5 | Plagman | 1606 | } |
331 | terminx | 1607 | else if (num2 > 9) |
5 | Plagman | 1608 | { |
2896 | helixhorne | 1609 | rotatesprite_fs(sbarx(x+17),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
1610 | rotatesprite_fs(sbarx(x+21),sby,sbscale,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10); |
||
425 | terminx | 1611 | return; |
5 | Plagman | 1612 | } |
587 | terminx | 1613 | else |
2896 | helixhorne | 1614 | rotatesprite_fs(sbarx(x+25),sby,sbscale,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10); |
5 | Plagman | 1615 | } |
1616 | |||
2896 | helixhorne | 1617 | static void G_DrawWeapAmounts(const DukePlayer_t *p,int32_t x,int32_t y,int32_t u) |
5 | Plagman | 1618 | { |
1205 | terminx | 1619 | int32_t cw = p->curr_weapon; |
5 | Plagman | 1620 | |
1621 | if (u&4) |
||
1622 | { |
||
1144 | terminx | 1623 | if (u != -1) G_PatchStatusBar(88,178,88+37,178+6); //original code: (96,178,96+12,178+6); |
1143 | terminx | 1624 | G_DrawWeapNum2(PISTOL_WEAPON,x,y, |
1625 | p->ammo_amount[PISTOL_WEAPON],p->max_ammo_amount[PISTOL_WEAPON], |
||
1626 | 12-20*(cw == PISTOL_WEAPON)); |
||
5 | Plagman | 1627 | } |
1628 | if (u&8) |
||
1629 | { |
||
1144 | terminx | 1630 | if (u != -1) G_PatchStatusBar(88,184,88+37,184+6); //original code: (96,184,96+12,184+6); |
1143 | terminx | 1631 | G_DrawWeapNum2(SHOTGUN_WEAPON,x,y+6, |
1632 | p->ammo_amount[SHOTGUN_WEAPON],p->max_ammo_amount[SHOTGUN_WEAPON], |
||
1625 | terminx | 1633 | (((p->gotweapon & (1<<SHOTGUN_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1634 | (cw == SHOTGUN_WEAPON)); |
5 | Plagman | 1635 | } |
1636 | if (u&16) |
||
1637 | { |
||
1144 | terminx | 1638 | if (u != -1) G_PatchStatusBar(88,190,88+37,190+6); //original code: (96,190,96+12,190+6); |
1143 | terminx | 1639 | G_DrawWeapNum2(CHAINGUN_WEAPON,x,y+12, |
1640 | p->ammo_amount[CHAINGUN_WEAPON],p->max_ammo_amount[CHAINGUN_WEAPON], |
||
1625 | terminx | 1641 | (((p->gotweapon & (1<<CHAINGUN_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1642 | (cw == CHAINGUN_WEAPON)); |
5 | Plagman | 1643 | } |
1644 | if (u&32) |
||
1645 | { |
||
1144 | terminx | 1646 | if (u != -1) G_PatchStatusBar(127,178,127+29,178+6); //original code: (135,178,135+8,178+6); |
1143 | terminx | 1647 | G_DrawWeapNum(RPG_WEAPON,x+39,y, |
1648 | p->ammo_amount[RPG_WEAPON],p->max_ammo_amount[RPG_WEAPON], |
||
1625 | terminx | 1649 | (((p->gotweapon & (1<<RPG_WEAPON)) == 0)*9)+12-19* |
1143 | terminx | 1650 | (cw == RPG_WEAPON)); |
5 | Plagman | 1651 | } |
1652 | if (u&64) |
||
1653 | { |
||
1144 | terminx | 1654 | if (u != -1) G_PatchStatusBar(127,184,127+29,184+6); //original code: (135,184,135+8,184+6); |
1143 | terminx | 1655 | G_DrawWeapNum(HANDBOMB_WEAPON,x+39,y+6, |
1656 | p->ammo_amount[HANDBOMB_WEAPON],p->max_ammo_amount[HANDBOMB_WEAPON], |
||
1625 | terminx | 1657 | (((!p->ammo_amount[HANDBOMB_WEAPON])|((p->gotweapon & (1<<HANDBOMB_WEAPON)) == 0))*9)+12-19* |
1143 | terminx | 1658 | ((cw == HANDBOMB_WEAPON) || (cw == HANDREMOTE_WEAPON))); |
5 | Plagman | 1659 | } |
1660 | if (u&128) |
||
1661 | { |
||
1144 | terminx | 1662 | if (u != -1) G_PatchStatusBar(127,190,127+29,190+6); //original code: (135,190,135+8,190+6); |
5 | Plagman | 1663 | |
425 | terminx | 1664 | if (p->subweapon&(1<<GROW_WEAPON)) |
1143 | terminx | 1665 | G_DrawWeapNum(SHRINKER_WEAPON,x+39,y+12, |
1666 | p->ammo_amount[GROW_WEAPON],p->max_ammo_amount[GROW_WEAPON], |
||
1625 | terminx | 1667 | (((p->gotweapon & (1<<GROW_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1668 | (cw == GROW_WEAPON)); |
335 | terminx | 1669 | else |
1143 | terminx | 1670 | G_DrawWeapNum(SHRINKER_WEAPON,x+39,y+12, |
1671 | p->ammo_amount[SHRINKER_WEAPON],p->max_ammo_amount[SHRINKER_WEAPON], |
||
1625 | terminx | 1672 | (((p->gotweapon & (1<<SHRINKER_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1673 | (cw == SHRINKER_WEAPON)); |
5 | Plagman | 1674 | } |
1675 | if (u&256) |
||
1676 | { |
||
1144 | terminx | 1677 | if (u != -1) G_PatchStatusBar(158,178,162+29,178+6); //original code: (166,178,166+8,178+6); |
5 | Plagman | 1678 | |
1143 | terminx | 1679 | G_DrawWeapNum(DEVISTATOR_WEAPON,x+70,y, |
1680 | p->ammo_amount[DEVISTATOR_WEAPON],p->max_ammo_amount[DEVISTATOR_WEAPON], |
||
1625 | terminx | 1681 | (((p->gotweapon & (1<<DEVISTATOR_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1682 | (cw == DEVISTATOR_WEAPON)); |
5 | Plagman | 1683 | } |
1684 | if (u&512) |
||
1685 | { |
||
1144 | terminx | 1686 | if (u != -1) G_PatchStatusBar(158,184,162+29,184+6); //original code: (166,184,166+8,184+6); |
428 | terminx | 1687 | |
1143 | terminx | 1688 | G_DrawWeapNum(TRIPBOMB_WEAPON,x+70,y+6, |
1689 | p->ammo_amount[TRIPBOMB_WEAPON],p->max_ammo_amount[TRIPBOMB_WEAPON], |
||
1625 | terminx | 1690 | (((p->gotweapon & (1<<TRIPBOMB_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1691 | (cw == TRIPBOMB_WEAPON)); |
5 | Plagman | 1692 | } |
1693 | |||
1694 | if (u&65536L) |
||
1695 | { |
||
1144 | terminx | 1696 | if (u != -1) G_PatchStatusBar(158,190,162+29,190+6); //original code: (166,190,166+8,190+6); |
425 | terminx | 1697 | |
1143 | terminx | 1698 | G_DrawWeapNum(-1,x+70,y+12, |
1699 | p->ammo_amount[FREEZE_WEAPON],p->max_ammo_amount[FREEZE_WEAPON], |
||
1625 | terminx | 1700 | (((p->gotweapon & (1<<FREEZE_WEAPON)) == 0)*9)+12-18* |
1143 | terminx | 1701 | (cw == FREEZE_WEAPON)); |
5 | Plagman | 1702 | } |
1703 | } |
||
1704 | |||
2944 | helixhorne | 1705 | // yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords. |
1706 | static void G_DrawDigiNum_(int32_t x, int32_t yofs, int32_t y, int32_t n, char s, int32_t cs) |
||
5 | Plagman | 1707 | { |
3836 | hendricks2 | 1708 | if (!(cs & ROTATESPRITE_FULL16)) |
5 | Plagman | 1709 | { |
3836 | hendricks2 | 1710 | x <<= 16; |
1711 | y <<= 16; |
||
5 | Plagman | 1712 | } |
1713 | |||
3836 | hendricks2 | 1714 | G_DrawTXDigiNumZ(DIGITALNUM, sbarx16(x), yofs + sbary16(y), n, s, 0, cs|ROTATESPRITE_FULL16, 0, 0, xdim-1, ydim-1, sbarsc(65536L)); |
5 | Plagman | 1715 | } |
1716 | |||
2944 | helixhorne | 1717 | static inline void G_DrawDigiNum(int32_t x, int32_t y, int32_t n, char s, int32_t cs) |
1718 | { |
||
1719 | G_DrawDigiNum_(x, 0, y, n, s, cs); |
||
1720 | } |
||
1721 | |||
1658 | terminx | 1722 | void G_DrawTXDigiNumZ(int32_t starttile, int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal, |
1723 | int32_t cs,int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t z) |
||
5 | Plagman | 1724 | { |
2086 | helixhorne | 1725 | char b[12]; |
3836 | hendricks2 | 1726 | Bsprintf(b,"%d",n); |
5 | Plagman | 1727 | |
3836 | hendricks2 | 1728 | if (!(cs & ROTATESPRITE_FULL16)) |
5 | Plagman | 1729 | { |
3836 | hendricks2 | 1730 | x <<= 16; |
1731 | y <<= 16; |
||
5 | Plagman | 1732 | } |
1733 | |||
3836 | hendricks2 | 1734 | G_ScreenText(starttile, x, y, z, 0, 0, b, s, pal, cs|2|ROTATESPRITE_FULL16, 0, (4<<16), (8<<16), (1<<16), 0, TEXT_XCENTER|TEXT_DIGITALNUMBER, x1, y1, x2, y2); |
5 | Plagman | 1735 | } |
1736 | |||
2566 | helixhorne | 1737 | static void G_DrawAltDigiNum(int32_t x, int32_t y, int32_t n, char s, int32_t cs) |
934 | terminx | 1738 | { |
1205 | terminx | 1739 | int32_t i, j = 0, k, p, c; |
2086 | helixhorne | 1740 | char b[12]; |
1205 | terminx | 1741 | int32_t rev = (x < 0); |
1742 | int32_t shd = (y < 0); |
||
934 | terminx | 1743 | |
2896 | helixhorne | 1744 | const int32_t sbscale = sbarsc(65536); |
1745 | |||
934 | terminx | 1746 | if (rev) x = -x; |
946 | terminx | 1747 | if (shd) y = -y; |
934 | terminx | 1748 | |
2086 | helixhorne | 1749 | i = Bsprintf(b,"%d",n); |
934 | terminx | 1750 | |
1229 | terminx | 1751 | for (k=i-1; k>=0; k--) |
934 | terminx | 1752 | { |
2566 | helixhorne | 1753 | p = althud_numbertile + b[k]-'0'; |
4623 | terminx | 1754 | j += tilesiz[p].x+1; |
934 | terminx | 1755 | } |
1756 | c = x-(j>>1); |
||
1757 | |||
1758 | if (rev) |
||
1759 | { |
||
1229 | terminx | 1760 | for (k=0; k<i; k++) |
934 | terminx | 1761 | { |
2566 | helixhorne | 1762 | p = althud_numbertile + b[k]-'0'; |
3346 | terminx | 1763 | if (shd && getrendermode() >= REND_POLYMOST && althud_shadows) |
3837 | hendricks2 | 1764 | rotatesprite_fs(sbarxr(c+j-1),sbary(y+1),sbscale,0,p,127,4,cs|POLYMOSTTRANS2); |
2896 | helixhorne | 1765 | rotatesprite_fs(sbarxr(c+j),sbary(y),sbscale,0,p,s,althud_numberpal,cs); |
4623 | terminx | 1766 | j -= tilesiz[p].x+1; |
934 | terminx | 1767 | } |
1768 | return; |
||
1769 | } |
||
2566 | helixhorne | 1770 | |
934 | terminx | 1771 | j = 0; |
1229 | terminx | 1772 | for (k=0; k<i; k++) |
934 | terminx | 1773 | { |
2566 | helixhorne | 1774 | p = althud_numbertile + b[k]-'0'; |
3346 | terminx | 1775 | if (shd && getrendermode() >= REND_POLYMOST && althud_shadows) |
3837 | hendricks2 | 1776 | rotatesprite_fs(sbarx(c+j+1),sbary(y+1),sbscale,0,p,127,4,cs|POLYMOSTTRANS2); |
2896 | helixhorne | 1777 | rotatesprite_fs(sbarx(c+j),sbary(y),sbscale,0,p,s,althud_numberpal,cs); |
4623 | terminx | 1778 | j += tilesiz[p].x+1; |
934 | terminx | 1779 | } |
1780 | } |
||
1781 | |||
3676 | hendricks2 | 1782 | static int32_t invensc(int32_t maximum) // used to reposition the inventory icon selector as the HUD scales |
1783 | { |
||
1784 | return scale(maximum << 16, ud.statusbarscale - 36, 100 - 36); |
||
1785 | } |
||
1786 | |||
2896 | helixhorne | 1787 | static void G_DrawInventory(const DukePlayer_t *p) |
5 | Plagman | 1788 | { |
3676 | hendricks2 | 1789 | int32_t n, j = 0, x = 0, y; |
5 | Plagman | 1790 | |
1572 | terminx | 1791 | n = (p->inv_amount[GET_JETPACK] > 0)<<3; |
335 | terminx | 1792 | if (n&8) j++; |
1572 | terminx | 1793 | n |= (p->inv_amount[GET_SCUBA] > 0)<<5; |
335 | terminx | 1794 | if (n&32) j++; |
1572 | terminx | 1795 | n |= (p->inv_amount[GET_STEROIDS] > 0)<<1; |
335 | terminx | 1796 | if (n&2) j++; |
1572 | terminx | 1797 | n |= (p->inv_amount[GET_HOLODUKE] > 0)<<2; |
335 | terminx | 1798 | if (n&4) j++; |
1572 | terminx | 1799 | n |= (p->inv_amount[GET_FIRSTAID] > 0); |
335 | terminx | 1800 | if (n&1) j++; |
1572 | terminx | 1801 | n |= (p->inv_amount[GET_HEATS] > 0)<<4; |
335 | terminx | 1802 | if (n&16) j++; |
1572 | terminx | 1803 | n |= (p->inv_amount[GET_BOOTS] > 0)<<6; |
335 | terminx | 1804 | if (n&64) j++; |
5 | Plagman | 1805 | |
3676 | hendricks2 | 1806 | x = (160-(j*11))<<16; // nearly center |
5 | Plagman | 1807 | |
1808 | j = 0; |
||
1809 | |||
3676 | hendricks2 | 1810 | if (ud.screen_size < 8) // mini-HUDs or no HUD |
1811 | { |
||
1812 | y = 172<<16; |
||
5 | Plagman | 1813 | |
4595 | terminx | 1814 | if (ud.screen_size == 4 && ud.althud == 1) // modern mini-HUD |
4623 | terminx | 1815 | y -= invensc(tilesiz[BIGALPHANUM].y+10); // slide on the y-axis |
3676 | hendricks2 | 1816 | } |
1817 | else // full HUD |
||
1818 | { |
||
4623 | terminx | 1819 | y = (200<<16) - (sbarsc(tilesiz[BOTTOMSTATUSBAR].y<<16) + (12<<16) + (tilesiz[BOTTOMSTATUSBAR].y<<(16-1))); |
3676 | hendricks2 | 1820 | |
1821 | if (!ud.statusbarmode) // original non-overlay mode |
||
4623 | terminx | 1822 | y += sbarsc(tilesiz[BOTTOMSTATUSBAR].y<<16)>>1; // account for the viewport y-size as the HUD scales |
3676 | hendricks2 | 1823 | } |
1824 | |||
1825 | if (ud.screen_size == 4 && !ud.althud) // classic mini-HUD |
||
1826 | x += invensc(ud.multimode > 1 ? 56 : 65); // slide on the x-axis |
||
1827 | |||
333 | terminx | 1828 | while (j <= 9) |
5 | Plagman | 1829 | { |
333 | terminx | 1830 | if (n&(1<<j)) |
5 | Plagman | 1831 | { |
333 | terminx | 1832 | switch (n&(1<<j)) |
5 | Plagman | 1833 | { |
1632 | terminx | 1834 | case 1: |
3676 | hendricks2 | 1835 | rotatesprite_win(x,y,65536L,0,FIRSTAID_ICON,0,0,2+16); |
337 | terminx | 1836 | break; |
1632 | terminx | 1837 | case 2: |
3676 | hendricks2 | 1838 | rotatesprite_win(x+(1<<16),y,65536L,0,STEROIDS_ICON,0,0,2+16); |
337 | terminx | 1839 | break; |
1632 | terminx | 1840 | case 4: |
3676 | hendricks2 | 1841 | rotatesprite_win(x+(2<<16),y,65536L,0,HOLODUKE_ICON,0,0,2+16); |
337 | terminx | 1842 | break; |
1632 | terminx | 1843 | case 8: |
3676 | hendricks2 | 1844 | rotatesprite_win(x,y,65536L,0,JETPACK_ICON,0,0,2+16); |
337 | terminx | 1845 | break; |
1632 | terminx | 1846 | case 16: |
3676 | hendricks2 | 1847 | rotatesprite_win(x,y,65536L,0,HEAT_ICON,0,0,2+16); |
337 | terminx | 1848 | break; |
1632 | terminx | 1849 | case 32: |
3676 | hendricks2 | 1850 | rotatesprite_win(x,y,65536L,0,AIRTANK_ICON,0,0,2+16); |
337 | terminx | 1851 | break; |
1852 | case 64: |
||
3676 | hendricks2 | 1853 | rotatesprite_win(x,y-(1<<16),65536L,0,BOOT_ICON,0,0,2+16); |
337 | terminx | 1854 | break; |
5 | Plagman | 1855 | } |
1856 | |||
3676 | hendricks2 | 1857 | x += 22<<16; |
5 | Plagman | 1858 | |
331 | terminx | 1859 | if (p->inven_icon == j+1) |
3676 | hendricks2 | 1860 | rotatesprite_win(x-(2<<16),y+(19<<16),65536L,1024,ARROW,-32,0,2+16); |
5 | Plagman | 1861 | } |
1862 | |||
1863 | j++; |
||
1864 | } |
||
1865 | } |
||
1866 | |||
1143 | terminx | 1867 | void G_DrawFrags(void) |
5 | Plagman | 1868 | { |
1205 | terminx | 1869 | int32_t i, j = 0; |
2896 | helixhorne | 1870 | const int32_t orient = 2+8+16+64; |
5 | Plagman | 1871 | |
2379 | helixhorne | 1872 | for (TRAVERSE_CONNECT(i)) |
2896 | helixhorne | 1873 | if (i > j) |
1874 | j = i; |
||
5 | Plagman | 1875 | |
2896 | helixhorne | 1876 | for (i=0; i<=(j>>2); i++) |
1877 | rotatesprite_fs(0,(8*i)<<16,65600, 0, FRAGBAR, 0,0,orient); |
||
5 | Plagman | 1878 | |
2379 | helixhorne | 1879 | for (TRAVERSE_CONNECT(i)) |
5 | Plagman | 1880 | { |
2896 | helixhorne | 1881 | const DukePlayer_t *ps = g_player[i].ps; |
1882 | minitext(21+(73*(i&3)), 2+((i&28)<<1), g_player[i].user_name, ps->palookup, 2+8+16); |
||
1883 | Bsprintf(tempbuf, "%d", ps->frag-ps->fraggedself); |
||
1884 | minitext(17+50+(73*(i&3)), 2+((i&28)<<1), tempbuf, ps->palookup, 2+8+16); |
||
5 | Plagman | 1885 | } |
1886 | } |
||
1887 | |||
2896 | helixhorne | 1888 | static int32_t G_GetInvAmount(const DukePlayer_t *p) |
1889 | { |
||
1890 | switch (p->inven_icon) |
||
1891 | { |
||
3115 | terminx | 1892 | case ICON_FIRSTAID: |
2896 | helixhorne | 1893 | return p->inv_amount[GET_FIRSTAID]; |
3115 | terminx | 1894 | case ICON_STEROIDS: |
2896 | helixhorne | 1895 | return ((p->inv_amount[GET_STEROIDS]+3)>>2); |
3115 | terminx | 1896 | case ICON_HOLODUKE: |
2896 | helixhorne | 1897 | return ((p->inv_amount[GET_HOLODUKE]+15)/24); |
3115 | terminx | 1898 | case ICON_JETPACK: |
2896 | helixhorne | 1899 | return ((p->inv_amount[GET_JETPACK]+15)>>4); |
3115 | terminx | 1900 | case ICON_HEATS: |
2896 | helixhorne | 1901 | return p->inv_amount[GET_HEATS]/12; |
3115 | terminx | 1902 | case ICON_SCUBA: |
2896 | helixhorne | 1903 | return ((p->inv_amount[GET_SCUBA]+63)>>6); |
3115 | terminx | 1904 | case ICON_BOOTS: |
2896 | helixhorne | 1905 | return (p->inv_amount[GET_BOOTS]>>1); |
1906 | } |
||
261 | terminx | 1907 | |
2896 | helixhorne | 1908 | return -1; |
1909 | } |
||
1910 | |||
1911 | static int32_t G_GetInvOn(const DukePlayer_t *p) |
||
1912 | { |
||
1913 | switch (p->inven_icon) |
||
1914 | { |
||
3115 | terminx | 1915 | case ICON_HOLODUKE: |
2896 | helixhorne | 1916 | return p->holoduke_on; |
3115 | terminx | 1917 | case ICON_JETPACK: |
2896 | helixhorne | 1918 | return p->jetpack_on; |
3115 | terminx | 1919 | case ICON_HEATS: |
2896 | helixhorne | 1920 | return p->heat_on; |
1921 | } |
||
1922 | |||
1923 | return 0x80000000; |
||
1924 | } |
||
1925 | |||
3556 | helixhorne | 1926 | static int32_t G_GetMorale(int32_t p_i, int32_t snum) |
1927 | { |
||
1928 | #if !defined LUNATIC |
||
1929 | return Gv_GetVarByLabel("PLR_MORALE",-1, p_i, snum); |
||
1930 | #else |
||
3557 | helixhorne | 1931 | UNREFERENCED_PARAMETER(p_i); |
1932 | UNREFERENCED_PARAMETER(snum); |
||
3556 | helixhorne | 1933 | return -1; |
1934 | #endif |
||
1935 | } |
||
1936 | |||
4595 | terminx | 1937 | static inline void rotatesprite_althud(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,int8_t dashade, char dapalnum, int32_t dastat) |
1938 | { |
||
1939 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
||
1940 | rotatesprite_(sbarx(sx+1), sbary(sy+1), z, a, picnum, 127, 4, dastat + POLYMOSTTRANS2, 0, 0, 0, 0, xdim - 1, ydim - 1); |
||
1941 | rotatesprite_(sbarx(sx), sbary(sy), z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0, 0, xdim - 1, ydim - 1); |
||
1942 | } |
||
1943 | |||
1944 | static inline void rotatesprite_althudr(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, char dapalnum, int32_t dastat) |
||
1945 | { |
||
1946 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
||
1947 | rotatesprite_(sbarxr(sx + 1), sbary(sy + 1), z, a, picnum, 127, 4, dastat + POLYMOSTTRANS2, 0, 0, 0, 0, xdim - 1, ydim - 1); |
||
1948 | rotatesprite_(sbarxr(sx), sbary(sy), z, a, picnum, dashade, dapalnum, dastat, 0, 0, 0, 0, xdim - 1, ydim - 1); |
||
1949 | } |
||
1950 | |||
1205 | terminx | 1951 | static void G_DrawStatusBar(int32_t snum) |
5 | Plagman | 1952 | { |
2896 | helixhorne | 1953 | const DukePlayer_t *const p = g_player[snum].ps; |
2900 | helixhorne | 1954 | int32_t i, j, o, u; |
1205 | terminx | 1955 | int32_t permbit = 0; |
5 | Plagman | 1956 | |
4249 | hendricks2 | 1957 | #ifdef SPLITSCREEN_MOD_HACKS |
2944 | helixhorne | 1958 | const int32_t ss = g_fakeMultiMode ? 4 : ud.screen_size; |
2900 | helixhorne | 1959 | const int32_t althud = g_fakeMultiMode ? 0 : ud.althud; |
4249 | hendricks2 | 1960 | #else |
1961 | const int32_t ss = ud.screen_size; |
||
1962 | const int32_t althud = ud.althud; |
||
1963 | #endif |
||
2900 | helixhorne | 1964 | |
4623 | terminx | 1965 | const int32_t SBY = (200-tilesiz[BOTTOMSTATUSBAR].y); |
532 | terminx | 1966 | |
2896 | helixhorne | 1967 | const int32_t sb15 = sbarsc(32768), sb15h = sbarsc(49152); |
1968 | const int32_t sb16 = sbarsc(65536); |
||
1969 | |||
1970 | static int32_t item_icons[8]; |
||
1971 | |||
1972 | if (ss < 4) |
||
1973 | return; |
||
1974 | |||
1975 | if (item_icons[0] == 0) |
||
1976 | { |
||
1977 | int32_t iicons[8] = { -1, FIRSTAID_ICON, STEROIDS_ICON, HOLODUKE_ICON, |
||
1978 | JETPACK_ICON, HEAT_ICON, AIRTANK_ICON, BOOT_ICON }; |
||
1979 | Bmemcpy(item_icons, iicons, sizeof(item_icons)); |
||
1980 | } |
||
1981 | |||
3346 | terminx | 1982 | if (getrendermode() >= REND_POLYMOST) pus = NUMPAGES; // JBF 20040101: always redraw in GL |
5 | Plagman | 1983 | |
2901 | helixhorne | 1984 | if ((g_netServer || ud.multimode > 1) && ((GametypeFlags[ud.coop] & GAMETYPE_FRAGBAR) || g_fakeMultiMode)) |
5 | Plagman | 1985 | { |
1986 | if (pus) |
||
1143 | terminx | 1987 | G_DrawFrags(); |
5 | Plagman | 1988 | else |
1989 | { |
||
2379 | helixhorne | 1990 | for (TRAVERSE_CONNECT(i)) |
1991 | if (g_player[i].ps->frag != sbar.frag[i]) |
||
1992 | { |
||
1993 | G_DrawFrags(); |
||
1994 | break; |
||
1995 | } |
||
331 | terminx | 1996 | |
5 | Plagman | 1997 | } |
2379 | helixhorne | 1998 | for (TRAVERSE_CONNECT(i)) |
1999 | if (i != myconnectindex) |
||
2000 | sbar.frag[i] = g_player[i].ps->frag; |
||
5 | Plagman | 2001 | } |
2002 | |||
2003 | if (ss == 4) //DRAW MINI STATUS BAR: |
||
2004 | { |
||
2900 | helixhorne | 2005 | if (althud) |
934 | terminx | 2006 | { |
2900 | helixhorne | 2007 | // ALTERNATIVE STATUS BAR |
2008 | |||
4595 | terminx | 2009 | int32_t hudoffset = althud == 2 ? 32 : 200; |
1205 | terminx | 2010 | static int32_t ammo_sprites[MAX_WEAPONS]; |
934 | terminx | 2011 | |
5057 | hendricks2 | 2012 | if (EDUKE32_PREDICT_FALSE(ammo_sprites[0] == 0)) |
934 | terminx | 2013 | { |
2014 | /* this looks stupid but it lets us initialize static memory to dynamic values |
||
2015 | these values can be changed from the CONs with dynamic tile remapping |
||
2016 | but we don't want to have to recreate the values in memory every time |
||
2017 | the HUD is drawn */ |
||
2018 | |||
5057 | hendricks2 | 2019 | int32_t asprites[MAX_WEAPONS] = { -1, AMMO, SHOTGUNAMMO, BATTERYAMMO, |
2896 | helixhorne | 2020 | RPGAMMO, HBOMBAMMO, CRYSTALAMMO, DEVISTATORAMMO, |
1207 | terminx | 2021 | TRIPBOMBSPRITE, FREEZEAMMO+1, HBOMBAMMO, GROWAMMO |
2022 | }; |
||
2896 | helixhorne | 2023 | Bmemcpy(ammo_sprites, asprites, sizeof(ammo_sprites)); |
934 | terminx | 2024 | } |
2025 | |||
2896 | helixhorne | 2026 | // rotatesprite_fs(sbarx(5+1),sbary(200-25+1),sb15h,0,SIXPAK,0,4,10+16+1+32); |
2027 | // rotatesprite_fs(sbarx(5),sbary(200-25),sb15h,0,SIXPAK,0,0,10+16); |
||
4595 | terminx | 2028 | rotatesprite_althud(2,hudoffset-21,sb15h,0,COLA,0,0,10+16+256); |
935 | terminx | 2029 | |
934 | terminx | 2030 | if (sprite[p->i].pal == 1 && p->last_extra < 2) |
4595 | terminx | 2031 | G_DrawAltDigiNum(40,-(hudoffset-22),1,-16,10+16+256); |
953 | terminx | 2032 | else if (!althud_flashing || p->last_extra > (p->max_player_health>>2) || totalclock&32) |
1089 | terminx | 2033 | { |
1205 | terminx | 2034 | int32_t s = -8; |
1089 | terminx | 2035 | if (althud_flashing && p->last_extra > p->max_player_health) |
2036 | s += (sintable[(totalclock<<5)&2047]>>10); |
||
4595 | terminx | 2037 | G_DrawAltDigiNum(40,-(hudoffset-22),p->last_extra,s,10+16+256); |
1089 | terminx | 2038 | } |
934 | terminx | 2039 | |
4595 | terminx | 2040 | rotatesprite_althud(62,hudoffset-25,sb15h,0,SHIELD,0,0,10+16+256); |
934 | terminx | 2041 | |
1490 | terminx | 2042 | { |
3556 | helixhorne | 2043 | int32_t lAmount = G_GetMorale(p->i, snum); |
2044 | if (lAmount == -1) |
||
2045 | lAmount = p->inv_amount[GET_SHIELD]; |
||
4595 | terminx | 2046 | G_DrawAltDigiNum(105,-(hudoffset-22),lAmount,-16,10+16+256); |
1490 | terminx | 2047 | } |
1658 | terminx | 2048 | |
5057 | hendricks2 | 2049 | if (ammo_sprites[p->curr_weapon] >= 0) |
2050 | { |
||
2051 | i = (tilesiz[ammo_sprites[p->curr_weapon]].y >= 50) ? 16384 : 32768; |
||
2052 | rotatesprite_althudr(57,hudoffset-15,sbarsc(i),0,ammo_sprites[p->curr_weapon],0,0,10+512); |
||
2053 | } |
||
934 | terminx | 2054 | |
4650 | terminx | 2055 | if (PWEAPON(snum, p->curr_weapon, WorksLike) == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON; |
934 | terminx | 2056 | else i = p->curr_weapon; |
1658 | terminx | 2057 | |
4650 | terminx | 2058 | if (PWEAPON(snum, p->curr_weapon, WorksLike) != KNEE_WEAPON && |
962 | terminx | 2059 | (!althud_flashing || totalclock&32 || p->ammo_amount[i] > (p->max_ammo_amount[i]/10))) |
4595 | terminx | 2060 | G_DrawAltDigiNum(-20,-(hudoffset-22),p->ammo_amount[i],-16,10+16+512); |
934 | terminx | 2061 | |
941 | terminx | 2062 | o = 102; |
934 | terminx | 2063 | permbit = 0; |
2064 | |||
2065 | if (p->inven_icon) |
||
2066 | { |
||
2896 | helixhorne | 2067 | const int32_t orient = 10+16+permbit+256; |
2068 | |||
3115 | terminx | 2069 | i = ((unsigned)p->inven_icon < ICON_MAX) ? item_icons[p->inven_icon] : -1; |
4595 | terminx | 2070 | |
934 | terminx | 2071 | if (i >= 0) |
4595 | terminx | 2072 | rotatesprite_althud(231-o,hudoffset-21-2,sb16,0,i,0,0,orient); |
934 | terminx | 2073 | |
3346 | terminx | 2074 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
4595 | terminx | 2075 | minitextshade(292-30-o+1,hudoffset-10-3+1,"%",127,4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX); |
2076 | minitext(292-30-o,hudoffset-10-3,"%",6, orient+ROTATESPRITE_MAX); |
||
934 | terminx | 2077 | |
2896 | helixhorne | 2078 | i = G_GetInvAmount(p); |
2079 | j = G_GetInvOn(p); |
||
2080 | |||
4595 | terminx | 2081 | G_DrawInvNum(-(284-30-o),0,hudoffset-6-3,(uint8_t)i,0,10+permbit+256); |
2896 | helixhorne | 2082 | |
934 | terminx | 2083 | if (j > 0) |
2084 | { |
||
3346 | terminx | 2085 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
4595 | terminx | 2086 | minitextshade(288-30-o+1,hudoffset-20-3+1,"On",127,4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX); |
2087 | minitext(288-30-o,hudoffset-20-3,"On",0, orient+ROTATESPRITE_MAX); |
||
934 | terminx | 2088 | } |
1205 | terminx | 2089 | else if ((uint32_t)j != 0x80000000) |
934 | terminx | 2090 | { |
3346 | terminx | 2091 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
4595 | terminx | 2092 | minitextshade(284-30-o+1,hudoffset-20-3+1,"Off",127,4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX); |
2093 | minitext(284-30-o,hudoffset-20-3,"Off",2, orient+ROTATESPRITE_MAX); |
||
934 | terminx | 2094 | } |
1677 | terminx | 2095 | |
3115 | terminx | 2096 | if (p->inven_icon >= ICON_SCUBA) |
934 | terminx | 2097 | { |
3346 | terminx | 2098 | if (getrendermode() >= REND_POLYMOST && althud_shadows) |
4595 | terminx | 2099 | minitextshade(284-35-o+1,hudoffset-20-3+1,"Auto",127,4, POLYMOSTTRANS+orient+ROTATESPRITE_MAX); |
2100 | minitext(284-35-o,hudoffset-20-3,"Auto",2, orient+ROTATESPRITE_MAX); |
||
934 | terminx | 2101 | } |
2102 | } |
||
4602 | terminx | 2103 | |
2104 | if (ud.althud == 2) |
||
2105 | hudoffset += 40; |
||
2106 | |||
2107 | if (p->got_access&1) rotatesprite_althudr(39, hudoffset-43, sb15, 0, ACCESSCARD, 0, 0, 10+16+512); |
||
2108 | if (p->got_access&4) rotatesprite_althudr(34, hudoffset-41, sb15, 0, ACCESSCARD, 0, 23, 10+16+512); |
||
2109 | if (p->got_access&2) rotatesprite_althudr(29, hudoffset-39, sb15, 0, ACCESSCARD, 0, 21, 10+16+512); |
||
934 | terminx | 2110 | } |
2900 | helixhorne | 2111 | else |
2112 | { |
||
2113 | // ORIGINAL MINI STATUS BAR |
||
4249 | hendricks2 | 2114 | int32_t orient = 2+8+16+256, yofssh=0; |
1658 | terminx | 2115 | |
4249 | hendricks2 | 2116 | #ifdef SPLITSCREEN_MOD_HACKS |
2117 | int32_t yofs=0; |
||
2118 | |||
2944 | helixhorne | 2119 | if (g_fakeMultiMode) |
2120 | { |
||
2121 | const int32_t sidebyside = (ud.screen_size!=0); |
||
2122 | |||
2123 | if (sidebyside && snum==1) |
||
2124 | { |
||
2125 | orient |= RS_CENTERORIGIN; |
||
2126 | } |
||
2127 | else if (!sidebyside && snum==0) |
||
2128 | { |
||
2129 | yofs = -100; |
||
2130 | yofssh = yofs<<16; |
||
2131 | } |
||
2132 | } |
||
4249 | hendricks2 | 2133 | #endif |
2944 | helixhorne | 2134 | |
2135 | rotatesprite_fs(sbarx(5), yofssh+sbary(200-28), sb16, 0, HEALTHBOX, 0, 21, orient); |
||
2900 | helixhorne | 2136 | if (p->inven_icon) |
2944 | helixhorne | 2137 | rotatesprite_fs(sbarx(69), yofssh+sbary(200-30), sb16, 0, INVENTORYBOX, 0, 21, orient); |
5 | Plagman | 2138 | |
2902 | helixhorne | 2139 | // health |
2935 | helixhorne | 2140 | { |
2141 | int32_t health = (sprite[p->i].pal == 1 && p->last_extra < 2) ? 1 : p->last_extra; |
||
2944 | helixhorne | 2142 | G_DrawDigiNum_(20, yofssh, 200-17, health, -16, orient); |
2935 | helixhorne | 2143 | } |
5 | Plagman | 2144 | |
2944 | helixhorne | 2145 | rotatesprite_fs(sbarx(37), yofssh+sbary(200-28), sb16, 0, AMMOBOX, 0, 21, orient); |
5 | Plagman | 2146 | |
4650 | terminx | 2147 | if (PWEAPON(snum, p->curr_weapon, WorksLike) == HANDREMOTE_WEAPON) |
2944 | helixhorne | 2148 | i = HANDBOMB_WEAPON; |
2149 | else |
||
2150 | i = p->curr_weapon; |
||
2151 | G_DrawDigiNum_(53, yofssh, 200-17, p->ammo_amount[i], -16, orient); |
||
5 | Plagman | 2152 | |
2900 | helixhorne | 2153 | o = 158; |
2154 | permbit = 0; |
||
2155 | if (p->inven_icon) |
||
2156 | { |
||
2935 | helixhorne | 2157 | // orient |= permbit; |
5 | Plagman | 2158 | |
3115 | terminx | 2159 | i = ((unsigned)p->inven_icon < ICON_MAX) ? item_icons[p->inven_icon] : -1; |
2900 | helixhorne | 2160 | if (i >= 0) |
2944 | helixhorne | 2161 | rotatesprite_fs(sbarx(231-o), yofssh+sbary(200-21), sb16, 0, i, 0, 0, orient); |
5 | Plagman | 2162 | |
2935 | helixhorne | 2163 | // scale by status bar size |
2164 | orient |= ROTATESPRITE_MAX; |
||
2896 | helixhorne | 2165 | |
2944 | helixhorne | 2166 | minitext_yofs = yofssh; |
2167 | minitext(292-30-o, 190, "%", 6, orient); |
||
2902 | helixhorne | 2168 | |
2900 | helixhorne | 2169 | i = G_GetInvAmount(p); |
2170 | j = G_GetInvOn(p); |
||
2896 | helixhorne | 2171 | |
2944 | helixhorne | 2172 | G_DrawInvNum(284-30-o, yofssh, 200-6, (uint8_t)i, 0, orient&~16); |
2896 | helixhorne | 2173 | |
2900 | helixhorne | 2174 | if (j > 0) |
2944 | helixhorne | 2175 | minitext(288-30-o, 180, "On", 0, orient); |
2900 | helixhorne | 2176 | else if ((uint32_t)j != 0x80000000) |
2944 | helixhorne | 2177 | minitext(284-30-o, 180, "Off", 2, orient); |
2896 | helixhorne | 2178 | |
3115 | terminx | 2179 | if (p->inven_icon >= ICON_SCUBA) |
2944 | helixhorne | 2180 | minitext(284-35-o, 180, "Auto", 2, orient); |
2181 | |||
2182 | minitext_yofs = 0; |
||
2900 | helixhorne | 2183 | } |
5 | Plagman | 2184 | } |
2900 | helixhorne | 2185 | |
5 | Plagman | 2186 | return; |
2187 | } |
||
2188 | |||
2189 | //DRAW/UPDATE FULL STATUS BAR: |
||
2190 | |||
335 | terminx | 2191 | if (pus) |
2192 | { |
||
2193 | pus = 0; |
||
2194 | u = -1; |
||
2195 | } |
||
331 | terminx | 2196 | else u = 0; |
5 | Plagman | 2197 | |
335 | terminx | 2198 | if (sbar.frag[myconnectindex] != p->frag) |
2199 | { |
||
2200 | sbar.frag[myconnectindex] = p->frag; |
||
2201 | u |= 32768; |
||
2202 | } |
||
2203 | if (sbar.got_access != p->got_access) |
||
2204 | { |
||
2205 | sbar.got_access = p->got_access; |
||
2206 | u |= 16384; |
||
2207 | } |
||
261 | terminx | 2208 | |
423 | terminx | 2209 | if (sbar.last_extra != p->last_extra) |
5 | Plagman | 2210 | { |
423 | terminx | 2211 | sbar.last_extra = p->last_extra; |
2212 | u |= 1; |
||
2213 | } |
||
2214 | |||
2215 | { |
||
3556 | helixhorne | 2216 | int32_t lAmount = G_GetMorale(p->i, snum); |
331 | terminx | 2217 | if (lAmount == -1) |
2896 | helixhorne | 2218 | lAmount = p->inv_amount[GET_SHIELD]; |
2219 | if (sbar.inv_amount[GET_SHIELD] != |