DEADSOFTWARE

c5494a41757ba3d9fed7ed303a65747528dc8042
[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;
51 // low level
52 static int gammaa = 0;
53 static char main_pal[256][3];
54 static char std_pal[256][3];
55 static byte gamcor[5][64]={
56 #include "gamma.dat"
57 };
59 extern byte bright[256]; // vga.c
60 extern byte mixmap[256][256]; // vga.c
61 extern byte clrmap[256*12]; // vga.c
63 extern int g_trans; // game.c
64 extern byte transdraw; // game.c
65 extern void *horiz; // view.c
66 extern int sky_type; // view.c
67 extern int lt_time, lt_type, lt_side, lt_ypos, lt_force; // game.c
69 extern byte savname[7][24]; // files.c
70 extern char g_music[8]; // game.c
71 extern short snd_vol; // sound.c
72 extern short mus_vol; // music.c
74 void Z_drawfld(byte *, int); // vga.c
76 /* --- misc --- */
78 static void *Z_getspr (char n[4], int s, int d, char *dir) {
79 int h = F_getsprid(n, s, d);
80 if (dir) {
81 *dir = (h & 0x8000) ? 1 : 0;
82 }
83 return V_getvgaimg(h);
84 }
86 static void Z_putbfch (int c) {
87 vgaimg *p;
88 if (c > 32 && c < 160) {
89 p = bfh[c - '!'];
90 } else {
91 p = NULL;
92 }
93 if (p) {
94 V_spr(prx, pry, p);
95 prx += p->w - 1;
96 } else {
97 prx += 12;
98 }
99 }
101 static void Z_putsfch(int c) {
102 vgaimg *p;
103 if (c > 32 && c < 160) {
104 p = sfh[c - '!'];
105 } else {
106 p = NULL;
108 if (p) {
109 V_spr(prx, pry, p);
110 prx += p->w - 1;
111 } else {
112 prx += 7;
116 static void Z_gotoxy (int x, int y) {
117 prx = x;
118 pry = y;
121 static void Z_printbf(char *s, ...) {
122 int i;
123 va_list ap;
124 char buf[80];
125 va_start(ap, s);
126 vsprintf(buf, s, ap);
127 va_end(ap);
128 for (i = 0; buf[i]; ++i) {
129 switch (buf[i]) {
130 case '\n':
131 pry += 13;
132 case '\r':
133 prx = 0;
134 break;
135 default:
136 Z_putbfch((byte)buf[i]);
141 static void Z_printsf (char *s, ...) {
142 int i;
143 va_list ap;
144 char buf[80];
145 va_start(ap, s);
146 vsprintf(buf, s, ap);
147 va_end(ap);
148 for (i = 0; buf[i]; ++i) {
149 switch(buf[i]) {
150 case '\n':
151 pry += 8;
152 case '\r':
153 prx=0;
154 break;
155 default:
156 Z_putsfch((byte)buf[i]);
161 static void Z_drawspr (int x, int y, void *p, char d) {
162 if (d) {
163 V_spr2(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p);
164 } else {
165 V_spr(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p);
169 static void Z_clrst (void) {
170 V_pic(SCRW - 120, w_o, stone);
171 int y = ((vgaimg*)stone)->h;
172 while (y < HT) {
173 V_pic(SCRW - 120, w_o + y, stone2);
174 y += ((vgaimg*)stone)->h;
178 static void Z_drawstlives (char n) {
179 V_setrect(SCRW - 40, 30, w_o, 40);
180 V_spr(SCRW - 35, w_o + 17, sth[n]);
183 static void Z_drawstkeys (byte k) {
184 int x, n;
185 V_setrect(SCRW - 120, 70, w_o + 77, 23);
186 for (k >>= 4, n = 0, x = SCRW - 75; n < 3; ++n, k >>= 1, x += 9) {
187 if (k & 1) {
188 V_spr(x, w_o + 91, keys[n]);
193 static void Z_drawstair (int a) {
194 V_setrect(SCRW - 120, 120, w_o + 49, 2);
195 if (a > 0) {
196 if (a > MAXAIR) {
197 a = MAXAIR;
199 a = a * 100 / MAXAIR;
200 V_clr(SCRW - 110, a, w_o + 49, 2, 0xC8);
204 static void Z_drawstprcnt (int y, int n) {
205 char s[20];
206 int l, i, x, c;
207 V_setrect(SCRW - 120, 70, y * 19 + 7 + w_o, 19);
208 sprintf(s, "%3d%%", n);
209 l = strlen(s);
210 x = SCRW - 110;
211 for (i = 0; i < l; ++i, x += 14) {
212 if (s[i] >='0' && s[i] <= '9') {
213 c = s[i] - '0';
214 } else if (s[i] == '-') {
215 c = 10;
216 } else if (s[i] == '%') {
217 c = 11;
218 } else {
219 c = -1;
221 if (c >= 0) {
222 V_spr(x, y * 19 + 7 + w_o, sth[c]);
227 static void Z_drawstnum (int n) {
228 char s[20];
229 int l, i, x, c;
230 V_setrect(SCRW - 50, 50, w_o + 77, 23);
231 if (g_dm) {
232 sprintf(s, "%d", n);
233 l = strlen(s);
234 x = (115 - l * 14) + SCRW - 120;
235 for (i = 0; i < l; ++i, x += 14) {
236 if (s[i] >= '0' && s[i] <= '9') {
237 c = s[i] - '0';
238 } else if (s[i] == '-') {
239 c = 10;
240 } else if(s[i] == '%') {
241 c = 11;
242 } else {
243 c =- 1;
245 if (c >= 0) {
246 V_spr(x, w_o + 77 + 5, sth[c]);
252 static void Z_drawstwpn (int n, int a) {
253 char s[20];
254 int l, i, x, c;
255 i = n;
256 V_setrect(SCRW - 120, 120, w_o + 58, 23);
257 if (i >= 0) {
258 V_spr(SCRW - 88, w_o + 58 + 19, sth[i + 12]);
260 if (n >= 2) {
261 sprintf(s, "%d", a);
262 l = strlen(s);
263 x = SCRW - 10 - l * 14;
264 for (i = 0; i < l; ++i, x += 14) {
265 if (s[i] >= '0' && s[i] <= '9') {
266 c = s[i] - '0';
267 } else if (s[i] == '-') {
268 c = 10;
269 } else if (s[i] == '%') {
270 c = 11;
271 } else {
272 c = -1;
274 if (c >= 0) {
275 V_spr(x, w_o + 58 + 2, sth[c]);
281 static void Z_drawmanspr (int x, int y, void *p, char d, byte color) {
282 if (d) {
283 V_manspr2(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p, color);
284 } else {
285 V_manspr(x - w_x + WD / 2, y - w_y + HT / 2 + 1 + w_o, p, color);
289 /* --- menu --- */
291 static int gm_tm = 0; // ???
293 static vgaimg *PL_getspr (int s, int d) {
294 return plr_spr[(s - 'A') * 2 + d];
297 static int GM_draw (void) {
298 enum {MENU, MSG}; // copypasted from menu.c!
299 enum {
300 CANCEL, NEWGAME, LOADGAME, SAVEGAME, OPTIONS, QUITGAME, QUIT, ENDGAME, ENDGM,
301 PLR1, PLR2, COOP, DM, VOLUME, GAMMA, LOAD, SAVE, PLCOLOR, PLCEND, MUSIC, INTERP,
302 SVOLM, SVOLP, MVOLM, MVOLP, GAMMAM, GAMMAP, PL1CM, PL1CP, PL2CM, PL2CP
303 }; // copypasted from menu.c!
304 int i, j, k, y;
305 ++gm_tm;
306 V_setrect(0, SCRW, 0, SCRH);
307 if (!mnu && !gm_redraw) {
308 return 0;
310 gm_redraw = 0;
311 if (!mnu) {
312 return 1;
314 if (mnu->type == MENU) {
315 y = (200 - mnu -> n * 16 - 20) / 2;
316 Z_gotoxy(mnu->x, y - 10); Z_printbf(mnu->ttl);
317 for (i = 0; i < mnu->n; ++i) {
318 if (mnu->t[i] == LOAD || mnu->t[i] == SAVE) {
319 j = y + i * 16 + 29;
320 V_spr(mnu->x, j, mslotl);
321 for (k = 8; k < 184; k += 8) {
322 V_spr(mnu->x + k, j, mslotm);
324 V_spr(mnu->x+184,j,mslotr);
325 Z_gotoxy(mnu->x+4,j-8);
326 if (input && i == save_mnu.cur) {
327 Z_printsf("%s_", ibuf);
328 } else {
329 Z_printsf("%s", savname[i]);
331 } else {
332 Z_gotoxy(mnu->x + (mnu->t[i] >= SVOLM ? (mnu->t[i] >= PL1CM ? 50 : 152) : 0), y + i * 16 + 20);
333 Z_printbf(mnu->m[i]);
335 if (mnu->t[i] == MUSIC) {
336 Z_printbf(" '%.8s'",g_music);
337 } else if(mnu->t[i] == INTERP) {
338 Z_printbf("%s", fullscreen ? "ON" : "OFF");
339 } else if(mnu->t[i] >= PL1CM) {
340 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]);
341 } else if(mnu->t[i] >= SVOLM) {
342 j = y + i * 16 + 20;
343 V_spr(mnu->x, j, mbarl);
344 for (k = 8; k < 144; k += 8) {
345 V_spr(mnu->x + k, j, mbarm);
347 V_spr(mnu->x + 144, j, mbarr);
348 switch(mnu->t[i]) {
349 case SVOLM: k = snd_vol; break;
350 case MVOLM: k = mus_vol; break;
351 case GAMMAM: k = gammaa << 5; break;
353 V_spr(mnu->x + 8 + k, j, mbaro);
356 V_spr(mnu->x - 25, y + mnu->cur * 16 + 20 - 8, msklh[(gm_tm / 6) & 1]);
357 } else {
358 Z_gotoxy((320 - strlen(mnu->ttl) * 7) / 2, 90); Z_printsf(mnu->ttl);
359 Z_gotoxy(136, 100); Z_printsf("(Y/N)");
361 return 1;
364 /* --- dots --- */
366 static void DOT_draw (void) {
367 int i;
368 for (i = 0; i < MAXDOT; ++i) {
369 if (dot[i].t) {
370 V_dot(dot[i].o.x - w_x + WD / 2, dot[i].o.y - w_y + HT / 2 + 1 + w_o, dot[i].c);
375 /* --- items --- */
377 static void IT_draw (void) {
378 int i, s;
379 for (i = 0; i < MAXITEM; ++i) {
380 s = -1;
381 if (it[i].t && it[i].s >= 0) {
382 switch(it[i].t & 0x7FFF) {
383 case I_ARM1:
384 s = it[i].s / 9 + 18;
385 break;
386 case I_ARM2:
387 s = it[i].s / 9 + 20;
388 break;
389 case I_MEGA:
390 s = it[i].s / 2 + 22;
391 break;
392 case I_INVL:
393 s = it[i].s / 2 + 26;
394 break;
395 case I_SUPER:
396 case I_RTORCH:
397 case I_GTORCH:
398 case I_BTORCH:
399 s = it[i].s / 2 + (it[i].t - I_SUPER) * 4 + 35;
400 break;
401 case I_GOR1: case I_FCAN:
402 s = it[i].s / 2 + (it[i].t - I_GOR1) * 3 + 51;
403 break;
404 case I_AQUA:
405 s = 30;
406 break;
407 case I_SUIT:
408 s = 34;
409 break;
410 case I_KEYR:
411 case I_KEYG:
412 case I_KEYB:
413 s = (it[i].t & 0x7FFF) - I_KEYR + 31;
414 break;
415 case I_GUN2:
416 s = 57;
417 break;
418 default:
419 s = (it[i].t & 0x7FFF) - 1;
422 if (s >= 0) {
423 Z_drawspr(it[i].o.x, it[i].o.y, item_spr[s], item_sprd[s]);
428 /* --- player --- */
430 static int standspr (player_t *p) {
431 if (p->f & PLF_UP) {
432 return 'X';
433 } else if (p->f & PLF_DOWN) {
434 return 'Z';
435 } else {
436 return 'E';
440 static int wpnspr (player_t *p) {
441 if (p->f & PLF_UP) {
442 return 'C';
443 } else if(p->f & PLF_DOWN) {
444 return 'E';
445 } else {
446 return 'A';
450 static void PL_draw (player_t *p) {
451 enum {STAND, GO, DIE, SLOP, DEAD, MESS, OUT, FALL}; // copypasted from player.c!
452 static int wytab[] = {-1, -2, -1, 0};
453 int s = 'A';
454 int w = 0;
455 int wx = 0;
456 int wy = 0;
457 switch (p->st) {
458 case STAND:
459 if (p->f & PLF_FIRE) {
460 s = standspr(p) + 1;
461 w = wpnspr(p) + 1;
462 } else if (p->pain) {
463 s = 'G';
464 w = 'A';
465 wx = p->d ? 2 : -2;
466 wy = 1;
467 } else {
468 s = standspr(p);
469 w = wpnspr(p);
471 break;
472 case DEAD:
473 s = 'N';
474 break;
475 case MESS:
476 s = 'W';
477 break;
478 case GO:
479 if (p->pain) {
480 s = 'G';
481 w = 'A';
482 wx = p->d ? 2 : -2;
483 wy = 1;
484 } else {
485 s = plr_goanim[p->s / 8];
486 w = (p->f & PLF_FIRE) ? 'B' : 'A';
487 wx = p->d ? 2 : -2;
488 wy = 1 + wytab[s - 'A'];
490 break;
491 case DIE:
492 s = plr_dieanim[p->s];
493 break;
494 case SLOP:
495 s = plr_slopanim[p->s];
496 break;
497 case OUT:
498 s = 0;
499 break;
501 if (p->wpn == 0) {
502 w = 0;
504 if (w) {
505 Z_drawspr(p->o.x + wx, p->o.y + wy, plr_wpn[p->wpn][w - 'A'], p->d);
507 if (s) {
508 Z_drawmanspr(p->o.x, p->o.y, plr_spr[(s - 'A') * 2 + p->d], plr_sprd[(s - 'A') * 2 + p->d], p->color);
512 static void PL_drawst (player_t *p) {
513 int i;
514 V_setrect(WD, 120, w_o, HT);
515 Z_clrst();
516 if (p->drawst & PL_DRAWAIR) {
517 if (p->air < PL_AIR) {
518 Z_drawstair(p->air);
521 if (p->drawst & PL_DRAWLIFE) {
522 Z_drawstprcnt(0, p->life);
524 if (p->drawst & PL_DRAWARMOR) {
525 Z_drawstprcnt(1, p->armor);
527 if (p->drawst & PL_DRAWWPN) {
528 switch(p->wpn) {
529 case 2:
530 case 5:
531 i = p->ammo;
532 break;
533 case 3:
534 case 4:
535 case 9:
536 i = p->shel;
537 break;
538 case 6:
539 i = p->rock;
540 break;
541 case 10:
542 i = p->fuel;
543 break;
544 case 7:
545 case 8:
546 i = p->cell;
547 break;
549 Z_drawstwpn(p->wpn, i);
551 if (p->drawst & PL_DRAWFRAG) {
552 Z_drawstnum(p->frag);
554 if (p->drawst & PL_DRAWKEYS) {
555 Z_drawstkeys(p->keys);
557 if (!_2pl) {
558 if (p->drawst & PL_DRAWLIVES) {
559 Z_drawstlives(p->lives);
564 /* --- monster --- */
566 #define MANCOLOR 0xD0
568 static void MN_draw (void) {
569 enum {SLEEP, GO, RUN, CLIMB, DIE, DEAD, ATTACK, SHOOT, PAIN, WAIT, REVIVE, RUNOUT}; // copypasted from monster.c!
570 int i;
571 for (i = 0; i < MAXMN; ++i) {
572 if (mn[i].t) {
573 if (mn[i].t >= MN_PL_DEAD) {
574 Z_drawmanspr(mn[i].o.x, mn[i].o.y, pl_spr[mn[i].t - MN_PL_DEAD], 0, mn[i].d);
575 continue;
577 if ((mn[i].t != MN_SOUL && mn[i].t != MN_PAIN) || mn[i].st != DEAD) {
578 if (mn[i].t != MN_MAN) {
579 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]);
580 } else {
581 if (mn[i].ap[mn[i].ac] == 'E' || mn[i].ap[mn[i].ac] == 'F') {
582 Z_drawspr(mn[i].o.x, mn[i].o.y, mn_sgun[mn[i].ap[mn[i].ac] - 'E'], mn[i].d);
584 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);
587 if (mn[i].t == MN_VILE && mn[i].st == SHOOT) {
588 Z_drawspr(mn[i].tx, mn[i].ty, mn_fspr[mn[i].ac / 3], 0);
594 /* --- weapon --- */
596 static void WP_draw (void) {
597 enum {NONE, ROCKET, PLASMA, APLASMA, BALL1, BALL2, BALL7, BFGBALL, BFGHIT, MANF, REVF, FIRE}; // copypasted from weapons.c!
598 int i, s, d, x, y;
599 for (i = 0; i < MAXWPN; ++i) {
600 s = -1;
601 d = 0;
602 switch (wp[i].t) {
603 case NONE:
604 default:
605 break;
606 case REVF:
607 case ROCKET:
608 d = wp[i].s;
609 if (d < 2) {
610 d = wp[i].o.xv > 0 ? 1 : 0;
611 x = abs(wp[i].o.xv);
612 y = wp[i].o.yv;
613 s = 0;
614 if (y < 0) {
615 if (-y >= x) {
616 s = 30;
618 } else if (y > 0) {
619 if (y >= x / 2) {
620 s = 31;
623 } else {
624 s = (d - 2) / 2 + 1;
625 d = 0;
627 break;
628 case MANF:
629 s=wp[i].s;
630 if (s >= 2) {
631 s /= 2;
632 break;
634 case PLASMA:
635 case APLASMA:
636 case BALL1:
637 case BALL7:
638 case BALL2:
639 s = wp[i].s;
640 if (s >= 2) {
641 s = s / 2 + 1;
643 switch (wp[i].t) {
644 case PLASMA:
645 s += 4;
646 break;
647 case APLASMA:
648 s += 11;
649 break;
650 case BALL1:
651 s += 32;
652 break;
653 case BALL2:
654 s += 42;
655 break;
656 case BALL7:
657 s += 37;
658 d = wp[i].o.xv >= 0 ? 1 : 0;
659 break;
660 case MANF:
661 s += 47;
662 d=(wp[i].o.xv>=0)?1:0;break;
664 break;
665 case BFGBALL:
666 s = wp[i].s;
667 if (s >= 2) {
668 s = s / 2 + 1;
670 s += 18;
671 break;
672 case BFGHIT:
673 s = wp[i].s / 2 + 26;
674 break;
676 if (s >= 0) {
677 Z_drawspr(wp[i].o.x, wp[i].o.y, wp_spr[s * 2 + d], wp_sprd[s * 2 + d]);
682 /* --- smoke --- */
684 static void SMK_draw (void) {
685 int i, s;
686 for (i = 0; i < MAXSMOK; ++i) {
687 if (sm[i].t) {
688 switch (sm[i].s) {
689 case 0:
690 s = sm[i].t;
691 if (s >= (SMSN - 1) * 3) {
692 s = 0;
693 } else {
694 s = SMSN - 1 - s / 3;
696 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);
697 break;
698 case 1:
699 s = sm[i].t;
700 if (s >= FLSN - 1) {
701 s = 0;
702 } else {
703 s = FLSN - 1 - s;
705 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);
706 break;
712 /* --- fx --- */
714 static void FX_draw (void) {
715 enum {NONE, TFOG, IFOG, BUBL}; // copypasted from fx.c
716 int i, s;
717 for (i = 0; i < MAXFX; ++i) {
718 s = -1;
719 switch (fx[i].t) {
720 case TFOG:
721 s = fx[i].s / 2;
722 break;
723 case IFOG:
724 s = fx[i].s / 2 + 10;
725 break;
726 case BUBL:
727 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);
728 continue;
730 if (s >= 0) {
731 Z_drawspr(fx[i].x, fx[i].y, fx_spr[s], fx_sprd[s]);
736 /* --- view --- */
738 static void W_adjust (void) {
739 int MAXX = FLDW * CELW - WD / 2;
740 int MAXY = FLDH * CELH - HT / 2;
741 if (w_x < WD / 2) w_x = WD / 2;
742 if (w_y < HT / 2) w_y = HT / 2;
743 if (w_x > MAXX) w_x = MAXX;
744 if (w_y > MAXY) w_y = MAXY;
747 static void W_draw(void) {
748 W_adjust();
749 V_setrect(0, WD, w_o + 1, HT);
750 if (w_horiz) {
751 vgaimg *img = (vgaimg*)horiz;
752 int x = 0;
753 int d = 0;
754 do {
755 int y = w_o;
756 d &= ~2;
757 do {
758 V_rotspr(x, y, img, d);
759 y += img->h;
760 d ^= 2;
761 } while (y < HT + w_o);
762 x += img->w;
763 d ^= 1;
764 } while (x < WD);
765 if (sky_type == 2) {
766 if (lt_time < 0) {
767 if (!lt_side) {
768 V_spr(0, w_o + lt_ypos, ltn[lt_type][lt_time < -5 ? 0 : 1]);
769 } else {
770 V_spr2(WD - 1, w_o + lt_ypos, ltn[lt_type][lt_time < -5 ? 0 : 1]);
774 } else {
775 V_clr(0, WD, w_o + 1, HT, 0x97);
777 Z_drawfld((byte*)fldb, 1);
778 DOT_draw();
779 IT_draw();
780 PL_draw(&pl1);
781 if (_2pl) {
782 PL_draw(&pl2);
784 MN_draw();
785 WP_draw();
786 SMK_draw();
787 FX_draw();
788 Z_drawfld((byte*)fldf, 0);
789 if (sky_type == 2) {
790 if (lt_time == -4 || lt_time == -2) {
791 V_remap_rect(0, WD, w_o + 1, HT, clrmap + 256 * 11);
796 /* --- game --- */
798 #define PL_FLASH 90
800 static void drawview (player_t *p) {
801 if (p->looky < -SCRH / 4) {
802 p->looky = -SCRH / 4;
803 } else if (p->looky > SCRH / 4) {
804 p->looky = SCRH / 4;
806 w_x = p->o.x;
807 w_y = p->o.y - 12 + p->looky;
808 W_draw();
809 PL_drawst(p);
812 static int get_pu_st (int t) {
813 if (t >= PL_FLASH) {
814 return 1;
815 } else if((t / 9) & 1) {
816 return 0;
817 } else {
818 return 1;
822 static void pl_info (player_t *p, int y) {
823 dword t = p->kills * 10920 / g_time;
824 Z_gotoxy(25, y); Z_printbf("KILLS");
825 Z_gotoxy(25, y + 15); Z_printbf("KPM");
826 Z_gotoxy(25, y + 30); Z_printbf("SECRETS %u / %u", p->secrets, sw_secrets);
827 Z_gotoxy(255, y); Z_printbf("%u", p->kills);
828 Z_gotoxy(255, y + 15); Z_printbf("%u.%u", t / 10, t % 10);
831 void R_draw (void) {
832 int h;
833 word hr, mn, sc;
834 if (g_trans && !transdraw) {
835 return;
837 switch (g_st) {
838 case GS_ENDANIM:
839 case GS_END2ANIM:
840 case GS_DARKEN:
841 case GS_BVIDEO:
842 case GS_EVIDEO:
843 case GS_END3ANIM:
844 return;
845 case GS_TITLE:
846 V_center(1);
847 V_pic(0, 0, scrnh[0]);
848 V_center(0);
849 break;
850 case GS_ENDSCR:
851 V_center(1);
852 V_clr(0, SCRW, 0, SCRH, 0);
853 V_pic(0, 0, scrnh[2]);
854 V_center(0);
855 break;
856 case GS_INTER:
857 V_center(1);
858 V_clr(0, SCRW, 0, SCRH, 0);
859 V_pic(0, 0, scrnh[1]);
860 Z_gotoxy(60, 20);
861 Z_printbf("LEVEL COMPLETE");
862 Z_calc_time(g_time, &hr, &mn, &sc);
863 Z_gotoxy(115, 40);
864 Z_printbf("TIME %u:%02u:%02u", hr, mn, sc);
865 h = 60;
866 if (_2pl) {
867 Z_gotoxy(80, h);
868 Z_printbf("PLAYER ONE");
869 Z_gotoxy(80, h + 70);
870 Z_printbf("PLAYER TWO");
871 h += SCRH / 10;
873 pl_info(&pl1, h);
874 if (_2pl) {
875 pl_info(&pl2, h + 70);
877 V_center(0);
878 break;
880 V_center(1);
881 if (g_st != GS_GAME) {
882 if (g_trans) {
883 return;
885 GM_draw();
886 V_copytoscr(0, SCRW, 0, SCRH);
887 return;
889 V_center(0);
890 if (_2pl) {
891 w_o = 0;
892 WD = SCRW - 120;
893 HT = SCRH / 2 - 2;
894 drawview(&pl1);
895 w_o = SCRH / 2;
896 WD = SCRW - 120;
897 HT = SCRH / 2 - 2;
898 drawview(&pl2);
899 } else{
900 w_o = 0;
901 WD = SCRW - 120;
902 HT = SCRH - 2;
903 drawview(&pl1);
905 if (g_trans) {
906 return;
908 V_center(1);
909 if (GM_draw()) {
910 pl1.drawst = 0xFF;
911 pl2.drawst = 0xFF;
912 V_copytoscr(0,SCRW,0,SCRH);
913 return;
915 V_center(0);
916 if (pl1.invl) {
917 h = get_pu_st(pl1.invl) * 6;
918 } else if (pl1.pain < 15) {
919 h = 0;
920 } else if (pl1.pain < 35) {
921 h = 1;
922 } else if (pl1.pain < 55) {
923 h = 2;
924 } else if (pl1.pain < 75) {
925 h=3;
926 } else if (pl1.pain < 95) {
927 h=4;
928 } else {
929 h = 5;
931 if (h != 0) {
932 V_maptoscr(0, SCRW - 120, 1, _2pl ? SCRH / 2 - 2 : SCRH - 2, clrmap + h * 256);
933 } else {
934 V_copytoscr(0, SCRW - 120, 1, _2pl ? SCRH / 2 - 2 : SCRH - 2);
936 if (pl1.drawst) {
937 V_copytoscr(SCRW - 120, 120, 0, _2pl ? SCRH / 2 : SCRH);
939 pl1.drawst = 0xFF;
940 if (_2pl) {
941 if (pl2.invl) {
942 h = get_pu_st(pl2.invl) * 6;
943 } else if (pl2.pain < 15) {
944 h = 0;
945 } else if (pl2.pain < 35) {
946 h = 1;
947 } else if (pl2.pain < 55) {
948 h = 2;
949 } else if (pl2.pain < 75) {
950 h = 3;
951 } else if (pl2.pain < 95) {
952 h = 4;
953 } else {
954 h = 5;
956 if (h) {
957 V_maptoscr(0, SCRW - 120, SCRH / 2 + 1, SCRH / 2 - 2, clrmap + h * 256);
958 } else {
959 V_copytoscr(0, SCRW - 120, SCRH / 2 + 1, SCRH / 2 - 2);
961 if (pl2.drawst) {
962 V_copytoscr(SCRW - 120, 120, SCRH / 2, SCRH / 2);
964 pl2.drawst = 0xFF;
968 void R_alloc (void) {
969 int i, j, n;
970 char s[10];
971 logo("R_alloc: загрузка графики\n");
972 // game
973 scrnh[0] = V_loadvgaimg("TITLEPIC");
974 scrnh[1] = V_loadvgaimg("INTERPIC");
975 scrnh[2] = V_loadvgaimg("ENDPIC");
976 cd_scr = M_lock(F_getresid("CD1PIC"));
977 for (i = 0; i < 2; ++i) {
978 sprintf(s, "LTN%c", i + '1');
979 for (j = 0; j < 2; ++j) {
980 ltn[i][j] = Z_getspr(s, j, 0, NULL);
983 // smoke
984 for (i = 0; i < SMSN; ++i) {
985 smk_spr[i] = Z_getspr("SMOK", i, 0, NULL);
987 for (i = 0; i < FLSN; ++i) {
988 smk_fspr[i] = Z_getspr("FLAM", i, 0, NULL);
990 // fx
991 for (i = 0; i < 10; ++i) {
992 fx_spr[i] = Z_getspr("TFOG", i, 0, fx_sprd + i);
994 for (; i < 15; ++i) {
995 fx_spr[i] = Z_getspr("IFOG", i - 10, 0, fx_sprd + i);
997 // weapons
998 for (i = 0; i < 4; ++i) {
999 wp_spr[i * 2] = Z_getspr("MISL", i, 1, wp_sprd + i * 2);
1000 wp_spr[i * 2 + 1] = Z_getspr("MISL", i, 2, wp_sprd + i * 2 + 1);
1002 for (; i < 6; ++i) {
1003 wp_spr[i * 2] = Z_getspr("PLSS", i - 4, 1, wp_sprd + i * 2);
1004 wp_spr[i * 2 + 1] = Z_getspr("PLSS", i - 4, 2, wp_sprd + i * 2 + 1);
1006 for (; i < 11; ++i) {
1007 wp_spr[i * 2] = Z_getspr("PLSE", i - 6, 1, wp_sprd + i * 2);
1008 wp_spr[i * 2 + 1] = Z_getspr("PLSE", i - 6, 2, wp_sprd + i * 2 + 1);
1010 for (; i < 13; ++i) {
1011 wp_spr[i * 2] = Z_getspr("APLS", i - 11, 1, wp_sprd + i * 2);
1012 wp_spr[i * 2 + 1] = Z_getspr("APLS", i - 11, 2, wp_sprd + i * 2 + 1);
1014 for (; i < 18; ++i) {
1015 wp_spr[i * 2] = Z_getspr("APBX", i - 13, 1, wp_sprd + i * 2);
1016 wp_spr[i * 2 + 1] = Z_getspr("APBX", i - 13, 2, wp_sprd + i * 2 + 1);
1018 for(; i < 20; ++i) {
1019 wp_spr[i * 2] = Z_getspr("BFS1", i - 18, 1, wp_sprd + i * 2);
1020 wp_spr[i * 2 + 1] = Z_getspr("BFS1", i - 18, 2, wp_sprd + i * 2 + 1);
1022 for (; i < 26; ++i) {
1023 wp_spr[i * 2] = Z_getspr("BFE1", i - 20, 1, wp_sprd + i * 2);
1024 wp_spr[i * 2 + 1] = Z_getspr("BFE1", i - 20, 2, wp_sprd + i * 2 + 1);
1026 for (; i < 30; ++i) {
1027 wp_spr[i * 2] = Z_getspr("BFE2", i - 26, 1, wp_sprd + i * 2);
1028 wp_spr[i * 2 + 1] = Z_getspr("BFE2", i - 26, 2, wp_sprd + i * 2 + 1);
1030 for (; i < 32; ++i) {
1031 wp_spr[i * 2] = Z_getspr("MISL", i - 30 + 4, 1, wp_sprd + i * 2);
1032 wp_spr[i * 2 + 1] = Z_getspr("MISL", i - 30 + 4, 2, wp_sprd + i * 2 + 1);
1034 for (; i < 37; ++i) {
1035 wp_spr[i * 2] = Z_getspr("BAL1", i - 32, 1, wp_sprd + i * 2);
1036 wp_spr[i * 2 + 1] = Z_getspr("BAL1", i - 32, 2, wp_sprd + i * 2 + 1);
1038 for (; i < 42; ++i) {
1039 wp_spr[i * 2] = Z_getspr("BAL7", i - 37, 1, wp_sprd + i * 2);
1040 wp_spr[i * 2 + 1] = Z_getspr("BAL7", i - 37, 2, wp_sprd + i * 2 + 1);
1042 for (; i < 47; ++i) {
1043 wp_spr[i * 2] = Z_getspr("BAL2", i - 42, 1, wp_sprd + i * 2);
1044 wp_spr[i * 2 + 1] = Z_getspr("BAL2", i - 42, 2, wp_sprd + i * 2 + 1);
1046 for (; i < 49; ++i) {
1047 wp_spr[i * 2] = Z_getspr("MANF", i - 47, 1, wp_sprd + i * 2);
1048 wp_spr[i * 2 + 1] = Z_getspr("MANF", i - 47, 2, wp_sprd + i * 2 + 1);
1050 // items
1051 static char snm[18][4] = {
1052 "CLIP", "SHEL", "ROCK", "CELL", "AMMO", "SBOX", "BROK", "CELP",
1053 "STIM", "MEDI", "BPAK",
1054 "CSAW", "SHOT", "SGN2", "MGUN", "LAUN", "PLAS", "BFUG"
1055 };
1056 static char n4[4][4] = {
1057 "SOUL", "SMRT", "SMGT", "SMBT"
1058 };
1059 static char n3[2][4] = {
1060 "GOR1", "FCAN"
1061 };
1062 for (i = 0; i < 18; ++i) {
1063 item_spr[i] = Z_getspr(snm[i], 0, 0, item_sprd + i);
1065 for (; i < 20; ++i) {
1066 item_spr[i] = Z_getspr("ARM1", i - 18, 0, item_sprd + i);
1067 item_spr[i + 2] = Z_getspr("ARM2", i - 18, 0, item_sprd + i);
1069 i+=2;
1070 for (; i < 26; ++i) {
1071 item_spr[i] = Z_getspr("MEGA", i - 22, 0, item_sprd + i);
1073 for (; i < 30; ++i) {
1074 item_spr[i] = Z_getspr("PINV", i - 26, 0, item_sprd + i);
1076 item_spr[30] = Z_getspr("AQUA", 0, 0, item_sprd + 30);
1077 item_spr[31] = Z_getspr("KEYR", 0, 0, item_sprd + 31);
1078 item_spr[32] = Z_getspr("KEYG", 0, 0, item_sprd + 32);
1079 item_spr[33] = Z_getspr("KEYB", 0, 0, item_sprd + 33);
1080 item_spr[34] = Z_getspr("SUIT", 0, 0, item_sprd + 34);
1081 for (n = 35, j = 0; j < 4; ++j) {
1082 for (i = 0; i < 4; ++i, ++n) {
1083 item_spr[n] = Z_getspr(n4[j], i, 0, item_sprd + n);
1086 for (j = 0; j < 2; ++j) {
1087 for (i = 0; i < 3; ++i, ++n) {
1088 item_spr[n] = Z_getspr(n3[j], i, 0, item_sprd + n);
1091 item_spr[57] = Z_getspr("GUN2", 0, 0, item_sprd + 57);
1092 // player
1093 for (i = 0; i < 27; ++i) {
1094 plr_spr[i * 2] = Z_getspr("PLAY", i, 1, plr_sprd + i * 2);
1095 plr_spr[i * 2 + 1] = Z_getspr("PLAY", i, 2, plr_sprd + i * 2 + 1);
1097 strncpy(s, "PWPx", 4);
1098 for (i = 1; i < 11; ++i) {
1099 s[3] = (i < 10 ? '0' : 'A' - 10) + i;
1100 for (j = 0; j < 6; ++j) {
1101 plr_wpn[i][j] = Z_getspr(s, j, 1, NULL);
1104 // monsters
1105 static char msn[MN_TN][4] = {
1106 "SARG", "TROO", "POSS", "SPOS", "CYBR", "CPOS", "BOSS", "BOS2", "HEAD", "SKUL",
1107 "PAIN", "SPID", "BSPI", "FATT", "SKEL", "VILE", "FISH", "BAR1", "ROBO", "PLAY"
1108 };
1109 static int mms[MN_TN] = {
1110 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,
1111 20*2, 17*2, 29*2, 6*2, 2*2, 17*2, 23*2
1112 };
1113 mn_sgun[0] = Z_getspr("PWP4", 0, 1, NULL);
1114 mn_sgun[1] = Z_getspr("PWP4", 1, 1, NULL);
1115 for (j = 0; j < MN_TN; ++j) {
1116 for (i = 0; i < mms[j]; ++i) {
1117 mn_spr[j][i] = Z_getspr(msn[j], i / 2, (i & 1) + 1, &mn_sprd[j][i]);
1119 if (j == MN_BARREL - 1) {
1120 for (i = 4; i < 14; ++i) {
1121 mn_spr[j][i] = Z_getspr("BEXP", i / 2 - 2, (i & 1) + 1, &mn_sprd[j][i]);
1125 for (i = 0; i < 8; ++i) {
1126 mn_fspr[i] = Z_getspr("FIRE", i, 0, NULL);
1128 pl_spr[0] = Z_getspr("PLAY", 'N' - 'A', 0, NULL);
1129 pl_spr[1] = Z_getspr("PLAY", 'W' - 'A', 0, NULL);
1130 // misc
1131 static char mnm[22][8]={
1132 "STTNUM0","STTNUM1","STTNUM2","STTNUM3","STTNUM4",
1133 "STTNUM5","STTNUM6","STTNUM7","STTNUM8","STTNUM9",
1134 "STTMINUS","STTPRCNT",
1135 "FISTA0","CSAWA0","PISTA0","SHOTA0","SGN2A0","MGUNA0","LAUNA0",
1136 "PLASA0","BFUGA0","GUN2A0"
1137 };
1138 stone=V_loadvgaimg("STONE");
1139 stone2=V_loadvgaimg("STONE2");
1140 keys[0]=V_loadvgaimg("KEYRA0");
1141 keys[1]=V_loadvgaimg("KEYGA0");
1142 keys[2]=V_loadvgaimg("KEYBA0");
1143 for (i = 0; i < 22; ++i) {
1144 sth[i] = V_loadvgaimg(mnm[i]);
1146 strcpy(s, "STBF_*");
1147 for (i = '!'; i < 160; ++i) {
1148 s[5] = i;
1149 bfh[i - '!'] = V_getvgaimg(F_findres(s));
1151 for (i = '!'; i < 160; ++i) {
1152 sprintf(s, "STCFN%03d", i);
1153 sfh[i - '!'] = V_getvgaimg(F_findres(s));
1155 strcpy(s, "WINUM*");
1156 for (i = '0'; i <= '9'; ++i) {
1157 s[5] = i;
1158 bfh[i - '!'] = V_loadvgaimg(s);
1160 bfh[':' - '!'] = V_loadvgaimg("WICOLON");
1161 // menu
1162 msklh[0] = V_loadvgaimg("M_SKULL1");
1163 msklh[1] = V_loadvgaimg("M_SKULL2");
1164 mbarl = V_loadvgaimg("M_THERML");
1165 mbarm = V_loadvgaimg("M_THERMM");
1166 mbarr = V_loadvgaimg("M_THERMR");
1167 mbaro = V_loadvgaimg("M_THERMO");
1168 mslotl = V_loadvgaimg("M_LSLEFT");
1169 mslotm = V_loadvgaimg("M_LSCNTR");
1170 mslotr = V_loadvgaimg("M_LSRGHT");
1173 void R_setgamma(int g) {
1174 int t;
1175 g = g < 0 ? 0 : (g > 4 ? 4 : g);
1176 gammaa = g;
1177 for (t = 0; t < 256; ++t) {
1178 std_pal[t][0]=gamcor[gammaa][main_pal[t][0]];
1179 std_pal[t][1]=gamcor[gammaa][main_pal[t][1]];
1180 std_pal[t][2]=gamcor[gammaa][main_pal[t][2]];
1182 VP_setall(std_pal);
1185 int R_getgamma (void) {
1186 return gammaa;
1189 void R_toggle_fullscreen (void) {
1190 fullscreen = !fullscreen;
1191 V_toggle();
1194 void R_init () {
1195 int i;
1196 F_loadres(F_getresid("PLAYPAL"), main_pal, 0, 768);
1197 for (i = 0; i < 256; ++i) {
1198 bright[i] = ((int) main_pal[i][0] + main_pal[i][1] + main_pal[i][2]) * 8 / (63 * 3);
1200 F_loadres(F_getresid("MIXMAP"), mixmap, 0, 0x10000);
1201 F_loadres(F_getresid("COLORMAP"), clrmap, 0, 256*12);
1202 logo("V_init: настройка видео\n");
1203 if (V_init() != 0) {
1204 ERR_failinit("Не могу установить видеорежим VGA");
1206 //R_setgamma(gammaa);
1207 V_setrect(0, SCRW, 0, SCRH);
1208 V_setscr(scrbuf);
1209 V_clr(0, SCRW, 0, SCRH, 0);
1210 R_alloc();
1213 void R_done (void) {
1214 V_done();