DEADSOFTWARE

fully move highter level rendering code in separate file
[flatwaifu.git] / src / render.c
1 #include <string.h>
2 #include <stdarg.h>
3 #include "glob.h"
4 #include "render.h"
5 #include "view.h"
6 #include "player.h"
7 #include "switch.h"
8 #include "vga.h"
9 #include "menu.h"
10 #include "misc.h"
11 #include "dots.h"
12 #include "items.h"
13 #include "monster.h"
14 #include "weapons.h"
15 #include "smoke.h"
16 #include "fx.h"
17 #include "memory.h"
19 // game
20 static vgaimg *scrnh[3]; // TITLEPIC INTERPIC ENDPIC
21 static vgaimg *ltn[2][2];
22 static void *cd_scr;
23 // smoke
24 static vgaimg *smk_spr[SMSN];
25 static vgaimg *smk_fspr[FLSN];
26 // fx
27 static vgaimg *fx_spr[15];
28 static char fx_sprd[15];
29 // weapons
30 static vgaimg *wp_spr[49*2];
31 static char wp_sprd[49*2];
32 // items
33 static vgaimg *item_spr[58];
34 static char item_sprd[58];
35 // player
36 static vgaimg *plr_spr[27*2];
37 static char plr_sprd[27*2];
38 static vgaimg *plr_wpn[11][6];
39 // monsters
40 static vgaimg *pl_spr[2];
41 static vgaimg *mn_spr[MN_TN][29*2];
42 static char mn_sprd[MN_TN][29*2];
43 static vgaimg *mn_fspr[8];
44 static vgaimg *mn_sgun[2];
45 // misc
46 #define MAXAIR 1091
47 static vgaimg *sth[22], *bfh[160 - '!'], *sfh[160 - '!'], *stone, *stone2, *keys[3];
48 static int prx = 0, pry = 0;
49 // menu
50 static vgaimg *msklh[2], *mbarl, *mbarm, *mbarr, *mbaro, *mslotl, *mslotm, *mslotr;
52 extern byte clrmap[256*12]; // main.c
54 extern int g_trans; // game.c
55 extern byte transdraw; // game.c
56 extern void *horiz; // view.c
57 extern int sky_type; // view.c
58 extern int lt_time, lt_type, lt_side, lt_ypos, lt_force; // game.c
60 extern byte savname[7][24]; // files.c
61 extern char g_music[8]; // game.c
62 extern short snd_vol; // sound.c
63 extern short mus_vol; // music.c
65 void Z_drawfld(byte *, int); // vga.c
67 /* --- misc --- */
69 static void *Z_getspr (char n[4], int s, int d, char *dir) {
70 int h = F_getsprid(n, s, d);
71 if (dir) {
72 *dir = (h & 0x8000) ? 1 : 0;
73 }
74 return V_getvgaimg(h);
75 }
77 static void Z_putbfch (int c) {
78 vgaimg *p;
79 if (c > 32 && c < 160) {
80 p = bfh[c - '!'];
81 } else {
82 p = NULL;
83 }
84 if (p) {
85 V_spr(prx, pry, p);
86 prx += p->w - 1;
87 } else {
88 prx += 12;
89 }
90 }
92 static void Z_putsfch(int c) {
93 vgaimg *p;
94 if (c > 32 && c < 160) {
95 p = sfh[c - '!'];
96 } else {
97 p = NULL;
98 }
99 if (p) {
100 V_spr(prx, pry, p);
101 prx += p->w - 1;
102 } else {
103 prx += 7;
107 static void Z_gotoxy (int x, int y) {
108 prx = x;
109 pry = y;
112 static void Z_printbf(char *s, ...) {
113 int i;
114 va_list ap;
115 char buf[80];
116 va_start(ap, s);
117 vsprintf(buf, s, ap);
118 va_end(ap);
119 for (i = 0; buf[i]; ++i) {
120 switch (buf[i]) {
121 case '\n':
122 pry += 13;
123 case '\r':
124 prx = 0;
125 break;
126 default:
127 Z_putbfch((byte)buf[i]);
132 static void Z_printsf (char *s, ...) {
133 int i;
134 va_list ap;
135 char buf[80];
136 va_start(ap, s);
137 vsprintf(buf, s, ap);
138 va_end(ap);
139 for (i = 0; buf[i]; ++i) {
140 switch(buf[i]) {
141 case '\n':
142 pry += 8;
143 case '\r':
144 prx=0;
145 break;
146 default:
147 Z_putsfch((byte)buf[i]);
152 static void Z_drawspr (int x, int y, void *p, char d) {
153 if (d) {
154 V_spr2(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p);
155 } else {
156 V_spr(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p);
160 static void Z_clrst (void) {
161 V_pic(SCRW - 120, w_o, stone);
162 int y = ((vgaimg*)stone)->h;
163 while (y < HT) {
164 V_pic(SCRW - 120, w_o + y, stone2);
165 y += ((vgaimg*)stone)->h;
169 static void Z_drawstlives (char n) {
170 V_setrect(SCRW - 40, 30, w_o, 40);
171 V_spr(SCRW - 35, w_o + 17, sth[n]);
174 static void Z_drawstkeys (byte k) {
175 int x, n;
176 V_setrect(SCRW - 120, 70, w_o + 77, 23);
177 for (k >>= 4, n = 0, x = SCRW - 75; n < 3; ++n, k >>= 1, x += 9) {
178 if (k & 1) {
179 V_spr(x, w_o + 91, keys[n]);
184 static void Z_drawstair (int a) {
185 V_setrect(SCRW - 120, 120, w_o + 49, 2);
186 if (a > 0) {
187 if (a > MAXAIR) {
188 a = MAXAIR;
190 a = a * 100 / MAXAIR;
191 V_clr(SCRW - 110, a, w_o + 49, 2, 0xC8);
195 static void Z_drawstprcnt (int y, int n) {
196 char s[20];
197 int l, i, x, c;
198 V_setrect(SCRW - 120, 70, y * 19 + 7 + w_o, 19);
199 sprintf(s, "%3d%%", n);
200 l = strlen(s);
201 x = SCRW - 110;
202 for (i = 0; i < l; ++i, x += 14) {
203 if (s[i] >='0' && s[i] <= '9') {
204 c = s[i] - '0';
205 } else if (s[i] == '-') {
206 c = 10;
207 } else if (s[i] == '%') {
208 c = 11;
209 } else {
210 c = -1;
212 if (c >= 0) {
213 V_spr(x, y * 19 + 7 + w_o, sth[c]);
218 static void Z_drawstnum (int n) {
219 char s[20];
220 int l, i, x, c;
221 V_setrect(SCRW - 50, 50, w_o + 77, 23);
222 if (g_dm) {
223 sprintf(s, "%d", n);
224 l = strlen(s);
225 x = (115 - l * 14) + SCRW - 120;
226 for (i = 0; i < l; ++i, x += 14) {
227 if (s[i] >= '0' && s[i] <= '9') {
228 c = s[i] - '0';
229 } else if (s[i] == '-') {
230 c = 10;
231 } else if(s[i] == '%') {
232 c = 11;
233 } else {
234 c =- 1;
236 if (c >= 0) {
237 V_spr(x, w_o + 77 + 5, sth[c]);
243 static void Z_drawstwpn (int n, int a) {
244 char s[20];
245 int l, i, x, c;
246 i = n;
247 V_setrect(SCRW - 120, 120, w_o + 58, 23);
248 if (i >= 0) {
249 V_spr(SCRW - 88, w_o + 58 + 19, sth[i + 12]);
251 if (n >= 2) {
252 sprintf(s, "%d", a);
253 l = strlen(s);
254 x = SCRW - 10 - l * 14;
255 for (i = 0; i < l; ++i, x += 14) {
256 if (s[i] >= '0' && s[i] <= '9') {
257 c = s[i] - '0';
258 } else if (s[i] == '-') {
259 c = 10;
260 } else if (s[i] == '%') {
261 c = 11;
262 } else {
263 c = -1;
265 if (c >= 0) {
266 V_spr(x, w_o + 58 + 2, sth[c]);
272 static void Z_drawmanspr (int x, int y, void *p, char d, byte color) {
273 if (d) {
274 V_manspr2(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p, color);
275 } else {
276 V_manspr(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p, color);
280 /* --- menu --- */
282 static int gm_tm = 0; // ???
284 static vgaimg *PL_getspr (int s, int d) {
285 return plr_spr[(s - 'A') * 2 + d];
288 static int GM_draw (void) {
289 enum {MENU, MSG}; // copypasted from menu.c!
290 enum {
291 CANCEL, NEWGAME, LOADGAME, SAVEGAME, OPTIONS, QUITGAME, QUIT, ENDGAME, ENDGM,
292 PLR1, PLR2, COOP, DM, VOLUME, GAMMA, LOAD, SAVE, PLCOLOR, PLCEND, MUSIC, INTERP,
293 SVOLM, SVOLP, MVOLM, MVOLP, GAMMAM, GAMMAP, PL1CM, PL1CP, PL2CM, PL2CP
294 }; // copypasted from menu.c!
295 int i, j, k, y;
296 ++gm_tm;
297 V_setrect(0, SCRW, 0, SCRH);
298 if (!mnu && !gm_redraw) {
299 return 0;
301 gm_redraw = 0;
302 if (!mnu) {
303 return 1;
305 if (mnu->type == MENU) {
306 y = (200 - mnu -> n * 16 - 20) / 2;
307 Z_gotoxy(mnu->x, y - 10); Z_printbf(mnu->ttl);
308 for (i = 0; i < mnu->n; ++i) {
309 if (mnu->t[i] == LOAD || mnu->t[i] == SAVE) {
310 j = y + i * 16 + 29;
311 V_spr(mnu->x, j, mslotl);
312 for (k = 8; k < 184; k += 8) {
313 V_spr(mnu->x + k, j, mslotm);
315 V_spr(mnu->x+184,j,mslotr);
316 Z_gotoxy(mnu->x+4,j-8);
317 if (input && i == save_mnu.cur) {
318 Z_printsf("%s_", ibuf);
319 } else {
320 Z_printsf("%s", savname[i]);
322 } else {
323 Z_gotoxy(mnu->x + (mnu->t[i] >= SVOLM ? (mnu->t[i] >= PL1CM ? 50 : 152) : 0), y + i * 16 + 20);
324 Z_printbf(mnu->m[i]);
326 if (mnu->t[i] == MUSIC) {
327 Z_printbf(" '%.8s'",g_music);
328 } else if(mnu->t[i] == INTERP) {
329 Z_printbf("%s", fullscreen ? "ON" : "OFF");
330 } else if(mnu->t[i] >= PL1CM) {
331 V_manspr(mnu->x + (mnu->t[i] == PL1CM ? 15 : 35), y + i * 16 + 20 + 14, PL_getspr(*panimp, 0), pcolortab[(mnu->t[i] == PL1CM) ? p1color : p2color]);
332 } else if(mnu->t[i] >= SVOLM) {
333 j = y + i * 16 + 20;
334 V_spr(mnu->x, j, mbarl);
335 for (k = 8; k < 144; k += 8) {
336 V_spr(mnu->x + k, j, mbarm);
338 V_spr(mnu->x + 144, j, mbarr);
339 switch(mnu->t[i]) {
340 case SVOLM: k = snd_vol; break;
341 case MVOLM: k = mus_vol; break;
342 case GAMMAM: k = gammaa << 5; break;
344 V_spr(mnu->x + 8 + k, j, mbaro);
347 V_spr(mnu->x - 25, y + mnu->cur * 16 + 20 - 8, msklh[(gm_tm / 6) & 1]);
348 } else {
349 Z_gotoxy((320 - strlen(mnu->ttl) * 7) / 2, 90); Z_printsf(mnu->ttl);
350 Z_gotoxy(136, 100); Z_printsf("(Y/N)");
352 return 1;
355 /* --- dots --- */
357 static void DOT_draw (void) {
358 int i;
359 for (i = 0; i < MAXDOT; ++i) {
360 if (dot[i].t) {
361 V_dot(dot[i].o.x - w_x + WD / 2, dot[i].o.y - w_y + HT / 2 + 1 + w_o, dot[i].c);
366 /* --- items --- */
368 static void IT_draw (void) {
369 int i, s;
370 for (i = 0; i < MAXITEM; ++i) {
371 s = -1;
372 if (it[i].t && it[i].s >= 0) {
373 switch(it[i].t & 0x7FFF) {
374 case I_ARM1:
375 s = it[i].s / 9 + 18;
376 break;
377 case I_ARM2:
378 s = it[i].s / 9 + 20;
379 break;
380 case I_MEGA:
381 s = it[i].s / 2 + 22;
382 break;
383 case I_INVL:
384 s = it[i].s / 2 + 26;
385 break;
386 case I_SUPER:
387 case I_RTORCH:
388 case I_GTORCH:
389 case I_BTORCH:
390 s = it[i].s / 2 + (it[i].t - I_SUPER) * 4 + 35;
391 break;
392 case I_GOR1: case I_FCAN:
393 s = it[i].s / 2 + (it[i].t - I_GOR1) * 3 + 51;
394 break;
395 case I_AQUA:
396 s = 30;
397 break;
398 case I_SUIT:
399 s = 34;
400 break;
401 case I_KEYR:
402 case I_KEYG:
403 case I_KEYB:
404 s = (it[i].t & 0x7FFF) - I_KEYR + 31;
405 break;
406 case I_GUN2:
407 s = 57;
408 break;
409 default:
410 s = (it[i].t & 0x7FFF) - 1;
413 if (s >= 0) {
414 Z_drawspr(it[i].o.x, it[i].o.y, item_spr[s], item_sprd[s]);
419 /* --- player --- */
421 static int standspr (player_t *p) {
422 if (p->f & PLF_UP) {
423 return 'X';
424 } else if (p->f & PLF_DOWN) {
425 return 'Z';
426 } else {
427 return 'E';
431 static int wpnspr (player_t *p) {
432 if (p->f & PLF_UP) {
433 return 'C';
434 } else if(p->f & PLF_DOWN) {
435 return 'E';
436 } else {
437 return 'A';
441 static void PL_draw (player_t *p) {
442 enum {STAND, GO, DIE, SLOP, DEAD, MESS, OUT, FALL}; // copypasted from player.c!
443 static int wytab[] = {-1, -2, -1, 0};
444 int s = 'A';
445 int w = 0;
446 int wx = 0;
447 int wy = 0;
448 switch (p->st) {
449 case STAND:
450 if (p->f & PLF_FIRE) {
451 s = standspr(p) + 1;
452 w = wpnspr(p) + 1;
453 } else if (p->pain) {
454 s = 'G';
455 w = 'A';
456 wx = p->d ? 2 : -2;
457 wy = 1;
458 } else {
459 s = standspr(p);
460 w = wpnspr(p);
462 break;
463 case DEAD:
464 s = 'N';
465 break;
466 case MESS:
467 s = 'W';
468 break;
469 case GO:
470 if (p->pain) {
471 s = 'G';
472 w = 'A';
473 wx = p->d ? 2 : -2;
474 wy = 1;
475 } else {
476 s = plr_goanim[p->s / 8];
477 w = (p->f & PLF_FIRE) ? 'B' : 'A';
478 wx = p->d ? 2 : -2;
479 wy = 1 + wytab[s - 'A'];
481 break;
482 case DIE:
483 s = plr_dieanim[p->s];
484 break;
485 case SLOP:
486 s = plr_slopanim[p->s];
487 break;
488 case OUT:
489 s = 0;
490 break;
492 if (p->wpn == 0) {
493 w = 0;
495 if (w) {
496 Z_drawspr(p->o.x + wx, p->o.y + wy, plr_wpn[p->wpn][w - 'A'], p->d);
498 if (s) {
499 Z_drawmanspr(p->o.x, p->o.y, plr_spr[(s - 'A') * 2 + p->d], plr_sprd[(s - 'A') * 2 + p->d], p->color);
503 static void PL_drawst (player_t *p) {
504 int i;
505 V_setrect(WD, 120, w_o, HT);
506 Z_clrst();
507 if (p->drawst & PL_DRAWAIR) {
508 if (p->air < PL_AIR) {
509 Z_drawstair(p->air);
512 if (p->drawst & PL_DRAWLIFE) {
513 Z_drawstprcnt(0, p->life);
515 if (p->drawst & PL_DRAWARMOR) {
516 Z_drawstprcnt(1, p->armor);
518 if (p->drawst & PL_DRAWWPN) {
519 switch(p->wpn) {
520 case 2:
521 case 5:
522 i = p->ammo;
523 break;
524 case 3:
525 case 4:
526 case 9:
527 i = p->shel;
528 break;
529 case 6:
530 i = p->rock;
531 break;
532 case 10:
533 i = p->fuel;
534 break;
535 case 7:
536 case 8:
537 i = p->cell;
538 break;
540 Z_drawstwpn(p->wpn, i);
542 if (p->drawst & PL_DRAWFRAG) {
543 Z_drawstnum(p->frag);
545 if (p->drawst & PL_DRAWKEYS) {
546 Z_drawstkeys(p->keys);
548 if (!_2pl) {
549 if (p->drawst & PL_DRAWLIVES) {
550 Z_drawstlives(p->lives);
555 /* --- monster --- */
557 #define MANCOLOR 0xD0
559 static void MN_draw (void) {
560 enum {SLEEP, GO, RUN, CLIMB, DIE, DEAD, ATTACK, SHOOT, PAIN, WAIT, REVIVE, RUNOUT}; // copypasted from monster.c!
561 int i;
562 for (i = 0; i < MAXMN; ++i) {
563 if (mn[i].t) {
564 if (mn[i].t >= MN_PL_DEAD) {
565 Z_drawmanspr(mn[i].o.x, mn[i].o.y, pl_spr[mn[i].t - MN_PL_DEAD], 0, mn[i].d);
566 continue;
568 if ((mn[i].t != MN_SOUL && mn[i].t != MN_PAIN) || mn[i].st != DEAD) {
569 if (mn[i].t != MN_MAN) {
570 Z_drawspr(mn[i].o.x, mn[i].o.y, mn_spr[mn[i].t - 1][(mn[i].ap[mn[i].ac] - 'A') * 2 + mn[i].d], mn_sprd[mn[i].t - 1][(mn[i].ap[mn[i].ac] - 'A') * 2 + mn[i].d]);
571 } else {
572 if (mn[i].ap[mn[i].ac] == 'E' || mn[i].ap[mn[i].ac] == 'F') {
573 Z_drawspr(mn[i].o.x, mn[i].o.y, mn_sgun[mn[i].ap[mn[i].ac] - 'E'], mn[i].d);
575 Z_drawmanspr(mn[i].o.x, mn[i].o.y, mn_spr[mn[i].t - 1][(mn[i].ap[mn[i].ac] - 'A') * 2 + mn[i].d], mn_sprd[mn[i].t - 1][(mn[i].ap[mn[i].ac] - 'A') * 2 + mn[i].d], MANCOLOR);
578 if (mn[i].t == MN_VILE && mn[i].st == SHOOT) {
579 Z_drawspr(mn[i].tx, mn[i].ty, mn_fspr[mn[i].ac / 3], 0);
585 /* --- weapon --- */
587 static void WP_draw (void) {
588 enum {NONE, ROCKET, PLASMA, APLASMA, BALL1, BALL2, BALL7, BFGBALL, BFGHIT, MANF, REVF, FIRE}; // copypasted from weapons.c!
589 int i, s, d, x, y;
590 for (i = 0; i < MAXWPN; ++i) {
591 s = -1;
592 d = 0;
593 switch (wp[i].t) {
594 case NONE:
595 default:
596 break;
597 case REVF:
598 case ROCKET:
599 d = wp[i].s;
600 if (d < 2) {
601 d = wp[i].o.xv > 0 ? 1 : 0;
602 x = abs(wp[i].o.xv);
603 y = wp[i].o.yv;
604 s = 0;
605 if (y < 0) {
606 if (-y >= x) {
607 s = 30;
609 } else if (y > 0) {
610 if (y >= x / 2) {
611 s = 31;
614 } else {
615 s = (d - 2) / 2 + 1;
616 d = 0;
618 break;
619 case MANF:
620 s=wp[i].s;
621 if (s >= 2) {
622 s /= 2;
623 break;
625 case PLASMA:
626 case APLASMA:
627 case BALL1:
628 case BALL7:
629 case BALL2:
630 s = wp[i].s;
631 if (s >= 2) {
632 s = s / 2 + 1;
634 switch (wp[i].t) {
635 case PLASMA:
636 s += 4;
637 break;
638 case APLASMA:
639 s += 11;
640 break;
641 case BALL1:
642 s += 32;
643 break;
644 case BALL2:
645 s += 42;
646 break;
647 case BALL7:
648 s += 37;
649 d = wp[i].o.xv >= 0 ? 1 : 0;
650 break;
651 case MANF:
652 s += 47;
653 d=(wp[i].o.xv>=0)?1:0;break;
655 break;
656 case BFGBALL:
657 s = wp[i].s;
658 if (s >= 2) {
659 s = s / 2 + 1;
661 s += 18;
662 break;
663 case BFGHIT:
664 s = wp[i].s / 2 + 26;
665 break;
667 if (s >= 0) {
668 Z_drawspr(wp[i].o.x, wp[i].o.y, wp_spr[s * 2 + d], wp_sprd[s * 2 + d]);
673 /* --- smoke --- */
675 static void SMK_draw (void) {
676 int i, s;
677 for (i = 0; i < MAXSMOK; ++i) {
678 if (sm[i].t) {
679 switch (sm[i].s) {
680 case 0:
681 s = sm[i].t;
682 if (s >= (SMSN - 1) * 3) {
683 s = 0;
684 } else {
685 s = SMSN - 1 - s / 3;
687 V_sprf((sm[i].x >> 8) - w_x + WD / 2, (sm[i].y >> 8) - w_y + HT / 2 + 1 + w_o, smk_spr[s], &smoke_sprf);
688 break;
689 case 1:
690 s = sm[i].t;
691 if (s >= FLSN - 1) {
692 s = 0;
693 } else {
694 s = FLSN - 1 - s;
696 V_sprf((sm[i].x >> 8) - w_x + WD / 2, (sm[i].y >> 8) - w_y + HT / 2 + 1 + w_o, smk_fspr[s], &flame_sprf);
697 break;
703 /* --- fx --- */
705 static void FX_draw (void) {
706 enum {NONE, TFOG, IFOG, BUBL}; // copypasted from fx.c
707 int i, s;
708 for (i = 0; i < MAXFX; ++i) {
709 s = -1;
710 switch (fx[i].t) {
711 case TFOG:
712 s = fx[i].s / 2;
713 break;
714 case IFOG:
715 s = fx[i].s / 2 + 10;
716 break;
717 case BUBL:
718 V_dot((fx[i].x >> 8) - w_x + WD / 2, (fx[i].y >> 8) - w_y + HT / 2 + 1 + w_o, 0xC0 + fx[i].s);
719 continue;
721 if (s >= 0) {
722 Z_drawspr(fx[i].x, fx[i].y, fx_spr[s], fx_sprd[s]);
727 /* --- view --- */
729 static void W_adjust (void) {
730 int MAXX = FLDW * CELW - WD / 2;
731 int MAXY = FLDH * CELH - HT / 2;
732 if (w_x < WD / 2) w_x = WD / 2;
733 if (w_y < HT / 2) w_y = HT / 2;
734 if (w_x > MAXX) w_x = MAXX;
735 if (w_y > MAXY) w_y = MAXY;
738 static void W_draw(void) {
739 W_adjust();
740 V_setrect(0, WD, w_o + 1, HT);
741 if (w_horiz) {
742 vgaimg *img = (vgaimg*)horiz;
743 int x = 0;
744 int d = 0;
745 do {
746 int y = w_o;
747 d &= ~2;
748 do {
749 V_rotspr(x, y, img, d);
750 y += img->h;
751 d ^= 2;
752 } while (y < HT + w_o);
753 x += img->w;
754 d ^= 1;
755 } while (x < WD);
756 if (sky_type == 2) {
757 if (lt_time < 0) {
758 if (!lt_side) {
759 V_spr(0, w_o + lt_ypos, ltn[lt_type][lt_time < -5 ? 0 : 1]);
760 } else {
761 V_spr2(WD - 1, w_o + lt_ypos, ltn[lt_type][lt_time < -5 ? 0 : 1]);
765 } else {
766 V_clr(0, WD, w_o + 1, HT, 0x97);
768 Z_drawfld((byte*)fldb, 1);
769 DOT_draw();
770 IT_draw();
771 PL_draw(&pl1);
772 if (_2pl) {
773 PL_draw(&pl2);
775 MN_draw();
776 WP_draw();
777 SMK_draw();
778 FX_draw();
779 Z_drawfld((byte*)fldf, 0);
780 if (sky_type == 2) {
781 if (lt_time == -4 || lt_time == -2) {
782 V_remap_rect(0, WD, w_o + 1, HT, clrmap + 256 * 11);
787 /* --- game --- */
789 #define PL_FLASH 90
791 static void drawview (player_t *p) {
792 if (p->looky < -SCRH / 4) {
793 p->looky = -SCRH / 4;
794 } else if (p->looky > SCRH / 4) {
795 p->looky = SCRH / 4;
797 w_x = p->o.x;
798 w_y = p->o.y - 12 + p->looky;
799 W_draw();
800 PL_drawst(p);
803 static int get_pu_st (int t) {
804 if (t >= PL_FLASH) {
805 return 1;
806 } else if((t / 9) & 1) {
807 return 0;
808 } else {
809 return 1;
813 static void pl_info (player_t *p, int y) {
814 dword t = p->kills * 10920 / g_time;
815 Z_gotoxy(25, y); Z_printbf("KILLS");
816 Z_gotoxy(25, y + 15); Z_printbf("KPM");
817 Z_gotoxy(25, y + 30); Z_printbf("SECRETS %u / %u", p->secrets, sw_secrets);
818 Z_gotoxy(255, y); Z_printbf("%u", p->kills);
819 Z_gotoxy(255, y + 15); Z_printbf("%u.%u", t / 10, t % 10);
822 void G_draw (void) {
823 int h;
824 word hr, mn, sc;
825 if (g_trans && !transdraw) {
826 return;
828 switch (g_st) {
829 case GS_ENDANIM:
830 case GS_END2ANIM:
831 case GS_DARKEN:
832 case GS_BVIDEO:
833 case GS_EVIDEO:
834 case GS_END3ANIM:
835 return;
836 case GS_TITLE:
837 V_center(1);
838 V_pic(0, 0, scrnh[0]);
839 V_center(0);
840 break;
841 case GS_ENDSCR:
842 V_center(1);
843 V_clr(0, SCRW, 0, SCRH, 0);
844 V_pic(0, 0, scrnh[2]);
845 V_center(0);
846 break;
847 case GS_INTER:
848 V_center(1);
849 V_clr(0, SCRW, 0, SCRH, 0);
850 V_pic(0, 0, scrnh[1]);
851 Z_gotoxy(60, 20);
852 Z_printbf("LEVEL COMPLETE");
853 Z_calc_time(g_time, &hr, &mn, &sc);
854 Z_gotoxy(115, 40);
855 Z_printbf("TIME %u:%02u:%02u", hr, mn, sc);
856 h = 60;
857 if (_2pl) {
858 Z_gotoxy(80, h);
859 Z_printbf("PLAYER ONE");
860 Z_gotoxy(80, h + 70);
861 Z_printbf("PLAYER TWO");
862 h += SCRH / 10;
864 pl_info(&pl1, h);
865 if (_2pl) {
866 pl_info(&pl2, h + 70);
868 V_center(0);
869 break;
871 V_center(1);
872 if (g_st != GS_GAME) {
873 if (g_trans) {
874 return;
876 GM_draw();
877 V_copytoscr(0, SCRW, 0, SCRH);
878 return;
880 V_center(0);
881 if (_2pl) {
882 w_o = 0;
883 WD = SCRW - 120;
884 HT = SCRH / 2 - 2;
885 drawview(&pl1);
886 w_o = SCRH / 2;
887 WD = SCRW - 120;
888 HT = SCRH / 2 - 2;
889 drawview(&pl2);
890 } else{
891 w_o = 0;
892 WD = SCRW - 120;
893 HT = SCRH - 2;
894 drawview(&pl1);
896 if (g_trans) {
897 return;
899 V_center(1);
900 if (GM_draw()) {
901 pl1.drawst = 0xFF;
902 pl2.drawst = 0xFF;
903 V_copytoscr(0,SCRW,0,SCRH);
904 return;
906 V_center(0);
907 if (pl1.invl) {
908 h = get_pu_st(pl1.invl) * 6;
909 } else if (pl1.pain < 15) {
910 h = 0;
911 } else if (pl1.pain < 35) {
912 h = 1;
913 } else if (pl1.pain < 55) {
914 h = 2;
915 } else if (pl1.pain < 75) {
916 h=3;
917 } else if (pl1.pain < 95) {
918 h=4;
919 } else {
920 h = 5;
922 if (h != 0) {
923 V_maptoscr(0, SCRW - 120, 1, _2pl ? SCRH / 2 - 2 : SCRH - 2, clrmap + h * 256);
924 } else {
925 V_copytoscr(0, SCRW - 120, 1, _2pl ? SCRH / 2 - 2 : SCRH - 2);
927 if (pl1.drawst) {
928 V_copytoscr(SCRW - 120, 120, 0, _2pl ? SCRH / 2 : SCRH);
930 pl1.drawst = 0xFF;
931 if (_2pl) {
932 if (pl2.invl) {
933 h = get_pu_st(pl2.invl) * 6;
934 } else if (pl2.pain < 15) {
935 h = 0;
936 } else if (pl2.pain < 35) {
937 h = 1;
938 } else if (pl2.pain < 55) {
939 h = 2;
940 } else if (pl2.pain < 75) {
941 h = 3;
942 } else if (pl2.pain < 95) {
943 h = 4;
944 } else {
945 h = 5;
947 if (h) {
948 V_maptoscr(0, SCRW - 120, SCRH / 2 + 1, SCRH / 2 - 2, clrmap + h * 256);
949 } else {
950 V_copytoscr(0, SCRW - 120, SCRH / 2 + 1, SCRH / 2 - 2);
952 if (pl2.drawst) {
953 V_copytoscr(SCRW - 120, 120, SCRH / 2, SCRH / 2);
955 pl2.drawst = 0xFF;
959 void R_alloc (void) {
960 int i, j, n;
961 char s[10];
962 // game
963 scrnh[0] = V_loadvgaimg("TITLEPIC");
964 scrnh[1] = V_loadvgaimg("INTERPIC");
965 scrnh[2] = V_loadvgaimg("ENDPIC");
966 cd_scr = M_lock(F_getresid("CD1PIC"));
967 for (i = 0; i < 2; ++i) {
968 sprintf(s, "LTN%c", i + '1');
969 for (j = 0; j < 2; ++j) {
970 ltn[i][j] = Z_getspr(s, j, 0, NULL);
973 // smoke
974 for (i = 0; i < SMSN; ++i) {
975 smk_spr[i] = Z_getspr("SMOK", i, 0, NULL);
977 for (i = 0; i < FLSN; ++i) {
978 smk_fspr[i] = Z_getspr("FLAM", i, 0, NULL);
980 // fx
981 for (i = 0; i < 10; ++i) {
982 fx_spr[i] = Z_getspr("TFOG", i, 0, fx_sprd + i);
984 for (; i < 15; ++i) {
985 fx_spr[i] = Z_getspr("IFOG", i - 10, 0, fx_sprd + i);
987 // weapons
988 for (i = 0; i < 4; ++i) {
989 wp_spr[i * 2] = Z_getspr("MISL", i, 1, wp_sprd + i * 2);
990 wp_spr[i * 2 + 1] = Z_getspr("MISL", i, 2, wp_sprd + i * 2 + 1);
992 for (; i < 6; ++i) {
993 wp_spr[i * 2] = Z_getspr("PLSS", i - 4, 1, wp_sprd + i * 2);
994 wp_spr[i * 2 + 1] = Z_getspr("PLSS", i - 4, 2, wp_sprd + i * 2 + 1);
996 for (; i < 11; ++i) {
997 wp_spr[i * 2] = Z_getspr("PLSE", i - 6, 1, wp_sprd + i * 2);
998 wp_spr[i * 2 + 1] = Z_getspr("PLSE", i - 6, 2, wp_sprd + i * 2 + 1);
1000 for (; i < 13; ++i) {
1001 wp_spr[i * 2] = Z_getspr("APLS", i - 11, 1, wp_sprd + i * 2);
1002 wp_spr[i * 2 + 1] = Z_getspr("APLS", i - 11, 2, wp_sprd + i * 2 + 1);
1004 for (; i < 18; ++i) {
1005 wp_spr[i * 2] = Z_getspr("APBX", i - 13, 1, wp_sprd + i * 2);
1006 wp_spr[i * 2 + 1] = Z_getspr("APBX", i - 13, 2, wp_sprd + i * 2 + 1);
1008 for(; i < 20; ++i) {
1009 wp_spr[i * 2] = Z_getspr("BFS1", i - 18, 1, wp_sprd + i * 2);
1010 wp_spr[i * 2 + 1] = Z_getspr("BFS1", i - 18, 2, wp_sprd + i * 2 + 1);
1012 for (; i < 26; ++i) {
1013 wp_spr[i * 2] = Z_getspr("BFE1", i - 20, 1, wp_sprd + i * 2);
1014 wp_spr[i * 2 + 1] = Z_getspr("BFE1", i - 20, 2, wp_sprd + i * 2 + 1);
1016 for (; i < 30; ++i) {
1017 wp_spr[i * 2] = Z_getspr("BFE2", i - 26, 1, wp_sprd + i * 2);
1018 wp_spr[i * 2 + 1] = Z_getspr("BFE2", i - 26, 2, wp_sprd + i * 2 + 1);
1020 for (; i < 32; ++i) {
1021 wp_spr[i * 2] = Z_getspr("MISL", i - 30 + 4, 1, wp_sprd + i * 2);
1022 wp_spr[i * 2 + 1] = Z_getspr("MISL", i - 30 + 4, 2, wp_sprd + i * 2 + 1);
1024 for (; i < 37; ++i) {
1025 wp_spr[i * 2] = Z_getspr("BAL1", i - 32, 1, wp_sprd + i * 2);
1026 wp_spr[i * 2 + 1] = Z_getspr("BAL1", i - 32, 2, wp_sprd + i * 2 + 1);
1028 for (; i < 42; ++i) {
1029 wp_spr[i * 2] = Z_getspr("BAL7", i - 37, 1, wp_sprd + i * 2);
1030 wp_spr[i * 2 + 1] = Z_getspr("BAL7", i - 37, 2, wp_sprd + i * 2 + 1);
1032 for (; i < 47; ++i) {
1033 wp_spr[i * 2] = Z_getspr("BAL2", i - 42, 1, wp_sprd + i * 2);
1034 wp_spr[i * 2 + 1] = Z_getspr("BAL2", i - 42, 2, wp_sprd + i * 2 + 1);
1036 for (; i < 49; ++i) {
1037 wp_spr[i * 2] = Z_getspr("MANF", i - 47, 1, wp_sprd + i * 2);
1038 wp_spr[i * 2 + 1] = Z_getspr("MANF", i - 47, 2, wp_sprd + i * 2 + 1);
1040 // items
1041 static char snm[18][4] = {
1042 "CLIP", "SHEL", "ROCK", "CELL", "AMMO", "SBOX", "BROK", "CELP",
1043 "STIM", "MEDI", "BPAK",
1044 "CSAW", "SHOT", "SGN2", "MGUN", "LAUN", "PLAS", "BFUG"
1045 };
1046 static char n4[4][4] = {
1047 "SOUL", "SMRT", "SMGT", "SMBT"
1048 };
1049 static char n3[2][4] = {
1050 "GOR1", "FCAN"
1051 };
1052 for (i = 0; i < 18; ++i) {
1053 item_spr[i] = Z_getspr(snm[i], 0, 0, item_sprd + i);
1055 for (; i < 20; ++i) {
1056 item_spr[i] = Z_getspr("ARM1", i - 18, 0, item_sprd + i);
1057 item_spr[i + 2] = Z_getspr("ARM2", i - 18, 0, item_sprd + i);
1059 i+=2;
1060 for (; i < 26; ++i) {
1061 item_spr[i] = Z_getspr("MEGA", i - 22, 0, item_sprd + i);
1063 for (; i < 30; ++i) {
1064 item_spr[i] = Z_getspr("PINV", i - 26, 0, item_sprd + i);
1066 item_spr[30] = Z_getspr("AQUA", 0, 0, item_sprd + 30);
1067 item_spr[31] = Z_getspr("KEYR", 0, 0, item_sprd + 31);
1068 item_spr[32] = Z_getspr("KEYG", 0, 0, item_sprd + 32);
1069 item_spr[33] = Z_getspr("KEYB", 0, 0, item_sprd + 33);
1070 item_spr[34] = Z_getspr("SUIT", 0, 0, item_sprd + 34);
1071 for (n = 35, j = 0; j < 4; ++j) {
1072 for (i = 0; i < 4; ++i, ++n) {
1073 item_spr[n] = Z_getspr(n4[j], i, 0, item_sprd + n);
1076 for (j = 0; j < 2; ++j) {
1077 for (i = 0; i < 3; ++i, ++n) {
1078 item_spr[n] = Z_getspr(n3[j], i, 0, item_sprd + n);
1081 item_spr[57] = Z_getspr("GUN2", 0, 0, item_sprd + 57);
1082 // player
1083 for (i = 0; i < 27; ++i) {
1084 plr_spr[i * 2] = Z_getspr("PLAY", i, 1, plr_sprd + i * 2);
1085 plr_spr[i * 2 + 1] = Z_getspr("PLAY", i, 2, plr_sprd + i * 2 + 1);
1087 strncpy(s, "PWPx", 4);
1088 for (i = 1; i < 11; ++i) {
1089 s[3] = (i < 10 ? '0' : 'A' - 10) + i;
1090 for (j = 0; j < 6; ++j) {
1091 plr_wpn[i][j] = Z_getspr(s, j, 1, NULL);
1094 // monsters
1095 static char msn[MN_TN][4] = {
1096 "SARG", "TROO", "POSS", "SPOS", "CYBR", "CPOS", "BOSS", "BOS2", "HEAD", "SKUL",
1097 "PAIN", "SPID", "BSPI", "FATT", "SKEL", "VILE", "FISH", "BAR1", "ROBO", "PLAY"
1098 };
1099 static int mms[MN_TN] = {
1100 14*2, 21*2, 21*2, 21*2, 16*2, 20*2, 15*2, 15*2, 12*2, 11*2, 13*2, 19*2, 16*2,
1101 20*2, 17*2, 29*2, 6*2, 2*2, 17*2, 23*2
1102 };
1103 mn_sgun[0] = Z_getspr("PWP4", 0, 1, NULL);
1104 mn_sgun[1] = Z_getspr("PWP4", 1, 1, NULL);
1105 for (j = 0; j < MN_TN; ++j) {
1106 for (i = 0; i < mms[j]; ++i) {
1107 mn_spr[j][i] = Z_getspr(msn[j], i / 2, (i & 1) + 1, &mn_sprd[j][i]);
1109 if (j == MN_BARREL - 1) {
1110 for (i = 4; i < 14; ++i) {
1111 mn_spr[j][i] = Z_getspr("BEXP", i / 2 - 2, (i & 1) + 1, &mn_sprd[j][i]);
1115 for (i = 0; i < 8; ++i) {
1116 mn_fspr[i] = Z_getspr("FIRE", i, 0, NULL);
1118 pl_spr[0] = Z_getspr("PLAY", 'N' - 'A', 0, NULL);
1119 pl_spr[1] = Z_getspr("PLAY", 'W' - 'A', 0, NULL);
1120 // misc
1121 static char mnm[22][8]={
1122 "STTNUM0","STTNUM1","STTNUM2","STTNUM3","STTNUM4",
1123 "STTNUM5","STTNUM6","STTNUM7","STTNUM8","STTNUM9",
1124 "STTMINUS","STTPRCNT",
1125 "FISTA0","CSAWA0","PISTA0","SHOTA0","SGN2A0","MGUNA0","LAUNA0",
1126 "PLASA0","BFUGA0","GUN2A0"
1127 };
1128 stone=V_loadvgaimg("STONE");
1129 stone2=V_loadvgaimg("STONE2");
1130 keys[0]=V_loadvgaimg("KEYRA0");
1131 keys[1]=V_loadvgaimg("KEYGA0");
1132 keys[2]=V_loadvgaimg("KEYBA0");
1133 for (i = 0; i < 22; ++i) {
1134 sth[i] = V_loadvgaimg(mnm[i]);
1136 strcpy(s, "STBF_*");
1137 for (i = '!'; i < 160; ++i) {
1138 s[5] = i;
1139 bfh[i - '!'] = V_getvgaimg(F_findres(s));
1141 for (i = '!'; i < 160; ++i) {
1142 sprintf(s, "STCFN%03d", i);
1143 sfh[i - '!'] = V_getvgaimg(F_findres(s));
1145 strcpy(s, "WINUM*");
1146 for (i = '0'; i <= '9'; ++i) {
1147 s[5] = i;
1148 bfh[i - '!'] = V_loadvgaimg(s);
1150 bfh[':' - '!'] = V_loadvgaimg("WICOLON");
1151 // menu
1152 msklh[0] = V_loadvgaimg("M_SKULL1");
1153 msklh[1] = V_loadvgaimg("M_SKULL2");
1154 mbarl = V_loadvgaimg("M_THERML");
1155 mbarm = V_loadvgaimg("M_THERMM");
1156 mbarr = V_loadvgaimg("M_THERMR");
1157 mbaro = V_loadvgaimg("M_THERMO");
1158 mslotl = V_loadvgaimg("M_LSLEFT");
1159 mslotm = V_loadvgaimg("M_LSCNTR");
1160 mslotr = V_loadvgaimg("M_LSRGHT");