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