ref: 0c46469f2135819a33663e80657a7c4c521dd66e
parent: ddcaa37baf64e0fc44f8ebf051005a0b0a1fd29b
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Sat Jan 28 00:13:19 EST 2017
playable game, most relevant seqs, usable menus, fixes - fs: fix setting sfxs .pcm for missing pcms, again - drw: fix wrong fizzout offsets - gm: disallow picking up items after death - gm: fix reverted mouse buttons 2 and 3 - hub: rework implementation to allow all the crazy permutations - hub: (refbug) actual fizzlein when starting regular game - map: fix disabled guy spawns with GDbaby - map: fix opool size not taking in account the two dummy nodes - rend: fix tiles .vis overflow - rend: scaltab: just generate a scaler for every height, save doesn't do anything here - snd: handle disabled sound - snd: move one-time opl2 settings to initsnd - snd: allow playing pcm when al sfx are disabled - wl3d: remove -x and make difc param to -w mandatory - wl3d: ignore first mouse event after grab to prevent crazy deltas - sod/sdm: already in game message done in ctl rather than in difc; this is arguably better (simpler, no flicker) - notes: map load screen is purely cosmetic
--- a/dat.h
+++ b/dat.h
@@ -15,6 +15,7 @@
typedef struct Static Static;
typedef struct Tile Tile;
typedef struct Game Game;
+typedef struct Score Score;
enum{
WL6,
@@ -43,8 +44,9 @@
Ke
};
extern int msense;
-extern int kbon, mson;
-extern int kb, mΔx, mΔy, mΔb;
+extern int vwsize;
+extern int kbon;
+extern int kb, mΔx, mΔy, mb;
extern int sfxon, muson, pcmon;
extern int sfxlck;
extern Rune keys[];
@@ -51,7 +53,8 @@
extern void (*step)(void);
extern int Δtc;
extern int nosleep;
-extern int mtc;
+extern int autorun;
+extern int qtc;
enum{
Vw = 320,
@@ -64,6 +67,8 @@
};
extern uchar *px, pxb[], fzb[];
extern int npx, scale;
+extern void (*mclear)(void);
+extern void (*stripe)(int);
enum{
C0,
@@ -226,12 +231,16 @@
Sangeltired = Sotto,
Ssend = Sfett,
+ Msdwon = 6,
+ Mend = 7,
Mintro = 7,
Mmenu = 14,
+ Minter = 16,
Mnazjazz = 18,
Maward = 20,
Mroster = 23,
Mtower = 23,
+ Mwon = 24,
Pbackdrop = 0,
Pmouselback,
@@ -597,7 +606,6 @@
extern s32int sint[], *cost;
struct View{
- int size;
int dx;
int dy;
int ofs;
@@ -1224,15 +1232,21 @@
WPmg,
WPgatling,
+ GMup = 0,
+ GMsetec,
+ GMret,
+
EDfizz = 1,
+ EDcam,
+ EDcam2,
EDdem,
EDkey,
EDdie,
- EDcam,
- EDcam2,
EDup,
EDsetec,
- EDwon
+ EDwon,
+ EDspear,
+ EDmsg
};
struct Game{
int hp;
@@ -1243,24 +1257,39 @@
int lives;
int keys;
int pt;
+ int oldpt;
int to1up;
int wfrm;
int facefrm;
int map;
int difc;
- int lvltc;
- int kills;
- int nkills;
- int secret;
- int nsecret;
- int treasure;
- int ntreasure;
+ int tc;
+ int eptm;
+ int kp;
+ int ktot;
+ int epk;
+ int sp;
+ int stot;
+ int eps;
+ int tp;
+ int ttot;
+ int ept;
int won;
int mut;
int end;
+ int com;
int demo;
int record;
int load;
};
extern Game gm;
-extern int god, noclip, onestep;
+extern int allrecv, god, noclip, slomo;
+
+struct Score{
+ char name[58];
+ int n;
+ int lvl;
+ int ep;
+};
+extern Score scs[];
+extern char savs[][32];
--- a/debug.c
+++ b/debug.c
@@ -10,187 +10,19 @@
int esc;
s16int level,i;
- if (Keyboard[sc_B]) // B = border color
+ if (Keyboard[sc_O])
{
- CenterWindow(24,3);
- PrintY+=6;
- US_Print(" Border color (0-15):");
- VW_UpdateScreen();
- esc = !US_LineInput (px,py,str,NULL,true,2,0);
- if (!esc)
- {
- level = atoi (str);
- if (level>=0 && level<=15)
- VW_ColorBorder (level);
- }
- return 1;
- }
-
- if (Keyboard[sc_E]) // E = quit level
- {
- if (tedlevel)
- Quit (NULL);
- gm.φ = ex_completed;
-// gamestate.mapon++;
- }
-
- if (Keyboard[sc_F]) // F = facing spot
- {
- CenterWindow (14,4);
- US_Print ("X:");
- US_PrintUnsigned (player->x);
- US_Print ("\nY:");
- US_PrintUnsigned (player->y);
- US_Print ("\nA:");
- US_PrintUnsigned (player->angle);
- VW_UpdateScreen();
- IN_Ack();
- return 1;
- }
-
- if (Keyboard[sc_G]) // G = god mode
- {
- CenterWindow (12,2);
- if (godmode)
- US_PrintCentered ("God mode OFF");
- else
- US_PrintCentered ("God mode ON");
- VW_UpdateScreen();
- IN_Ack();
- godmode ^= 1;
- return 1;
- }
- if (Keyboard[sc_H]) // H = hurt self
- {
- IN_ClearKeysDown ();
- hurt (16,NULL);
- }
- else if (Keyboard[sc_I]) // I = item cheat
- {
- CenterWindow (12,3);
- US_PrintCentered ("Free items!");
- VW_UpdateScreen();
- givep (100000);
- HealSelf (99);
- if (gm.bestw<WPgatling)
- givew (gm.bestw+1);
- gamestate.ammo += 50;
- if (gamestate.ammo > 99)
- gamestate.ammo = 99;
- huda ();
- IN_Ack ();
- return 1;
- }
-#ifdef SPEAR
- else if (Keyboard[sc_N]) // N = no clip
- {
- noclip^=1;
- CenterWindow (18,3);
- if (noclip)
- US_PrintCentered ("No clipping ON");
- else
- US_PrintCentered ("No clipping OFF");
- VW_UpdateScreen();
- IN_Ack ();
- return 1;
- }
-#endif
-#if 0
- else if (Keyboard[sc_O]) // O = overhead
- {
ViewMap();
return 1;
}
-#endif
- else if (Keyboard[sc_Q]) // Q = fast quit
- Quit (NULL);
- else if (Keyboard[sc_S]) // S = slow motion
- {
- onestep^=1;
- CenterWindow (18,3);
- if (onestep)
- US_PrintCentered ("Slow motion ON");
- else
- US_PrintCentered ("Slow motion OFF");
- VW_UpdateScreen();
- IN_Ack ();
- return 1;
- }
- else if (Keyboard[sc_T]) // T = shape test
- {
- ShapeTest ();
- return 1;
- }
- else if (Keyboard[sc_V]) // V = extra VBLs
- {
- CenterWindow(30,3);
- PrintY+=6;
- US_Print(" Add how many extra VBLs(0-8):");
- VW_UpdateScreen();
- esc = !US_LineInput (px,py,str,NULL,true,2,0);
- if (!esc)
- {
- level = atoi (str);
- if (level>=0 && level<=8)
- extravbls = level;
- }
- return 1;
- }
- else if (Keyboard[sc_W]) // W = warp to level
- {
- CenterWindow(26,3);
- PrintY+=6;
-#ifndef SPEAR
- US_Print(" Warp to which level(1-10):");
-#else
- US_Print(" Warp to which level(1-21):");
-#endif
- VW_UpdateScreen();
- esc = !US_LineInput (px,py,str,NULL,true,2,0);
- if (!esc)
- {
- level = atoi (str);
-#ifndef SPEAR
- if (level>0 && level<11)
-#else
- if (level>0 && level<22)
-#endif
- {
- gamestate.mapon = level-1;
- gm.φ = ex_warped;
- }
- }
- return 1;
- }
- else if (Keyboard[sc_X]) // X = item cheat
- {
- CenterWindow (12,3);
- US_PrintCentered ("Extra stuff!");
- VW_UpdateScreen();
- // DEBUG: put stuff here
- IN_Ack ();
- return 1;
- }
-
return 0;
}
-
-#if 0
-/*
-===================
-=
-= OverheadRefresh
-=
-===================
-*/
-
void OverheadRefresh (void)
{
u16int x,y,endx,endy,sx,sy;
u16int tile;
-
endx = maporgx+VIEWTILEX;
endy = maporgy+VIEWTILEY;
@@ -232,17 +64,7 @@
}
}
-#endif
-#if 0
-/*
-===================
-=
-= ViewMap
-=
-===================
-*/
-
void ViewMap (void)
{
int button0held;
@@ -276,7 +98,6 @@
maporgy--;
if (controly > 0 && maporgy<mapheight-VIEWTILEY)
maporgy++;
-
#if 0
if (c.button0 && !button0held)
{
@@ -295,5 +116,3 @@
IN_ClearKeysDown ();
}
-#endif
-
--- a/drw.c
+++ b/drw.c
@@ -9,13 +9,14 @@
Spr *sprs;
int scale, npx;
-uchar *px, pxb[Va], fzb[Vw*Vhud];
+uchar *px, pxb[Va], *fzd, fzb[Vw*Vhud];
View vw;
+void (*mclear)(void);
+void (*stripe)(int);
static Col *fcol;
static u32int *fref;
static int fi, fo, fdt;
-static uchar *fzd;
static int fzc, fzdx, fzdy, fzdn, fzn, fzout;
static uchar wl6ceil[] = {
@@ -53,6 +54,76 @@
}
void
+out(void)
+{
+ int n;
+ u32int c;
+ uchar *s, *d, *w;
+
+ d = px;
+ s = pxb;
+ n = scale * 3;
+ while(s < pxb + sizeof pxb){
+ c = pal[*s++];
+ w = d + n;
+ while(d < w){
+ *d++ = c;
+ *d++ = c>>8;
+ *d++ = c>>16;
+ }
+ }
+ flush();
+}
+
+void
+put(int x, int y, int dx, int dy, int c)
+{
+ uchar *d;
+
+ d = pxb + x + y*Vw;
+ while(dy-- > 0){
+ memset(d, c, dx);
+ d += Vw;
+ }
+}
+
+void
+pput(int x, int y, int dx, int dy, uchar *s)
+{
+ uchar *d;
+
+ d = pxb + x + y*Vw;
+ while(dy-- > 0){
+ memcpy(d, s, dx);
+ s += dx;
+ d += Vw;
+ }
+}
+
+void
+fill(int c)
+{
+ memset(pxb, c, sizeof pxb);
+}
+
+void
+clear(void)
+{
+ int n;
+ uchar c, *p;
+
+ c = ver < SDM ? wl6ceil[gm.map] : sodceil[gm.map];
+ p = pxb + vw.ofs;
+ n = 0;
+ while(n++ < vw.dy){
+ memset(p, c, vw.dx);
+ p += Vw;
+ if(n == vw.dy/2)
+ c = 0x19;
+ }
+}
+
+void
fizz(void)
{
int i, x, y, ofs;
@@ -78,16 +149,18 @@
{
if(save)
memcpy(fzb, pxb + vw.ofs, (vw.dy-1) * Vw + vw.dx-1);
+ fzdx = vw.dx;
+ fzdy = vw.dy;
+ fzd = pxb + vw.ofs;
if(c < 0){
- fzd = pxb + vw.ofs;
- fzdx = vw.dx;
- fzdy = vw.dy;
fzdn = Va / 20;
fzout = 0;
}else{
- fzd = pxb;
- fzdx = Vw;
- fzdy = Vhud;
+ if(gm.won){
+ fzd = pxb;
+ fzdx = Vw;
+ fzdy = Vhud;
+ }
fzdn = Va / 70;
fzout = 1;
fzc = c;
@@ -157,64 +230,30 @@
}
void
-palpic(uchar *s)
+palfill(Col *c)
{
- u32int *p;
+ u32int v, *p;
- p = pal = pals[Csod];
- while(p < pals[Csod] + nelem(pals[0])){
- *p++ = s[0]*255/63<<16 | s[1]*255/63<<8 | s[2]*255/63;
- s += 3;
- }
+ p = pals[Csod];
+ v = c->r << 16 | c->g << 8 | c->b;
+ while(p < pals[Cend])
+ *p++ = v;
+ pal = pals[Csod];
}
void
-out(void)
+palpic(uchar *s)
{
- int n;
- u32int c;
- uchar *s, *d, *w;
+ u32int *p;
- d = px;
- s = pxb;
- n = scale * 3;
- while(s < pxb + sizeof pxb){
- c = pal[*s++];
- w = d + n;
- while(d < w){
- *d++ = c;
- *d++ = c>>8;
- *d++ = c>>16;
- }
+ p = pals[Csod];
+ while(p < pals[Csod] + nelem(pals[0])){
+ *p++ = s[0]*255/63 << 16 | s[1]*255/63 << 8 | s[2]*255/63;
+ s += 3;
}
- flush();
+ pal = pals[Csod];
}
-void
-pput(int x, int y, int dx, int dy, uchar *s)
-{
- uchar *d;
-
- d = pxb + x + y*Vw;
- while(dy-- > 0){
- memcpy(d, s, dx);
- s += dx;
- d += Vw;
- }
-}
-
-void
-put(int x, int y, int dx, int dy, int c)
-{
- uchar *d;
-
- d = pxb + x + y*Vw;
- while(dy-- > 0){
- memset(d, c, dx);
- d += Vw;
- }
-}
-
int
txt(int x, int y, char *t, int col)
{
@@ -299,9 +338,12 @@
}
void
-fill(int c)
+txtcen(int y, char *t, int c)
{
- memset(pxb, c, sizeof pxb);
+ int n;
+
+ n = txtw(t);
+ txt((Vw - n) / 2, y, t, c);
}
void
@@ -340,12 +382,65 @@
}
void
+wlmclear(void)
+{
+ put(0, 0, Vw, Vh, 0x29);
+}
+void
+sdmclear(void)
+{
+ pic(0, 0, pict[Pbackdrop]);
+}
+
+void
+wlstripe(int y)
+{
+ put(0, y, Vw, 24, 0);
+ put(0, y+22, 320, 1, 0x2c);
+}
+void
+sdstripe(int y)
+{
+ put(0, y, Vw, 22, 0);
+ put(0, y+23, 320, 1, 0);
+}
+
+void
+outbox(int x, int y, int dx, int dy, int c1, int c2)
+{
+ put(x, y, dx, 1, c2);
+ put(x, y+1, 1, dy-1, c2);
+ put(x, y+dy, dx+1, 1, c1);
+ put(x+dx, y, 1, dy, c1);
+}
+
+void
+box(int x, int y, int dx, int dy, int col, int out, int out2)
+{
+ put(x+1, y+1, dx-1, dy-1, col);
+ outbox(x, y, dx, dy, out, out2);
+}
+
+void
+viewbox(void)
+{
+ int x, y;
+
+ x = Vhud - vw.dx / 2 - 1;
+ y = (Vhud - vw.dy) / 2 - 1;
+ put(0, 0, 320, Vhud, 0x7f);
+ box(x, y, vw.dx+1, vw.dy+1, 0, 0x7d, 0);
+ put(x, y+vw.dy+1, 1, 1, 0x7c);
+}
+
+void
hudf(void)
{
int p;
if(gm.hp > 0){
- p = god ? pict[Pgod] : pict[Pface1] + 3 * (100 - gm.hp >> 4);
+ p = ver >= SDM && god ? pict[Pgod]
+ : pict[Pface1] + 3 * (100 - gm.hp >> 4);
p += gm.facefrm;
}else
p = gm.mut ? pict[Pmut] : pict[Pface8];
@@ -367,7 +462,10 @@
void
hudm(void)
{
- hudnp(16, 176, 2, ver == SOD && gm.map == 20 ? 18 : gm.map+1);
+ int n;
+
+ n = ver == SOD ? (gm.map == 20 ? 18 : gm.map + 1) : gm.map % 10 + 1;
+ hudnp(16, 176, 2, n);
}
void
@@ -396,18 +494,16 @@
}
void
-clear(void)
+view(void)
{
- int n;
- uchar c, *p;
-
- c = ver < SDM ? wl6ceil[gm.map] : sodceil[gm.map];
- p = pxb + vw.ofs;
- n = 0;
- while(n++ < vw.dy){
- memset(p, c, vw.dx);
- p += Vw;
- if(n == vw.dy/2)
- c = 0x19;
- }
+ viewbox();
+ pic(0, Vhud, pict[Pstat]);
+ hudf();
+ hudh();
+ hudl();
+ hudm();
+ huda();
+ hudk();
+ hudw();
+ hudp();
}
--- a/fns.h
+++ b/fns.h
@@ -1,5 +1,4 @@
void* emalloc(ulong);
-void* erealloc(void*, ulong);
void grab(int);
void toss(void);
void flush(void);
@@ -6,22 +5,32 @@
char* demof(char*);
u16int* readmap(int);
void dat(char*);
+void out(void);
+void put(int, int, int, int, int);
+void pput(int, int, int, int, uchar*);
+void fill(int);
+void clear(void);
void fizz(void);
void fizzop(int, int);
void fadeout(void);
void fadein(void);
void fadeop(Col*, int);
+void palfill(Col*);
void palpic(uchar*);
-void out(void);
-void pput(int, int, int, int, uchar*);
-void put(int, int, int, int, int);
int txt(int, int, char*, int);
int txtnl(int, int, char*, int);
int txth(char*);
int txtw(char*);
-void fill(int);
+void txtcen(int, char*, int);
void pic(int, int, int);
void pictxt(int, int, char*);
+void wlmclear(void);
+void sdmclear(void);
+void wlstripe(int);
+void sdstripe(int);
+void outbox(int, int, int, int, int, int);
+void box(int, int, int, int, int, int, int);
+void viewbox(void);
void hudf(void);
void hudh(void);
void hudl(void);
@@ -30,16 +39,17 @@
void hudk(void);
void hudw(void);
void hudp(void);
-void clear(void);
+void view(void);
void scalspr(int, int, int);
s32int ffs(s32int, s32int);
void render(void);
-void initscal(void);
-void setvw(int);
+void setvw(void);
void tab(void);
+int quickkey(Rune);
void gend(void);
-void mstep(void);
-void init(char*);
+void eatcs(void);
+void qstep(void);
+void init(char*, int, int);
void drop(Tile*, int);
void dropen(Door*);
void druse(Door*);
@@ -51,12 +61,21 @@
void mapmus(void);
void initmap(void);
void sodmap(void);
+void dieturn(void);
+void die(void);
void camwarp(void);
+void givew(int);
+void givep(int);
void bonus(Static*);
+void crm114(int);
+void eatcs(void);
int rnd(void);
void gstep(void);
-void demo(void);
-void initg(int, uchar*);
+void nextmap(void);
+void game(void);
+void spshunt(void);
+void greset(void);
+void ginit(uchar*, int, int);
uchar* opl2out(uchar*, int);
void opl2wr(int, int);
void opl2init(int);
--- a/fs.c
+++ b/fs.c
@@ -805,7 +805,7 @@
p = pcmt[ver<SDM ? 0 : 1];
e = p + npcm;
for(pcm=pcms; p<e; p++, pcm++)
- if(*p != Send)
+ if(*p != Send && pcm->p != nil)
sfxs[*p].pcm = pcm;
sfxs[Sscream3].pcm = sfxs[ver<SDM ? Sscream2 : Sscream4].pcm; /* why */
}
@@ -999,12 +999,6 @@
}
static void
-cfg(void)
-{
- msense = 5;
-}
-
-static void
loadscr(void)
{
Biobuf *bf;
@@ -1089,8 +1083,7 @@
rfork(RFNAMEG);
if(bind(".", dir, MBEFORE|MCREATE) < 0 || chdir(dir) < 0)
- fprint(2, "dat: %r\n");
-
+ sysfatal("dat: %r\n");
e = ext;
loadscr();
ext = e;
@@ -1106,5 +1099,4 @@
sodmap();
}
ext = e;
- cfg();
}
--- a/game.c
+++ b/game.c
@@ -1,72 +1,6 @@
int ingame,fizzlein;
u16int latchpics[NUMLATCHPICS];
-s32int spearx,speary;
-u16int spearangle;
-int spearflag;
-
-//
-// ELEVATOR BACK MAPS - REMEMBER (-1)!!
-//
-s16int ElevatorBackTo[]={1,1,7,3,5,3};
-
-void DrawPlayBorderSides (void)
-{
- s16int xl,yl;
-
- xl = 160-vw.dx/2;
- yl = (200-STATUSLINES-vw.dy)/2;
-
- VWB_Bar (0,0,xl-1,200-STATUSLINES,127);
- VWB_Bar (xl+vw.dx+1,0,xl-2,200-STATUSLINES,127);
-
- VWB_Vlin (yl-1,yl+vw.dy,xl-1,0);
- VWB_Vlin (yl-1,yl+vw.dy,xl+vw.dx,125);
-}
-
-void DrawAllPlayBorderSides (void)
-{
- u16int i,temp;
-
- temp = bufferofs;
- for (i=0;i<3;i++)
- {
- bufferofs = screenloc[i];
- DrawPlayBorderSides ();
- }
- bufferofs = temp;
-}
-
-void DrawAllPlayBorder (void)
-{
- u16int i,temp;
-
- temp = bufferofs;
- for (i=0;i<3;i++)
- {
- bufferofs = screenloc[i];
- DrawPlayBorder ();
- }
- bufferofs = temp;
-}
-
-void DrawPlayBorder (void)
-{
- s16int xl,yl;
-
- VWB_Bar (0,0,320,200-STATUSLINES,127);
-
- xl = 160-vw.dx/2;
- yl = (200-STATUSLINES-vw.dy)/2;
- VWB_Bar (xl,yl,vw.dx,vw.dy,0);
-
- VWB_Hlin (xl-1,xl+vw.dx,yl-1,0);
- VWB_Hlin (xl-1,xl+vw.dx,yl+vw.dy,125);
- VWB_Vlin (yl-1,yl+vw.dy,xl-1,0);
- VWB_Vlin (yl-1,yl+vw.dy,xl+vw.dx,125);
- VWB_Plot (xl-1,yl+vw.dy,124);
-}
-
#define MAXDEMOSIZE 8192
void StartDemoRecord (s16int levelnumber)
@@ -108,8 +42,6 @@
CA_WriteFile (demoname,(void far *)demobuffer,length);
}
}
-
-
MM_FreePtr (&demobuffer);
}
@@ -167,119 +99,6 @@
#define DEATHROTATE 2
-void Died (void)
-{
- float fangle;
- s32int dx,dy;
- s16int iangle,curangle,clockwise,counter,change;
-
- gamestate.weapon = -1; // take away weapon
- sfx (Sdie);
-//
-// swing around to face attacker
-//
- dx = killer->x - player->x;
- dy = player->y - killer->y;
-
- fangle = atan2(dy,dx); // returns -pi to pi
- if (fangle<0)
- fangle = Fpi*2+fangle;
-
- iangle = fangle/(Fpi*2)*ANGLES;
-
- if (player->angle > iangle)
- {
- counter = player->angle - iangle;
- clockwise = ANGLES-player->angle + iangle;
- }
- else
- {
- clockwise = iangle - player->angle;
- counter = player->angle + ANGLES-iangle;
- }
-
- curangle = player->angle;
-
- if (clockwise<counter)
- {
- //
- // rotate clockwise
- //
- if (curangle>iangle)
- curangle -= ANGLES;
- do
- {
- change = tics*DEATHROTATE;
- if (curangle + change > iangle)
- change = iangle-curangle;
-
- curangle += change;
- player->angle += change;
- if (player->angle >= ANGLES)
- player->angle -= ANGLES;
-
- render ();
- ttic ();
- } while (curangle != iangle);
- }
- else
- {
- //
- // rotate counterclockwise
- //
- if (curangle<iangle)
- curangle += ANGLES;
- do
- {
- change = -tics*DEATHROTATE;
- if (curangle + change < iangle)
- change = iangle-curangle;
-
- curangle += change;
- player->angle += change;
- if (player->angle < 0)
- player->angle += ANGLES;
-
- render ();
- ttic ();
- } while (curangle != iangle);
- }
-
-//
-// fade to red
-//
- pal = pals[C0];
-
- bufferofs += screenofs;
- VW_Bar (0,0,vw.dx,vw.dy,4);
- IN_ClearKeysDown ();
- FizzleFade(bufferofs,displayofs+screenofs,vw.dx,vw.dy,70,false);
- bufferofs -= screenofs;
- IN_UserInput(100);
- SD_WaitSoundDone ();
-
- if (tedlevel == false) // SO'S YA DON'T GET KILLED WHILE LAUNCHING!
- gamestate.lives--;
-
- if (gamestate.lives > -1)
- {
- gm.hp = 100;
- gm.w = gm.bestw = gm.lastw = WPpistol;
- gm.ammo = STARTAMMO;
- gm.keys = 0;
- atkfrm = 0;
- atktc = 0;
- gm.wfrm = 0;
- hudk();
- hudw();
- huda();
- hudh();
- hudf();
- hudl();
- }
-
-}
-
void GameLoop (void)
{
s16int i,xl,yl,xh,yh;
@@ -303,14 +122,6 @@
else
initmap ();
-#ifdef SPEAR
- if (gamestate.mapon == 20) // give them the key allways
- {
- gamestate.keys |= 1;
- hudk ();
- }
-#endif
-
ingame = true;
mapmus ();
PM_CheckMainMem ();
@@ -325,38 +136,6 @@
startplayloop:
PlayLoop ();
-#ifdef SPEAR
- if (spearflag)
- {
- SD_StopSound();
- sfx(Sspear);
- if (DigiMode != sds_Off)
- {
- s32int lasttimecount = TimeCount;
-
- while(TimeCount < lasttimecount+150)
- //while(DigiPlaying!=false)
- SD_Poll();
- }
- else
- SD_WaitSoundDone();
-
- gamestate.oldscore = gm.pt;
- gamestate.mapon = 20;
- initmap ();
- mapmus ();
- PM_CheckMainMem ();
- oplr->x = spearx;
- oplr->y = speary;
- oplr->tx = spearx >> Dtlshift;
- oplr->ty = speary >> Dtlshift;
- oplr->θ2 = spearangle;
- oplr->areaid = oplr->tl->p0 - MTfloor;
- spearflag = false;
- goto startplayloop;
- }
-#endif
-
stopmus ();
ingame = false;
@@ -370,112 +149,10 @@
{
case ex_completed:
case ex_secretlevel:
- gamestate.keys = 0;
- hudk ();
- VW_FadeOut ();
-
-
- LevelCompleted (); // do the intermission
-#ifdef SPEARDEMO
- if (gamestate.mapon == 1)
- {
- died = true; // don't "get psyched!"
-
- VW_FadeOut ();
-
- CheckHighScore (gm.pt,gamestate.mapon+1);
-
- #pragma warn -sus
- _fstrcpy(MainMenu[viewscores].string,"View Scores");
- MainMenu[viewscores].routine = CP_ViewScores;
- #pragma warn +sus
-
- return;
- }
-#endif
-
- gamestate.oldscore = gm.pt;
-
-#ifndef SPEAR
- //
- // COMING BACK FROM SECRET LEVEL
- //
- if (gamestate.mapon == 9)
- gamestate.mapon = ElevatorBackTo[gamestate.episode]; // back from secret
- else
- //
- // GOING TO SECRET LEVEL
- //
- if (gm.φ == ex_secretlevel)
- gamestate.mapon = 9;
-#else
-
-#define FROMSECRET1 3
-#define FROMSECRET2 11
-
- //
- // GOING TO SECRET LEVEL
- //
- if (gm.φ == ex_secretlevel)
- switch(gamestate.mapon)
- {
- case FROMSECRET1: gamestate.mapon = 18; break;
- case FROMSECRET2: gamestate.mapon = 19; break;
- }
- else
- //
- // COMING BACK FROM SECRET LEVEL
- //
- if (gamestate.mapon == 18 || gamestate.mapon == 19)
- switch(gamestate.mapon)
- {
- case 18: gamestate.mapon = FROMSECRET1+1; break;
- case 19: gamestate.mapon = FROMSECRET2+1; break;
- }
-#endif
- else
- //
- // GOING TO NEXT LEVEL
- //
- gamestate.mapon++;
-
-
break;
-
case ex_died:
- Died ();
- died = true; // don't "get psyched!"
-
- if (gamestate.lives > -1)
- break; // more lives left
-
- VW_FadeOut ();
-
- CheckHighScore (gm.pt,gamestate.mapon+1);
-
- #pragma warn -sus
- _fstrcpy(MainMenu[viewscores].string,"View Scores");
- MainMenu[viewscores].routine = CP_ViewScores;
- #pragma warn +sus
-
return;
-
case ex_victorious:
-
-#ifndef SPEAR
- VW_FadeOut ();
-#else
- VL_FadeOut (0,255,0,17,17,300);
-#endif
- Victory ();
-
- CheckHighScore (gm.pt,gamestate.mapon+1);
-
- #pragma warn -sus
- _fstrcpy(MainMenu[viewscores].string,"View Scores");
- MainMenu[viewscores].routine = CP_ViewScores;
- #pragma warn +sus
-
return;
}
} while (1);
--- a/gm.c
+++ b/gm.c
@@ -11,33 +11,33 @@
extern QLock inlck;
Rune keys[Ke] = {
- [K↑] Kup,
- [K↓] Kdown,
- [K←] Kleft,
- [K→] Kright,
- [Krun] Kshift,
[Kfire] Kctl,
- [Kopen] ' ',
[Kstrafe] Kalt,
+ [Krun] Kshift,
+ [Kopen] ' ',
[Kknife] '1',
[Kpistol] '2',
[Kmg] '3',
[Kgatling] '4',
+ [K↑] Kup,
+ [K↓] Kdown,
+ [K←] Kleft,
+ [K→] Kright,
[Kmenu] Kesc
};
Game gm;
int msense;
-int god, noclip, onestep;
+int allrecv, god, noclip, slomo;
+typedef struct Crm Crm;
enum{
Ncrm = 7
};
-
-typedef struct Crm Crm;
struct Crm{
char s[Ncrm];
void (*f)(void);
};
+static char crs[Ncrm];
static int rndi, rndt[] = {
0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66, 74, 21,
@@ -60,14 +60,13 @@
static int demfrm;
static int kon, kold, kΔx, kΔy;
static s16int kΔθ;
-static int allrecv, firing, noise;
+static int firing, noise, dirty;
static char *dem, *deme;
-static Crm crms[];
-static char crs[Ncrm];
static int dmgtc, bonustc, facetc, funtc;
static Obj *camobj;
-static int bosskillx, bosskilly;
-static int gotspear, spearx, speary, spearθ;
+static int killx, killy;
+static int dieΔθ, diedir;
+static int spearx, speary, spearθ;
static int atk[][4] = {
{0, 2, 0, -1},
{0, 1, 0, -1},
@@ -91,15 +90,6 @@
}
static void
-givew(int n)
-{
- givea(6);
- if(gm.bestw < n)
- gm.w = gm.lastw = gm.bestw = n;
- hudw();
-}
-
-static void
givek(int n)
{
gm.keys |= 1 << n;
@@ -116,17 +106,6 @@
}
static void
-givep(int n)
-{
- gm.pt += n;
- while(gm.pt >= gm.to1up){
- gm.to1up += 40000;
- givel();
- }
- hudp();
-}
-
-static void
giveh(int n)
{
gm.hp += n;
@@ -287,10 +266,11 @@
static void
yelp(Obj *o)
{
- int n, s[] = {
+ static int s[] = {
Sscream1, Sscream2, Sscream3, Sscream4,
Sscream5, Sscream7, Sscream8, Sscream9
};
+ int n;
n = gm.map;
if((ver == WL6 && n % 10 == 9 || ver == SOD && (n == 18 || n == 19)) && !rnd())
@@ -303,7 +283,6 @@
sfxatt(Sscream6, 1, o->x, o->y);
return;
}
-
switch(o->type){
case Omut: sfxatt(Smutdie, 1, o->x, o->y); break;
case Ogd: sfxatt(s[rnd()%(ver==WL1?2:8)], 1, o->x, o->y); break;
@@ -368,8 +347,8 @@
break;
case Oschb:
givep(5000);
- bosskillx = oplr->x;
- bosskilly = oplr->y;
+ killx = oplr->x;
+ killy = oplr->y;
ostate(o, stt+GSschbdie1);
yelp(o);
break;
@@ -380,14 +359,14 @@
break;
case Ootto:
givep(5000);
- bosskillx = oplr->x;
- bosskilly = oplr->y;
+ killx = oplr->x;
+ killy = oplr->y;
ostate(o, stt+GSottodie1);
break;
case Ofett:
givep(5000);
- bosskillx = oplr->x;
- bosskilly = oplr->y;
+ killx = oplr->x;
+ killy = oplr->y;
ostate(o, stt+GSfettdie1);
break;
case Ofake:
@@ -400,8 +379,8 @@
break;
case Ohitler:
givep(5000);
- bosskillx = oplr->x;
- bosskilly = oplr->y;
+ killx = oplr->x;
+ killy = oplr->y;
ostate(o, stt+GShitlerdie1);
yelp(o);
break;
@@ -434,7 +413,7 @@
drop(tl, Rkey1);
break;
}
- gm.kills++;
+ gm.kp++;
o->f &= ~OFshootable;
o->f |= OFnomark;
tl->o = nil;
@@ -472,8 +451,9 @@
gm.hp -= n;
if(gm.hp <= 0){
gm.hp = 0;
- gm.end = EDdie;
- camobj = from;
+ gm.end = gm.demo || gm.record ? EDdem : EDdie;
+ killx = from->x;
+ killy = from->y;
if(ver >= SDM && from->type == Oneedle)
gm.mut++;
}
@@ -527,7 +507,6 @@
py = oplr->y >> 8;
ptx = oplr->tx;
pty = oplr->ty;
-
if(ptx != otx){
if(ptx > otx){
δ = 256 - (ox & 0xff);
@@ -541,7 +520,6 @@
dy = 0x7fff;
else if(dy < -0x7fff)
dy = -0x7fff;
-
y = oy + (dy * δ >> 8);
x = otx + dx;
ptx += dx;
@@ -568,7 +546,6 @@
dx = 0x7fff;
else if(dx < -0x7fff)
dx = -0x7fff;
-
x = ox + (dx * δ >> 8);
y = oty + dy;
pty += dy;
@@ -1311,9 +1288,8 @@
gm.end = EDcam2;
return;
}
- gm.won++;
gm.end = EDcam;
- mtc = 0;
+ qtc = 0;
dofizz++;
camobj = o;
}
@@ -1374,7 +1350,6 @@
static void
kmove(void)
{
- int θ;
s16int u;
oplr->v = 0;
@@ -1387,12 +1362,7 @@
kΔθ += kΔx;
u = kΔθ / 20;
kΔθ -= u * 20;
- θ = oplr->θ - u;
- if(θ >= 360)
- θ -= 360;
- if(θ < 0)
- θ += 360;
- oplr->θ = θ;
+ oplr->θ = (oplr->θ - u + 360) % 360;
}
if(kΔy < 0)
thrust(oplr->θ, -kΔy * 150);
@@ -1420,7 +1390,7 @@
}
c->to = tl->tl;
c->tl = tl->tl;
- gm.secret++;
+ gm.sp++;
pusher.tl = tl;
pusher.isvert = θ;
pusher.φ = 1;
@@ -1463,6 +1433,7 @@
kold |= 1<<Kopen;
tl->tl++; /* flip switch */
gm.end = oplr->tl->p0 == MTsetec ? EDsetec : EDup;
+ stopmus();
sfx(Slvlend);
sfxlck++;
return;
@@ -1690,163 +1661,6 @@
}
static void
-crmwapr(void)
-{
- allrecv++;
-}
-static void
-crmamo(void)
-{
- gm.ammo = 99;
- huda();
-}
-static void
-crmkey(void)
-{
- gm.keys = 15;
- hudk();
-}
-static void
-crmwep(void)
-{
- if(gm.bestw < WPgatling)
- givew(gm.bestw + 1);
-}
-static void
-crmmli(void)
-{
- gm.hp = 100;
- gm.ammo = 99;
- gm.keys = 15;
- givew(WPgatling);
- gm.pt = 0;
- gm.lvltc += 42000;
- hudw();
- hudh();
- hudk();
- huda();
- hudp();
-}
-static void
-crmmap(void)
-{
-}
-static void
-crmgod(void)
-{
- if(ver < SDM)
- return;
- god ^= 1;
- if(god)
- sfx(Sendb2);
- else
- sfx(Snobonus);
-}
-static void
-crmclp(void)
-{
- if(ver < SDM)
- return;
- noclip ^= 1;
-}
-static void
-crmslo(void)
-{
- onestep ^= 1;
-}
-static void
-crmskp(void)
-{
-}
-static void
-crmwrp(void)
-{
-}
-
-static Crm crms[] = {
- {"fgd135", crmwapr},
- {"opepak", crmamo},
- {"opeopn", crmkey},
- {"opephz", crmwep},
- {"opemli", crmmli},
- {"opepda", crmmap},
- {"opedqd", crmgod},
- {"opeclp", crmclp},
- {"opeslo", crmslo},
- {"opeskp", crmskp},
- {"opewrp", crmwrp}
-};
-
-static char *
-crm114(void)
-{
- int n;
- Crm *p, *e;
-
- n = strlen(crs);
- p = crms;
- e = crms + 1;
- if(allrecv){
- p++;
- e = crms + nelem(crms);
- }
- while(p < e){
- if(strncmp(crs, p->s, n) != 0){
- memset(crs, 0, sizeof crs);
- return crs;
- }else if(n = Ncrm-1){
- p->f();
- memset(crs, 0, sizeof crs);
- return crs;
- }
- p++;
- }
- return crs+n;
-}
-static int
-quickkey(Rune r)
-{
- switch(r){
- case Kesc:
- case KF|1:
- case KF|2:
- case KF|3:
- case KF|4:
- case KF|5:
- case KF|6:
- case KF|7:
- case KF|8:
- case KF|9:
- ;
- }
- return 0;
-}
-static void
-eatcs(void)
-{
- int i, d;
- char *p, rc[UTFmax];
- Rune r;
-
- if(gm.demo && nbrecv(csc, nil) > 0){
- gm.end = EDkey;
- return;
- }
- if(gm.record)
- return;
- i = 0;
- p = crs + strlen(crs);
- while(nbrecv(csc, &r) > 0 && i++ < 6){
- if(quickkey(r))
- continue;
- d = runetochar(rc, &r);
- if(p + d < crs + sizeof crs){
- memcpy(p, rc, d);
- p = crm114();
- }
- }
-}
-static void
gamein(void)
{
int mx, my, scale;
@@ -1854,10 +1668,16 @@
qlock(&inlck);
mx = mΔx;
my = mΔy;
- kon = kb | mΔb & 5 | (mΔb & 2) << 2;
mΔx = mΔy = 0;
+ kon = kb | mb & 1 | (mb & 2) << 2 | (mb & 4) >> 1;
qunlock(&inlck);
+ if(kon & 1<<Kmenu){
+ gm.end = EDkey;
+ return;
+ }
+ if(autorun)
+ kon |= 1<<Krun;
kΔx = kΔy = 0;
scale = Δtc * (kon & 1<<Krun ? 70 : 35);
if(kon & 1<<K↑)
@@ -1884,6 +1704,8 @@
static void
demoin(void)
{
+ if(dem >= deme)
+ sysfatal("demoin: read past end of lump");
kon = *dem++;
kΔx = *dem++ * Δtc;
kΔy = *dem++ * Δtc;
@@ -1894,7 +1716,7 @@
input(void)
{
kold = kon;
- if(gm.demo && dem < deme)
+ if(gm.demo)
demoin();
else
gamein();
@@ -1909,7 +1731,7 @@
if(kon & 1<<Kopen & ~kold)
kon &= ~(1<<Kopen);
if(kon & 1<<Kfire & ~kold)
- kon &= ~(1<<Kfire);
+ kon &= ~(1<<Kfire);
}
}
@@ -2381,17 +2203,167 @@
pal = pals[C0];
}
+static void
+crmchop(void)
+{
+ gm.tc = 99 * 60 * Tb;
+ gm.pt = 0;
+ hudp();
+ bonustc = 6 * (Cfad-Cwht);
+ dirty = 1;
+}
+static void
+crmrcv(void)
+{
+ allrecv++;
+ sfx(Snobonus);
+}
+static void
+crmmed(void)
+{
+ giveh(100);
+ sfx(Shealth2);
+ crmchop();
+}
+static void
+crmamo(void)
+{
+ givea(99);
+ sfx(Sgetammo);
+ crmchop();
+}
+static void
+crmkey(void)
+{
+ givek(0);
+ givek(1);
+ sfx(Sgetkey);
+ crmchop();
+}
+static void
+crmwep(void)
+{
+ givew(WPgatling);
+ sfx(Sgetgatling);
+ crmchop();
+}
+static void
+crmmli(void)
+{
+ giveh(100);
+ givea(99);
+ givek(0);
+ givek(1);
+ givew(WPgatling);
+ sfx(Sgetgatling);
+ crmchop();
+}
+static void
+crmmap(void)
+{
+}
+static void
+crmgod(void)
+{
+ god ^= 1;
+ if(god){
+ sfx(Sendb2);
+ crmchop();
+ }else
+ sfx(Snobonus);
+}
+static void
+crmclp(void)
+{
+ noclip ^= 1;
+ if(noclip){
+ sfx(Sbonus4);
+ crmchop();
+ }else
+ sfx(Snobonus);
+}
+static void
+crmslo(void)
+{
+ slomo ^= 1;
+ if(slomo){
+ sfx(Sbonus4);
+ crmchop();
+ }else
+ sfx(Snobonus);
+}
+static void
+crmskp(void)
+{
+ gm.end = EDup;
+ if(ver < SDM && gm.map % 10 == 8 || ver >= SDM && gm.map == 20)
+ gm.end = EDwon;
+ sfx(Slvlend);
+ crmchop();
+}
+static void
+crmmus(void)
+{
+ mus(nrand(ver < SDM ? 27 : 24));
+}
+
void
+dieturn(void)
+{
+ int Δθ;
+
+ Δθ = Δtc * 2;
+ if(dieΔθ - Δθ < 0)
+ Δθ = dieΔθ;
+ dieΔθ -= Δθ;
+ oplr->θ = (oplr->θ + Δθ * diedir + 360) % 360;
+ render();
+ out();
+ if(dieΔθ != 0)
+ qtc = 0;
+ else
+ pal = pals[C0];
+}
+
+void
+die(void)
+{
+ int θ, lrot, rrot;
+ double fθ;
+
+ gm.w = -1;
+ gm.lives--;
+ stopmus();
+ sfx(Sdie);
+ fizzop(0x4, 0);
+ fθ = atan2(oplr->y - killy, killx - oplr->x);
+ if(fθ < 0)
+ fθ += Fpi * 2;
+ θ = fθ / (Fpi * 2) * 360;
+ lrot = θ - oplr->θ;
+ rrot = oplr->θ - θ;
+ if(oplr->θ > θ)
+ lrot += 360;
+ else
+ rrot += 360;
+ if(lrot < rrot){
+ diedir = 1;
+ dieΔθ = abs(lrot % 360);
+ }else{
+ diedir = -1;
+ dieΔθ = abs(rrot % 360);
+ }
+}
+
+void
camwarp(void)
{
- int Δx, Δy, Δr;
+ int Δr;
double θ;
- oplr->x = bosskillx;
- oplr->y = bosskilly;
- Δx = camobj->x - oplr->x;
- Δy = oplr->y - camobj->y;
- θ = atan2(Δy, Δx);
+ oplr->x = killx;
+ oplr->y = killy;
+ θ = atan2(oplr->y - camobj->y, camobj->x - oplr->x);
if(θ < 0)
θ = Fpi * 2 + θ;
oplr->θ = θ / (Fpi * 2) * 360;
@@ -2414,8 +2386,36 @@
}
void
+givew(int n)
+{
+ givea(6);
+ if(gm.bestw < n)
+ gm.w = gm.lastw = gm.bestw = n;
+ hudw();
+ if(n == WPgatling){
+ pic(136, 164, pict[Pgat]);
+ facetc = 0;
+ }
+}
+
+void
+givep(int n)
+{
+ if(dirty)
+ return;
+ gm.pt += n;
+ while(gm.pt >= gm.to1up){
+ gm.to1up += 40000;
+ givel();
+ }
+ hudp();
+}
+
+void
bonus(Static *s)
{
+ if(gm.hp == 0)
+ s->item = Rnil;
switch(s->item){
case Rstim:
if(gm.hp == 100)
@@ -2433,22 +2433,22 @@
case Rcross:
sfx(Sbonus1);
givep(100);
- gm.treasure++;
+ gm.tp++;
break;
case Rchalice:
sfx(Sbonus2);
givep(500);
- gm.treasure++;
+ gm.tp++;
break;
case Rbible:
sfx(Sbonus3);
givep(1000);
- gm.treasure++;
+ gm.tp++;
break;
case Rcrown:
sfx(Sbonus4);
givep(5000);
- gm.treasure++;
+ gm.tp++;
break;
case Rclip1:
if(gm.ammo == 99)
@@ -2475,8 +2475,6 @@
case Rchaingun:
sfx(Sgetgatling);
givew(WPgatling);
- pic(136, 164, pict[Pgat]);
- facetc = 0;
break;
case R1up:
sfx(S1up);
@@ -2483,7 +2481,7 @@
giveh(99);
givea(25);
givel();
- gm.treasure++;
+ gm.tp++;
break;
case Rfood:
if(gm.hp == 100)
@@ -2504,16 +2502,81 @@
giveh(1);
break;
case Rspear:
- gotspear++;
spearx = oplr->x;
speary = oplr->y;
spearθ = oplr->θ;
- gm.end = EDup;
+ gm.end = gm.demo || gm.record ? EDdem : EDspear;
}
bonustc = 6 * (Cfad-Cwht);
s->tl = nil;
}
+void
+crm114(int n)
+{
+ static Crm crms[] = {
+ {"fgd135", crmrcv},
+ {"opeaid", crmmed},
+ {"opepak", crmamo},
+ {"opeopn", crmkey},
+ {"opephz", crmwep},
+ {"opemli", crmmli},
+ {"opepda", crmmap},
+ {"opedqd", crmgod},
+ {"opeclp", crmclp},
+ {"opeslo", crmslo},
+ {"opeskp", crmskp},
+ {"opemus", crmmus}
+ };
+ Crm *p, *e;
+
+ p = crms;
+ e = crms + 1;
+ if(allrecv){
+ p++;
+ e = crms + nelem(crms);
+ }
+ while(p < e){
+ if(strncmp(crs, p->s, n) == 0){
+ if(n == Ncrm-1){
+ p->f();
+ memset(crs, 0, sizeof crs);
+ }
+ return;
+ }
+ p++;
+ }
+ memset(crs, 0, sizeof crs);
+}
+
+void
+eatcs(void)
+{
+ int i, d;
+ char *p, rc[UTFmax];
+ Rune r;
+
+ if(gm.demo){
+ if(nbrecv(csc, nil) > 0)
+ gm.end = EDkey;
+ return;
+ }
+ i = 0;
+ p = crs + strlen(crs);
+ while(nbrecv(csc, &r) > 0 && i++ < Ncrm-1){
+ if(quickkey(r))
+ return;
+ if(gm.record)
+ continue;
+ d = runetochar(rc, &r);
+ if(p + d < crs + sizeof crs){
+ memcpy(p, rc, d);
+ p += d;
+ crm114(p - crs);
+ }
+ }
+}
+
int
rnd(void)
{
@@ -2524,11 +2587,11 @@
void
gstep(void)
{
- if(gm.demo || gm.record){
+ if(gm.demo || gm.record || slomo){
if(demfrm-- != 0)
return;
demfrm = 3;
- Δtc = 4;
+ Δtc = slomo ? 1 : 4;
}
input();
noise = 0;
@@ -2535,8 +2598,8 @@
uworld();
upal();
render();
- mtc += Δtc;
- gm.lvltc += Δtc;
+ qtc += Δtc;
+ gm.tc += Δtc;
if(dofizz){
dofizz = 0;
if(!gm.end)
@@ -2553,9 +2616,34 @@
}
void
-demo(void)
+nextmap(void)
{
+ static int setece[] = {1, 11, 27, 33, 45, 53};
+ int n, e, m;
+
+ m = gm.map;
+ n = m + 1;
+ if(ver < SDM){
+ e = m / 10;
+ if(gm.com == GMret)
+ n = setece[e];
+ else if(gm.com == GMsetec)
+ n = e + 9;
+ }else{
+ if(gm.com == GMret)
+ n = m == 18 ? 4 : m == 19 ? 12 : m + 1;
+ else if(gm.com == GMsetec)
+ n = m == 3 ? 18 : m == 11 ? 19 : m + 1;
+ }
+ gm.map = n;
+}
+
+void
+game(void)
+{
initmap();
+ killx = oplr->x;
+ killy = oplr->y;
mapmus();
pal = pals[C0];
dofizz++;
@@ -2563,8 +2651,56 @@
}
void
-initg(int r, uchar *p)
+spshunt(void)
{
+ gm.oldpt = gm.pt;
+ gm.map = 20;
+ dmgtc = bonustc = 0;
+ initmap();
+ sfx(Sspear);
+ oplr->x = spearx;
+ oplr->y = speary;
+ oplr->tx = spearx >> Dtlshift;
+ oplr->ty = speary >> Dtlshift;
+ oplr->θ = spearθ;
+ oplr->areaid = oplr->tl->p0 - MTfloor;
+}
+
+void
+greset(void)
+{
+ if(gm.w == -1){
+ gm.hp = 100;
+ gm.ammo = 8;
+ gm.w = gm.lastw = gm.bestw = WPpistol;
+ }
+ gm.pt = gm.oldpt;
+ gm.tc = 0;
+ gm.kp = gm.sp = gm.tp = 0;
+ gm.ktot = gm.stot = gm.ttot = 0;
+ gm.wfrm = gm.facefrm = 0;
+ gm.keys = 0;
+ gm.won = gm.mut = 0;
+ dmgtc = bonustc = facetc = funtc = 0;
+ firing = 0;
+ kb = 0;
+ mb = 0;
+ kon = kold = 0;
+ mΔx = mΔy = 0;
+ kΔθ = 0;
+ allrecv = 0;
+ dirty = 0;
+ slomo = noclip = god = 0;
+ if(ver == SOD && gm.map == 20)
+ givek(0);
+}
+
+void
+ginit(uchar *p, int m, int d)
+{
+ int r;
+
+ r = 1;
memset(&gm, 0, sizeof gm);
if(p != nil){
gm.demo++;
@@ -2575,20 +2711,16 @@
if((deme-dem) % 3 != 0)
sysfatal("initd: invalid demo lump\n");
demfrm = 0;
+ r = 0;
+ greset();
+ }else if(m != -1){
+ gm.map = m;
+ gm.difc = d;
}
+ rndi = r ? time(nil) & 0xff : 0;
gm.hp = 100;
gm.ammo = 8;
gm.lives = 3;
gm.w = gm.lastw = gm.bestw = WPpistol;
gm.to1up = GPextra;
- rndi = r ? time(nil) & 0xff : 0;
- dmgtc = bonustc = facetc = funtc = 0;
- firing = 0;
- kon = kold = 0;
- kΔθ = 0;
- allrecv = 0;
- sfxlck = 0;
- gotspear = 0;
- if(ver == SOD && gm.map == 20)
- givek(0);
}
--- a/hub.c
+++ b/hub.c
@@ -7,20 +7,8 @@
extern Channel *csc;
-int mtc;
-
-typedef struct Score Score;
-typedef struct Seq Seq;
-typedef struct Item Item;
-typedef struct Menu Menu;
-
-struct Score{
- char name[58];
- int n;
- int lvl;
- int ep;
-};
-static Score sc[] = {
+int qtc;
+Score scs[] = {
{"id software-'92", 10000, 1},
{"Adrian Carmack", 10000, 1},
{"John Carmack", 10000, 1},
@@ -29,56 +17,236 @@
{"John Romero", 10000, 1},
{"Jay Wilbur", 10000, 1},
};
+char savs[10][32];
+typedef struct Fade Fade;
+typedef struct Sp Sp;
+typedef struct Seq Seq;
+typedef struct Item Item;
+typedef struct Menu Menu;
+
enum{
- Lload,
+ LMctl,
+ LMnew,
+ LMdifc,
+ LMsnd,
+ LMin,
+ LMsav,
+ LMmsg,
+
+ Lload = 0,
Lintro,
+ Lftitle,
Ltitle,
Lcreds,
Lscore,
+ Lfpants,
+ Lpants,
Ldemo,
+ Lpsych,
+ Lgame,
+ Lretry,
+ Lmsg,
+ Lcont1,
+ Lcont2,
+ Lgcont,
+ Lfdie,
+ Ldie,
+ Ldie2,
+ Lhigh,
Lcam,
+ Lspear,
Linter,
- Lwin,
+ Linteri,
+ Linterm,
+ Linterw,
+ Lintere,
+ Lsinter,
+ Lsdmend,
+ Lcolp,
+ Lcolp2,
+ Lcolp3,
+ Lwon,
+ Lwon2,
+ Lsdepi,
+ Lpres,
+ Lroll1,
+ Lroll2,
+ Lroll3,
+ Lroll4,
+ Lroll5,
+ Lroll6,
+ Lroll7,
Ldecay,
- Linctl,
Lctl,
+ Ltoctl,
+ Lftoctl,
+ Lmtoctl,
Lcur,
- Lesc,
- Lback,
- Lwait,
- Lsfxwait,
- Lack,
+ Lftonew,
+ Lmtonew,
+ Lnewgame,
+ Lnctl,
+ Ldenied,
+ Ldifc1,
+ Ldifc2,
+ Ldifc3,
+ Ldifc4,
+ Ldifc5,
+ Lfsnd,
+ Lmsnd,
+ Lsctl,
+ Lsndtog,
+ Lfin,
+ Lmin,
+ Lictl,
+ Lintog,
+ Lfsens,
+ Lmsens,
+ Lsectl,
+ Lfsav,
+ Lmsav,
+ Lsvctl,
+ Lflod,
+ Lmlod,
+ Lldctl,
+ Lfvw,
+ Lmvw,
+ Lvwctl,
+ Lfmscore,
Lmscore,
- Lpants,
+ Lend,
+ Lcurgame,
Lquit,
Lmexit,
Lexit
};
-struct Seq{
+struct Sp{
int dt;
void (*f)(void);
};
+struct Fade{
+ Col c;
+ int dt;
+};
+struct Seq{
+ void (*init)(void);
+ Sp *s;
+ Sp *e;
+ Seq *q;
+ Fade *f;
+};
+static Seq *qsp, *qesc, ql[];
+static Sp *qp;
+
+enum{
+ DMbg,
+ DMoff,
+ DMbrd,
+ DMbrd2,
+ DMend,
+
+ DIreg = 0x17,
+ DIsee = 0x4a,
+ DIeps = 0x6b,
+ DIrhi = 0x13,
+ DIshi = 0x47,
+ DIepi = 0xd0,
+};
+static int mcol[DMend] = {[DMbg] 0x2d, 0};
+
+#define SEL(c) ((c) - 4 + (((c) >> 1 ^ (c)) >> 5 & 1))
+#define UNSEL(c) ((c) + 4 - (((c) >> 1 ^ (c)) >> 5 & 1))
+
struct Item{
char *s;
int c;
- Menu *m;
+ Seq *q;
+ int a;
};
+static Item
+ictl[] = {
+ {"New Game", SEL(DIreg), ql+Lftonew},
+ {"Sound", DIreg, ql+Lfsnd},
+ {"Control", DIreg, ql+Lfin},
+ {"Load Game", DIreg, ql+Lflod},
+ {"Save Game", DIreg, ql+Lfsav},
+ {"Change View", DIreg, ql+Lfvw},
+ {"View Scores", DIreg, ql+Lfmscore},
+ {"Back to Demo", DIreg, ql+Lftitle},
+ {"Quit", DIreg, ql+Lquit}
+},
+inew[] = {
+ {"Episode 1\nEscape from Wolfenstein", SEL(DIreg), ql+Ldifc1},
+ {nil},
+ {"Episode 2\nOperation: Eisenfaust", DIreg, ql+Ldifc1},
+ {nil},
+ {"Episode 3\nDie, Fuhrer, Die!", DIreg, ql+Ldifc1},
+ {nil},
+ {"Episode 4\nA Dark Secret", DIreg, ql+Ldifc1},
+ {nil},
+ {"Episode 5\nTrail of the Madman", DIreg, ql+Ldifc1},
+ {nil},
+ {"Episode 6\nConfrontation", DIreg, ql+Ldifc1},
+ {nil}
+},
+idifc[] = {
+ {"Can I play, Daddy?", DIreg, ql+Ldifc4},
+ {"Don't hurt me.", DIreg, ql+Ldifc4},
+ {"Bring 'em on!", SEL(DIreg), ql+Ldifc4},
+ {"I am Death incarnate!", DIreg, ql+Ldifc4}
+},
+isnd[] = {
+ {"None", SEL(DIreg), ql+Lsndtog},
+ {"PC Speaker"},
+ {"AdLib/Sound Blaster", DIreg, nil, 1},
+ {nil},
+ {nil},
+ {"None", DIreg, ql+Lsndtog},
+ {"Disney Sound Source"},
+ {"Sound Blaster", DIreg, nil, 1},
+ {nil},
+ {nil},
+ {"None", DIreg, ql+Lsndtog},
+ {"AdLib/Sound Blaster", DIreg, nil, 1}
+},
+iin[] = {
+ {"Mouse Enabled", SEL(DIreg), ql+Lintog, 1},
+ {"Autorun Enabled", DIreg, ql+Lintog},
+ {"Mouse Sensitivity", DIreg, ql+Lfsens}
+},
+isv[] = {
+ {"", SEL(DIreg), nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil},
+ {"", DIreg, nil}
+},
+imsg[] = {
+ {nil}
+};
struct Menu{
- void (*init)(void);
- Seq *qs;
- Seq *qe;
- Menu *m;
- Col *c;
- Item *is;
- Item *ie;
- Item *ip;
- int cx;
- int cy;
- int cur;
+ Item *p;
+ Item *s;
+ Item *e;
+ int x;
+ int y;
+ int n;
};
-static Menu *mp, ml[];
-static Seq *mqp;
+static Menu *mp, ml[] = {
+ [LMctl] {ictl, ictl, ictl+nelem(ictl), 72},
+ [LMnew] {inew, inew, inew+nelem(inew), 8},
+ [LMdifc] {idifc+2, idifc, idifc+nelem(idifc), 48},
+ [LMsnd] {isnd, isnd, isnd+nelem(isnd), 48},
+ [LMin] {iin, iin, iin+nelem(iin), 24},
+ [LMsav] {isv, isv, isv+nelem(isv), 80},
+ [LMmsg] {imsg}
+};
static char *ends[] = {
"Dost thou wish to\nleave with such hasty\nabandon?",
@@ -103,198 +271,436 @@
};
static char **quits;
-enum{
- Dbg,
- Doff,
- Dbrd,
- Dbrd2,
- Dend
-};
-static int mcol[Dend] = {[Dbg] 0x2d, 0};
+static Fade
+ fblk = {{0, 0, 0}, 30},
+ ftra = {{0, 0, 0}, 10},
+ fctl = {{0xae, 0, 0}, 10},
+ focl = {{0, 0x44, 0x44}, 300},
+ ficl = {{0, 0x44, 0x44}, 30},
+ fecl = {{0, 0x44, 0x44}, 5};
+static int irr[4], *irp;
+static int iri, iry, irb;
+
static uchar **demd;
static char *demf;
-static void (*mclear)(void);
-static void (*stripe)(int);
+static void
+reset(Seq *p)
+{
+ qp = p->s;
+ qtc = 0;
+ if(p == qsp)
+ return;
+ toss();
+ if(qp->f != fadeout)
+ pal = pals[C0];
+ qsp = p;
+ if(p->init != nil)
+ p->init();
+ if(p->f != nil)
+ fadeop(&p->f->c, p->f->dt);
+}
static void
-wlmclear(void)
+pblink(void)
{
- put(0, 0, Vw, Vh, 0x29);
+ if(mp->n == 0)
+ txt(mp->x, mp->y, "_", 0);
+ else
+ put(mp->x, mp->y, fnt->w['_'], fnt->h, DIreg);
+ out();
+ mp->n ^= 1;
}
+
static void
-sdmclear(void)
+blink(void)
{
- pic(0, 0, pict[Pbackdrop]);
+ put(mp->x, mp->y, 24, 16, mcol[DMbg]);
+ pic(mp->x, mp->y, pict[Pcur1] + mp->n);
+ out();
+ mp->n ^= 1;
}
static void
-wlstripe(int y)
+iswp(Item *on, Item *off)
{
- put(0, y, Vw, 24, 0);
- put(0, y+22, 320, 1, 0x2c);
+ on->a = 1;
+ on->q = nil;
+ off->a = 0;
+ off->q = ql+Lsndtog;
}
+
static void
-sdstripe(int y)
+toggle(void)
{
- put(0, y, Vw, 22, 0);
- put(0, y+23, 320, 1, 0);
+ Item *i;
+
+ i = mp->s;
+ switch(mp - ml){
+ case LMsnd:
+ if(mp->p->a)
+ return;
+ switch(mp->p - i){
+ case 0: iswp(i, i+2); stopsfx(); sfxon = 0; break;
+ case 2: iswp(i+2, i); sfxon++; sfx(Sshoot); break;
+ case 5: iswp(i+5, i+7); pcmon = 0; break;
+ case 7: iswp(i+7, i+5); pcmon++; break;
+ case 10: iswp(i+10, i+11); stopmus(); muson = 0; sfx(Sshoot); break;
+ case 11: iswp(i+11, i+10); muson++; mus(Mmenu); break;
+ }
+ break;
+ case LMin:
+ switch(mp->p - i){
+ tog: mp->p->a ^= 1; break;
+ case 0: grabon ^= 1; goto tog;
+ case 1: autorun ^= 1; goto tog;
+ }
+ break;
+ }
}
static void
-outbox(int x, int y, int dx, int dy, int c1, int c2)
+inctl(void)
{
- put(x, y, dx, 1, c2);
- put(x, y+1, 1, dy-1, c2);
- put(x, y+dy, dx+1, 1, c1);
- put(x+dx, y, 1, dy, c1);
+ Item *i, *e;
+ Menu *m;
+
+ m = ml+LMctl;
+ i = m->s;
+ i[4].c = mcol[DMoff];
+ i[6].s = "View Scores";
+ i[6].q = ql+Lfmscore;
+ i[6].c = DIreg;
+ i[7].s = "Back to Demo";
+ i[7].q = ql+Lftitle;
+ i[7].c = DIreg;
+ m->p = m->s;
+ m->p->c = SEL(DIreg);
+ if(ver >= SDM)
+ i[0].q = ql+Ldifc1;
+ else
+ for(i=ml[LMnew].s, e=ml[LMnew].e; i<e && i->q!=ql+Ldenied; i++)
+ i->q = ql+Ldifc1;
}
static void
-box(int x, int y, int dx, int dy, int col, int out, int out2)
+ingctl(void)
{
- put(x+1, y+1, dx-1, dy-1, col);
- outbox(x, y, dx, dy, out, out2);
+ Item *i, *e;
+
+ i = ml[LMctl].s;
+ i[4].c = DIreg;
+ i[6].s = "End Game";
+ i[6].q = ql+Lend;
+ i[7].s = "Back to Game";
+ i[7].q = ql+Lcont1;
+ i[7].c = DIsee;
+ if(i[0].q == ql+Ldifc1)
+ i[0].q = ql+Lcurgame;
+ else
+ for(i=ml[LMnew].s, e=ml[LMnew].e; i<e && i->q!=ql+Ldenied; i++)
+ i->q = ql+Lcurgame;
}
static void
-viewbox(void)
+mbox(int x, int y, int dx, int dy)
{
- int x, y;
+ box(x, y, dx, dy, mcol[DMbg], mcol[DMbrd2], mcol[DMoff]);
+}
- x = Vhud - vw.dx / 2 - 1;
- y = (Vhud - vw.dy) / 2 - 1;
- put(0, 0, 320, Vhud, 0x7f);
- box(x, y, vw.dx+1, vw.dy+1, 0, 0x7d, 0);
- put(x, y+vw.dy+1, 1, 1, 0x7c);
+static void
+msg(char *s, int o)
+{
+ int x, y, w, h, curw;
+ char *nl;
+
+ fnt = fnts+1;
+ h = txth(s);
+ w = txtw(s);
+ nl = strrchr(s, '\n');
+ curw = txtw(nl != nil ? nl + 1 : s);
+ w = w > curw + 10 ? w : curw + 10;
+ x = Vw / 2 - w / 2;
+ y = (step == gstep ? Vhud : Vh) / 2 - h / 2;
+ box(x - 5, y - 5, w + 10, h + 10, DIreg, 0, DIrhi);
+ txtnl(x, y, s, 0);
+ if(o)
+ out();
+ mp = ml+LMmsg;
+ mp->n = 0;
+ mp->x = x + curw;
+ mp->y = y + h - fnt->h;
}
static void
-view(void)
+quit(void)
{
- viewbox();
- pic(0, Vhud, pict[Pstat]);
- hudf();
- hudh();
- hudl();
- hudm();
- huda();
- hudk();
- hudw();
- hudp();
+ msg(quits[nrand(nelem(ends)/2)], 0);
+ mp->p->q = ql+Lmexit;
+ qesc = ql+Lctl;
}
static void
-fixedw(char *s)
+curgame(void)
{
- char c;
+ msg("You are currently in\na game. Continuing will\nerase old game. Ok?", 0);
+ mp->p->q = ql+Ldifc1;
+ qesc = ver < SDM ? ql+Lftoctl : ql+Lctl;
+}
- while(c = *s, c != 0)
- *s++ = c - '0' + 129;
+static void
+mend2(void)
+{
+ view();
+ render();
+ gm.lives = 0;
+ ql[Ldie].q = ql+Ldie2;
}
static void
-reset(Menu *m)
+mend(void)
{
- Seq *q;
+ msg("Are you sure you want\nto end the game you\nare playing? (Y or N):", 0);
+ mp->p->q = ql+Lfdie;
+ qesc = ql+Lctl;
+}
- q = m->qs;
- mqp = q;
- mtc = 0;
- if(m != mp){
- toss();
- if(q->f != fadeout && mp != ml+Lpants)
- pal = pals[C0];
- mp = m;
- if(m->init != nil)
- m->init();
- if(m->c != nil)
- fadeop(m->c, q->dt);
- }
+static void
+denied(void)
+{
+ msg("Please select \"Read This!\"\nfrom the Options menu to\n"
+ "find out how to order this\nepisode from Apogee.", 1);
+ stopsfx();
+ sfx(Snoway);
}
static void
-blink(void)
+sdmend(void)
{
+ sfx(S1up);
+ msg("This concludes your demo\nof Spear of Destiny! Now,\n"
+ "go to your local software\nstore and buy it!", 1);
+}
+
+static void
+setdifc(void)
+{
+ int m, d;
+
+ m = ver < SDM ? (ml[LMnew].p - ml[LMnew].s) * 5 : 0;
+ d = ml[LMdifc].p - ml[LMdifc].s;
+ ginit(nil, m, d);
+ ingctl();
+ palfill(&fctl.c);
+}
+
+static void
+difc(void)
+{
Menu *m;
+ Item *i, *e;
- m = mp;
- if(m == ml+Lctl){
- put(m->cx, m->cy, 24, 16, mcol[Dbg]);
- pic(m->cx, m->cy, pict[Pcur1]+m->cur);
- }else if(m == ml+Lquit){
- if(m->cur == 0)
- txt(m->cx, m->cy, "_", 0);
- else
- put(m->cx, m->cy, fnt->w['_'], fnt->h, 0x17);
+ mclear();
+ pic(112, 184, pict[Pmouselback]);
+ if(ver < SDM){
+ txt(70, 68, "How tough are you?", DIshi);
+ qesc = ql+Lftonew;
+ }else{
+ pic(70, 68, pict[Pdiffc]);
+ qesc = ql+Lftoctl;
}
- out();
- m->cur ^= 1;
+ mbox(45, 90, 225, 67);
+ m = ml+LMdifc;
+ mp = m;
+ i = m->s;
+ e = m->e;
+ do{
+ txt(74, 100 + 13 * (i - m->s), i->s, i->c);
+ }while(++i < e);
+ pic(235, 107, pict[Pbaby] + m->p - m->s);
+ m->n = 0;
+ m->y = 98 + 13 * (m->p - m->s);
}
static void
-ask(void)
+newgame(void)
{
- Rune r;
+ int n;
+ Item *i, *e;
+ Menu *m;
- if(nbrecv(csc, &r) <= 0)
- return;
- if(r == 'y'){
- sfx(Sshoot);
- reset(ml+Lmexit);
- }
- else if(r == 'n' || r == Kesc){
- sfx(Sesc);
- reset(ml+Lctl);
- }
+ mclear();
+ pic(112, 184, pict[Pmouselback]);
+ mbox(6, 19, 308, 162);
+ txtcen(2, "Which episode to play?", DIshi);
+ for(n=0; n<6; n++)
+ pic(40, 23 + n * 26, pict[Pep1] + n);
+ m = ml+LMnew;
+ mp = m;
+ i = m->s;
+ e = m->e;
+ do{
+ txtnl(98, 23 + 13 * (i - m->s), i->s, i->c);
+ i += 2;
+ }while(i < e);
+ qesc = ql+Lftoctl;
+ m->n = 0;
+ m->y = 21 + 13 * (m->p - m->s);
}
static void
-quit(void)
+snd(void)
{
- int x, y, w, h, curw;
- char *s, *nl;
+ Item *i, *e;
+ Menu *m;
- s = quits[nrand(nelem(ends)/2)];
- h = txth(s);
- w = txtw(s);
- nl = strrchr(s, '\n');
- curw = txtw(nl != nil ? nl+1 : s);
- w = w > curw+10 ? w : curw+10;
- y = 200/2 - h/2;
- x = Vhud - w/2;
+ mclear();
+ pic(112, 184, pict[Pmouselback]);
+ mbox(40, 17, 250, 45);
+ mbox(40, 82, 250, 45);
+ mbox(40, 147, 250, 32);
+ pic(96, 0, pict[Psfx]);
+ pic(96, 65, pict[Ppcm]);
+ pic(96, 130, pict[Pmus]);
+ m = ml+LMsnd;
+ mp = m;
+ i = m->s;
+ e = m->e;
+ do{
+ if(i->s == nil)
+ continue;
+ txt(100, 20 + 13 * (i - m->s), i->s, i->c);
+ pic(72, 22 + 13 * (i - m->s), pict[i->a ? Psel : Punsel]);
+ }while(++i < e);
+ qesc = ql+Lftoctl;
+ m->n = 0;
+ m->y = 18 + 13 * (m->p - m->s);
+}
- box(x-5, y-5, w+10, h+10, 0x17, 0, 0x13);
- txtnl(x, y, s, 0);
- mp->cx = x+curw;
- mp->cy = y + h - fnt->h;
+static void
+sens(void)
+{
+ int n;
+
+ mclear();
+ pic(112, 184, pict[Pmouselback]);
+ mbox(10, 80, 300, 30);
+ txtcen(82, "Adjust Mouse Sensitivity", DIsee);
+ txt(14, 95, "Slow", DIreg);
+ txt(269, 95, "Fast", DIreg);
+ put(60, 97, 200, 10, DIreg);
+ outbox(60, 97, 200, 10, 0x0, DIrhi);
+ n = 60 + 20 * iri;
+ put(n + 1, 98, 19, 9, DIshi);
+ outbox(n, 97, 20, 10, 0x0, DIsee);
+ qesc = ql+Lfin;
}
static void
+in(void)
+{
+ Menu *m;
+ Item *i, *e;
+
+ mclear();
+ stripe(10);
+ pic(80, 0, pict[Pctl]);
+ pic(112, 184, pict[Pmouselback]);
+ mbox(16, 65, 284, 45);
+ m = ml+LMin;
+ mp = m;
+ i = m->s;
+ e = m->e;
+ do{
+ txt(80, 70 + 13 * (i - m->s), i->s, i->c);
+ if(i < e - 1)
+ pic(56, 73 + 13 * (i - m->s), pict[i->a ? Psel : Punsel]);
+ }while(++i < e);
+ qesc = ql+Lftoctl;
+ m->n = 0;
+ m->y = 68 + 13 * (m->p - m->s);
+ iri = msense;
+}
+
+static void
+savitem(int i, int c)
+{
+ outbox(109, 55 + i * 13, 136, 11, c, c);
+ fnt = fnts;
+ txt(111, 56 + i * 13, savs[i][0] == 0 ? " - empty -" : savs[i], c);
+ fnt = fnts+1;
+}
+
+static void
+sav(void)
+{
+ Menu *m;
+ Item *i, *e;
+
+ mclear();
+ pic(112, 184, pict[Pmouselback]);
+ mbox(75, 50, 175, 140);
+ stripe(10);
+ pic(56, 0, pict[qsp->q == ql+Lsvctl ? Psave : Pload]);
+ m = ml+LMsav;
+ mp = m;
+ i = m->s;
+ e = m->e;
+ do
+ savitem(i - m->s, i->c);
+ while(++i < e);
+ qesc = ql+Lftoctl;
+ m->n = 0;
+ m->y = 53 + 13 * (m->p - m->s);
+}
+
+static void
+mvw(void)
+{
+ int dx, dy;
+
+ dx = vw.dx;
+ dy = vw.dy;
+ vw.dx = iri * 16;
+ vw.dy = iri * 8;
+ viewbox();
+ vw.dx = dx;
+ vw.dy = dy;
+ put(0, Vhud, Vw, 40, 0x7f);
+ txtcen(161, "Use arrows to size", DIrhi);
+ txtcen(161 + fnt->h, "ENTER to accept", DIrhi);
+ txtcen(161 + 2 * fnt->h, "ESC to cancel", DIrhi);
+ qesc = ql+Lftoctl;
+}
+
+static void
ctl(void)
{
Menu *m;
- Item *i, *s, *e;
+ Item *i, *e;
mclear();
pic(112, 184, pict[Pmouselback]);
stripe(10);
pic(80, 0, pict[Popt]);
- box(68, 52, 178, 6+13*9, mcol[Dbg], mcol[Dbrd2], mcol[Doff]);
-
+ mbox(68, 52, 178, 123);
fnt = fnts+1;
- m = ml+Lctl;
- s = i = m->is;
- e = m->ie;
+ m = ml+LMctl;
+ mp = m;
+ i = m->s;
+ e = m->e;
do
- txt(100, 55+13*(i-s), i->s, i->c);
+ txt(100, 55 + 13 * (i - m->s), i->s, i->c);
while(++i < e);
- m->cur = 0;
- m->cx = 72;
- m->cy = 53+13*(m->ip-s);
- if(mp == m)
- mus(Mmenu);
+ qesc = ql+Lquit;
+ m->n = 0;
+ m->y = 53 + 13 * (m->p - m->s);
+ if(qsp == ql+Ltoctl)
+ stopsfx();
+ mus(Mmenu);
+ grab(0);
+ iri = vwsize;
}
static void
@@ -304,116 +710,160 @@
}
static void
-movcur(Menu *m, Item *p, int dir)
+slcur(int dir)
{
+ iri += dir;
+ switch(qsp - ql){
+ case Lsectl:
+ if(iri < 0)
+ iri = 0;
+ else if(iri > 9)
+ iri = 9;
+ break;
+ case Lvwctl:
+ if(iri < 4)
+ iri = 4;
+ else if(iri > 19)
+ iri = 19;
+ break;
+ }
+ qsp->init();
+ out();
+}
+
+static void
+slider(void)
+{
+ Rune r;
+
+ if(nbrecv(csc, &r) <= 0)
+ return;
+ switch(r){
+ case Kleft: case Kdown: slcur(-1); break;
+ case Kright: case Kup: slcur(1); break;
+ case Kesc: sfx(Sesc); reset(qesc); break;
+ case '\n':
+ case ' ':
+ switch(qsp - ql){
+ case Lsectl: msense = iri; break;
+ case Lvwctl: vwsize = iri; msg("Thinking...", 1); setvw(); break;
+ }
+ sfx(Sshoot);
+ reset(qesc);
+ break;
+ }
+}
+
+static void
+movcur(Item *p, int dir)
+{
Item *i;
- p->c = 0x17;
+ p->c = UNSEL(p->c);
i = p;
do{
i += dir;
- if(i < m->is)
- i = m->ie-1;
- else if(i == m->ie)
- i = m->is;
- }while(i->c != 0x17);
- i->c = 0x13;
- m->ip = i;
- m->cur = 0;
- if(i != p+dir){
+ if(i < mp->s)
+ i = mp->e - 1;
+ else if(i == mp->e)
+ i = mp->s;
+ }while(i->c == mcol[DMoff] || i->c == 0);
+ i->c = SEL(i->c);
+ mp->p = i;
+ mp->n = 0;
+ if(i != p + dir){
cursfx();
- reset(ml+Lctl);
- ctl();
+ reset(qsp);
+ if(qsp->init != nil)
+ qsp->init();
return;
}
- put(m->cx, m->cy, 24, 16, mcol[Dbg]);
- m->cy += dir * 6;
+ put(mp->x, mp->y, 24, 16, mcol[DMbg]);
+ mp->y += dir * 6;
blink();
sfx(Sdrawgun1);
- reset(ml+Lcur);
+ ql[Lcur].q = qsp;
+ reset(ql+Lcur);
}
static void
cwalk(void)
{
+ static char s[UTFmax*2], *sp = s;
Rune r;
- Menu *m;
+ Seq *q;
Item *i;
- static int p;
if(nbrecv(csc, &r) <= 0)
return;
- m = mp;
- i = m->ip;
+ i = mp->p;
switch(r){
- case Kup: movcur(m, i, -1); break;
- case Kdown: movcur(m, i, 1); break;
- case Kesc: sfx(Sesc); reset(ml+Lquit); break;
- case 'i': p++; break;
- case 'd':
- if(ver == SOD && p == 1)
- reset(ml+Lpants);
- break;
+ case Kup: movcur(i, -1); break;
+ case Kdown: movcur(i, 1); break;
+ case Kesc: sfx(Sesc); reset(qesc); break;
case '\n':
- m = i->m;
- if(m == nil)
+ case ' ':
+ q = i->q;
+ if(q == nil)
break;
- if(m != ml+Lquit && m != ml+Lesc)
+ if(q != ql+Lquit && q != ql+Lftitle)
sfx(Sshoot);
- reset(m);
+ reset(q);
+ break;
+ default:
+ if(ver < SOD)
+ break;
+ sp += runetochar(sp, &r);
+ if(strncmp(s, "id", sp-s) == 0){
+ if(sp - s == 2){
+ reset(ql+Lfpants);
+ sp = s;
+ }
+ }else
+ sp = s;
}
- if(r != 'i')
- p = 0;
}
static void
-inctl(void)
+ask(void)
{
- Item *i;
- Menu *m;
+ Rune r;
- m = ml+Lctl;
- if(m->ip != nil)
- m->ip->c = 0x17;
- i = m->is;
- m->ip = i;
- i[0].c = 0x13;
- i[4].c = mcol[Doff];
- grab(0);
- ctl();
- stopsfx();
+ if(nbrecv(csc, &r) <= 0)
+ return;
+ if(r == 'y'){
+ sfx(Sshoot);
+ reset(mp->p->q);
+ }else if(r == 'n' || r == Kesc){
+ sfx(Sesc);
+ reset(qesc);
+ }
}
static void
-skipstep(void)
+skip(void)
{
- if(nbrecv(csc, nil) > 0){
- mqp++;
- mtc = 0;
- }
+ if(nbrecv(csc, nil) > 0)
+ reset(ql+Ldecay);
}
-
static void
-skiploop(void)
+swait(void)
{
- if(nbrecv(csc, nil) > 0)
- reset(ml+Ldecay);
+ if(lastsfx() >= 0)
+ qtc = 0;
+ else
+ sfxlck = 0;
}
-
static void
-ack(void)
+nbwait(void)
{
if(nbrecv(csc, nil) > 0)
- reset(ml+Lback);
+ qtc = qp->dt;
}
-
static void
-swait(void)
+bwait(void)
{
- if(lastsfx() < 0){
- reset(ml+Linter);
- step = mstep;
- }
+ qtc = nbrecv(csc, nil) > 0 ? qp->dt : 0;
}
static void
@@ -422,33 +872,350 @@
pic(0, 0, pict[Pid1]);
pic(0, 80, pict[Pid2]);
palpic(exts[Eid]);
- fadeop(mp->c, mp->qs->dt);
mus(Mnazjazz);
}
static void
-iwin(void)
+roll(void)
{
+ pic(0, 0, pict[Pend1]+iri);
+ palpic(exts[Eend1+iri]);
+ iri++;
+ if(iri == 9)
+ iri = 1;
}
static void
-win(void)
+pres3(void)
{
+ put(0, 180, Vw, 20, 0);
+ txtcen(180, "With the spear gone, the Allies will finally", DIepi);
+ /* bug: typo "by able to" */
+ txtcen(180 + fnt->h, "be able to destroy Hitler...", DIepi);
+ out();
+ iri = 3;
}
+static void
+pres2(void)
+{
+ txtcen(180, "We owe you a great debt, Mr. Blazkowicz.", DIepi);
+ txtcen(180 + fnt->h, "You have served your country well.", DIepi);
+ out();
+}
+static void
+pres1(void)
+{
+ pic(0, 0, pict[Pend1]+2);
+ palpic(exts[Eend1+2]);
+ fnt = fnts;
+}
+static void
+sdepi(void)
+{
+ pic(0, 0, pict[Pend1]);
+ palpic(exts[Eend1]);
+}
static void
-iscore(void)
+won(void)
{
+ int n;
+ char a[10];
+
+ put(0, 0, Vw, Vhud, 0x7f);
+ pic(8, 4, pict[Pwin]);
+ pictxt(144, 16, "YOU WIN!");
+ pictxt(112, 48, "TOTAL TIME");
+ if(gm.eptm > 99 * 60)
+ gm.eptm = 99 * 60 + 99;
+ sprint(a, "%02d:%02d", gm.eptm / 60, gm.eptm % 60);
+ pictxt(113, 64, a);
+ pictxt(96, 96, "AVERAGES");
+ n = ver < SDM ? 8 : 14;
+ sprint(a, "KILL %3d%%", (gm.epk / n));
+ pictxt(112, 112, a);
+ sprint(a, "SECRET %3d%%", (gm.eps / n));
+ pictxt(80, 128, a);
+ sprint(a, "TREASURE %3d%%", (gm.ept / n));
+ pictxt(48, 144, a);
+ if(ver == WL6 && gm.difc >= GDmed){
+ pic(240, 64, pict[Ptc]);
+ fnt = fnts;
+ n = gm.eptm / 60;
+ a[0] = 'A' + (n / 10 ^ n % 10 ^ 0xa);
+ n = gm.eptm % 60;
+ a[1] = 'A' + (n / 10 ^ n % 10 ^ 0xa);
+ a[2] = 'A' + (a[0] ^ a[1]);
+ a[3] = 0;
+ txt(241, 72, a, DIshi);
+ }
+ fnt = fnts+1;
+ mus(ver < SDM ? Mwon : Msdwon);
+ grab(0);
}
+
static void
+colp(void)
+{
+ pic(124, 44, pict[Pcollapse] + iri++);
+ out();
+}
+static void
+incolp(void)
+{
+ iri = 1;
+ fill(0x7f);
+ pic(124, 44, pict[Pcollapse]);
+ mus(Mend);
+}
+
+static void
+breathe(void)
+{
+ static int n, t;
+
+ if(++t > 35){
+ t = 0;
+ n ^= 1;
+ pic(0, 16, pict[n ? Pguy2 : Pguy]);
+ out();
+ }
+}
+
+static void
+sinterw(void)
+{
+ breathe();
+ if(nbrecv(csc, nil) <= 0)
+ qtc = 0;
+}
+
+static void
+siscore(void)
+{
+ givep(15000);
+ gm.oldpt = gm.pt;
+}
+static void
+sinter(void)
+{
+ put(0, 0, Vw, Vhud, 0x7f);
+ pic(0, 16, pict[Pguy]);
+ if(ver < SDM)
+ pictxt(112, 32, "SECRET FLOOR\n COMPLETED!");
+ else{
+ switch(gm.map){
+ case 4: pictxt(112, 32, " TRANS\n GROSSE\nDEFEATED!"); break;
+ case 9: pictxt(112, 32, "BARNACLE\nWILHELM\nDEFEATED!"); break;
+ case 15: pictxt(112, 32, "UBERMUTANT\nDEFEATED!"); break;
+ case 17: pictxt(112, 32, " DEATH\n KNIGHT\nDEFEATED!"); break;
+ case 18: pictxt(104, 32, "SECRET TUNNEL\n AREA\n COMPLETED!"); break;
+ case 19: pictxt(104, 32, "SECRET CASTLE\n AREA\n COMPLETED!"); break;
+ }
+ }
+ if(gm.map == 17){ /* solely for crmskp */
+ gm.com = GMup;
+ gm.map = 19;
+ }
+ pictxt(80, 128, "15000 BONUS!");
+ mus(Minter);
+}
+
+static void
+interw(void)
+{
+ breathe();
+ if(nbrecv(csc, nil) > 0)
+ reset(ver == SDM && gm.map == 1 ? ql+Lsdmend : ql+Lintere);
+}
+
+static void
+intere(void)
+{
+ givep(irb);
+ gm.oldpt = gm.pt;
+ qsp->q = ql+Linterw;
+}
+
+static void
+interskip(void)
+{
+ int n;
+ char a[10];
+
+ irb = irr[0] * 500;
+ irb += 10000 * ((irr[1] == 100) + (irr[2] == 100) + (irr[3] == 100));
+ n = sprint(a, "%d", irb);
+ pictxt((36 - n * 2) * 8, 56, a);
+ n = sprint(a, "%d", irr[1]);
+ pictxt((37 - n * 2) * 8, 112, a);
+ n = sprint(a, "%d", irr[2]);
+ pictxt((37 - n * 2) * 8, 128, a);
+ n = sprint(a, "%d", irr[3]);
+ pictxt((37 - n * 2) * 8, 144, a);
+ intere();
+}
+
+static void
+interb(void)
+{
+ if(nbrecv(csc, nil) > 0)
+ interskip();
+ else if(lastsfx() >= 0){
+ breathe();
+ qtc = 0;
+ }
+}
+
+static void
+interm(void)
+{
+ int n;
+ char a[10];
+
+ if(nbrecv(csc, nil) > 0){
+ interskip();
+ return;
+ }
+ if(*irp == 100){
+ stopsfx();
+ irb += 10000;
+ n = sprint(a, "%d", irb);
+ pictxt((36 - n * 2) * 8, 56, a);
+ out();
+ sfx(S100);
+ }else if(*irp == 0)
+ sfx(Snobonus);
+ else
+ sfx(Sendb2);
+ iri = 0;
+ qsp->q = ql+Linteri;
+ qsp->q->q = ql+Linteri;
+ switch(++irp - irr){
+ case 1: iry = 112; break;
+ case 2: iry = 128; break;
+ case 3: iry = 144; break;
+ case 4: intere(); break;
+ }
+}
+
+static void
+interi(void)
+{
+ int n;
+ char a[10];
+
+ if(nbrecv(csc, nil) > 0){
+ interskip();
+ return;
+ }
+ n = sprint(a, "%d", iri);
+ pictxt((37 - n * 2) * 8, iry, a);
+ sfx(Sendb1);
+ out();
+ iri += 10;
+ if(iri == *irp + 10){
+ ql[Linterm].s[0].dt = *irp == 100 || *irp == 0 ? 30 : 0;
+ qsp->q = ql+Linterm;
+ }else if(iri >= *irp)
+ iri = *irp;
+}
+
+static void
+interp(void)
+{
+ int m;
+ char a[10];
+
+ m = sprint(a, "%d", iri * 500);
+ pictxt((18 - m) * 16, 56, a);
+ sfx(Sendb1);
+ out();
+ iri += 50;
+ if(iri == *irp + 50){
+ sfx(Sendb2);
+ iri = 0;
+ irb += iri * 500;
+ iry = 112;
+ irp++;
+ qsp->s[0].f = interi;
+ }else if(iri >= *irp)
+ iri = *irp;
+}
+
+static void
inter(void)
{
+ static int wlpar[] = {
+ 90, 120, 120, 210, 180, 180, 150, 150, 0, 0,
+ 90, 210, 180, 120, 240, 360, 60, 180, 0, 0,
+ 90, 90, 150, 150, 210, 150, 120, 360, 0, 0,
+ 120, 120, 90, 60, 270, 210, 120, 270, 0, 0,
+ 150, 90, 150, 150, 240, 180, 270, 210, 0, 0,
+ 390, 240, 270, 360, 300, 330, 330, 510, 0, 0
+ },
+ sdpar[] = {
+ 90, 210, 165, 210, 0, 270, 195, 165, 285, 0,
+ 390, 270, 165, 270, 360, 0, 360, 0, 0, 0
+ };
+ int s, p;
+ char a[10];
+
+ put(0, 0, Vw, Vhud, 0x7f);
+ pic(0, 16, pict[Pguy]);
+ pictxt(112, 16, "FLOOR\nCOMPLETED");
+ sprint(a, "%d", ver<SDM ? gm.map % 10 + 1 : gm.map + 1);
+ pictxt(208, 16, a);
+ pictxt(112, 56, "BONUS 0");
+ pictxt(128, 80, "TIME");
+ pictxt(128, 96, " PAR");
+ p = ver < SDM ? wlpar[gm.map] : sdpar[gm.map];
+ sprint(a, "%02d:%2d", p / 60, p % 60);
+ pictxt(208, 96, a);
+ pictxt(72, 112, "KILL RATIO %");
+ pictxt(40, 128, "SECRET RATIO %");
+ pictxt(8, 144, "TREASURE RATIO %");
+ s = gm.tc / Tb;
+ if(s > 99 * 60)
+ s = 99 * 60;
+ sprint(a, "%02d:%02d", s / 60, s % 60);
+ pictxt(208, 80, a);
+ gm.eptm += s;
+ memset(irr, 0, sizeof irr);
+ s = p - s;
+ irr[0] = s > 0 ? s : 0;
+ if(gm.ktot)
+ irr[1] = gm.kp * 100 / gm.ktot;
+ if(gm.stot)
+ irr[2] = gm.sp * 100 / gm.stot;
+ if(gm.ttot)
+ irr[3] = gm.tp * 100 / gm.ttot;
+ gm.epk += irr[1];
+ gm.eps += irr[2];
+ gm.ept += irr[3];
+ irp = irr;
+ iri = 0;
+ irb = 0;
+ if(irr[0] == 0){
+ ql[Linteri].s[0].f = interi;
+ iry = 112;
+ irp++;
+ }else
+ ql[Linteri].s[0].f = interp;
+ ql[Linteri].q = ql+Linteri;
+ mus(Minter);
}
static void
gcont(void)
{
+ kb = 0;
+ mΔx = mΔy = 0;
+ mb = 0;
+ if(!gm.demo){
+ kbon++;
+ grab(1);
+ }
step = gstep;
- gm.end = 0;
}
static void
@@ -455,7 +1222,7 @@
camtxt2(void)
{
camwarp();
- mtc = 32;
+ qtc = 32;
render();
fizzop(-1, 1);
put(0, 0, Vw, Vhud, 0x7f);
@@ -469,9 +1236,49 @@
}
static void
+cont(void)
+{
+ view();
+ render();
+ mapmus();
+}
+
+static void
+ingam(void)
+{
+ greset();
+ view();
+}
+
+static void
+psych2(void)
+{
+ int n;
+
+ n = (qtc - 1) * 16 + 6;
+ if(n > 214 || nbrecv(csc, nil) > 0){
+ n = 214;
+ qp = qsp->e - 1;
+ qtc = 0;
+ }
+ put(53, 101, n, 2, 0x37);
+ put(53, 101, n-1, 1, 0x32);
+ out();
+}
+
+static void
+psych(void)
+{
+ ingam();
+ mapmus();
+ put(0, 0, Vw, Vhud, 0x7f);
+ pic(48, 56, pict[Ppsyched]);
+}
+
+static void
indem(void)
{
- initg(0, *demd++);
+ ginit(*demd++, -1, 0);
if(demd >= epis)
demd = dems;
view();
@@ -478,6 +1285,15 @@
}
static void
+fixedw(char *s)
+{
+ char c;
+
+ while(c = *s, c != 0)
+ *s++ = c - '0' + 129;
+}
+
+static void
score(void)
{
int x, y;
@@ -490,25 +1306,22 @@
pic(32, 68, pict[Pname]);
pic(160, 68, pict[Plvl]);
pic(224, 68, pict[Phigh]);
-
fnt = fnts;
- for(s=sc, y=76; s<sc+nelem(sc); s++, y+=16){
+ for(s=scs, y=76; s<scs+nelem(scs); s++, y+=16){
txt(32, y, s->name, 0xf);
-
sprint(a, "%d", s->lvl);
fixedw(a);
x = 176 - txtw(a);
if(ver == WL6){
- sprint(b, "E%d/L", s->ep+1);
- x += txt(x-6, y, b, 0xf) - 6;
+ sprint(b, "E%d/L", s->ep + 1);
+ x += txt(x - 6, y, b, 0xf) - 6;
}
txt(x, y, a, 0xf);
-
sprint(a, "%d", s->n);
fixedw(a);
txt(264 - txtw(a), y, a, 0xf);
}
- if(mp == ml+Lmscore)
+ if(qsp != ql+Lscore)
mus(Mroster);
}
static void
@@ -520,11 +1333,9 @@
mclear();
pic(0, 0, pict[Pscores]);
-
fnt = fnts+1;
- for(s=sc, y=76; s<sc+nelem(sc); s++, y+=16){
- txt(16, y, s->name, 0x13);
-
+ for(s=scs, y=76; s<scs+nelem(scs); s++, y+=16){
+ txt(16, y, s->name, DIrhi);
if(s->lvl == 21)
pic(176, y-1, pict[Pspear]);
else{
@@ -531,15 +1342,25 @@
sprint(a, "%d", s->lvl);
txt(194 - txtw(a), y, a, 0xf);
}
-
sprint(a, "%d", s->n);
txt(292 - txtw(a), y, a, 0xf);
}
- if(mp == ml+Lmscore)
+ if(qsp != ql+Lscore)
mus(Maward);
}
static void
+high(void)
+{
+ if(ver < SDM)
+ score();
+ else
+ sdscore();
+ inctl();
+ grab(0);
+}
+
+static void
creds(void)
{
pic(0, 0, pict[Pcreds]);
@@ -573,179 +1394,354 @@
threadexitsall(nil);
}
-static Item ictl[] = {
- {"New Game", 0x17},
- {"Sound", 0x17},
- {"Control", 0x17},
- {"Load Game", 0x17},
- {"Save Game", 0x17},
- {"Change View", 0x17},
- {"View Scores", 0x17, ml+Lmscore},
- {"Back to Demo", 0x17, ml+Lesc},
- {"Quit", 0x17, ml+Lquit}
-};
-
-static Col fblk, fmenu = { 0xae, 0, 0 };
-static Seq *mqp,
- introq[] = {{30, fadein}, {7*Tb, skiploop}, {30, fadeout}},
- titleq[] = {{30, fadein}, {15*Tb, skiploop}, {30, fadeout}},
- loopq[] = {{30, fadein}, {10*Tb, skiploop}, {30, fadeout}},
- scoreq[] = {{30, fadein}, {10*Tb, skiploop}, {30, fadeout}},
- demoq[] = {{30, fadein}, {1, demo}, {41, fizz}, {1, gcont}, {30, fadeout}},
- camq[] = {{100, nil}, {144, fizz}, {0, camtxt}, {300, skipstep}, {0, camtxt2}, {41, fizz}, {1, gcont}, {100, nil}, {30, fadeout}},
- interq[] = {{30, fadein}, {0, iscore}, {30, fadeout}},
- winq[] = {{30, fadein}, {0, iwin}, {30, fadeout}},
- decq[] = {{30, fadeout}},
- inctlq[] = {{10, fadein}},
+static Sp
+ loadq[] = {{30, fadeout}},
+ introq[] = {{30, fadein}, {7*Tb, skip}, {30, fadeout}},
+ titleq[] = {{30, fadein}, {15*Tb, skip}, {30, fadeout}},
+ loopq[] = {{30, fadein}, {10*Tb, skip}, {30, fadeout}},
+ scoreq[] = {{30, fadein}, {10*Tb, skip}, {30, fadeout}},
+ pantsq[] = {{30, fadein}, {1, bwait}, {30, fadeout}},
+ psychq[] = {{30, fadein}, {14, psych2}, {70, nbwait}, {30, fadeout}},
+ gamq[] = {{30, fadein}, {1, game}, {41, fizz}, {1, gcont}, {30, fadeout}},
+ gamsq[] = {{1, game}, {41, fizz}, {1, gcont}, {30, fadeout}},
+ contq[] = {{30, fadein}, {1, gcont}, {30, fadeout}},
+ msgq[] = {{1, bwait}, {1, gcont}, {30, fadeout}},
+ gcontq[] = {{1, gcont}, {30, fadeout}},
+ dieq[] = {{1, dieturn}, {144, fizz}, {100, nbwait}, {1, swait}},
+ fdieq[] = {{0, ctl}, {1, blink}, {30, fadeout}, {1, mend2}, {30, fadein}},
+ camq[] = {{100, nil}, {144, fizz}, {0, camtxt}, {300, nbwait}, {0, camtxt2}, {41, fizz}, {1, gcont}, {100, nil}, {0, stopmus}, {30, fadeout}},
+ spq[] = {{1, swait}, {0, mapmus}, {1, gcont}, {30, fadeout}},
+ interq[] = {{1, swait}, {30, fadein}},
+ interiq[] = {{0, nil}, {1, interb}},
+ intermq[] = {{0, nil}, {1, interm}, {1, interb}},
+ interwq[] = {{1, interw}},
+ intereq[] = {{0, nextmap}, {30, fadeout}},
+ sinterq[] = {{1, swait}, {30, fadein}, {0, siscore}, {1, sinterw}, {0, nextmap}, {30, fadeout}},
+ sdmq[] = {{1, bwait}, {30, fadeout}},
+ colpq[] = {{300, fadeout}},
+ colp2q[] = {{30, fadein}, {2*Tb, nil}, {0, colp}, {105, nil}, {0, colp}, {105, nil}, {0, colp}, {3*Tb, nil}},
+ colp3q[] = {{5, fadeout}},
+ wonq[] = {{1, swait}, {30, fadein}, {1, bwait}},
+ won2q[] = {{0, nil}, {30, fadeout}},
+ sdeq[] = {{30, fadein}, {1, bwait}, {30, fadeout}},
+ presq[] = {{30, fadein}, {0, pres2}, {10*Tb, nbwait}, {0, pres3}, {10*Tb, nbwait}, {30, fadeout}},
+ highq[] = {{30, fadein}, {1, bwait}, {30, fadeout}},
+ escq[] = {{10, fadeout}},
+ toctlq[] = {{10, fadein}},
ctlq[] = {{0, blink}, {70, cwalk}, {0, blink}, {8, cwalk}},
+ slq[] = {{1, slider}},
curq[] = {{8, nil}, {0, cursfx}},
- escq[] = {{10, fadeout}},
- backq[] = {{10, fadeout}, {0, ctl}, {10, fadein}},
- waitq[] = {{1, skiploop}},
- swaitq[] = {{1, swait}},
- ackq[] = {{1, ack}},
- mscoreq[] = {{10, fadeout}, {0, score}, {10, fadein}},
- pantsq[] = {{30, fadeout}, {0, pants}, {30, fadein}},
- quitq[] = {{0, blink}, {10, ask}},
- mexitq[] = {{10, fadeout}},
+ togq[] = {{1, toggle}},
+ mscoreq[] = {{10, fadein}, {1, bwait}, {10, fadeout}},
+ quitq[] = {{0, pblink}, {10, ask}},
+ ackq[] = {{1, bwait}},
exitq[] = {{1, exit}};
-
-static Menu *mp, ml[] = {
- [Lload] {nil, decq, decq+nelem(decq), ml+Lintro, &fblk},
- [Lintro] {intro, introq, introq+nelem(introq), ml+Ltitle, &fblk},
- [Ltitle] {title, titleq, titleq+nelem(titleq), ml+Lcreds, &fblk},
- [Lcreds] {creds, loopq, loopq+nelem(loopq), ml+Lscore, &fblk},
- [Lscore] {score, loopq, loopq+nelem(loopq), ml+Ldemo, &fblk},
- [Ldemo] {indem, demoq, demoq+nelem(demoq), nil, &fblk},
- [Lcam] {nil, camq, camq+nelem(camq), nil},
- [Linter] {inter, interq, interq+nelem(interq), nil, &fblk},
- [Lwin] {win, winq, winq+nelem(winq), nil, &fblk},
- [Ldecay] {nil, decq, decq+nelem(decq), ml+Linctl},
- [Linctl] {inctl, inctlq, inctlq+nelem(inctlq), ml+Lctl, &fblk},
- [Lctl] {ctl, ctlq, ctlq+nelem(ctlq), ml+Lctl, nil, ictl, ictl+nelem(ictl)},
- [Lcur] {nil, curq, curq+nelem(curq), ml+Lctl},
- [Lesc] {nil, escq, escq+nelem(escq), ml+Ltitle, &fblk},
- [Lback] {nil, backq, backq+nelem(backq), ml+Lctl, &fmenu},
- [Lwait] {nil, waitq, waitq+nelem(waitq), ml+Lwait},
- [Lsfxwait] {nil, swaitq, swaitq+nelem(swaitq), ml+Lsfxwait},
- [Lack] {nil, ackq, ackq+nelem(ackq), ml+Lack},
- [Lmscore] {nil, mscoreq, mscoreq+nelem(mscoreq), ml+Lack, &fmenu},
- [Lpants] {nil, pantsq, pantsq+nelem(pantsq), ml+Lwait, &fblk},
- [Lquit] {quit, quitq, quitq+nelem(quitq), ml+Lquit},
- [Lmexit] {nil, mexitq, mexitq+nelem(mexitq), ml+Lexit, &fmenu},
+static Seq ql[] = {
+ [Lload] {nil, loadq, loadq+nelem(loadq), ql+Lintro, &fblk},
+ [Lintro] {intro, introq, introq+nelem(introq), ql+Ltitle, &fblk},
+ [Lftitle] {nil, escq, escq+nelem(escq), ql+Ltitle, &ftra},
+ [Ltitle] {title, titleq, titleq+nelem(titleq), ql+Lcreds, &fblk},
+ [Lcreds] {creds, loopq, loopq+nelem(loopq), ql+Lscore, &fblk},
+ [Lscore] {score, loopq, loopq+nelem(loopq), ql+Ldemo, &fblk},
+ [Lfpants] {nil, loadq, loadq+nelem(loadq), ql+Lpants, &fblk},
+ [Lpants] {pants, pantsq, pantsq+nelem(pantsq), ql+Ltoctl, &fblk},
+ [Ldemo] {indem, gamq, gamq+nelem(gamq), nil, &fblk},
+ [Lpsych] {psych, psychq, psychq+nelem(psychq), ql+Lgame, &fblk},
+ [Lgame] {view, gamq, gamq+nelem(gamq), nil, &fblk},
+ [Lretry] {ingam, gamsq, gamsq+nelem(gamsq), nil},
+ [Lmsg] {nil, msgq, msgq+nelem(msgq), nil, &fblk},
+ [Lcont1] {nil, escq, escq+nelem(escq), ql+Lcont2, &ftra},
+ [Lcont2] {cont, contq, contq+nelem(contq), nil, &fblk},
+ [Lgcont] {cont, gcontq, gcontq+nelem(gcontq), nil, &fblk},
+ [Lfdie] {nil, fdieq, fdieq+nelem(fdieq), ql+Ldie, &fblk},
+ [Ldie] {die, dieq, dieq+nelem(dieq), nil},
+ [Ldie2] {nil, loadq, loadq+nelem(loadq), ql+Lhigh, &fblk},
+ [Lhigh] {high, highq, highq+nelem(highq), ql+Ltitle, &fblk},
+ [Lcam] {nil, camq, camq+nelem(camq), nil, &fblk},
+ [Lspear] {spshunt, spq, spq+nelem(spq), nil, &fblk},
+ [Linter] {inter, interq, interq+nelem(interq), ql+Linteri, &fblk},
+ [Linteri] {nil, interiq, interiq+nelem(interiq), nil},
+ [Linterm] {nil, intermq, intermq+nelem(intermq), ql+Linteri},
+ [Linterw] {nil, interwq, interwq+nelem(interwq), ql+Linterw},
+ [Lintere] {nil, intereq, intereq+nelem(intereq), ql+Lpsych, &fblk},
+ [Lsinter] {sinter, sinterq, sinterq+nelem(sinterq), ql+Lpsych, &fblk},
+ [Lsdmend] {sdmend, sdmq, sdmq+nelem(sdmq), ql+Lhigh, &fblk},
+ [Lcolp] {nil, colpq, colpq+nelem(colpq), ql+Lcolp2, &focl},
+ [Lcolp2] {incolp, colp2q, colp2q+nelem(colp2q), ql+Lcolp3, &ficl},
+ [Lcolp3] {nil, colp3q, colp3q+nelem(colp3q), ql+Lwon, &fecl},
+ [Lwon] {won, wonq, wonq+nelem(wonq), ql+Lwon2, &fblk},
+ [Lwon2] {nil, won2q, won2q+nelem(won2q), ql+Lhigh, &fblk},
+ [Lsdepi] {sdepi, sdeq, sdeq+nelem(sdeq), ql+Lpres, &fblk},
+ [Lpres] {pres1, presq, presq+nelem(presq), ql+Lroll1, &fblk},
+ [Lroll1] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll2, &fblk},
+ [Lroll2] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll3, &fblk},
+ [Lroll3] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll4, &fblk},
+ [Lroll4] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll5, &fblk},
+ [Lroll5] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll6, &fblk},
+ [Lroll6] {roll, sdeq, sdeq+nelem(sdeq), ql+Lroll7, &fblk},
+ [Lroll7] {roll, sdeq, sdeq+nelem(sdeq), ql+Lhigh, &fblk},
+ [Ldecay] {nil, loadq, loadq+nelem(loadq), ql+Ltoctl},
+ [Ltoctl] {ctl, toctlq, toctlq+nelem(toctlq), ql+Lctl, &ftra},
+ [Lftoctl] {nil, escq, escq+nelem(escq), ql+Lmtoctl, &fctl},
+ [Lmtoctl] {ctl, toctlq, toctlq+nelem(toctlq), ql+Lctl, &fctl},
+ [Lctl] {ctl, ctlq, ctlq+nelem(ctlq), ql+Lctl},
+ [Lcur] {nil, curq, curq+nelem(curq), ql+Lctl},
+ [Lftonew] {nil, escq, escq+nelem(escq), ql+Lmtonew, &fctl},
+ [Lmtonew] {newgame, toctlq, toctlq+nelem(toctlq), ql+Lnctl, &fctl},
+ [Lnewgame] {newgame, toctlq, toctlq+nelem(toctlq), ql+Lnctl, &fctl},
+ [Lnctl] {newgame, ctlq, ctlq+nelem(ctlq), ql+Lnctl},
+ [Ldenied] {denied, ackq, ackq+nelem(ackq), ql+Lnctl},
+ [Ldifc1] {nil, escq, escq+nelem(escq), ql+Ldifc2, &fctl},
+ [Ldifc2] {difc, toctlq, toctlq+nelem(toctlq), ql+Ldifc3, &fctl},
+ [Ldifc3] {difc, ctlq, ctlq+nelem(ctlq), ql+Ldifc3},
+ [Ldifc4] {nil, escq, escq+nelem(escq), ql+Ldifc5, &fctl},
+ [Ldifc5] {setdifc, loadq, loadq+nelem(loadq), ql+Lpsych, &fblk},
+ [Lfsnd] {nil, escq, escq+nelem(escq), ql+Lmsnd, &fctl},
+ [Lmsnd] {snd, toctlq, toctlq+nelem(toctlq), ql+Lsctl, &fctl},
+ [Lsctl] {snd, ctlq, ctlq+nelem(ctlq), ql+Lsctl},
+ [Lsndtog] {nil, togq, togq+nelem(togq), ql+Lsctl},
+ [Lfin] {nil, escq, escq+nelem(escq), ql+Lmin, &fctl},
+ [Lmin] {in, toctlq, toctlq+nelem(toctlq), ql+Lictl, &fctl},
+ [Lictl] {in, ctlq, ctlq+nelem(ctlq), ql+Lictl},
+ [Lintog] {nil, togq, togq+nelem(togq), ql+Lictl},
+ [Lfsav] {nil, escq, escq+nelem(escq), ql+Lmsav, &fctl},
+ [Lmsav] {sav, toctlq, toctlq+nelem(toctlq), ql+Lsvctl, &fctl},
+ [Lsvctl] {sav, ctlq, ctlq+nelem(ctlq), ql+Lsvctl},
+ [Lflod] {nil, escq, escq+nelem(escq), ql+Lmlod, &fctl},
+ [Lmlod] {sav, toctlq, toctlq+nelem(toctlq), ql+Lldctl, &fctl},
+ [Lldctl] {sav, ctlq, ctlq+nelem(ctlq), ql+Lldctl},
+ [Lfsens] {nil, escq, escq+nelem(escq), ql+Lmsens, &fctl},
+ [Lmsens] {sens, toctlq, toctlq+nelem(toctlq), ql+Lsectl, &fctl},
+ [Lsectl] {sens, slq, slq+nelem(slq), ql+Lsectl},
+ [Lfvw] {nil, escq, escq+nelem(escq), ql+Lmvw, &fctl},
+ [Lmvw] {mvw, toctlq, toctlq+nelem(toctlq), ql+Lvwctl, &fctl},
+ [Lvwctl] {mvw, slq, slq+nelem(slq), ql+Lvwctl},
+ [Lfmscore] {nil, escq, escq+nelem(escq), ql+Lmscore, &fctl},
+ [Lmscore] {score, mscoreq, mscoreq+nelem(mscoreq), ql+Lmtoctl, &fctl},
+ [Lend] {mend, quitq, quitq+nelem(quitq), ql+Lend},
+ [Lcurgame] {curgame, quitq, quitq+nelem(quitq), ql+Lcurgame},
+ [Lquit] {quit, quitq, quitq+nelem(quitq), ql+Lquit},
+ [Lmexit] {nil, escq, escq+nelem(escq), ql+Lexit, &fctl},
[Lexit] {nil, exitq, exitq+nelem(exitq)}
};
static void
-dend(void)
+initseqs(void)
{
- gm.demo = gm.record = 0;
- pal = pals[Cfad];
+ Item *i;
+
+ mclear = wlmclear;
+ stripe = wlstripe;
+ quits = ends;
+ if(ver == WL1){
+ for(i=ml[LMnew].s+2; i<ml[LMnew].e; i+=2){
+ i->c = DIeps;
+ i->q = ql+Ldenied;
+ }
+ }
+ if(ver >= SDM){
+ mclear = sdmclear;
+ stripe = sdstripe;
+ ql[Ltitle].init = sdtitle;
+ ql[Lscore].init = sdscore;
+ ql[Lmscore].init = sdscore;
+ ql[Lwon].f = &ficl;
+ ql[Lwon2].q = ql+Lsdepi;
+ fctl.c = (Col){0, 0, 0xce};
+ mcol[DMbg] = 0x9d;
+ quits += nelem(ends)/2;
+ }
+ mcol[DMoff] = mcol[DMbg] ^ 6;
+ mcol[DMbrd] = mcol[DMbg] ^ 4;
+ mcol[DMbrd2] = mcol[DMbg] ^ 14;
+ ml[LMsnd].s[1].c = mcol[DMoff];
+ ml[LMsnd].s[6].c = mcol[DMoff];
+}
+
+static void
+cfg(void)
+{
+ muson = sfxon = pcmon = 1;
+ grabon++;
+ autorun = 0;
+ msense = 5;
+ vwsize = 15;
+ /* fs.c: load config file and read values */
+ if(msense < 0)
+ msense = 0;
+ else if(msense > 9)
+ msense = 9;
+ if(vwsize < 4)
+ vwsize = 4;
+ else if(vwsize > 19)
+ vwsize = 19;
+ setvw();
+}
+
+static void
+sqend(void)
+{
+ if(!gm.demo && !gm.record)
+ return;
+ qsp->q = gm.end == EDkey ? ql+Ltoctl : ql+Ltitle;
if(demf != nil){
free(demf);
demf = nil;
demd = dems;
if(demexit)
- mp->m = ml+Lexit;
+ qsp->q = ql+Lexit;
}
+ gm.demo = gm.record = 0;
}
+static void
+edfizz(void)
+{
+ fizzop(-1, 1);
+ put((Vw - vw.dx) / 2, (Vhud - vw.dy) / 2, vw.dx, vw.dy,
+ qsp == ql+Lretry ? 4 : 0);
+ out();
+}
+static void
+edcam(void)
+{
+ gm.won++;
+ out();
+ fizzop(0x7f, 0);
+ reset(ql+Lcam);
+ qsp->q = ql+Lwon;
+}
+static void
+eddie(void)
+{
+ u32int *p;
+
+ p = pal;
+ reset(ql+Ldie);
+ pal = p;
+ if(gm.lives >= 0)
+ qsp->q = ql+Lretry;
+ else
+ qsp->q = ql+Ldie2;
+}
+static void
+edup(void)
+{
+ gm.keys = 0;
+ hudk();
+ if(ver < SDM && gm.map % 10 == 9 || ver >= SDM
+ && (gm.map == 4 || gm.map == 9 || gm.map == 15 || gm.map >= 17)){
+ gm.com = GMret;
+ qsp->q = ql+Lsinter;
+ }else if(gm.end == EDsetec){
+ gm.com = GMsetec;
+ qsp->q = ql+Linter;
+ }else{
+ gm.com = GMup;
+ qsp->q = ql+Linter;
+ }
+}
+static void
+edspear(void)
+{
+ reset(ql+Lspear);
+ qp->dt = pcmon ? 150 : 1;
+ qp->f = pcmon ? nil : swait;
+}
+static void
+edwon(void)
+{
+ stopmus();
+ qsp->q = ql+Lwon;
+ if(ver == SOD)
+ reset(ql+Lcolp);
+}
void
gend(void)
{
+ kbon = 0;
switch(gm.end){
- case EDfizz:
- fizzop(-1, 1);
- put((Vw - vw.dx) / 2, (Vhud - vw.dy) / 2, vw.dx, vw.dy, 0);
- out();
- break;
- enddem:
- case EDdem:
- mp->m = ml+Ltitle;
- dend();
- break;
- case EDcam:
- if(gm.record || gm.demo)
- scalspr(SPdemo, vw.dx/2, vw.dy+1);
- out();
- fizzop(0x7f, 0);
- reset(ml+Lcam);
- mp->m = gm.demo || gm.record ? ml+Ltitle : ml+Lwin;
- break;
- case EDcam2:
- if(gm.demo || gm.record)
- dend();
- else
- pal = pals[Cfad];
- scalspr(SPcam, vw.dx/2, vw.dy+1);
- break;
- case EDkey:
- mp->m = ml+Linctl;
- dend();
- break;
- case EDdie:
- if(gm.demo || gm.record)
- goto enddem;
- break;
- case EDup:
- case EDsetec:
- case EDwon:
- if(gm.demo || gm.record)
- goto enddem;
- mp->m = ml+Lsfxwait;
- break;
+ case EDfizz: edfizz(); break;
+ case EDcam: edcam(); break;
+ case EDcam2: scalspr(SPcam, vw.dx / 2, vw.dy + 1); sqend(); break;
+ case EDdem: sqend(); break;
+ case EDkey: qsp->q = ql+Ltoctl; sqend(); break;
+ case EDdie: eddie(); break;
+ case EDup: /* wet floor */
+ case EDsetec: edup(); sqend(); break;
+ case EDspear: edspear(); break;
+ case EDwon: edwon(); sqend(); break;
+ case EDmsg:;
}
- mtc = 0;
- step = mstep;
+ gm.end = 0;
+ pal = pals[Cfad];
+ qtc = 0;
+ step = qstep;
}
+int
+quickkey(Rune r)
+{
+ switch(r){
+ case KF|1:
+ case KF|2:
+ case KF|3:
+ case KF|4:
+ case KF|5:
+ case KF|6:
+ case KF|7:
+ case KF|8:
+ case KF|9:
+ default: return 0;
+ case KF|10: reset(ql+Lquit); qesc = ql+Lgcont; break;
+ }
+ gm.end = EDmsg;
+ grab(0);
+ return 1;
+}
+
void
-mstep(void)
+qstep(void)
{
- Menu *m;
- Seq *q;
+ Sp *p;
rep:
- m = mp;
- q = mqp;
- mtc += Δtc;
- if(q->f != nil)
- q->f();
- if(mtc >= q->dt){
- if(++mqp == m->qe)
- reset(m->m);
- mtc = 0;
+ p = qp;
+ qtc += Δtc;
+ if(p->f != nil)
+ p->f();
+ if(p != qp)
+ return;
+ if(qtc >= p->dt){
+ if(++qp == qsp->e){
+ reset(qsp->q);
+ return;
+ }
+ qtc = 0;
}
- if(q->dt == 0)
+ if(p->dt == 0)
goto rep;
}
void
-init(char *f)
+init(char *f, int m, int d)
{
- tab();
- mclear = wlmclear;
- stripe = wlstripe;
- quits = ends;
- if(ver >= SDM){
- mclear = sdmclear;
- stripe = sdstripe;
- ml[Ltitle].init = sdtitle;
- ml[Lscore].init = sdscore;
- mscoreq[1].f = sdscore;
- fmenu = (Col){0, 0, 0xce};
- mcol[Dbg] = 0x9d;
- quits += nelem(ends)/2;
- }
- mcol[Doff] = mcol[Dbg] ^ 6;
- mcol[Dbrd] = mcol[Dbg] ^ 4;
- mcol[Dbrd2] = mcol[Dbg] ^ 14;
+ cfg();
+ initseqs();
+ inctl();
demd = dems;
- reset(ml+Lload);
- setvw(15);
+ reset(ql+Lload);
+ if(m != -1){
+ if(d > GDhard)
+ d = GDhard;
+ qsp->q = ql+Lpsych;
+ ginit(nil, m, d);
+ ingctl();
+ return;
+ }
if(f != nil){
demf = demof(f);
demd = (uchar **)&demf;
- mp->m = ml+Ldemo;
+ qsp->q = ql+Ldemo;
}
mus(ver<SDM ? Mintro : Mtower);
}
--- a/in.c
+++ /dev/null
@@ -1,182 +1,0 @@
-#define MaxPlayers 4
-#define NumCodes 128
-
-// Stuff for the mouse
-#define MReset 0
-#define MButtons 3
-#define MDelta 11
-
-#define MouseInt 0x33
-#define Mouse(x) _AX = x,geninterrupt(MouseInt)
-
-typedef enum {
- demo_Off,demo_Record,demo_Playback,demo_PlayDone
- } Demo;
-typedef enum {
- ctrl_Keyboard,
- ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2,
- ctrl_Mouse
- } ControlType;
-typedef enum {
- motion_Left = -1,motion_Up = -1,
- motion_None = 0,
- motion_Right = 1,motion_Down = 1
- } Motion;
-typedef enum {
- dir_North,dir_NorthEast,
- dir_East,dir_SouthEast,
- dir_South,dir_SouthWest,
- dir_West,dir_NorthWest,
- dir_None
- } Direction;
-typedef struct {
- int button0,button1,button2,button3;
- s16int x,y;
- Motion xaxis,yaxis;
- Direction dir;
- } CursorInfo;
-typedef CursorInfo ControlInfo;
-typedef struct {
- u8int button0,button1,
- upleft, up, upright,
- left, right,
- downleft, down, downright;
- } KeyboardDef;
-
-// Function prototypes
-#define IN_KeyDown(code) (Keyboard[(code)])
-#define IN_ClearKey(code) {Keyboard[code] = false;\
- if (code == LastScan) LastScan = sc_None;}
-
-int Keyboard[NumCodes];
-KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
-ControlType Controls[MaxPlayers];
-Demo DemoMode = demo_Off;
-u8int _seg *DemoBuffer;
-u16int DemoOffset,DemoSize;
-
-static Direction DirTable[] = // Quick lookup for total direction
-{
- dir_NorthWest, dir_North, dir_NorthEast,
- dir_West, dir_None, dir_East,
- dir_SouthWest, dir_South, dir_SouthEast
- };
-
-void
-IN_ReadControl(s16int player,ControlInfo *info)
-{
- int realdelta;
- u8int dbyte;
- u16int buttons;
- s16int dx,dy;
- Motion mx,my;
- ControlType type;
-register KeyboardDef *def;
-
- dx = dy = 0;
- mx = my = motion_None;
- buttons = 0;
-
- if (DemoMode == demo_Playback)
- {
- dbyte = DemoBuffer[DemoOffset + 1];
- my = (dbyte & 3) - 1;
- mx = ((dbyte >> 2) & 3) - 1;
- buttons = (dbyte >> 4) & 3;
-
- if (!(--DemoBuffer[DemoOffset]))
- {
- DemoOffset += 2;
- if (DemoOffset >= DemoSize)
- DemoMode = demo_PlayDone;
- }
-
- realdelta = false;
- }
- else if (DemoMode == demo_PlayDone)
- Quit("Demo playback exceeded");
- else
- {
- switch (type = Controls[player])
- {
- case ctrl_Keyboard:
- def = &KbdDefs;
-
- if (Keyboard[def->upleft])
- mx = motion_Left,my = motion_Up;
- else if (Keyboard[def->upright])
- mx = motion_Right,my = motion_Up;
- else if (Keyboard[def->downleft])
- mx = motion_Left,my = motion_Down;
- else if (Keyboard[def->downright])
- mx = motion_Right,my = motion_Down;
-
- if (Keyboard[def->up])
- my = motion_Up;
- else if (Keyboard[def->down])
- my = motion_Down;
-
- if (Keyboard[def->left])
- mx = motion_Left;
- else if (Keyboard[def->right])
- mx = motion_Right;
-
- if (Keyboard[def->button0])
- buttons += 1 << 0;
- if (Keyboard[def->button1])
- buttons += 1 << 1;
- realdelta = false;
- break;
- case ctrl_Mouse:
- INL_GetMouseDelta(&dx,&dy);
- buttons = INL_GetMouseButtons();
- realdelta = true;
- break;
- }
- }
-
- if (realdelta)
- {
- mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
- my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
- }
- else
- {
- dx = mx * 127;
- dy = my * 127;
- }
-
- info->x = dx;
- info->xaxis = mx;
- info->y = dy;
- info->yaxis = my;
- info->button0 = buttons & (1 << 0);
- info->button1 = buttons & (1 << 1);
- info->button2 = buttons & (1 << 2);
- info->button3 = buttons & (1 << 3);
- info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
-
- if (DemoMode == demo_Record)
- {
- // Pack the control info into a byte
- dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
-
- if
- (
- (DemoBuffer[DemoOffset + 1] == dbyte)
- && (DemoBuffer[DemoOffset] < 255)
- )
- (DemoBuffer[DemoOffset])++;
- else
- {
- if (DemoOffset || DemoBuffer[DemoOffset])
- DemoOffset += 2;
-
- if (DemoOffset >= DemoSize)
- Quit("Demo buffer overflow");
-
- DemoBuffer[DemoOffset] = 1;
- DemoBuffer[DemoOffset + 1] = dbyte;
- }
- }
-}
--- a/inter.c
+++ b/inter.c
@@ -1,807 +1,15 @@
-// WL_INTER.C
-
-#include "WL_DEF.H"
-#pragma hdrstop
-
-
-//==========================================================================
-
-/*
-==================
-=
-= CLearSplitVWB
-=
-==================
-*/
-
-void ClearSplitVWB (void)
-{
- memset (update,0,sizeof(update));
- WindowX = 0;
- WindowY = 0;
- WindowW = 320;
- WindowH = 160;
-}
-
-
-//==========================================================================
-
-#ifdef SPEAR
-#ifndef SPEARDEMO
-////////////////////////////////////////////////////////
-//
-// End of Spear of Destiny
-//
-////////////////////////////////////////////////////////
-
-void EndScreen (s16int palette, s16int screen)
-{
- CA_CacheScreen (screen);
- VW_UpdateScreen ();
- VL_FadeIn(0,255,grsegs[palette],30);
- IN_ClearKeysDown ();
- IN_Ack ();
- VW_FadeOut ();
-}
-
-
-void EndSpear(void)
-{
- EndScreen (Eend1, Pend1);
-
- CA_CacheScreen (Pend1+2);
- VW_UpdateScreen ();
- VL_FadeIn(0,255,Eend1+2,30);
- fontnumber = 0;
- fontcolor = 0xd0;
- WindowX = 0;
- WindowW = 320;
- PrintX = 0;
- PrintY = 180;
- US_CPrint ("We owe you a great debt, Mr. Blazkowicz.\n");
- US_CPrint ("You have served your country well.");
- VW_UpdateScreen ();
- IN_StartAck ();
- TimeCount = 0;
- while (!IN_CheckAck () && TimeCount < 700);
-
- PrintX = 0;
- PrintY = 180;
- VWB_Bar(0,180,320,20,0);
- US_CPrint ("With the spear gone, the Allies will finally\n");
- US_CPrint ("be able to destroy Hitler...");
- VW_UpdateScreen ();
- IN_StartAck ();
- TimeCount = 0;
- while (!IN_CheckAck () && TimeCount < 700);
-
- VW_FadeOut ();
-
- EndScreen (Eend1+3, Pend1+3);
- EndScreen (Eend1+4, Pend1+4);
- EndScreen (Eend1+5, Pend1+5);
- EndScreen (Eend1+6, Pend1+6);
- EndScreen (Eend1+7, Pend1+7);
- EndScreen (Eend1+8, Pend1+8);
- EndScreen (Eend1+1, Pend1+1);
-
- MainMenu[savegame].active = 0;
-}
-#endif
-#endif
-
-//==========================================================================
-
-/*
-==================
-=
-= Victory
-=
-==================
-*/
-
void Victory (void)
{
-#ifndef SPEARDEMO
- s32int sec;
- s16int i,min,kr,sr,tr,x;
- char tempstr[8];
-
-#define RATIOX 6
-#define RATIOY 14
-#define TIMEX 14
-#define TIMEY 8
-
-
-#ifdef SPEAR
- StartCPMusic (7);
-
- VWB_Bar(0,0,320,200,VIEWCOLOR);
- VWB_DrawPic (124,44,Pcollapse);
- VW_UpdateScreen ();
- VW_FadeIn ();
- VW_WaitVBL(2*70);
- VWB_DrawPic (124,44,Pcollapse+1);
- VW_UpdateScreen ();
- VW_WaitVBL(105);
- VWB_DrawPic (124,44,Pcollapse+2);
- VW_UpdateScreen ();
- VW_WaitVBL(105);
- VWB_DrawPic (124,44,Pcollapse+3);
- VW_UpdateScreen ();
- VW_WaitVBL(3*70);
-
- VL_FadeOut (0,255,0,17,17,5);
-#endif
-
-#ifndef SPEAR
- StartCPMusic (24);
-#else
- StartCPMusic (6);
-#endif
- ClearSplitVWB ();
-
- VWB_Bar (0,0,320,200-STATUSLINES,127);
- pictxt(18*8, 2*8, "YOU WIN!");
-
- pictxt(TIMEX*8, TIMEY-2*8, "TOTAL TIME");
-
- pictxt(12*8, RATIOY-2*8, "AVERAGES");
-
- pictxt(RATIOX+8*8, RATIOY*8, "KILL %");
- pictxt(RATIOX+4*8, RATIOY+2*8, "SECRET %");
- pictxt(RATIOX*8, RATIOY+4*8, "TREASURE %");
-
- VWB_DrawPic (8,4,Pwin);
-
-#ifndef SPEAR
- for (kr = sr = tr = sec = i = 0;i < 8;i++)
-#else
- for (kr = sr = tr = sec = i = 0;i < 20;i++)
-#endif
- {
- sec += LevelRatios[i].time;
- kr += LevelRatios[i].kill;
- sr += LevelRatios[i].secret;
- tr += LevelRatios[i].treasure;
- }
-
-#ifndef SPEAR
- kr /= 8;
- sr /= 8;
- tr /= 8;
-#else
- kr /= 14;
- sr /= 14;
- tr /= 14;
-#endif
-
- min = sec/60;
- sec %= 60;
-
- if (min > 99)
- min = sec = 99;
-
- i = TIMEX*8+1;
- VWB_DrawPic(i,TIMEY*8,P0+(min/10));
- i += 2*8;
- VWB_DrawPic(i,TIMEY*8,P0+(min%10));
- i += 2*8;
- pictxt(i/8*8, TIMEY*8, ":");
- i += 1*8;
- VWB_DrawPic(i,TIMEY*8,P0+(sec/10)); /* huh? */
- i += 2*8;
- VWB_DrawPic(i,TIMEY*8,P0+(sec%10));
- VW_UpdateScreen ();
-
- itoa(kr,tempstr,10);
- x=RATIOX+24-strlen(tempstr)*2;
- pictxt(x*8, RATIOY*8, tempstr);
-
- itoa(sr,tempstr,10);
- x=RATIOX+24-strlen(tempstr)*2;
- pictxt(x*8, RATIOY+2*8, tempstr);
-
- itoa(tr,tempstr,10);
- x=RATIOX+24-strlen(tempstr)*2;
- pictxt(x*8, RATIOY+4*8, tempstr);
-
-
-#ifndef UPLOAD
-#ifndef SPEAR
- //
- // TOTAL TIME VERIFICATION CODE
- //
- if (gamestate.difficulty>=GDmed)
- {
- VWB_DrawPic (30*8,TIMEY*8,Ptc);
- fontnumber = 0;
- fontcolor = READHCOLOR;
- PrintX = 30*8-3;
- PrintY = TIMEY*8+8;
- PrintX+=4;
- tempstr[0] = (((min/10)^(min%10))^0xa)+'A';
- tempstr[1] = (((sec/10)^(sec%10))^0xa)+'A';
- tempstr[2] = (tempstr[0]^tempstr[1])+'A';
- tempstr[3] = 0;
- US_Print(tempstr);
- }
-#endif
-#endif
-
-
- fontnumber = 1;
-
- VW_UpdateScreen ();
- VW_FadeIn ();
-
+ won();
IN_Ack();
-
VW_FadeOut ();
-
#ifndef SPEAR
EndText();
#else
EndSpear();
#endif
-
-#endif // SPEARDEMO
}
-//
-// Breathe Mr. BJ!!!
-//
-void BJ_Breathe(void)
-{
- static s16int which=0,max=10;
- s16int pics[2]={Pguy,Pguy2};
-
-
- if (TimeCount>max)
- {
- which^=1;
- VWB_DrawPic(0,16,pics[which]);
- VW_UpdateScreen();
- TimeCount=0;
- max=35;
- }
-}
-
-
-
-/*
-==================
-=
-= LevelCompleted
-=
-= Entered with the screen faded out
-= Still in split screen mode with the status bar
-=
-= Exit with the screen faded out
-=
-==================
-*/
-
-#ifndef SPEAR
-LRstruct LevelRatios[8];
-#else
-LRstruct LevelRatios[20];
-#endif
-
-void LevelCompleted (void)
-{
- #define VBLWAIT 30
- #define PAR_AMOUNT 500
- #define PERCENT100AMT 10000
- typedef struct {
- float time;
- char timestr[6];
- } times;
-
- s16int x,i,min,sec,ratio,kr,sr,tr;
- u16int temp;
- char tempstr[10];
- s32int bonus,timeleft=0;
- times parTimes[]=
- {
-#ifndef SPEAR
- //
- // Episode One Par Times
- //
- {1.5, "01:30"},
- {2, "02:00"},
- {2, "02:00"},
- {3.5, "03:30"},
- {3, "03:00"},
- {3, "03:00"},
- {2.5, "02:30"},
- {2.5, "02:30"},
- {0, "??:??"}, // Boss level
- {0, "??:??"}, // Secret level
-
- //
- // Episode Two Par Times
- //
- {1.5, "01:30"},
- {3.5, "03:30"},
- {3, "03:00"},
- {2, "02:00"},
- {4, "04:00"},
- {6, "06:00"},
- {1, "01:00"},
- {3, "03:00"},
- {0, "??:??"},
- {0, "??:??"},
-
- //
- // Episode Three Par Times
- //
- {1.5, "01:30"},
- {1.5, "01:30"},
- {2.5, "02:30"},
- {2.5, "02:30"},
- {3.5, "03:30"},
- {2.5, "02:30"},
- {2, "02:00"},
- {6, "06:00"},
- {0, "??:??"},
- {0, "??:??"},
-
- //
- // Episode Four Par Times
- //
- {2, "02:00"},
- {2, "02:00"},
- {1.5, "01:30"},
- {1, "01:00"},
- {4.5, "04:30"},
- {3.5, "03:30"},
- {2, "02:00"},
- {4.5, "04:30"},
- {0, "??:??"},
- {0, "??:??"},
-
- //
- // Episode Five Par Times
- //
- {2.5, "02:30"},
- {1.5, "01:30"},
- {2.5, "02:30"},
- {2.5, "02:30"},
- {4, "04:00"},
- {3, "03:00"},
- {4.5, "04:30"},
- {3.5, "03:30"},
- {0, "??:??"},
- {0, "??:??"},
-
- //
- // Episode Six Par Times
- //
- {6.5, "06:30"},
- {4, "04:00"},
- {4.5, "04:30"},
- {6, "06:00"},
- {5, "05:00"},
- {5.5, "05:30"},
- {5.5, "05:30"},
- {8.5, "08:30"},
- {0, "??:??"},
- {0, "??:??"}
-#else
- //
- // SPEAR OF DESTINY TIMES
- //
- {1.5, "01:30"},
- {3.5, "03:30"},
- {2.75, "02:45"},
- {3.5, "03:30"},
- {0, "??:??"}, // Boss 1
- {4.5, "04:30"},
- {3.25, "03:15"},
- {2.75, "02:45"},
- {4.75, "04:45"},
- {0, "??:??"}, // Boss 2
- {6.5, "06:30"},
- {4.5, "04:30"},
- {2.75, "02:45"},
- {4.5, "04:30"},
- {6, "06:00"},
- {0, "??:??"}, // Boss 3
- {6, "06:00"},
- {0, "??:??"}, // Boss 4
- {0, "??:??"}, // Secret level 1
- {0, "??:??"}, // Secret level 2
-#endif
- };
-
- ClearSplitVWB (); // set up for double buffering in split screen
- VWB_Bar (0,0,320,200-STATUSLINES,127);
- StartCPMusic(16);
-
-//
-// do the intermission
-//
- IN_ClearKeysDown();
- IN_StartAck();
-
- VWB_DrawPic(0,16,Pguy);
-
-#ifndef SPEAR
- if (mapon<8)
-#else
- if (mapon != 4 &&
- mapon != 9 &&
- mapon != 15 &&
- mapon < 17)
-#endif
- {
- pictxt(14*8, 2*8, "FLOOR\nCOMPLETED");
-
- pictxt(14*8, 7*8, "BONUS 0");
- pictxt(16*8, 10*8, "TIME");
- pictxt(16*8, 12*8, " PAR");
-
- pictxt(9*8, 14*8, "KILL RATIO %");
- pictxt(5*8, 16*8, "SECRET RATIO %");
- pictxt(1*8, 18*8, "TREASURE RATIO %");
-
- pictxt(26*8, 2*8, itoa(gamestate.mapon+1,tempstr,10));
-
- pictxt(26*8, 12*8, parTimes[gamestate.episode*10+mapon].timestr);
-
- //
- // PRINT TIME
- //
- sec=gm.lvltc/70;
-
- if (sec > 99*60) // 99 minutes max
- sec = 99*60;
-
- if (gm.lvltc<parTimes[gamestate.episode*10+mapon].time*4200)
- timeleft=(parTimes[gamestate.episode*10+mapon].time*4200)/70-sec;
-
- min=sec/60;
- sec%=60;
-
- i=26*8;
- VWB_DrawPic(i,10*8,P0+(min/10));
- i+=2*8;
- VWB_DrawPic(i,10*8,P0+(min%10));
- i+=2*8;
- pictxt(i/8*8, 10*8, ":");
- i+=1*8;
- VWB_DrawPic(i,10*8,P0+(sec/10));
- i+=2*8;
- VWB_DrawPic(i,10*8,P0+(sec%10));
-
- VW_UpdateScreen ();
- VW_FadeIn ();
-
-
- //
- // FIGURE RATIOS OUT BEFOREHAND
- //
- kr = sr = tr = 0;
- if (gm.nkills)
- kr=(gm.kills*100)/gm.nkills;
- if (gm.nsecret)
- sr=(gm.secret*100)/gm.nsecret;
- if (gm.ntreasure)
- tr=(gm.treasure*100)/gm.ntreasure;
-
-
- //
- // PRINT TIME BONUS
- //
- bonus=timeleft*PAR_AMOUNT;
- if (bonus)
- {
- for (i=0;i<=timeleft;i++)
- {
- ltoa((s32int)i*PAR_AMOUNT,tempstr,10);
- x=36-strlen(tempstr)*2;
- pictxt(x*8, 7*8, tempstr);
- if (!(i%(PAR_AMOUNT/10)))
- sfx(Sendb1);
- VW_UpdateScreen();
- while(SD_SoundPlaying())
- BJ_Breathe();
- if (IN_CheckAck())
- goto done;
- }
-
- VW_UpdateScreen();
- sfx(Sendb2);
- while(SD_SoundPlaying())
- BJ_Breathe();
- }
-
-
- #define RATIOXX 37
- //
- // KILL RATIO
- //
- ratio=kr;
- for (i=0;i<=ratio;i++)
- {
- itoa(i,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 14*8, tempstr);
- if (!(i%10))
- sfx(Sendb1);
- VW_UpdateScreen ();
- while(SD_SoundPlaying())
- BJ_Breathe();
-
- if (IN_CheckAck())
- goto done;
- }
- if (ratio==100)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- bonus+=PERCENT100AMT;
- ltoa(bonus,tempstr,10);
- x=(RATIOXX-1)-strlen(tempstr)*2;
- pictxt(x*8, 7*8, tempstr);
- VW_UpdateScreen();
- sfx(S100);
- }
- else
- if (!ratio)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- sfx(Snobonus);
- }
- else
- sfx(Sendb2);
-
- VW_UpdateScreen();
- while(SD_SoundPlaying())
- BJ_Breathe();
-
-
- //
- // SECRET RATIO
- //
- ratio=sr;
- for (i=0;i<=ratio;i++)
- {
- itoa(i,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 16*8, tempstr);
- if (!(i%10))
- sfx(Sendb1);
- VW_UpdateScreen ();
- while(SD_SoundPlaying())
- BJ_Breathe();
- BJ_Breathe();
-
- if (IN_CheckAck())
- goto done;
- }
- if (ratio==100)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- bonus+=PERCENT100AMT;
- ltoa(bonus,tempstr,10);
- x=(RATIOXX-1)-strlen(tempstr)*2;
- pictxt(x*8, 7*8, tempstr);
- VW_UpdateScreen();
- sfx(S100);
- }
- else
- if (!ratio)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- sfx(Snobonus);
- }
- else
- sfx(Sendb2);
- VW_UpdateScreen();
- while(SD_SoundPlaying())
- BJ_Breathe();
-
-
- //
- // TREASURE RATIO
- //
- ratio=tr;
- for (i=0;i<=ratio;i++)
- {
- itoa(i,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 18*8, tempstr);
- if (!(i%10))
- sfx(Sendb1);
- VW_UpdateScreen ();
- while(SD_SoundPlaying())
- BJ_Breathe();
- if (IN_CheckAck())
- goto done;
- }
- if (ratio==100)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- bonus+=PERCENT100AMT;
- ltoa(bonus,tempstr,10);
- x=(RATIOXX-1)-strlen(tempstr)*2;
- pictxt(x*8, 7*8, tempstr);
- VW_UpdateScreen();
- sfx(S100);
- }
- else
- if (!ratio)
- {
- VW_WaitVBL(VBLWAIT);
- SD_StopSound();
- sfx(Snobonus);
- }
- else
- sfx(Sendb2);
- VW_UpdateScreen();
- while(SD_SoundPlaying())
- BJ_Breathe();
-
-
- //
- // JUMP STRAIGHT HERE IF KEY PRESSED
- //
- done:
-
- itoa(kr,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 14*8, tempstr);
-
- itoa(sr,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 16*8, tempstr);
-
- itoa(tr,tempstr,10);
- x=RATIOXX-strlen(tempstr)*2;
- pictxt(x*8, 18*8, tempstr);
-
- bonus=(s32int)timeleft*PAR_AMOUNT+
- (PERCENT100AMT*(kr==100))+
- (PERCENT100AMT*(sr==100))+
- (PERCENT100AMT*(tr==100));
-
- givep(bonus);
- ltoa(bonus,tempstr,10);
- x=36-strlen(tempstr)*2;
- pictxt(x*8, 7*8, tempstr);
-
- //
- // SAVE RATIO INFORMATION FOR ENDGAME
- //
- LevelRatios[mapon].kill=kr;
- LevelRatios[mapon].secret=sr;
- LevelRatios[mapon].treasure=tr;
- LevelRatios[mapon].time=min*60+sec;
- }
- else
- {
-#ifdef SPEAR
-#ifndef SPEARDEMO
- switch(mapon)
- {
- case 4: pictxt(14*8, 4*8, " TRANS\n GROSSE\nDEFEATED!"); break;
- case 9: pictxt(14*8, 4*8, "BARNACLE\nWILHELM\nDEFEATED!"); break;
- case 15: pictxt(14*8, 4*8, "UBERMUTANT\nDEFEATED!"); break;
- case 17: pictxt(14*8, 4*8, " DEATH\n KNIGHT\nDEFEATED!"); break;
- case 18: pictxt(13*8, 4*8, "SECRET TUNNEL\n AREA\n COMPLETED!"); break;
- case 19: pictxt(13*8, 4*8, "SECRET CASTLE\n AREA\n COMPLETED!"); break;
- }
-#endif
-#else
- pictxt(14*8, 4*8, "SECRET FLOOR\n COMPLETED!");
-#endif
-
- pictxt(10*8, 16*8, "15000 BONUS!");
-
- VW_UpdateScreen();
- VW_FadeIn();
-
- givep(15000);
- }
-
-
- hudp();
- VW_UpdateScreen();
-
- TimeCount=0;
- IN_StartAck();
- while(!IN_CheckAck())
- BJ_Breathe();
-
-//
-// done
-//
-#ifdef SPEARDEMO
- if (gamestate.mapon == 1)
- {
- sfx (S1up);
- Message ("This concludes your demo\n"
- "of Spear of Destiny! Now,\n"
- "go to your local software\n"
- "store and buy it!");
-
- IN_ClearKeysDown();
- IN_Ack();
- }
-#endif
-
- VW_FadeOut ();
- temp = bufferofs;
- for (i=0;i<3;i++)
- {
- bufferofs = screenloc[i];
- DrawPlayBorder ();
- }
- bufferofs = temp;
-}
-
-
-
-//==========================================================================
-
-
-/*
-=================
-=
-= PreloadGraphics
-=
-= Fill the cache up
-=
-=================
-*/
-
-int PreloadUpdate(u16int current, u16int total)
-{
- u16int w = WindowW - 10;
-
-
- VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w,2,BLACK);
- w = ((s32int)w * current) / total;
- if (w)
- {
- VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w,2,0x37); //SECONDCOLOR);
- VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w-1,1,0x32);
-
- }
- VW_UpdateScreen();
- return false;
-}
-
-void PreloadGraphics(void)
-{
- hudm ();
- ClearSplitVWB (); // set up for double buffering in split screen
-
- VWB_Bar (0,0,320,200-STATUSLINES,127);
-
- LatchDrawPic (20-14,80-3*8,Ppsyched);
-
- WindowX = 160-14*8;
- WindowY = 80-3*8;
- WindowW = 28*8;
- WindowH = 48;
- VW_UpdateScreen();
- VW_FadeIn ();
-
- PM_Preload (PreloadUpdate);
- IN_UserInput (70);
- VW_FadeOut ();
-
- DrawPlayBorder ();
- VW_UpdateScreen ();
-}
-
void CheckHighScore (s32int score,u16int other)
{
u16int i,j;
@@ -867,5 +75,4 @@
IN_ClearKeysDown ();
IN_UserInput(500);
}
-
}
--- a/main.c
+++ b/main.c
@@ -1,17 +1,8 @@
-char str[80],str2[20];
-s16int tedlevelnum;
-int tedlevel;
-s16int dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,
- 5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};
-
-u16int screenofs;
-
int startgame;
s16int mouseadjustment;
char configname[13]="CONFIG.";
-
void ReadConfig(void)
{
s16int file;
@@ -61,7 +52,6 @@
mouseenabled = false;
MainMenu[6].active=1;
- MainItems.curpos=0;
}
else
{
@@ -132,11 +122,6 @@
}
}
-void NewGame (s16int difficulty,s16int episode)
-{
- → initg, w/o difficulty, map
-}
-
void DiskFlopAnim(s16int x,s16int y)
{
static char which=0;
@@ -368,123 +353,12 @@
return true;
}
-void SetupWalls (void) /* map tile values to scaled pics */
-{
- s16int i;
-
- for (i=1;i<MAXWALLTILES;i++)
- {
- horizwall[i]=(i-1)*2;
- vertwall[i]=(i-1)*2+1;
- }
-}
-
-#define PORTTILESHIGH 13 // non displayed port of this size
-
-void InitGame (void)
-{
- s16int i,x,y;
- u16int *blockstart;
-
- mapon = -1;
-
- for (i=0;i<MAPSIZE;i++)
- {
- farmapylookup[i] = i*64;
- }
-
- for (i=0;i<PORTTILESHIGH;i++)
- uwidthtable[i] = UPDATEWIDE*i;
-
- blockstart = &blockstarts[0];
- for (y=0;y<UPDATEHIGH;y++)
- for (x=0;x<UPDATEWIDE;x++)
- *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;
-
- updateptr = &update[0];
-
- bufferofs = 0;
- displayofs = 0;
- ReadConfig ();
-
- IntroScreen ();
-
- LoadLatchMem ();
- SetupWalls ();
-
- NewViewSize (vw.size);
-
- InitRedShifts ();
-
- displayofs = PAGE1START;
- bufferofs = PAGE2START;
-}
-
-int SetViewSize (u16int width, u16int height)
-{
- → setvw()
-}
-
-void ShowViewSize (s16int width)
-{
- s16int oldwidth,oldheight;
-
- oldwidth = vw.dx;
- oldheight = vw.dy;
-
- vw.dx = width*16;
- vw.dy = width*16*HEIGHTRATIO;
- DrawPlayBorder ();
-
- vw.dy = oldheight;
- vw.dx = oldwidth;
-}
-
-void NewViewSize (s16int width)
-{
- vw.size = width;
- SetViewSize (width*16,width*16*HEIGHTRATIO);
-}
-
void DemoLoop (void)
{
- static s16int LastDemo;
- s16int i,level;
- s32int nsize;
- uchar *nullblock;
-
-//
-// check for launch from ted
-//
- /* → if warping to map [tedlevel] */
- if (tedlevel)
- {
- NoWait = true;
- NewGame(1,0);
-
- /* → set difficulty level 1-4 if parameter passed as
- * gamestate.difficulty */
-
-#ifndef SPEAR
- gamestate.episode = tedlevelnum/10;
- gamestate.mapon = tedlevelnum%10;
-#else
- gamestate.episode = 0;
- gamestate.mapon = tedlevelnum;
-#endif
- GameLoop();
- Quit (NULL);
- }
-
- StartCPMusic(INTROSONG);
- // pg13
-
while (1)
{
- p = dems;
while (!NoWait)
{
- /* title loop */
PlayDemo(p++);
if(p >= epis)
p = dems;
@@ -492,13 +366,11 @@
break;
StartCPMusic(INTROSONG);
}
-
VW_FadeOut ();
if (Keyboard[sc_Tab] && debug)
RecordDemo ();
else
US_ControlPanel (0);
-
if (startgame || gm.load)
{
GameLoop ();
@@ -507,25 +379,3 @@
}
}
}
-
-void main (void)
-{
- if (wl6)
- {
- NewEmenu[2].active =
- NewEmenu[4].active =
- NewEmenu[6].active =
- NewEmenu[8].active =
- NewEmenu[10].active =
- EpisodeSelect[1] =
- EpisodeSelect[2] =
- EpisodeSelect[3] =
- EpisodeSelect[4] =
- EpisodeSelect[5] = 1;
- }
-
- InitGame ();
-
- DemoLoop();
-}
-
--- a/man/1/wl3d
+++ b/man/1/wl3d
@@ -13,10 +13,7 @@
.I datadir
] [
.B -w
-.I map
-] [
-.B -x
-.I 1-4
+.I map 0-3
]
.SH DESCRIPTION
.I Wl3d
@@ -34,7 +31,7 @@
.RE
.PP
The command line options are:
-.TP \w'\fLf\ \ \ \fIdemo'u
+.TP \w'\fLw\ \ \fI"map\ 0-3"'u
.B -2
Set game version to Spear of Destiny Mission 2: Return to Danger.
.TP
@@ -62,11 +59,8 @@
.B -s
Set game version to Spear of Destiny 1.0 retail.
.TP
-.BI -w\ map
-Warp to the given map number on startup.
-.TP
-.BI -x\ 1-4
-Set default game difficulty.
+.BI -w\ "map 0-3"
+Warp to the given map number with a given difficulty on startup.
.PD
.PP
.I Wl3d
@@ -103,10 +97,10 @@
.B -w
parameter is used, the game starts immediately at map number
.IR map ,
-and
-.B -x
-optionally sets the game difficulty to 1-4, from easiest to hardest,
-the default being 2.
+with difficulty set to
+.BR 0-3 ,
+.B 0
+being the easiest.
The
.B -p
parameter runs the program at the fastest speed possible for testing purposes.
@@ -138,9 +132,9 @@
.L sd2
and
.L sd3
-versions are the same as
-.L sod
-with the exception of substituting some of the data files.
+versions are variants of
+.LR sod ,
+only substituting some of the data files.
.PD
.SS Demo lumps
.I Wl3d
@@ -172,21 +166,30 @@
Most of
.I wl3d
has been rewritten from scratch, and some parts have been implemented differently from the reference.
-Most importantly, individual data lumps are no longer read and cached as needed, but rather all loaded into memory, uncompressed, and in some cases converted, at startup.
-This bumps the required amount of free memory up to around at least 5 megabytes, depending on the game version, architecture and window size.
-In addition, a single executable handles all supported game versions.
+Most importantly, individual data lumps are no longer read and cached as needed,
+but rather all loaded into memory, uncompressed, and in some cases converted,
+at startup.
+This bumps the required amount of free memory up to around at least 5 megabytes,
+depending on the game version, architecture and window size.
.PP
-Intro screens are now additional data files to be loaded on start up, rather than being compiled in, and must therefore be installed in the
+A single executable handles all supported game versions.
+.PP
+Intro screens are now additional data files to be loaded on startup,
+rather than being compiled in, and must therefore be installed in the
.IR datadir .
-Also unlike the reference implementation, these are displayed during data file loading, and are immediately faded out of afterwards.
+Also unlike the reference implementation,
+these are displayed during data file loading,
+and are immediately faded out of afterwards.
.PP
Copy protection code and the Spear of Destiny Jukebox have been excised.
-.PP
Menus are implemented differently, and some have been altered in functionality.
+Debug mode has been removed, and cheats work differently.
.PP
-Game keys are no longer set in the options menu, but rather in the config file.
-A single global configuration file is used, rather than a version dependent one.
-Also, while savegames are in a compatible format, config files are not.
+Game keys are no longer set in the options menu, but rather in the configuration file.
+A single configuration file is used for all game versions.
+Savegames and config files are incompatible in format.
+.PP
+The texture and sprite scaling implementation does not attempt to save memory and avoids quantization at close range.
.SH FILES
.TF /sys/games/lib/wl3d/intro.wl6
.TP
@@ -213,13 +216,14 @@
.SM OPL2
emulation, Adlib sound effects crack too much during playback.
.PP
+The upsampling implementation for digital sound effects is overkill given the number of constraints.
+It is also buggy and playback cracks too much.
+.PP
With sound effects enabled, the
.SM OPL2
emulation runs on every frame and
.L /dev/audio
is written to, even when no sound is playing.
-.PP
-The upsampling implementation for digital sound effects is overkill given the number of constraints.
.PP
Little is done in case the program is unable to run at a framerate of 70 Hz.
.PD
--- a/man/6/wl3d
+++ b/man/6/wl3d
@@ -9,36 +9,39 @@
.TP
.B audiohed
PC Speaker, Adlib, digital effects and music offsets in
-.B audiot
+.BR audiot .
.TP
.B audiot
-uncompressed PC Speaker, Adlib, digital effects and music lumps
+Uncompressed PC Speaker, Adlib, digital effects and music lumps.
.TP
.B config
-saved game settings and highscores
+Saved game settings and highscores.
.TP
.B gamemaps
-maps lump
+Map lumps.
.TP
.B maphead
-map offsets in
-.B gamemaps
+Map offsets in
+.BR gamemaps .
.TP
+.B savegam?
+Saved games.
+.TP
.B vgadict
-huffman dictionary for lumps contained in
-.B vgagraph
+Huffman dictionary for lumps contained in
+.BR vgagraph .
.TP
.B vgagraph
-fonts, pictures, tiles and screens, encoded for
+Fonts, pictures, tiles and screens, encoded for
.SM VGA
-graphics cards
+graphics cards.
.TP
.B vgahead
-graphics offsets in
-.B vgagraph
+Graphics offsets in
+.BR vgagraph .
.TP
.B vswap
-wall textures, sprites and raw pcm audio
+Wall textures, sprites and raw pcm audio.
.PD
.PP
Integers are stored in little-endian byte order.
@@ -64,7 +67,7 @@
for Spear of Destiny 1.0 demo and
.B sod
for Spear of Destiny 1.0 retail (including mission packs).
-Other versions are outside of the scope of this document.
+Other versions are outside the scope of this document.
.SH SOUND EFFECTS AND MUSIC
.SS Audiohed
.RS
@@ -128,8 +131,8 @@
format.
Each sound effect has a PC Speaker, Adlib and digital version.
.PP
-Each types of lump is stored in a specific format detailed below.
-No digital sounds are ever stored in
+Each type of lump is stored in a specific format detailed below.
+No digital sound is ever stored in
.BR audiot ,
having raw pcm lumps in
.B vswap
@@ -193,13 +196,13 @@
.I priority
is lower than the new one, it is interrupted, then substituted.
.PP
-At the end of playback, the engine resets the values of the instrument registers and writes a zero to registers
-.L 0xb0
-and
-.LR 0xc0 .
+At the end of playback, the engine resets the values of the instrument registers and writes a zero to register
+.LR 0xb0 .
.PP
.I Ignored
-contains 6 fields only used by Muse.
+contains 1 byte intended to be written to register
+.LR 0xc0 ,
+but never is, then 5 fields only used by Muse.
.I Tag
is a variable-length field suffixed by Muse and is also ignored.
.SS Digital sound effect
@@ -301,10 +304,14 @@
Maps are decomposed into three planes.
.B Gamemaps
holds an array of map headers, followed by doubly-compressed plane data.
-.IR Pls and pll
+.I Pls
+and
+.I pll
are respectively arrays of offsets and lengths for each plane.
Only the first two planes are ever used.
-.IR dx and dy
+.I dx
+and
+.I dy
are the planes' dimensions, and must both be 64.
.I Name
is an unused unterminated
@@ -312,11 +319,31 @@
string.
.I Planes
stores contiguously each plane's data.
-.SS Compression
+.PP
+The first plane is an array of [words].
+.PP
+The second plane is an array of [other words].
+.PP
+There are static limits for objects on the map:
+.TF "static objects"
+.TP
+.B actors
+150 (including the player)
+.TP
+.B doors
+64
+.TP
+.B static objects
+399
+.SS RLEW Compression
Each map plane is first compressed using
.SM RLEW,
then further using what is eponymously refered to as
.SM Carmack compression.
+.PP
+[words]
+.SS Carmack Compression
+[words]
.SH GRAPHICS
Graphics are either static data loaded in the executable, or huffman-compressed lumps contained in
.BR vgagraph .
@@ -420,13 +447,14 @@
.SM VGA
color planes rather than contiguously.
.SS Tiles
-Tiles used in Wolfenstein 3-D are exclusively of size 8x8, and thus stored as arrays of 64 bytes.
+These tiles are exclusively of size 8x8, and thus stored as arrays of 64 bytes.
All tiles are stored contiguously in a single lump following the last pic lump.
Their number is version dependent, but only the first 8 tiles are ever used.
.PP
-The tile lumps in Wolfenstein 3-D and Spear of Destiny versions all decode incorrectly and result in reads past the allocated buffer (or past the end of the lump).
+This lump decodes incorrectly in all game versions
+and results in reads past the allocated buffer (or past the end of the lump).
.IR Wl3d (1)
-skips this lump entirely.
+skips it entirely.
.SS Screens and demos
.RS
.IR misc [ ns ][]
@@ -535,6 +563,7 @@
for file offsets, and
.IR sz ,
for lengths in bytes.
+.PP
A chunk of size 0 is skipped.
This is permitted when the specific lump is never referenced,
which can occur in the
@@ -550,12 +579,15 @@
Because they are drawn vertically, they are stored as an array of coloumns.
In other words, if drawn as is using a given palette,
the tile would appear rotated by -90° then flipped along its vertical axis.
-The last 8 wall textures are door textures.
+The last 8 wall textures are used for doors.
.SS Sprites
.RS
.IR lx [2]
.IR rx [2]
.IR cofs [ rx-lx+1 ][2]
+.IR pad []
+.IR cmd []
+.IR pad []
.IR data []
.br
.BR cmd :
@@ -574,15 +606,19 @@
and must respect the following restrictions:
.PP
.RS
-.I lx ∈ {0,1,...,63}
+.BR lx \ ∈\ {0,1,...,63}
.br
-.I rx ∈ {32,33,...,63}
+.BR rx \ ∈\ {32,33,...,63}
.br
-.I lx ≤ rx
+.BR lx \ ≤\ rx
.RE
.PP
Sprites are drawn centered on the 32nd coloumn.
A left bound equal to or greater than 32 will offset the sprite to the right.
+Because of a bug in the original
+.SM DOS
+binaries, such a left bound results in reads past the lump
+and excess pixels may show up as garbage on the screen.
.PP
The following variable-length array,
.IR cofs ,
@@ -595,7 +631,7 @@
.I se / 2
are, respectively, an upper and lower bound,
defining a contiguous vertical strip of pixels to draw within a coloumn, with
-.I po + ss
+.I po + ss / 2
an offset into the sprite lump pointing to the strip's palette indices.
The
.I cmd
@@ -654,6 +690,8 @@
pcm lump,
as indicated in the pcm table.
.SH "CONFIGURATION FILE AND HIGHSCORES"
+[words]
+.SH "SAVED GAMES"
[words]
.SH "SEE ALSO"
.IR opl2 (1) ,
--- a/map.c
+++ b/map.c
@@ -24,7 +24,7 @@
Rblock, Rblock, Rgibs, Rblock, Rblock, Rnil, Rnil, Rnil, Rnil,
Rblock, Rblock, Rnil, Rclip2, Rammobox, Rblock, Rspear, Rclip2
};
-static Obj opool[Nobj];
+static Obj opool[Nobj+2];
static void
spawnstc(Tile *tl, int n)
@@ -50,7 +50,7 @@
case Rcrown:
case R1up:
if(!gm.load)
- gm.ntreasure++;
+ gm.ttot++;
/* wet floor */
default:
stce->f = OFbonus;
@@ -427,7 +427,7 @@
o->θ = θE;
o->f |= OFambush;
if(!gm.load)
- gm.nkills++;
+ gm.ktot++;
}
static void
@@ -485,6 +485,7 @@
θ = θS;
goto wlonly;
case Ofake:
+ /* bug? */
stt[GShitlerdie2].dt = pcmon ? 140 : 5;
s = stt+GSfake;
hp = 200 + 100 * gm.difc;
@@ -538,7 +539,7 @@
o->θ = θ;
o->f |= OFshootable | OFambush;
if(!gm.load)
- gm.nkills++;
+ gm.ktot++;
}
static void
@@ -605,7 +606,7 @@
o->θ = dir * 90;
if(!gm.load)
- gm.nkills++;
+ gm.ktot++;
if(patrol){
o->Δr = Dtlglobal;
o->on++;
@@ -622,7 +623,7 @@
int n, difc;
n = tl->p1;
- difc = GDeasy;
+ difc = GDbaby;
switch(n){
case 19: case 20: case 21: case 22:
spawnplr(tl, n-19);
@@ -638,64 +639,64 @@
break;
case 98:
if(!gm.load)
- gm.nsecret++;
+ gm.stot++;
break;
case 180: case 181: case 182: case 183: difc++; n-=36; /* wet floor */
- case 144: case 145: case 146: case 147: difc++; n-=36; /* wet floor */
+ case 144: case 145: case 146: case 147: difc+=2; n-=36; /* wet floor */
case 108: case 109: case 110: case 111:
if(difc <= gm.difc)
spawnguy(tl, Ogd, n-108, 0);
break;
case 184: case 185: case 186: case 187: difc++; n-=36; /* wet floor */
- case 148: case 149: case 150: case 151: difc++; n-=36; /* wet floor */
+ case 148: case 149: case 150: case 151: difc+=2; n-=36; /* wet floor */
case 112: case 113: case 114: case 115:
if(difc <= gm.difc)
spawnguy(tl, Ogd, n-112, 1);
break;
case 188: case 189: case 190: case 191: difc++; n-=36; /* wet floor */
- case 152: case 153: case 154: case 155: difc++; n-=36; /* wet floor */
+ case 152: case 153: case 154: case 155: difc+=2; n-=36; /* wet floor */
case 116: case 117: case 118: case 119:
if(difc <= gm.difc)
spawnguy(tl, Oofc, n-116, 0);
break;
case 192: case 193: case 194: case 195: difc++; n-=36; /* wet floor */
- case 156: case 157: case 158: case 159: difc++; n-=36; /* wet floor */
+ case 156: case 157: case 158: case 159: difc+=2; n-=36; /* wet floor */
case 120: case 121: case 122: case 123:
if(difc <= gm.difc)
spawnguy(tl, Oofc, n-120, 1);
break;
case 198: case 199: case 200: case 201: difc++; n-=36; /* wet floor */
- case 162: case 163: case 164: case 165: difc++; n-=36; /* wet floor */
+ case 162: case 163: case 164: case 165: difc+=2; n-=36; /* wet floor */
case 126: case 127: case 128: case 129:
if(difc <= gm.difc)
spawnguy(tl, Oss, n-126, 0);
break;
case 202: case 203: case 204: case 205: difc++; n-=36; /* wet floor */
- case 166: case 167: case 168: case 169: difc++; n-=36; /* wet floor */
+ case 166: case 167: case 168: case 169: difc+=2; n-=36; /* wet floor */
case 130: case 131: case 132: case 133:
if(difc <= gm.difc)
spawnguy(tl, Oss, n-130, 1);
break;
case 206: case 207: case 208: case 209: difc++; n-=36; /* wet floor */
- case 170: case 171: case 172: case 173: difc++; n-=36; /* wet floor */
+ case 170: case 171: case 172: case 173: difc+=2; n-=36; /* wet floor */
case 134: case 135: case 136: case 137:
if(difc <= gm.difc)
spawnguy(tl, Odog, n-134, 0);
break;
case 210: case 211: case 212: case 213: difc++; n-=36; /* wet floor */
- case 174: case 175: case 176: case 177: difc++; n-=36; /* wet floor */
+ case 174: case 175: case 176: case 177: difc+=2; n-=36; /* wet floor */
case 138: case 139: case 140: case 141:
if(difc <= gm.difc)
spawnguy(tl, Odog, n-138, 1);
break;
case 252: case 253: case 254: case 255: difc++; n-=18; /* wet floor */
- case 234: case 235: case 236: case 237: difc++; n-=18; /* wet floor */
+ case 234: case 235: case 236: case 237: difc+=2; n-=18; /* wet floor */
case 216: case 217: case 218: case 219:
if(difc <= gm.difc)
spawnguy(tl, Omut, n-216, 0);
break;
case 256: case 257: case 258: case 259: difc++; n-=18; /* wet floor */
- case 238: case 239: case 240: case 241: difc++; n-=18; /* wet floor */
+ case 238: case 239: case 240: case 241: difc+=2; n-=18; /* wet floor */
case 220: case 221: case 222: case 223:
if(difc <= gm.difc)
spawnguy(tl, Omut, n-220, 1);
@@ -812,7 +813,14 @@
o->ty = (tl-tiles) / Mapdxy;
osetglobal(o);
o->areaid = tl->p0 - MTfloor;
- o->tc = s->dt != 0 ? rnd() % s->dt : 0;
+ if(s->dt != 0){
+ o->tc = rnd() % s->dt;
+ /* bug: if .tc is 0, uobj won't update its state on its own,
+ * and moving objects randomly won't change their sprite */
+ if(!gm.record && !gm.demo && o->tc == 0)
+ o->tc = 1;
+ }else
+ o->tc = 0;
return o;
}
--- a/menu.c
+++ b/menu.c
@@ -1,227 +1,11 @@
-void CP_ReadThis(void);
-
-#define STARTITEM newgame
-
-#define ENDGAMESTR "Are you sure you want\nto end the game you\nare playing? (Y or N):"
-#define GAMESVD "There's already a game\nsaved at this position.\n Overwrite?"
-#define CURGAME "You are currently in\na game. Continuing will\nerase old game. Ok?"
-
-char far endStrings[9][80]=
-{
-#ifndef SPEAR
- {"Dost thou wish to\nleave with such hasty\nabandon?"},
- {"Chickening out...\nalready?"},
- {"Press N for more carnage.\nPress Y to be a weenie."},
- {"So, you think you can\nquit this easily, huh?"},
- {"Press N to save the world.\nPress Y to abandon it in\nits hour of need."},
- {"Press N if you are brave.\nPress Y to cower in shame."},
- {"Heroes, press N.\nWimps, press Y."},
- {"You are at an intersection.\nA sign says, 'Press Y to quit.'\n>"},
- {"For guns and glory, press N.\nFor work and worry, press Y."}
-#else
- "Heroes don't quit, but\ngo ahead and press Y\nif you aren't one.",
- "Press Y to quit,\nor press N to enjoy\nmore violent diversion.",
- "Depressing the Y key means\nyou must return to the\nhumdrum workday world.",
- "Hey, quit or play,\nY or N:\nit's your choice.",
- "Sure you don't want to\nwaste a few more\nproductive hours?",
- "I think you had better\nplay some more. Please\npress N...please?",
- "If you are tough, press N.\nIf not, press Y daintily.",
- "I'm thinkin' that\nyou might wanna press N\nto play more. You do it.",
- "Sure. Fine. Quit.\nSee if we care.\nGet it over with.\nPress Y."
-
-#endif
-};
-
-CP_iteminfo
- MainItems={MENU_X,MENU_Y,10,STARTITEM,24},
- SndItems={SM_X,SM_Y1,12,0,52},
- LSItems={LSM_X,LSM_Y,10,0,24},
- CtlItems={CTL_X,CTL_Y,6,-1,56},
- CusItems={8,CST_Y+13*2,9,-1,0},
- NewEitems={NE_X,NE_Y,11,0,88},
- NewItems={NM_X,NM_Y,4,2,24};
-
-#pragma warn -sus
-CP_itemtype far
-MainMenu[]=
-{
- {1,"New Game",CP_NewGame},
- {1,"Sound",CP_Sound},
- {1,"Control",CP_Control},
- {1,"Load Game",CP_LoadGame},
- {0,"Save Game",CP_SaveGame},
- {1,"Change View",CP_ChangeView},
-#ifndef SPEAR
- {2,"Read This!",CP_ReadThis},
-#endif
- {1,"View Scores",CP_ViewScores},
- {1,"Back to Demo",0},
- {1,"Quit",0}
-},
-
-far SndMenu[]=
-{
- {1,"None",0},
- {1,"PC Speaker",0},
- {1,"AdLib/Sound Blaster",0},
- {0,"",0},
- {0,"",0},
- {1,"None",0},
- {1,"Disney Sound Source",0},
- {1,"Sound Blaster",0},
- {0,"",0},
- {0,"",0},
- {1,"None",0},
- {1,"AdLib/Sound Blaster",0}
-},
-
-far CtlMenu[]=
-{
- {0,"Mouse Enabled",0},
- {0,"Joystick Enabled",0},
- {0,"Use joystick port 2",0},
- {0,"Gravis GamePad Enabled",0},
- {0,"Mouse Sensitivity",MouseSensitivity},
- {1,"Customize controls",CustomControls}
-},
-
-#pragma warn +sus
-
-#ifndef SPEAR
-far NewEmenu[]=
-{
- {1,"Episode 1\n"
- "Escape from Wolfenstein",0},
- {0,"",0},
- {3,"Episode 2\n"
- "Operation: Eisenfaust",0},
- {0,"",0},
- {3,"Episode 3\n"
- "Die, Fuhrer, Die!",0},
- {0,"",0},
- {3,"Episode 4\n"
- "A Dark Secret",0},
- {0,"",0},
- {3,"Episode 5\n"
- "Trail of the Madman",0},
- {0,"",0},
- {3,"Episode 6\n"
- "Confrontation",0}
-},
-#endif
-
-
-far NewMenu[]=
-{
- {1,"Can I play, Daddy?",0},
- {1,"Don't hurt me.",0},
- {1,"Bring 'em on!",0},
- {1,"I am Death incarnate!",0}
-},
-
-far LSMenu[]=
-{
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0},
- {1,"",0}
-},
-
-far CusMenu[]=
-{
- {1,"",0},
- {0,"",0},
- {0,"",0},
- {1,"",0},
- {0,"",0},
- {0,"",0},
- {1,"",0},
- {0,"",0},
- {1,"",0}
-}
-;
-
-
-s16int color_hlite[]={
- DEACTIVE,
- HIGHLIGHT,
- READHCOLOR,
- 0x67
- },
-
- color_norml[]={
- DEACTIVE,
- TEXTCOLOR,
- READCOLOR,
- 0x6b
- };
-
-s16int EpisodeSelect[6]={1};
-
-
s16int SaveGamesAvail[10],StartGame,SoundStatus=1,pickquick;
char SaveGameNames[10][32],SaveName[13]="SAVEGAM?.";
-
-////////////////////////////////////////////////////////////////////
-//
-// INPUT MANAGER SCANCODE TABLES
-//
-////////////////////////////////////////////////////////////////////
-static u8int
- *ScanNames[] = // Scan code names with single chars
- {
- "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
- "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",
- "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",
- "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",
- "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
- }, // DEBUG - consolidate these
- far ExtScanCodes[] = // Scan codes with >1 char names
- {
- 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,
- 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,
- 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,
- 0x50,0x4b,0x4d,0x00
- },
- *ExtScanNames[] = // Names corresponding to ExtScanCodes
- {
- "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",
- "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",
- "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
- "Down","Left","Right",""
- };
-
-
-////////////////////////////////////////////////////////////////////
-//
-// Wolfenstein Control Panel! Ta Da!
-//
-////////////////////////////////////////////////////////////////////
void US_ControlPanel(u8int scancode)
{
- s16int which,i,start;
-
-
if (ingame)
if (CP_CheckQuick(scancode))
return;
-
- StartCPMusic(MENUSONG);
- SetupControlPanel();
-
- //
- // F-KEYS FROM WITHIN GAME
- //
switch(scancode)
{
case sc_F1:
@@ -251,145 +35,10 @@
goto finishup;
finishup:
- CleanupControlPanel();
return;
}
-
- DrawMainMenu();
- MenuFadeIn();
- StartGame=0;
-
- //
- // MAIN MENU LOOP
- //
- do
- {
- which=HandleMenu(&MainItems,&MainMenu[0],NULL);
-
- #ifdef SPEAR
- #ifndef SPEARDEMO
- //
- // EASTER EGG FOR SPEAR OF DESTINY!
- //
- if (Keyboard[sc_I] && Keyboard[sc_D])
- {
- VW_FadeOut();
- StartCPMusic (18);
- MM_SortMem ();
- ClearMemory ();
-
- VWB_DrawPic(0,0,Pid1);
- VWB_DrawPic(0,80,Pid2);
-
- VW_UpdateScreen();
-
- VL_FadeIn(0,255,Eid,30); /* sod only */
-
- while (Keyboard[sc_I] || Keyboard[sc_D]);
- IN_ClearKeysDown();
- IN_Ack();
-
- VW_FadeOut();
-
- DrawMainMenu();
- StartCPMusic (MENUSONG);
- MenuFadeIn();
- }
- #endif
- #endif
-
- switch(which)
- {
- case viewscores:
- if (MainMenu[viewscores].routine == NULL)
- if (CP_EndGame())
- StartGame=1;
-
- DrawMainMenu();
- MenuFadeIn();
- break;
-
- case backtodemo:
- MM_SortMem();
- StartGame=1;
- if (!ingame)
- StartCPMusic(INTROSONG);
- VL_FadeOut(0,255,0,0,0,10);
- break;
-
- case -1:
- case quit:
- CP_Quit();
- break;
-
- default:
- if (!StartGame)
- {
- DrawMainMenu();
- MenuFadeIn();
- }
- }
-
- //
- // "EXIT OPTIONS" OR "NEW GAME" EXITS
- //
- } while(!StartGame);
-
- //
- // DEALLOCATE EVERYTHING
- //
- CleanupControlPanel();
-
- //
- // CHANGE MAINMENU ITEM
- //
- if (startgame || gm.load)
- {
- #pragma warn -sus
- MainMenu[viewscores].routine = NULL;
- _fstrcpy(MainMenu[viewscores].string,"End Game");
- #pragma warn +sus
- }
}
-
-////////////////////////
-//
-// DRAW MAIN MENU SCREEN
-//
-void DrawMainMenu(void)
-{
- ClearMScreen();
-
- VWB_DrawPic(112,184,Pmouselback);
- DrawStripes(10);
- VWB_DrawPic(84,0,Popt);
-
- DrawWindow(MENU_X-8,MENU_Y-3,MENU_W,MENU_H,BKGDCOLOR);
-
- //
- // CHANGE "GAME" AND "DEMO"
- //
- if (ingame)
- {
- _fstrcpy(&MainMenu[backtodemo].string[8],"Game");
- MainMenu[backtodemo].active=2;
- }
- else
- {
- _fstrcpy(&MainMenu[backtodemo].string[8],"Demo");
- MainMenu[backtodemo].active=1;
- }
-
- DrawMenu(&MainItems,&MainMenu[0]);
- VW_UpdateScreen();
-}
-
-////////////////////////////////////////////////////////////////////
-//
-// READ THIS!
-//
-////////////////////////////////////////////////////////////////////
void CP_ReadThis(void)
{
StartCPMusic(0);
@@ -397,11 +46,6 @@
StartCPMusic(MENUSONG);
}
-////////////////////////////////////////////////////////////////////
-//
-// CHECK QUICK-KEYS & QUIT (WHILE IN A GAME)
-//
-////////////////////////////////////////////////////////////////////
s16int CP_CheckQuick(u16int scancode)
{
switch(scancode)
@@ -513,99 +157,11 @@
PM_CheckMainMem ();
}
return 1;
-
- //
- // QUIT
- //
- case sc_F10:
- CA_CacheGrChunk(STARTFONT+1);
-
- WindowX=WindowY=0;
- WindowW=320;
- WindowH=160;
- if (Confirm(endStrings[rnd()&0x7+(rnd()&1)]))
- {
- s16int i;
-
-
- VW_UpdateScreen();
- SD_MusicOff();
- SD_StopSound();
- MenuFadeOut();
-
- //
- // SHUT-UP THE ADLIB
- //
- for (i=1;i<=0xf5;i++)
- alOut(i,0);
- Quit(NULL);
- }
-
- DrawAllPlayBorder();
- WindowH=200;
- fontnumber=0;
- return 1;
}
return 0;
}
-
-////////////////////////////////////////////////////////////////////
-//
-// END THE CURRENT GAME
-//
-////////////////////////////////////////////////////////////////////
-s16int CP_EndGame(void)
-{
- if (!Confirm(ENDGAMESTR))
- return 0;
-
- pickquick = gamestate.lives = 0;
- gm.φ = ex_died;
-
- #pragma warn -sus
- MainMenu[savegame].active = 0;
- MainMenu[viewscores].routine=CP_ViewScores;
- _fstrcpy(MainMenu[viewscores].string,"View Scores");
- #pragma warn +sus
-
- return 1;
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// VIEW THE HIGH SCORES
-//
-////////////////////////////////////////////////////////////////////
-void CP_ViewScores(void)
-{
- fontnumber=0;
-
-#ifdef SPEAR
- StartCPMusic (20);
-#else
- StartCPMusic (23);
-#endif
-
- DrawHighScores ();
- VW_UpdateScreen ();
- MenuFadeIn();
- fontnumber=1;
-
- IN_Ack();
-
- StartCPMusic(MENUSONG);
- MenuFadeOut();
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// START A NEW GAME
-//
-////////////////////////////////////////////////////////////////////
void CP_NewGame(void)
{
s16int which,episode;
@@ -703,267 +259,6 @@
pickquick = 0;
}
-
-#ifndef SPEAR
-/////////////////////
-//
-// DRAW NEW EPISODE MENU
-//
-void DrawNewEpisode(void)
-{
- s16int i;
-
- ClearMScreen();
- VWB_DrawPic(112,184,Pmouselback);
-
- DrawWindow(NE_X-4,NE_Y-4,NE_W+8,NE_H+8,BKGDCOLOR);
- SETFONTCOLOR(READHCOLOR,BKGDCOLOR);
- PrintY=2;
- WindowX=0;
- US_CPrint("Which episode to play?");
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- DrawMenu(&NewEitems,&NewEmenu[0]);
-
- for (i=0;i<6;i++)
- VWB_DrawPic(NE_X+32,NE_Y+i*26,Pep1+i);
-
- VW_UpdateScreen();
- MenuFadeIn();
- WaitKeyUp();
-}
-#endif
-
-/////////////////////
-//
-// DRAW NEW GAME MENU
-//
-void DrawNewGame(void)
-{
- ClearMScreen();
- VWB_DrawPic(112,184,Pmouselback);
-
- SETFONTCOLOR(READHCOLOR,BKGDCOLOR);
- PrintX=NM_X+20;
- PrintY=NM_Y-32;
-
-#ifndef SPEAR
- US_Print("How tough are you?");
-#else
- VWB_DrawPic (PrintX,PrintY,Pdiffc);
-#endif
-
- DrawWindow(NM_X-5,NM_Y-10,NM_W,NM_H,BKGDCOLOR);
-
- DrawMenu(&NewItems,&NewMenu[0]);
- DrawNewGameDiff(NewItems.curpos);
- VW_UpdateScreen();
- MenuFadeIn();
- WaitKeyUp();
-}
-
-
-////////////////////////
-//
-// DRAW NEW GAME GRAPHIC
-//
-void DrawNewGameDiff(s16int w)
-{
- VWB_DrawPic(NM_X+185,NM_Y+7,w+Pbaby);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// HANDLE SOUND MENU
-//
-////////////////////////////////////////////////////////////////////
-void CP_Sound(void)
-{
- s16int which,i;
-
- DrawSoundMenu();
- MenuFadeIn();
- WaitKeyUp();
-
- do
- {
- which=HandleMenu(&SndItems,&SndMenu[0],NULL);
- //
- // HANDLE MENU CHOICES
- //
- switch(which)
- {
- //
- // SOUND EFFECTS
- //
- case 0:
- if (SoundMode!=sdm_Off)
- {
- SD_WaitSoundDone();
- SD_SetSoundMode(sdm_Off);
- DrawSoundMenu();
- }
- break;
- case 1:
- if (SoundMode!=sdm_PC)
- {
- SD_WaitSoundDone();
- SD_SetSoundMode(sdm_PC);
- CA_LoadAllSounds();
- DrawSoundMenu();
- ShootSnd();
- }
- break;
- case 2:
- if (SoundMode!=sdm_AdLib)
- {
- SD_WaitSoundDone();
- SD_SetSoundMode(sdm_AdLib);
- CA_LoadAllSounds();
- DrawSoundMenu();
- ShootSnd();
- }
- break;
-
- //
- // DIGITIZED SOUND
- //
- case 5:
- if (DigiMode!=sds_Off)
- {
- SD_SetDigiDevice(sds_Off);
- DrawSoundMenu();
- }
- break;
- case 6:
- if (DigiMode!=sds_SoundSource)
- {
- SD_SetDigiDevice(sds_SoundSource);
- DrawSoundMenu();
- ShootSnd();
- }
- break;
- case 7:
- if (DigiMode!=sds_SoundBlaster)
- {
- SD_SetDigiDevice(sds_SoundBlaster);
- DrawSoundMenu();
- ShootSnd();
- }
- break;
-
- //
- // MUSIC
- //
- case 10:
- if (MusicMode!=smm_Off)
- {
- SD_SetMusicMode(smm_Off);
- DrawSoundMenu();
- ShootSnd();
- }
- break;
- case 11:
- if (MusicMode!=smm_AdLib)
- {
- SD_SetMusicMode(smm_AdLib);
- DrawSoundMenu();
- ShootSnd();
- StartCPMusic(MENUSONG);
- }
- break;
- }
- } while(which>=0);
-
- MenuFadeOut();
-}
-
-
-//////////////////////
-//
-// DRAW THE SOUND MENU
-//
-void DrawSoundMenu(void)
-{
- s16int i,on;
-
- //
- // DRAW SOUND MENU
- //
- ClearMScreen();
- VWB_DrawPic(112,184,Pmouselback);
-
- DrawWindow(SM_X-8,SM_Y1-3,SM_W,SM_H1,BKGDCOLOR);
- DrawWindow(SM_X-8,SM_Y2-3,SM_W,SM_H2,BKGDCOLOR);
- DrawWindow(SM_X-8,SM_Y3-3,SM_W,SM_H3,BKGDCOLOR);
-
- //
- // IF NO ADLIB, NON-CHOOSENESS!
- //
- if (!AdLibPresent && !SoundBlasterPresent)
- {
- SndMenu[2].active=SndMenu[10].active=SndMenu[11].active=0;
- }
-
- if (!SoundSourcePresent)
- SndMenu[6].active=0;
-
- if (!SoundBlasterPresent)
- SndMenu[7].active=0;
-
- if (!SoundSourcePresent && !SoundBlasterPresent)
- SndMenu[5].active=0;
-
- DrawMenu(&SndItems,&SndMenu[0]);
- VWB_DrawPic(100,SM_Y1-20,Psfx);
- VWB_DrawPic(100,SM_Y2-20,Ppcm);
- VWB_DrawPic(100,SM_Y3-20,Pmus);
-
- for (i=0;i<SndItems.amount;i++)
- if (SndMenu[i].string[0])
- {
- //
- // DRAW SELECTED/NOT SELECTED GRAPHIC BUTTONS
- //
- on=0;
- switch(i)
- {
- //
- // SOUND EFFECTS
- //
- case 0: if (SoundMode==sdm_Off) on=1; break;
- case 1: if (SoundMode==sdm_PC) on=1; break;
- case 2: if (SoundMode==sdm_AdLib) on=1; break;
-
- //
- // DIGITIZED SOUND
- //
- case 5: if (DigiMode==sds_Off) on=1; break;
- case 6: if (DigiMode==sds_SoundSource) on=1; break;
- case 7: if (DigiMode==sds_SoundBlaster) on=1; break;
-
- //
- // MUSIC
- //
- case 10: if (MusicMode==smm_Off) on=1; break;
- case 11: if (MusicMode==smm_AdLib) on=1; break;
- }
-
- if (on)
- VWB_DrawPic(SM_X+24,SM_Y1+i*13+2,Psel);
- else
- VWB_DrawPic(SM_X+24,SM_Y1+i*13+2,Punsel);
- }
-
- DrawMenuGun(&SndItems);
- VW_UpdateScreen();
-}
-
-
-//
-// DRAW LOAD/SAVE IN PROGRESS
-//
void DrawLSAction(s16int which)
{
#define LSA_X 96
@@ -988,12 +283,6 @@
VW_UpdateScreen();
}
-
-////////////////////////////////////////////////////////////////////
-//
-// LOAD SAVED GAMES
-//
-////////////////////////////////////////////////////////////////////
s16int CP_LoadGame(s16int quick)
{
s16int handle,which,exit=0;
@@ -1070,11 +359,6 @@
return exit;
}
-
-///////////////////////////////////
-//
-// HIGHLIGHT CURRENT SELECTED ENTRY
-//
void TrackWhichGame(s16int w)
{
static s16int lastgameon=0;
@@ -1085,19 +369,10 @@
lastgameon=w;
}
-
-////////////////////////////
-//
-// DRAW THE LOAD/SAVE SCREEN
-//
void DrawLoadSaveScreen(s16int loadsave)
{
- #define DISKX 100
- #define DISKY 0
-
s16int i;
-
ClearMScreen();
fontnumber=1;
VWB_DrawPic(112,184,Pmouselback);
@@ -1118,11 +393,6 @@
WaitKeyUp();
}
-
-///////////////////////////////////////////
-//
-// PRINT LOAD/SAVE GAME ENTRY W/BOX OUTLINE
-//
void PrintLSEntry(s16int w,s16int color)
{
SETFONTCOLOR(color,BKGDCOLOR);
@@ -1139,12 +409,6 @@
fontnumber=1;
}
-
-////////////////////////////////////////////////////////////////////
-//
-// SAVE CURRENT GAME
-//
-////////////////////////////////////////////////////////////////////
s16int CP_SaveGame(s16int quick)
{
s16int handle,which,exit=0;
@@ -1189,7 +453,7 @@
// OVERWRITE EXISTING SAVEGAME?
//
if (SaveGamesAvail[which])
- if (!Confirm(GAMESVD))
+ if (!Confirm("There's already a game\nsaved at this position.\n Overwrite?"))
{
DrawLoadSaveScreen(1);
continue;
@@ -1249,994 +513,9 @@
return exit;
}
-////////////////////////////////////////////////////////////////////
-//
-// DEFINE CONTROLS
-//
-////////////////////////////////////////////////////////////////////
-void CP_Control(void)
-{
- #define CTL_SPC 70
- enum {MOUSEENABLE,JOYENABLE,USEPORT2,PADENABLE,MOUSESENS,CUSTOMIZE};
- s16int i,which;
-
- DrawCtlScreen();
- MenuFadeIn();
- WaitKeyUp();
-
- do
- {
- which=HandleMenu(&CtlItems,&CtlMenu[0],NULL);
- switch(which)
- {
- case MOUSEENABLE:
- mouseenabled^=1;
- _CX=_DX=CENTER;
- Mouse(4);
- DrawCtlScreen();
- CusItems.curpos=-1;
- ShootSnd();
- break;
-
- case JOYENABLE:
- joystickenabled^=1;
- DrawCtlScreen();
- CusItems.curpos=-1;
- ShootSnd();
- break;
-
- case USEPORT2:
- joystickport^=1;
- DrawCtlScreen();
- ShootSnd();
- break;
-
- case PADENABLE:
- joypadenabled^=1;
- DrawCtlScreen();
- ShootSnd();
- break;
-
- case MOUSESENS:
- case CUSTOMIZE:
- DrawCtlScreen();
- MenuFadeIn();
- WaitKeyUp();
- break;
- }
- } while(which>=0);
-
- MenuFadeOut();
-}
-
-
-////////////////////////////////
-//
-// DRAW MOUSE SENSITIVITY SCREEN
-//
-void DrawMouseSens(void)
-{
- ClearMScreen();
- VWB_DrawPic(112,184,Pmouselback);
- DrawWindow(10,80,300,30,BKGDCOLOR);
-
- WindowX=0;
- WindowW=320;
- PrintY=82;
- SETFONTCOLOR(READCOLOR,BKGDCOLOR);
- US_CPrint("Adjust Mouse Sensitivity");
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- PrintX=14;
- PrintY=95;
- US_Print("Slow");
- PrintX=269;
- US_Print("Fast");
-
- VWB_Bar(60,97,200,10,TEXTCOLOR);
- DrawOutline(60,97,200,10,0,HIGHLIGHT);
- DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
- VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
-
- VW_UpdateScreen();
- MenuFadeIn();
-}
-
-
-///////////////////////////
-//
-// ADJUST MOUSE SENSITIVITY
-//
-void MouseSensitivity(void)
-{
- ControlInfo ci;
- s16int exit=0,oldMA;
-
-
- oldMA=mouseadjustment;
- DrawMouseSens();
- do
- {
- ReadAnyControl(&ci);
- switch(ci.dir)
- {
- case dir_North:
- case dir_West:
- if (mouseadjustment)
- {
- mouseadjustment--;
- VWB_Bar(60,97,200,10,TEXTCOLOR);
- DrawOutline(60,97,200,10,0,HIGHLIGHT);
- DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
- VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
- VW_UpdateScreen();
- sfx(Sdrawgun1);
- while(Keyboard[sc_LeftArrow]);
- WaitKeyUp();
- }
- break;
-
- case dir_South:
- case dir_East:
- if (mouseadjustment<9)
- {
- mouseadjustment++;
- VWB_Bar(60,97,200,10,TEXTCOLOR);
- DrawOutline(60,97,200,10,0,HIGHLIGHT);
- DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
- VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
- VW_UpdateScreen();
- sfx(Sdrawgun1);
- while(Keyboard[sc_RightArrow]);
- WaitKeyUp();
- }
- break;
- }
-
- if (ci.button0 || Keyboard[sc_Space] || Keyboard[sc_Enter])
- exit=1;
- else
- if (ci.button1 || Keyboard[sc_Escape])
- exit=2;
-
- } while(!exit);
-
- if (exit==2)
- {
- mouseadjustment=oldMA;
- sfx(Sesc);
- }
- else
- sfx(Sshoot);
-
- WaitKeyUp();
- MenuFadeOut();
-}
-
-
-///////////////////////////
-//
-// DRAW CONTROL MENU SCREEN
-//
-void DrawCtlScreen(void)
-{
- s16int i,x,y;
-
- ClearMScreen();
- DrawStripes(10);
- VWB_DrawPic(80,0,Pctl);
- VWB_DrawPic(112,184,Pmouselback);
- DrawWindow(CTL_X-8,CTL_Y-5,CTL_W,CTL_H,BKGDCOLOR);
- WindowX=0;
- WindowW=320;
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
-
-/*
- if (JoysPresent[0])
- CtlMenu[1].active=
- CtlMenu[2].active=
- CtlMenu[3].active=1;
-*/
-
- CtlMenu[2].active=CtlMenu[3].active=joystickenabled;
-
- if (MousePresent)
- {
- CtlMenu[4].active=
- CtlMenu[0].active=1;
- }
-
- CtlMenu[4].active=mouseenabled;
-
-
- DrawMenu(&CtlItems,&CtlMenu[0]);
-
-
- x=CTL_X+CtlItems.indent-24;
- y=CTL_Y+3;
- if (mouseenabled)
- VWB_DrawPic(x,y,Psel);
- else
- VWB_DrawPic(x,y,Punsel);
-
- y=CTL_Y+16;
- if (joystickenabled)
- VWB_DrawPic(x,y,Psel);
- else
- VWB_DrawPic(x,y,Punsel);
-
- y=CTL_Y+29;
- if (joystickport)
- VWB_DrawPic(x,y,Psel);
- else
- VWB_DrawPic(x,y,Punsel);
-
- y=CTL_Y+42;
- if (joypadenabled)
- VWB_DrawPic(x,y,Psel);
- else
- VWB_DrawPic(x,y,Punsel);
-
- //
- // PICK FIRST AVAILABLE SPOT
- //
- if (CtlItems.curpos<0 || !CtlMenu[CtlItems.curpos].active)
- for (i=0;i<6;i++)
- if (CtlMenu[i].active)
- {
- CtlItems.curpos=i;
- break;
- }
-
- DrawMenuGun(&CtlItems);
- VW_UpdateScreen();
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// CUSTOMIZE CONTROLS
-//
-////////////////////////////////////////////////////////////////////
-enum {FIRE,STRAFE,RUN,OPEN};
-char mbarray[4][3]={"b0","b1","b2","b3"},
- order[4]={RUN,OPEN,FIRE,STRAFE};
-
-
-void CustomControls(void)
-{
- s16int which;
-
-
- DrawCustomScreen();
- do
- {
- which=HandleMenu(&CusItems,&CusMenu[0],FixupCustom);
- switch(which)
- {
- case 0:
- DefineMouseBtns();
- DrawCustMouse(1);
- break;
- case 3:
- // joystick
- break;
- case 6:
- DefineKeyBtns();
- DrawCustKeybd(0);
- break;
- case 8:
- DefineKeyMove();
- DrawCustKeys(0);
- }
- } while(which>=0);
-
-
-
- MenuFadeOut();
-}
-
-
-////////////////////////
-//
-// DEFINE THE MOUSE BUTTONS
-//
-void DefineMouseBtns(void)
-{
- CustomCtrls mouseallowed={0,1,1,1};
- EnterCtrlData(2,&mouseallowed,DrawCustMouse,PrintCustMouse,MOUSE);
-}
-
-
-////////////////////////
-//
-// DEFINE THE KEYBOARD BUTTONS
-//
-void DefineKeyBtns(void)
-{
- CustomCtrls keyallowed={1,1,1,1};
- EnterCtrlData(8,&keyallowed,DrawCustKeybd,PrintCustKeybd,KEYBOARDBTNS);
-}
-
-
-////////////////////////
-//
-// DEFINE THE KEYBOARD BUTTONS
-//
-void DefineKeyMove(void)
-{
- CustomCtrls keyallowed={1,1,1,1};
- EnterCtrlData(10,&keyallowed,DrawCustKeys,PrintCustKeys,KEYBOARDMOVE);
-}
-
-
-////////////////////////
-//
-// ENTER CONTROL DATA FOR ANY TYPE OF CONTROL
-//
-enum {FWRD,RIGHT,BKWD,LEFT};
-s16int moveorder[4]={LEFT,RIGHT,FWRD,BKWD};
-
-void EnterCtrlData(s16int index,CustomCtrls *cust,void (*DrawRtn)(s16int),void (*PrintRtn)(s16int),s16int type)
-{
- s16int j,exit,tick,redraw,which,x,picked;
- ControlInfo ci;
-
-
- ShootSnd();
- PrintY=CST_Y+13*index;
- IN_ClearKeysDown();
- exit=0;
- redraw=1;
- //
- // FIND FIRST SPOT IN ALLOWED ARRAY
- //
- for (j=0;j<4;j++)
- if (cust->allowed[j])
- {
- which=j;
- break;
- }
-
- do
- {
- if (redraw)
- {
- x=CST_START+CST_SPC*which;
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
-
- DrawRtn(1);
- DrawWindow(x-2,PrintY,CST_SPC,11,TEXTCOLOR);
- DrawOutline(x-2,PrintY,CST_SPC,11,0,HIGHLIGHT);
- SETFONTCOLOR(0,TEXTCOLOR);
- PrintRtn(which);
- PrintX=x;
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- VW_UpdateScreen();
- WaitKeyUp();
- redraw=0;
- }
-
- ReadAnyControl(&ci);
-
- if (type==MOUSE || type==JOYSTICK)
- if (IN_KeyDown(sc_Enter)||IN_KeyDown(sc_Control)||IN_KeyDown(sc_Alt))
- {
- IN_ClearKeysDown();
- ci.button0=ci.button1=false;
- }
-
- //
- // CHANGE BUTTON VALUE?
- //
- if ((ci.button0|ci.button1|ci.button2|ci.button3)||
- ((type==KEYBOARDBTNS||type==KEYBOARDMOVE) && LastScan==sc_Enter))
- {
- tick=TimeCount=picked=0;
- SETFONTCOLOR(0,TEXTCOLOR);
-
- do
- {
- s16int button,result=0;
-
-
- if (type==KEYBOARDBTNS||type==KEYBOARDMOVE)
- IN_ClearKeysDown();
-
- //
- // FLASH CURSOR
- //
- if (TimeCount>10)
- {
- switch(tick)
- {
- case 0:
- VWB_Bar(x,PrintY+1,CST_SPC-2,10,TEXTCOLOR);
- break;
- case 1:
- PrintX=x;
- US_Print("?");
- sfx(Shitwall);
- }
- tick^=1;
- TimeCount=0;
- VW_UpdateScreen();
- }
-
- //
- // WHICH TYPE OF INPUT DO WE PROCESS?
- //
- switch(type)
- {
- case MOUSE:
- Mouse(3);
- button=_BX;
- switch(button)
- {
- case 1: result=1; break;
- case 2: result=2; break;
- case 4: result=3; break;
- }
-
- if (result)
- {
- s16int z;
-
-
- for (z=0;z<4;z++)
- if (order[which]==buttonmouse[z])
- {
- buttonmouse[z]=bt_nobutton;
- break;
- }
-
- buttonmouse[result-1]=order[which];
- picked=1;
- sfx(Shitdoor);
- }
- break;
-
- case JOYSTICK:
- if (ci.button0) result=1;
- else
- if (ci.button1) result=2;
- else
- if (ci.button2) result=3;
- else
- if (ci.button3) result=4;
-
- if (result)
- {
- s16int z;
-
-
- for (z=0;z<4;z++)
- if (order[which]==buttonjoy[z])
- {
- buttonjoy[z]=bt_nobutton;
- break;
- }
-
- buttonjoy[result-1]=order[which];
- picked=1;
- sfx(Shitdoor);
- }
- break;
-
- case KEYBOARDBTNS:
- if (LastScan)
- {
- buttonscan[order[which]]=LastScan;
- picked=1;
- ShootSnd();
- IN_ClearKeysDown();
- }
- break;
-
- case KEYBOARDMOVE:
- if (LastScan)
- {
- dirscan[moveorder[which]]=LastScan;
- picked=1;
- ShootSnd();
- IN_ClearKeysDown();
- }
- break;
- }
-
- //
- // EXIT INPUT?
- //
- if (IN_KeyDown(sc_Escape))
- {
- picked=1;
- continue;
- }
-
- } while(!picked);
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- redraw=1;
- WaitKeyUp();
- continue;
- }
-
- if (ci.button1 || IN_KeyDown(sc_Escape))
- exit=1;
-
- //
- // MOVE TO ANOTHER SPOT?
- //
- switch(ci.dir)
- {
- case dir_West:
- do
- {
- which--;
- if (which<0)
- which=3;
- } while(!cust->allowed[which]);
- redraw=1;
- sfx(Sdrawgun1);
- while(ReadAnyControl(&ci),ci.dir!=dir_None);
- IN_ClearKeysDown();
- break;
-
- case dir_East:
- do
- {
- which++;
- if (which>3)
- which=0;
- } while(!cust->allowed[which]);
- redraw=1;
- sfx(Sdrawgun1);
- while(ReadAnyControl(&ci),ci.dir!=dir_None);
- IN_ClearKeysDown();
- break;
- case dir_North:
- case dir_South:
- exit=1;
- }
- } while(!exit);
-
- sfx(Sesc);
- WaitKeyUp();
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
-}
-
-
-////////////////////////
-//
-// FIXUP GUN CURSOR OVERDRAW SHIT
-//
-void FixupCustom(s16int w)
-{
- static s16int lastwhich=-1;
- s16int y=CST_Y+26+w*13;
-
-
- VWB_Hlin(7,32,y-1,DEACTIVE);
- VWB_Hlin(7,32,y+12,BORD2COLOR);
-#ifndef SPEAR
- VWB_Hlin(7,32,y-2,BORDCOLOR);
- VWB_Hlin(7,32,y+13,BORDCOLOR);
-#else
- VWB_Hlin(7,32,y-2,BORD2COLOR);
- VWB_Hlin(7,32,y+13,BORD2COLOR);
-#endif
-
- switch(w)
- {
- case 0: DrawCustMouse(1); break;
- case 3: /* joystick */ break;
- case 6: DrawCustKeybd(1); break;
- case 8: DrawCustKeys(1);
- }
-
-
- if (lastwhich>=0)
- {
- y=CST_Y+26+lastwhich*13;
- VWB_Hlin(7,32,y-1,DEACTIVE);
- VWB_Hlin(7,32,y+12,BORD2COLOR);
-#ifndef SPEAR
- VWB_Hlin(7,32,y-2,BORDCOLOR);
- VWB_Hlin(7,32,y+13,BORDCOLOR);
-#else
- VWB_Hlin(7,32,y-2,BORD2COLOR);
- VWB_Hlin(7,32,y+13,BORD2COLOR);
-#endif
-
- if (lastwhich!=w)
- switch(lastwhich)
- {
- case 0: DrawCustMouse(0); break;
- case 3: /* joystick */ break;
- case 6: DrawCustKeybd(0); break;
- case 8: DrawCustKeys(0);
- }
- }
-
- lastwhich=w;
-}
-
-
-////////////////////////
-//
-// DRAW CUSTOMIZE SCREEN
-//
-void DrawCustomScreen(void)
-{
- s16int i;
-
- ClearMScreen();
- WindowX=0;
- WindowW=320;
- VWB_DrawPic(112,184,Pmouselback);
- DrawStripes(10);
- VWB_DrawPic(80,0,Pcustom);
-
- //
- // MOUSE
- //
- SETFONTCOLOR(READCOLOR,BKGDCOLOR);
- WindowX=0;
- WindowW=320;
-
-#ifndef SPEAR
- PrintY=CST_Y;
- US_CPrint("Mouse\n");
-#else
- PrintY = CST_Y+13;
- VWB_DrawPic (128,48,Pmouse);
-#endif
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- PrintX=CST_START;
- US_Print("Run");
- PrintX=CST_START+CST_SPC*1;
- US_Print("Open");
- PrintX=CST_START+CST_SPC*2;
- US_Print("Fire");
- PrintX=CST_START+CST_SPC*3;
- US_Print("Strafe\n");
-
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
- DrawCustMouse(0);
- US_Print("\n");
-
-
- //
- // JOYSTICK/PAD
- //
-#ifndef SPEAR
- SETFONTCOLOR(READCOLOR,BKGDCOLOR);
- US_CPrint("Joystick/Gravis GamePad\n");
-#else
- PrintY += 13;
- VWB_DrawPic (40,88,Pjs);
-#endif
-
-#ifdef SPEAR
- VWB_DrawPic (112,120,Pkb);
-#endif
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- PrintX=CST_START;
- US_Print("Run");
- PrintX=CST_START+CST_SPC*1;
- US_Print("Open");
- PrintX=CST_START+CST_SPC*2;
- US_Print("Fire");
- PrintX=CST_START+CST_SPC*3;
- US_Print("Strafe\n");
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
- //DrawCustJoy(0);
- US_Print("\n");
-
-
- //
- // KEYBOARD
- //
-#ifndef SPEAR
- SETFONTCOLOR(READCOLOR,BKGDCOLOR);
- US_CPrint("Keyboard\n");
-#else
- PrintY += 13;
-#endif
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- PrintX=CST_START;
- US_Print("Run");
- PrintX=CST_START+CST_SPC*1;
- US_Print("Open");
- PrintX=CST_START+CST_SPC*2;
- US_Print("Fire");
- PrintX=CST_START+CST_SPC*3;
- US_Print("Strafe\n");
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
- DrawCustKeybd(0);
- US_Print("\n");
-
-
- //
- // KEYBOARD MOVE KEYS
- //
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- PrintX=CST_START;
- US_Print("Left");
- PrintX=CST_START+CST_SPC*1;
- US_Print("Right");
- PrintX=CST_START+CST_SPC*2;
- US_Print("Frwd");
- PrintX=CST_START+CST_SPC*3;
- US_Print("Bkwrd\n");
- DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
- DrawCustKeys(0);
- //
- // PICK STARTING POINT IN MENU
- //
- if (CusItems.curpos<0)
- for (i=0;i<CusItems.amount;i++)
- if (CusMenu[i].active)
- {
- CusItems.curpos=i;
- break;
- }
-
-
- VW_UpdateScreen();
- MenuFadeIn();
-}
-
-
-void PrintCustMouse(s16int i)
-{
- s16int j;
-
- for (j=0;j<4;j++)
- if (order[i]==buttonmouse[j])
- {
- PrintX=CST_START+CST_SPC*i;
- US_Print(mbarray[j]);
- break;
- }
-}
-
-void DrawCustMouse(s16int hilight)
-{
- s16int i,color;
-
-
- color=TEXTCOLOR;
- if (hilight)
- color=HIGHLIGHT;
- SETFONTCOLOR(color,BKGDCOLOR);
-
- if (!mouseenabled)
- {
- SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
- CusMenu[0].active=0;
- }
- else
- CusMenu[0].active=1;
-
- PrintY=CST_Y+13*2;
- for (i=0;i<4;i++)
- PrintCustMouse(i);
-}
-
-void PrintCustKeybd(s16int i)
-{
- PrintX=CST_START+CST_SPC*i;
- US_Print(IN_GetScanName(buttonscan[order[i]]));
-}
-
-void DrawCustKeybd(s16int hilight)
-{
- s16int i,color;
-
-
- color=TEXTCOLOR;
- if (hilight)
- color=HIGHLIGHT;
- SETFONTCOLOR(color,BKGDCOLOR);
-
- PrintY=CST_Y+13*8;
- for (i=0;i<4;i++)
- PrintCustKeybd(i);
-}
-
-void PrintCustKeys(s16int i)
-{
- PrintX=CST_START+CST_SPC*i;
- US_Print(IN_GetScanName(dirscan[moveorder[i]]));
-}
-
-void DrawCustKeys(s16int hilight)
-{
- s16int i,color;
-
-
- color=TEXTCOLOR;
- if (hilight)
- color=HIGHLIGHT;
- SETFONTCOLOR(color,BKGDCOLOR);
-
- PrintY=CST_Y+13*10;
- for (i=0;i<4;i++)
- PrintCustKeys(i);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// CHANGE SCREEN VIEWING SIZE
-//
-////////////////////////////////////////////////////////////////////
-void CP_ChangeView(void)
-{
- s16int exit=0,oldview,newview;
- ControlInfo ci;
-
-
- WindowX=WindowY=0;
- WindowW=320;
- WindowH=200;
- newview=oldview=vw.dx/16;
- DrawChangeView(oldview);
-
- do
- {
- CheckPause();
- ReadAnyControl(&ci);
- switch(ci.dir)
- {
- case dir_South:
- case dir_West:
- newview--;
- if (newview<4)
- newview=4;
- ShowViewSize(newview);
- VW_UpdateScreen();
- sfx(Shitwall);
- TicDelay(10);
- break;
-
- case dir_North:
- case dir_East:
- newview++;
- if (newview>19)
- newview=19;
- ShowViewSize(newview);
- VW_UpdateScreen();
- sfx(Shitwall);
- TicDelay(10);
- break;
- }
-
- if (ci.button0 || Keyboard[sc_Enter])
- exit=1;
- else
- if (ci.button1 || Keyboard[sc_Escape])
- {
- vw.dx=oldview*16;
- sfx(Sesc);
- MenuFadeOut();
- return;
- }
-
- } while(!exit);
-
-
- if (oldview!=newview)
- {
- sfx (Sshoot);
- Message("Thinking...");
- NewViewSize(newview);
- }
-
- ShootSnd();
- MenuFadeOut();
-}
-
-
-/////////////////////////////
-//
-// DRAW THE CHANGEVIEW SCREEN
-//
-void DrawChangeView(s16int view)
-{
- VWB_Bar(0,160,320,40,VIEWCOLOR);
- ShowViewSize(view);
-
- PrintY=161;
- WindowX=0;
- WindowY=320;
- SETFONTCOLOR(HIGHLIGHT,BKGDCOLOR);
-
- US_CPrint("Use arrows to size\n");
- US_CPrint("ENTER to accept\n");
- US_CPrint("ESC to cancel");
- VW_UpdateScreen();
-
- MenuFadeIn();
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// QUIT THIS INFERNAL GAME!
-//
-////////////////////////////////////////////////////////////////////
-void CP_Quit(void)
-{
- s16int i;
-
- if (Confirm(endStrings[rnd()&0x7+(rnd()&1)]))
- {
- VW_UpdateScreen();
- SD_MusicOff();
- SD_StopSound();
- MenuFadeOut();
- //
- // SHUT-UP THE ADLIB
- //
- for (i=1;i<=0xf5;i++)
- alOut(i,0);
- Quit(NULL);
- }
-
- DrawMainMenu();
-}
-
-////////////////////////////////////////////////////////////////////
-//
-// Draw a window for a menu
-//
-////////////////////////////////////////////////////////////////////
-void DrawWindow(s16int x,s16int y,s16int w,s16int h,s16int wcolor)
-{
- VWB_Bar(x,y,w,h,wcolor);
- DrawOutline(x,y,w,h,BORD2COLOR,DEACTIVE);
-}
-
-
-void DrawOutline(s16int x,s16int y,s16int w,s16int h,s16int color1,s16int color2)
-{
- VWB_Hlin(x,x+w,y,color2);
- VWB_Vlin(y,y+h,x,color2);
- VWB_Hlin(x,x+w,y+h,color1);
- VWB_Vlin(y,y+h,x+w,color1);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// Setup Control Panel stuff - graphics, etc.
-//
-////////////////////////////////////////////////////////////////////
void SetupControlPanel(void)
{
- struct ffblk f;
- char name[13];
- s16int which,i;
-
-
//
- // CACHE GRAPHICS & SOUNDS
- //
-
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- fontnumber=1;
- WindowH=200;
-
- if (!ingame)
- CA_LoadAllSounds();
- else
- MainMenu[savegame].active=1;
-
- //
// SEE WHICH SAVE GAME FILES ARE AVAILABLE & READ STRING IN
//
strcpy(name,SaveName);
@@ -2256,551 +535,8 @@
strcpy(&SaveGameNames[which][0],temp);
}
} while(!findnext(&f));
-
- //
- // CENTER MOUSE
- //
- _CX=_DX=CENTER;
- Mouse(4);
}
-
-////////////////////////////////////////////////////////////////////
-//
-// Clean up all the Control Panel stuff
-//
-////////////////////////////////////////////////////////////////////
-void CleanupControlPanel(void)
-{
- fontnumber = 0;
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// Handle moving gun around a menu
-//
-////////////////////////////////////////////////////////////////////
-s16int HandleMenu(CP_iteminfo *item_i,CP_itemtype far *items,void (*routine)(s16int w))
-{
- char key;
- static s16int redrawitem=1,lastitem=-1;
- s16int i,x,y,basey,exit,which,shape,timer;
- ControlInfo ci;
-
-
- which=item_i->curpos;
- x=item_i->x&-8;
- basey=item_i->y-2;
- y=basey+which*13;
-
- VWB_DrawPic(x,y,Pcur1);
- SetTextColor(items+which,1);
- if (redrawitem)
- {
- PrintX=item_i->x+item_i->indent;
- PrintY=item_i->y+which*13;
- US_Print((items+which)->string);
- }
- //
- // CALL CUSTOM ROUTINE IF IT IS NEEDED
- //
- if (routine)
- routine(which);
- VW_UpdateScreen();
-
- shape=Pcur1;
- timer=8;
- exit=0;
- TimeCount=0;
- IN_ClearKeysDown();
-
-
- do
- {
- //
- // CHANGE GUN SHAPE
- //
- if (TimeCount>timer)
- {
- TimeCount=0;
- if (shape==Pcur1)
- {
- shape=Pcur2;
- timer=8;
- }
- else
- {
- shape=Pcur1;
- timer=70;
- }
- VWB_DrawPic(x,y,shape);
- if (routine)
- routine(which);
- VW_UpdateScreen();
- }
-
- CheckPause();
-
- //
- // SEE IF ANY KEYS ARE PRESSED FOR INITIAL CHAR FINDING
- //
- key=LastASCII;
- if (key)
- {
- s16int ok=0;
-
- if (key>='a')
- key-='a'-'A';
-
- for (i=which+1;i<item_i->amount;i++)
- if ((items+i)->active && (items+i)->string[0]==key)
- {
- EraseGun(item_i,items,x,y,which);
- which=i;
- DrawGun(item_i,items,x,&y,which,basey,routine);
- ok=1;
- IN_ClearKeysDown();
- break;
- }
-
- //
- // DIDN'T FIND A MATCH FIRST TIME THRU. CHECK AGAIN.
- //
- if (!ok)
- {
- for (i=0;i<which;i++)
- if ((items+i)->active && (items+i)->string[0]==key)
- {
- EraseGun(item_i,items,x,y,which);
- which=i;
- DrawGun(item_i,items,x,&y,which,basey,routine);
- IN_ClearKeysDown();
- break;
- }
- }
- }
-
- //
- // GET INPUT
- //
- ReadAnyControl(&ci);
- switch(ci.dir)
- {
- ////////////////////////////////////////////////
- //
- // MOVE UP
- //
- case dir_North:
-
- EraseGun(item_i,items,x,y,which);
-
- //
- // ANIMATE HALF-STEP
- //
- if (which && (items+which-1)->active)
- {
- y-=6;
- DrawHalfStep(x,y);
- }
-
- //
- // MOVE TO NEXT AVAILABLE SPOT
- //
- do
- {
- if (!which)
- which=item_i->amount-1;
- else
- which--;
- } while(!(items+which)->active);
-
- DrawGun(item_i,items,x,&y,which,basey,routine);
- //
- // WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
- //
- TicDelay(20);
- break;
-
- ////////////////////////////////////////////////
- //
- // MOVE DOWN
- //
- case dir_South:
-
- EraseGun(item_i,items,x,y,which);
- //
- // ANIMATE HALF-STEP
- //
- if (which!=item_i->amount-1 && (items+which+1)->active)
- {
- y+=6;
- DrawHalfStep(x,y);
- }
-
- do
- {
- if (which==item_i->amount-1)
- which=0;
- else
- which++;
- } while(!(items+which)->active);
-
- DrawGun(item_i,items,x,&y,which,basey,routine);
-
- //
- // WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
- //
- TicDelay(20);
- break;
- }
-
- if (ci.button0 ||
- Keyboard[sc_Space] ||
- Keyboard[sc_Enter])
- exit=1;
-
- if (ci.button1 ||
- Keyboard[sc_Escape])
- exit=2;
-
- } while(!exit);
-
-
- IN_ClearKeysDown();
-
- //
- // ERASE EVERYTHING
- //
- if (lastitem!=which)
- {
- VWB_Bar(x-1,y,25,16,BKGDCOLOR);
- PrintX=item_i->x+item_i->indent;
- PrintY=item_i->y+which*13;
- US_Print((items+which)->string);
- redrawitem=1;
- }
- else
- redrawitem=0;
-
- if (routine)
- routine(which);
- VW_UpdateScreen();
-
- item_i->curpos=which;
-
- lastitem=which;
- switch(exit)
- {
- case 1:
- //
- // CALL THE ROUTINE
- //
- if ((items+which)->routine!=NULL)
- {
- ShootSnd();
- MenuFadeOut();
- (items+which)->routine(0);
- }
- return which;
-
- case 2:
- sfx(Sesc);
- return -1;
- }
-
- return 0; // JUST TO SHUT UP THE ERROR MESSAGES!
-}
-
-
-//
-// ERASE GUN & DE-HIGHLIGHT STRING
-//
-void EraseGun(CP_iteminfo *item_i,CP_itemtype far *items,s16int x,s16int y,s16int which)
-{
- VWB_Bar(x-1,y,25,16,BKGDCOLOR);
- SetTextColor(items+which,0);
-
- PrintX=item_i->x+item_i->indent;
- PrintY=item_i->y+which*13;
- US_Print((items+which)->string);
- VW_UpdateScreen();
-}
-
-
-//
-// DRAW HALF STEP OF GUN TO NEXT POSITION
-//
-void DrawHalfStep(s16int x,s16int y)
-{
- VWB_DrawPic(x,y,Pcur1);
- VW_UpdateScreen();
- sfx(Sdrawgun1);
- TimeCount=0;
- while(TimeCount<8);
-}
-
-
-//
-// DRAW GUN AT NEW POSITION
-//
-void DrawGun(CP_iteminfo *item_i,CP_itemtype far *items,s16int x,s16int *y,s16int which,s16int basey,void (*routine)(s16int w))
-{
- VWB_Bar(x-1,*y,25,16,BKGDCOLOR);
- *y=basey+which*13;
- VWB_DrawPic(x,*y,Pcur1);
- SetTextColor(items+which,1);
-
- PrintX=item_i->x+item_i->indent;
- PrintY=item_i->y+which*13;
- US_Print((items+which)->string);
-
- //
- // CALL CUSTOM ROUTINE IF IT IS NEEDED
- //
- if (routine)
- routine(which);
- VW_UpdateScreen();
- sfx(Sdrawgun2);
-}
-
-////////////////////////////////////////////////////////////////////
-//
-// DELAY FOR AN AMOUNT OF TICS OR UNTIL CONTROLS ARE INACTIVE
-//
-////////////////////////////////////////////////////////////////////
-void TicDelay(s16int count)
-{
- ControlInfo ci;
-
-
- TimeCount=0;
- do
- {
- ReadAnyControl(&ci);
- } while(TimeCount<count && ci.dir!=dir_None);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// Draw a menu
-//
-////////////////////////////////////////////////////////////////////
-void DrawMenu(CP_iteminfo *item_i,CP_itemtype far *items)
-{
- s16int i,which=item_i->curpos;
-
-
- WindowX=PrintX=item_i->x+item_i->indent;
- WindowY=PrintY=item_i->y;
- WindowW=320;
- WindowH=200;
-
- for (i=0;i<item_i->amount;i++)
- {
- SetTextColor(items+i,which==i);
-
- PrintY=item_i->y+i*13;
- if ((items+i)->active)
- US_Print((items+i)->string);
- else
- {
- SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
- US_Print((items+i)->string);
- SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
- }
-
- US_Print("\n");
- }
-}
-
-void SetTextColor(CP_itemtype far *items,s16int hlight)
-{
- if (hlight)
- {SETFONTCOLOR(color_hlite[items->active],BKGDCOLOR);}
- else
- {SETFONTCOLOR(color_norml[items->active],BKGDCOLOR);}
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// WAIT FOR CTRLKEY-UP OR BUTTON-UP
-//
-////////////////////////////////////////////////////////////////////
-void WaitKeyUp(void)
-{
- ControlInfo ci;
- while(ReadAnyControl(&ci), ci.button0|
- ci.button1|
- ci.button2|
- ci.button3|
- Keyboard[sc_Space]|
- Keyboard[sc_Enter]|
- Keyboard[sc_Escape]);
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// READ KEYBOARD, JOYSTICK AND MOUSE FOR INPUT
-//
-////////////////////////////////////////////////////////////////////
-void ReadAnyControl(ControlInfo *ci)
-{
- s16int mouseactive=0;
-
-
- IN_ReadControl(0,ci);
-
- if (mouseenabled)
- {
- s16int mousey,mousex;
-
-
- // READ MOUSE MOTION COUNTERS
- // RETURN DIRECTION
- // HOME MOUSE
- // CHECK MOUSE BUTTONS
-
- Mouse(3);
- mousex=_CX;
- mousey=_DX;
-
- if (mousey<CENTER-SENSITIVE)
- {
- ci->dir=dir_North;
- _CX=_DX=CENTER;
- Mouse(4);
- mouseactive=1;
- }
- else
- if (mousey>CENTER+SENSITIVE)
- {
- ci->dir=dir_South;
- _CX=_DX=CENTER;
- Mouse(4);
- mouseactive=1;
- }
-
- if (mousex<CENTER-SENSITIVE)
- {
- ci->dir=dir_West;
- _CX=_DX=CENTER;
- Mouse(4);
- mouseactive=1;
- }
- else
- if (mousex>CENTER+SENSITIVE)
- {
- ci->dir=dir_East;
- _CX=_DX=CENTER;
- Mouse(4);
- mouseactive=1;
- }
-
- if (IN_MouseButtons())
- {
- ci->button0=IN_MouseButtons()&1;
- ci->button1=IN_MouseButtons()&2;
- ci->button2=IN_MouseButtons()&4;
- ci->button3=false;
- mouseactive=1;
- }
- }
-}
-
-
-////////////////////////////////////////////////////////////////////
-//
-// DRAW DIALOG AND CONFIRM YES OR NO TO QUESTION
-//
-////////////////////////////////////////////////////////////////////
-s16int Confirm(char far *string)
-{
- s16int xit=0,i,x,y,tick=0,time,whichsnd[2]={Sesc,Sshoot};
-
-
- Message(string);
- IN_ClearKeysDown();
-
- //
- // BLINK CURSOR
- //
- x=PrintX;
- y=PrintY;
- TimeCount=0;
-
- do
- {
- if (TimeCount>=10)
- {
- switch(tick)
- {
- case 0:
- VWB_Bar(x,y,8,13,TEXTCOLOR);
- break;
- case 1:
- PrintX=x;
- PrintY=y;
- US_Print("_");
- }
- VW_UpdateScreen();
- tick^=1;
- TimeCount=0;
- }
- } while(!Keyboard[sc_Y] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
-
- if (Keyboard[sc_Y])
- {
- xit=1;
- ShootSnd();
- }
-
- while(Keyboard[sc_Y] || Keyboard[sc_N] || Keyboard[sc_Escape]);
-
- IN_ClearKeysDown();
- sfx(whichsnd[xit]);
- return xit;
-}
-
-////////////////////////////////////////////////////////////////////
-//
-// PRINT A MESSAGE IN A WINDOW
-//
-////////////////////////////////////////////////////////////////////
-void Message(char far *string)
-{
- s16int h=0,w=0,mw=0,i,x,y,time;
- fontstruct _seg *font;
-
- fontnumber=1;
- h=font->height;
- for (i=0;i<_fstrlen(string);i++)
- if (string[i]=='\n')
- {
- if (w>mw)
- mw=w;
- w=0;
- h+=font->height;
- }
- else
- w+=font->width[string[i]];
-
- if (w+10>mw)
- mw=w+10;
-
- PrintY=(WindowH/2)-h/2;
- PrintX=WindowX=160-mw/2;
-
- DrawWindow(WindowX-5,PrintY-5,mw+10,h+10,TEXTCOLOR);
- DrawOutline(WindowX-5,PrintY-5,mw+10,h+10,0,HIGHLIGHT);
- SETFONTCOLOR(0,TEXTCOLOR);
- US_Print(string);
- VW_UpdateScreen();
-}
-
void StartCPMusic(s16int song)
{
SD_MusicOff();
@@ -2807,31 +543,6 @@
SD_mapmus((MusicGroup far *)audiosegs[STARTMUSIC + song]);
}
-///////////////////////////////////////////////////////////////////////////
-//
-// IN_GetScanName() - Returns a string containing the name of the
-// specified scan code
-//
-///////////////////////////////////////////////////////////////////////////
-u8int *
-IN_GetScanName(u8int scan)
-{
- u8int **p;
- u8int far *s;
-
- for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
- if (*s == scan)
- return(*p);
-
- return(ScanNames[scan]);
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// CHECK FOR PAUSE KEY (FOR MUSIC ONLY)
-//
-///////////////////////////////////////////////////////////////////////////
void CheckPause(void)
{
if (Paused)
@@ -2846,33 +557,5 @@
VW_WaitVBL(3);
IN_ClearKeysDown();
Paused=false;
- }
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// DRAW GUN CURSOR AT CORRECT POSITION IN MENU
-//
-///////////////////////////////////////////////////////////////////////////
-void DrawMenuGun(CP_iteminfo *iteminfo)
-{
- s16int x,y;
-
-
- x=iteminfo->x;
- y=iteminfo->y+iteminfo->curpos*13-2;
- VWB_DrawPic(x,y,Pcur1);
-}
-
-
-///////////////////////////////////////////////////////////////////////////
-//
-// DRAW SCREEN TITLE STRIPES
-//
-///////////////////////////////////////////////////////////////////////////
-
-void ShootSnd(void)
-{
- sfx(Sshoot);
+ }
}
--- a/menu.h
+++ /dev/null
@@ -1,216 +1,0 @@
-//
-// WL_MENU.H
-//
-#ifdef SPEAR
-
-#define BORDCOLOR 0x99
-#define BORD2COLOR 0x93
-#define DEACTIVE 0x9b
-#define BKGDCOLOR 0x9d
-
-#define MenuFadeOut() VL_FadeOut(0,255,0,0,51,10)
-
-#else
-
-#define BORDCOLOR 0x29
-#define BORD2COLOR 0x23
-#define DEACTIVE 0x2b
-#define BKGDCOLOR 0x2d
-
-#define MenuFadeOut() VL_FadeOut(0,255,43,0,0,10)
-
-#endif
-
-#define READCOLOR 0x4a
-#define READHCOLOR 0x47
-#define VIEWCOLOR 0x7f
-#define TEXTCOLOR 0x17
-#define HIGHLIGHT 0x13
-#define MenuFadeIn() VL_FadeIn(0,255,&gamepal,10)
-
-
-#ifndef SPEAR
-#define INTROSONG 7
-#else
-#define INTROSONG 23
-#endif
-
-#define SENSITIVE 60
-#define CENTER SENSITIVE*2
-
-#define MENU_X 76
-#define MENU_Y 55
-#define MENU_W 178
-#ifndef SPEAR
-#define MENU_H 13*10+6
-#else
-#define MENU_H 13*9+6
-#endif
-
-#define SM_X 48
-#define SM_W 250
-
-#define SM_Y1 20
-#define SM_H1 4*13-7
-#define SM_Y2 SM_Y1+5*13
-#define SM_H2 4*13-7
-#define SM_Y3 SM_Y2+5*13
-#define SM_H3 3*13-7
-
-#define CTL_X 24
-#define CTL_Y 70
-#define CTL_W 284
-#define CTL_H 13*7-7
-
-#define LSM_X 85
-#define LSM_Y 55
-#define LSM_W 175
-#define LSM_H 10*13+10
-
-#define NM_X 50
-#define NM_Y 100
-#define NM_W 225
-#define NM_H 13*4+15
-
-#define NE_X 10
-#define NE_Y 23
-#define NE_W 320-NE_X*2
-#define NE_H 200-NE_Y*2
-
-#define CST_X 20
-#define CST_Y 48
-#define CST_START 60
-#define CST_SPC 60
-
-
-//
-// TYPEDEFS
-//
-typedef struct {
- s16int x,y,amount,curpos,indent;
- } CP_iteminfo;
-
-typedef struct {
- s16int active;
- char string[36];
- void (* routine)(s16int temp1);
- } CP_itemtype;
-
-typedef struct {
- s16int allowed[4];
- } CustomCtrls;
-
-extern CP_itemtype far MainMenu[],far NewEMenu[];
-extern CP_iteminfo MainItems;
-
-//
-// FUNCTION PROTOTYPES
-//
-void SetupControlPanel(void);
-void CleanupControlPanel(void);
-
-void DrawMenu(CP_iteminfo *item_i,CP_itemtype far *items);
-s16int HandleMenu(CP_iteminfo *item_i,
- CP_itemtype far *items,
- void (*routine)(s16int w));
-void ClearMScreen(void);
-void DrawWindow(s16int x,s16int y,s16int w,s16int h,s16int wcolor);
-void DrawOutline(s16int x,s16int y,s16int w,s16int h,s16int color1,s16int color2);
-void WaitKeyUp(void);
-void ReadAnyControl(ControlInfo *ci);
-void TicDelay(s16int count);
-void StartCPMusic(s16int song);
-s16int Confirm(char far *string);
-void Message(char far *string);
-void CheckPause(void);
-void ShootSnd(void);
-void CheckSecretMissions(void);
-void BossKey(void);
-
-void DrawGun(CP_iteminfo *item_i,CP_itemtype far *items,s16int x,s16int *y,s16int which,s16int basey,void (*routine)(s16int w));
-void DrawHalfStep(s16int x,s16int y);
-void EraseGun(CP_iteminfo *item_i,CP_itemtype far *items,s16int x,s16int y,s16int which);
-void SetTextColor(CP_itemtype far *items,s16int hlight);
-void DrawMenuGun(CP_iteminfo *iteminfo);
-void DrawStripes(s16int y);
-
-void DefineMouseBtns(void);
-void DefineKeyBtns(void);
-void DefineKeyMove(void);
-void EnterCtrlData(s16int index,CustomCtrls *cust,void (*DrawRtn)(s16int),void (*PrintRtn)(s16int),s16int type);
-
-void DrawMainMenu(void);
-void DrawSoundMenu(void);
-void DrawLoadSaveScreen(s16int loadsave);
-void DrawNewEpisode(void);
-void DrawNewGame(void);
-void DrawChangeView(s16int view);
-void DrawMouseSens(void);
-void DrawCtlScreen(void);
-void DrawCustomScreen(void);
-void DrawLSAction(s16int which);
-void DrawCustMouse(s16int hilight);
-void DrawCustKeybd(s16int hilight);
-void DrawCustKeys(s16int hilight);
-void PrintCustMouse(s16int i);
-void PrintCustKeybd(s16int i);
-void PrintCustKeys(s16int i);
-
-void PrintLSEntry(s16int w,s16int color);
-void TrackWhichGame(s16int w);
-void DrawNewGameDiff(s16int w);
-void FixupCustom(s16int w);
-
-void CP_NewGame(void);
-void CP_Sound(void);
-s16int CP_LoadGame(s16int quick);
-s16int CP_SaveGame(s16int quick);
-void CP_Control(void);
-void CP_ChangeView(void);
-void CP_ExitOptions(void);
-void CP_Quit(void);
-void CP_ViewScores(void);
-s16int CP_EndGame(void);
-s16int CP_CheckQuick(u16int scancode);
-void CustomControls(void);
-void MouseSensitivity(void);
-
-//
-// VARIABLES
-//
-extern s16int SaveGamesAvail[10],StartGame,SoundStatus;
-extern char SaveGameNames[10][32],SaveName[13];
-
-enum {MOUSE,JOYSTICK,KEYBOARDBTNS,KEYBOARDMOVE}; // FOR INPUT TYPES
-
-enum
-{
- newgame,
- soundmenu,
- control,
- loadgame,
- savegame,
- changeview,
-
-#ifndef GOODTIMES
-#ifndef SPEAR
- readthis,
-#endif
-#endif
-
- viewscores,
- backtodemo,
- quit
-} menuitems;
-
-//
-// WL_INTER
-//
-typedef struct {
- s16int kill,secret,treasure;
- s32int time;
- } LRstruct;
-
-extern LRstruct LevelRatios[];
-
-void Write (s16int x,s16int y,char *string);
--- a/play.c
+++ b/play.c
@@ -1,49 +1,6 @@
-exit_t gm.φ;
-s16int DebugOk;
-objtype objlist[Nobj],*new,*obj,*player,*lastobj,
- *objfreelist,*killer;
-u16int farmapylookup[MAPSIZE];
-int onestep,godmode,noclip;
-s16int extravbls;
-u8int tilemap[MAPSIZE][MAPSIZE]; // wall values only
-u8int spotvis[MAPSIZE][MAPSIZE];
-objtype *actorat[MAPSIZE][MAPSIZE];
-
-//
-// replacing refresh manager
-//
-u16int mapwidth,mapheight,tics;
-int compatability;
-u8int *updateptr;
-u16int mapwidthtable[64];
-u16int uwidthtable[UPDATEHIGH];
-u16int blockstarts[UPDATEWIDE*UPDATEHIGH];
-u8int update[UPDATESIZE];
-
-//
-// control info
-//
-int mouseenabled,joystickenabled,joypadenabled,joystickprogressive;
-s16int joystickport;
-s16int dirscan[4] = {sc_UpArrow,sc_RightArrow,sc_DownArrow,sc_LeftArrow};
-s16int buttonscan[NUMBUTTONS] =
- {sc_Control,sc_Alt,sc_RShift,sc_Space,sc_1,sc_2,sc_3,sc_4};
-s16int buttonmouse[4]={bt_attack,bt_strafe,bt_use,bt_nobutton};
-s16int buttonjoy[4]={bt_attack,bt_strafe,bt_use,bt_run};
-
-int buttonheld[NUMBUTTONS];
-
char far *demoptr, far *lastdemoptr;
uchar *demobuffer;
-int buttonstate[NUMBUTTONS];
-
-objtype dummyobj;
-
-#define BASETURN 35
-#define RUNTURN 70
-#define JOYSCALE 2
-
void CheckKeys (void)
{
s16int i;
@@ -56,116 +13,6 @@
scan = LastScan;
-
- #ifdef SPEAR
- //
- // SECRET CHEAT CODE: TAB-G-F10
- //
- if (Keyboard[sc_Tab] &&
- Keyboard[sc_G] &&
- Keyboard[sc_F10])
- {
- WindowH = 160;
- if (godmode)
- {
- Message ("God mode OFF");
- sfx (Snobonus);
- }
- else
- {
- Message ("God mode ON");
- sfx (Sendb2);
- }
-
- IN_Ack();
- godmode ^= 1;
- DrawAllPlayBorderSides ();
- IN_ClearKeysDown();
- return;
- }
- #endif
-
-
- //
- // SECRET CHEAT CODE: 'MLI'
- //
- if (Keyboard[sc_M] &&
- Keyboard[sc_L] &&
- Keyboard[sc_I])
- {
- gamestate.health = 100;
- gamestate.ammo = 99;
- gamestate.keys = 3;
- gm.pt = 0;
- gm.lvltc += 42000L;
- givew (WPgatling);
-
- hudw();
- hudh();
- hudk();
- huda();
- hudp();
-
- ClearMemory ();
- ClearSplitVWB ();
- VW_ScreenToScreen (displayofs,bufferofs,80,160);
-
- Message("You now have 100% Health,\n"
- "99 Ammo and both Keys!\n\n"
- "Note that you have basically\n"
- "eliminated your chances of\n"
- "getting a high score!");
- PM_CheckMainMem ();
- IN_ClearKeysDown();
- IN_Ack();
-
- DrawAllPlayBorder ();
- }
-
- //
- // OPEN UP DEBUG KEYS
- //
- if (Keyboard[sc_BackSpace] &&
- Keyboard[sc_LShift] &&
- Keyboard[sc_Alt] &&
- debug)
- {
- ClearMemory ();
- ClearSplitVWB ();
- VW_ScreenToScreen (displayofs,bufferofs,80,160);
-
- Message("Debugging keys are\nnow available!");
- PM_CheckMainMem ();
- IN_ClearKeysDown();
- IN_Ack();
-
- DrawAllPlayBorderSides ();
- DebugOk=1;
- }
-
- //
- // TRYING THE KEEN CHEAT CODE!
- //
- if (Keyboard[sc_B] &&
- Keyboard[sc_A] &&
- Keyboard[sc_T])
- {
- ClearMemory ();
- ClearSplitVWB ();
- VW_ScreenToScreen (displayofs,bufferofs,80,160);
-
- Message("Commander Keen is also\n"
- "available from Apogee, but\n"
- "then, you already know\n"
- "that - right, Cheatmeister?!");
-
- PM_CheckMainMem ();
- IN_ClearKeysDown();
- IN_Ack();
-
- DrawAllPlayBorder ();
- }
-
//
// pause key weirdness can't be checked as a scan code
//
@@ -233,20 +80,4 @@
PM_CheckMainMem ();
return;
}
-
-//
-// TAB-? debug keys
-//
- if (Keyboard[sc_Tab] && DebugOk)
- {
- CA_CacheGrChunk (STARTFONT);
- fontnumber=0;
- SETFONTCOLOR(0,15);
- DebugKeys();
- if (MousePresent)
- Mouse(MDelta); // Clear accumulated mouse movement
- lasttimecount = TimeCount;
- return;
- }
-
}
--- a/rend.c
+++ b/rend.c
@@ -4,6 +4,7 @@
#include "fns.h"
s32int sint[360+90], *cost;
+int vwsize;
typedef struct Vis Vis;
typedef struct Scaler Scaler;
@@ -177,7 +178,7 @@
topspr(void)
{
if(ver < SDM && gm.won){
- if(oplr->s == stt+GSplrcam && mtc & 32)
+ if(oplr->s == stt+GSplrcam && qtc & 32)
scalspr(SPcam, vw.dx/2, vw.dy+1);
return;
}
@@ -644,7 +645,7 @@
n = tiles[x].tl;
if(n == 0){
vpass:
- tiles[x].vis++;
+ tiles[x].vis = 1;
tx += dtx;
rs = (yinh << 16 | yin & 0xffff) + dy;
yinh = rs >> 16;
@@ -688,7 +689,7 @@
n = tiles[y].tl;
if(n == 0){
hpass:
- tiles[y].vis++;
+ tiles[y].vis = 1;
ty += dty;
rs = (xinh << 16 | xin & 0xffff) + dx;
xinh = rs >> 16;
@@ -753,22 +754,14 @@
static void
scaltab(int maxdy)
{
- int save, dy;
+ int dy;
Scaler (*s)[nelem(scals[0])];
dy = 1;
memset(scals, 0, sizeof scals);
s = scals + 1;
- save = vw.dy / 2;
- while(dy <= maxdy){
- calcscal(*s++, dy * 2);
- if(dy >= save){
- memcpy(s[0], s[-1], sizeof scals[0]);
- memcpy(s[1], s[-1], sizeof scals[0]);
- s += 2, dy += 2;
- }
- dy++;
- }
+ while(dy <= maxdy)
+ calcscal(*s++, dy++ * 2);
memcpy(scals, scals+1, sizeof *scals);
sce = scals[dy-1];
}
@@ -843,41 +836,32 @@
}
void
-initscal(void)
+setvw(void)
{
int i, an, dx, *p, *q, *e;
double dface;
+ vw.dx = vwsize * 16 & ~15;
+ vw.dy = vwsize * 16 / 2 & ~1;
+ vw.mid = vw.dx / 2 - 1;
+ vw.Δhit = vw.dx / 10;
+ vw.ofs = Vw * (160 - vw.dy) / 2 + (Vw - vw.dx) / 2;
+ scaltab((vw.dx * 1.5) / 2);
+
dx = vw.dx / 2;
dface = Dfoclen + Dmin;
- prjw = dx * dface / (Dglob/2);
- prjh = prjw * Dtlglobal >> 6;
-
i = 0;
p = Δvwθ + dx;
e = p + dx;
q = p - 1;
- dx = vw.dx;
while(p < e){
/* start 0.5px over so vw.θ bisects two middle pixels */
- an = (float)atan(i++ * Dglob / dx / dface) * Rad;
+ an = (float)atan(i++ * Dglob / vw.dx / dface) * Rad;
*p++ = -an;
*q-- = an;
}
-
- scaltab((vw.dx * 1.5) / 2);
-}
-
-void
-setvw(int n)
-{
- vw.size = n;
- vw.dx = n * 16 & ~15;
- vw.dy = n * 16 / 2 & ~1;
- vw.mid = vw.dx / 2 - 1;
- vw.Δhit = vw.dx / 10;
- vw.ofs = Vw * (160 - vw.dy) / 2 + (Vw - vw.dx) / 2;
- initscal();
+ prjw = dx * dface / (Dglob/2);
+ prjh = prjw * Dtlglobal >> 6;
}
void
--- a/snd.c
+++ b/snd.c
@@ -219,7 +219,6 @@
if(sfxd == nil)
return;
opl2wr(Roct, 0);
- opl2wr(Rfed, 0);
sfxp = sfxe = nil;
sfxd = nil;
}
@@ -265,11 +264,13 @@
/* this spins constantly even when there's no music being played continuously,
* in essence only because some sound effects need an echo to play correctly.
* it sucks. */
-static void
+static int
opl2step(void)
{
uchar *p;
+ if(!muson && !sfxon)
+ return -1;
p = sbuf;
while(p < sbuf + sizeof sbuf){
if(stc == sdt && sfxd != nil)
@@ -279,6 +280,7 @@
p = opl2out(p, Nsamp);
stc++;
}
+ return 0;
}
/* stolen property cargocult upsampling */
@@ -421,9 +423,13 @@
void
sndstep(void)
{
- if(!muson && !sfxon)
+ if(sfd < 0)
return;
- opl2step();
+ if(opl2step() < 0){
+ if(!pcmon)
+ return;
+ memset(sbuf, 0, sizeof sbuf);
+ }
pcmstep();
if(!nosleep)
write(sfd, sbuf, sizeof sbuf);
@@ -432,6 +438,8 @@
void
stopsfx(void)
{
+ if(sfd < 0)
+ return;
stopal();
pcm = pcme = nil;
pcmd = nil;
@@ -453,7 +461,7 @@
Sfx *s;
uchar *r, *i;
- if(sfd < 0 || !sfxon || sfxlck)
+ if(sfd < 0 || sfxlck)
return;
s = sfxs+n;
if(pcmon && s->pcm != nil){
@@ -470,7 +478,7 @@
atty = y;
}else
atton = 0;
- }else{
+ }else if(sfxon){
if(sfxd != nil && s->pri < sfxd->pri)
return;
stopal();
@@ -496,10 +504,11 @@
{
int i;
+ if(sfd < 0)
+ return;
stopsfx();
if(!muson && !sfxon)
return;
- opl2wr(Ropm, 0);
for(i=Roct+1; i<Roct+9; i++)
opl2wr(i, 0);
imf = nil;
@@ -532,8 +541,9 @@
}
opl2init(Rate);
opl2wr(Rwse, 0x20);
+ opl2wr(Ropm, 0);
+ opl2wr(Rfed, 0);
for(n=0; n<nelem(hΔ)-1; n++)
hΔ[n] = h[n+1] - h[n];
sfd = fd;
- muson = sfxon = pcmon = 1;
}
--- a/us.h
+++ b/us.h
@@ -1,8 +1,3 @@
-#define MaxX 320
-#define MaxY 200
-
-#define MaxHelpLines 500
-
#define MaxHighName 57
#define MaxScores 7
typedef struct
@@ -12,91 +7,6 @@
u16int completed,episode;
} HighScore;
-#define MaxGameName 32
-#define MaxSaveGames 6
-typedef struct
- {
- char signature[4];
- u16int *oldtest;
- int present;
- char name[MaxGameName + 1];
- } SaveGame;
-
#define MaxString 128 // Maximum input string size
-typedef struct
- {
- s16int x,y,
- w,h,
- px,py;
- } WindowRec; // Record used to save & restore screen windows
-
-typedef enum
- {
- gd_Continue,
- gd_Easy,
- gd_Normal,
- gd_Hard
- } GameDiff;
-
-// Hack import for TED launch support
-extern int tedlevel;
-extern s16int tedlevelnum;
-extern void TEDDeath(void);
-
-extern int ingame, // Set by game code if a game is in progress
- abortgame, // Set if a game load failed
- gm.load, // Set if the current game was loaded
- NoWait,
- HighScoresDirty;
-extern char *abortprogram; // Set to error msg if program is dying
-extern GameDiff restartgame; // Normally gd_Continue, else starts game
-extern u16int PrintX,PrintY; // Current printing location in the window
-extern u16int WindowX,WindowY,// Current location of window
- WindowW,WindowH;// Current size of window
-
-extern int Button0,Button1,
- CursorBad;
-extern s16int CursorX,CursorY;
-
-extern void (*USL_MeasureString)(char far *,u16int *,u16int *),
- (*USL_DrawString)(char far *);
-
-extern int (*USL_SaveGame)(s16int),(*USL_LoadGame)(s16int);
-extern void (*USL_ResetGame)(void);
-extern SaveGame Games[MaxSaveGames];
extern HighScore Scores[];
-
-#define US_HomeWindow() {PrintX = WindowX; PrintY = WindowY;}
-
-extern void US_Startup(void),
- US_Setup(void),
- US_Shutdown(void),
- US_SetLoadSaveHooks(int (*load)(s16int),
- int (*save)(s16int),
- void (*reset)(void)),
- US_TextScreen(void),
- US_UpdateTextScreen(void),
- US_FinishTextScreen(void),
- US_DrawWindow(u16int x,u16int y,u16int w,u16int h),
- US_CenterWindow(u16int,u16int),
- US_SaveWindow(WindowRec *win),
- US_RestoreWindow(WindowRec *win),
- US_ClearWindow(void),
- US_SetPrintRoutines(void (*measure)(char far *,u16int *,u16int *),
- void (*print)(char far *)),
- US_PrintCentered(char far *s),
- US_CPrint(char far *s),
- US_CPrintLine(char far *s),
- US_Print(char far *s),
- US_PrintUnsigned(u32int n),
- US_PrintSigned(s32int n),
- US_StartCursor(void),
- US_ShutCursor(void),
- US_CheckHighScore(s32int score,u16int other),
-extern int US_UpdateCursor(void),
- US_LineInput(s16int x,s16int y,char *buf,char *def,int escok,
- s16int maxchars,s16int maxwidth);
-
- void USL_PrintInCenter(char far *s,Rct r);
- char *USL_GiveSaveName(u16int game);
--- a/us1.c
+++ b/us1.c
@@ -1,212 +1,3 @@
- char *abortprogram;
- int NoWait;
- u16int PrintX,PrintY;
- u16int WindowX,WindowY,WindowW,WindowH;
-
- int Button0,Button1,
- CursorBad;
- s16int CursorX,CursorY;
-
- void (*USL_MeasureString)(char far *,u16int *,u16int *) = VW_MeasurePropString,
- (*USL_DrawString)(char far *) = VWB_DrawPropString;
-
- SaveGame Games[MaxSaveGames];
-
-// Window/Printing routines
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_Print() - Prints a string in the current window. Newlines are
-// supported.
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_Print(char far *s)
-{
- char c,far *se;
- u16int w,h;
-
- while (*s)
- {
- se = s;
- while ((c = *se) && (c != '\n'))
- se++;
- *se = '\0';
-
- USL_MeasureString(s,&w,&h);
- px = PrintX;
- py = PrintY;
- USL_DrawString(s);
-
- s = se;
- if (c)
- {
- *se = c;
- s++;
-
- PrintX = WindowX;
- PrintY += h;
- }
- else
- PrintX += w;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_PrintUnsigned() - Prints an u32int
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_PrintUnsigned(u32int n)
-{
- char buffer[32];
-
- US_Print(ultoa(n,buffer,10));
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_PrintSigned() - Prints a s32int
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_PrintSigned(s32int n)
-{
- char buffer[32];
-
- US_Print(ltoa(n,buffer,10));
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// USL_PrintInCenter() - Prints a string in the center of the given rect
-//
-///////////////////////////////////////////////////////////////////////////
-void
-USL_PrintInCenter(char far *s,Rectangle r)
-{
- u16int w,h;
-
- USL_MeasureString(s,&w,&h);
-
- px = r.min.x + ((Dx(r) - w) / 2);
- py = r.min.y + ((Dy(r) - h) / 2);
- USL_DrawString(s);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_PrintCentered() - Prints a string centered in the current window.
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_PrintCentered(char far *s)
-{
- USL_PrintInCenter(s,Rect(WindowX,WindowY,WindowW+WindowX,WindowH+WindowY);
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_CPrintLine() - Prints a string centered on the current line and
-// advances to the next line. Newlines are not supported.
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_CPrintLine(char far *s)
-{
- u16int w,h;
-
- USL_MeasureString(s,&w,&h);
-
- if (w > WindowW)
- Quit("US_CPrintLine() - String exceeds width");
- px = WindowX + ((WindowW - w) / 2);
- py = PrintY;
- USL_DrawString(s);
- PrintY += h;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_CPrint() - Prints a string in the current window. Newlines are
-// supported.
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_CPrint(char far *s)
-{
- char c,far *se;
-
- while (*s)
- {
- se = s;
- while ((c = *se) && (c != '\n'))
- se++;
- *se = '\0';
-
- US_CPrintLine(s);
-
- s = se;
- if (c)
- {
- *se = c;
- s++;
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_ClearWindow() - Clears the current window to white and homes the
-// cursor
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_ClearWindow(void)
-{
- VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
- PrintX = WindowX;
- PrintY = WindowY;
-}
-
-///////////////////////////////////////////////////////////////////////////
-//
-// US_DrawWindow() - Draws a frame and sets the current window parms
-//
-///////////////////////////////////////////////////////////////////////////
-void
-US_DrawWindow(u16int x,u16int y,u16int w,u16int h)
-{
- u16int i,
- sx,sy,sw,sh;
-
- WindowX = x * 8;
- WindowY = y * 8;
- WindowW = w * 8;
- WindowH = h * 8;
-
- PrintX = WindowX;
- PrintY = WindowY;
-
- sx = (x - 1) * 8;
- sy = (y - 1) * 8;
- sw = (w + 1) * 8;
- sh = (h + 1) * 8;
-
- US_ClearWindow();
-
- VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
- for (i = sx + 8;i <= sx + sw - 8;i += 8)
- VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
- VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
-
- for (i = sy + 8;i <= sy + sh - 8;i += 8)
- VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
-}
-
-// Input routines
-
///////////////////////////////////////////////////////////////////////////
//
// USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
--- a/vh.asm
+++ /dev/null
@@ -1,110 +1,0 @@
-; ID_VL.ASM
-
- IDEAL
- MODEL MEDIUM,C
-
- INCLUDE 'ID_VL.EQU'
-
-SCREENSEG = 0a000h
-
-UPDATEWIDE = 20
-UPDATEHIGH = 13
-
- DATASEG
-
-
-EXTRN bufferofs :WORD
-EXTRN displayofs :WORD
-EXTRN ylookup :WORD
-EXTRN linewidth :WORD
-EXTRN blockstarts :WORD ;offsets from drawofs for each update block
-
-EXTRN update :BYTE
-
- CODESEG
-
-
-;=================
-;
-; VH_UpdateScreen
-;
-;=================
-
-PROC VH_UpdateScreen
-PUBLIC VH_UpdateScreen
-USES si,di
-
- mov dx,SC_INDEX
- mov ax,SC_MAPMASK+15*256
- out dx,ax
-
- mov dx,GC_INDEX
- mov al,GC_MODE
- out dx,al
-
- inc dx
- in al,dx
- and al,252
- or al,1
- out dx,al
-
- mov bx,UPDATEWIDE*UPDATEHIGH-1 ; bx is the tile number
- mov dx,[linewidth]
-
-;
-; see if the tile needs to be copied
-;
-@@checktile:
- test [update+bx],1
- jnz @@copytile
-@@next:
- dec bx
- jns @@checktile
-
-;
-; done
-;
- mov dx,GC_INDEX+1
- in al,dx
- and al,NOT 3
- or al,0
- out dx,al
- ret
-
-;
-; copy a tile
-;
-@@copytile:
- mov [update+bx],0
- shl bx,1
- mov si,[blockstarts+bx]
- shr bx,1
- mov di,si
- add si,[bufferofs]
- add di,[displayofs]
-
- mov ax,SCREENSEG
- mov ds,ax
-
-REPT 16
- mov al,[si]
- mov [di],al
- mov al,[si+1]
- mov [di+1],al
- mov al,[si+2]
- mov [di+2],al
- mov al,[si+3]
- mov [di+3],al
- add si,dx
- add di,dx
-ENDM
-
- mov ax,ss
- mov ds,ax
- jmp @@next
-
-ENDP
-
-
- END
-
--- a/vh.c
+++ /dev/null
@@ -1,230 +1,0 @@
-#define WHITE 15 // graphics mode independant colors
-#define BLACK 0
-#define FIRSTCOLOR 1
-#define SECONDCOLOR 12
-#define F_WHITE 15
-#define F_BLACK 0
-#define F_FIRSTCOLOR 1
-#define F_SECONDCOLOR 12
-
-#define MAXSHIFTS 1
-
-typedef struct
-{
- s16int width,height;
-} pictabletype;
-
-typedef struct
-{
- s16int height;
- s16int location[256];
- char width[256];
-} fontstruct;
-
-extern pictabletype _seg *pictable;
-extern pictabletype _seg *picmtable;
-extern spritetabletype _seg *spritetable;
-
-extern u8int fontcolor;
-extern s16int fontnumber;
-extern s16int px,py;
-
-#define VW_SetCRTC VL_SetCRTC
-#define VW_SetScreen VL_SetScreen
-#define VW_Bar VL_Bar
-#define VW_Plot VL_Plot
-#define VW_Hlin(x,z,y,c) VL_Hlin(x,y,(z)-(x)+1,c)
-#define VW_Vlin(y,z,x,c) VL_Vlin(x,y,(z)-(y)+1,c)
-#define VW_DrawPic VH_DrawPic
-#define VW_ColorBorder VL_ColorBorder
-#define VW_WaitVBL VL_WaitVBL
-#define VW_FadeIn() VL_FadeIn(0,255,&gamepal,30);
-#define VW_FadeOut() VL_FadeOut(0,255,0,0,0,30);
-#define VW_ScreenToScreen VL_ScreenToScreen
-#define VW_SetDefaultColors VH_SetDefaultColors
-#define EGAMAPMASK(x) VGAMAPMASK(x)
-#define EGAWRITEMODE(x) VGAWRITEMODE(x)
-#define LatchDrawChar(x,y,p) VL_LatchToScreen(latchpics[0]+(p)*16,2,8,x,y)
-#define LatchDrawTile(x,y,p) VL_LatchToScreen(latchpics[1]+(p)*64,4,16,x,y)
-#define NUMLATCHPICS 100
-
-#define PIXTOBLOCK 4 // 16 pixels to an update block
-
-u8int update[UPDATEHIGH][UPDATEWIDE];
-
-//==========================================================================
-
-pictabletype _seg *pictable;
-
-
-s16int px,py;
-u8int fontcolor,backcolor;
-s16int fontnumber;
-s16int bufferwidth,bufferheight;
-
-
-/*
-=============================================================================
-
- Double buffer management routines
-
-=============================================================================
-*/
-
-
-/*
-=======================
-=
-= VW_MarkUpdateBlock
-=
-= Takes a pixel bounded block and marks the tiles in bufferblocks
-= Returns 0 if the entire block is off the buffer screen
-=
-=======================
-*/
-
-s16int VW_MarkUpdateBlock (s16int x1, s16int y1, s16int x2, s16int y2)
-{
- s16int x,y,xt1,yt1,xt2,yt2,nextline;
- u8int *mark;
-
- xt1 = x1>>PIXTOBLOCK;
- yt1 = y1>>PIXTOBLOCK;
-
- xt2 = x2>>PIXTOBLOCK;
- yt2 = y2>>PIXTOBLOCK;
-
- if (xt1<0)
- xt1=0;
- else if (xt1>=UPDATEWIDE)
- return 0;
-
- if (yt1<0)
- yt1=0;
- else if (yt1>UPDATEHIGH)
- return 0;
-
- if (xt2<0)
- return 0;
- else if (xt2>=UPDATEWIDE)
- xt2 = UPDATEWIDE-1;
-
- if (yt2<0)
- return 0;
- else if (yt2>=UPDATEHIGH)
- yt2 = UPDATEHIGH-1;
-
- mark = updateptr + uwidthtable[yt1] + xt1;
- nextline = UPDATEWIDE - (xt2-xt1) - 1;
-
- for (y=yt1;y<=yt2;y++)
- {
- for (x=xt1;x<=xt2;x++)
- *mark++ = 1; // this tile will need to be updated
-
- mark += nextline;
- }
-
- return 1;
-}
-
-void VWB_DrawTile8 (s16int x, s16int y, s16int tile)
-{
- if (VW_MarkUpdateBlock (x,y,x+7,y+7))
- LatchDrawChar(x,y,tile);
-}
-
-void VWB_Plot (s16int x, s16int y, s16int color)
-{
- if (VW_MarkUpdateBlock (x,y,x,y))
- VW_Plot(x,y,color);
-}
-
-void VWB_Vlin (s16int y1, s16int y2, s16int x, s16int color)
-{
- if (VW_MarkUpdateBlock (x,y1,x,y2))
- VW_Vlin(y1,y2,x,color);
-}
-
-void VW_UpdateScreen (void)
-{
- VH_UpdateScreen ();
-}
-
-
-/*
-=============================================================================
-
- WOLFENSTEIN STUFF
-
-=============================================================================
-*/
-
-/*
-=====================
-=
-= LatchDrawPic
-=
-=====================
-*/
-
-void LatchDrawPic (u16int x, u16int y, u16int picnum)
-{
- u16int wide, height, source;
-
- wide = pictable[picnum-STARTPICS].width;
- height = pictable[picnum-STARTPICS].height;
- source = latchpics[2+picnum-LATCHPICS_LUMP_START];
-
- VL_LatchToScreen (source,wide/4,height,x*8,y);
-}
-
-
-//==========================================================================
-
-/*
-===================
-=
-= LoadLatchMem
-=
-===================
-*/
-
-void LoadLatchMem (void)
-{
- s16int i,j,p,m,width,height,start,end;
- u8int far *src;
- u16int destoff;
-
-//
-// tile 8s
-//
- → fuck this
- latchpics[0] = freelatch;
- src = (u8int _seg *)grsegs[STARTTILE8];
- destoff = freelatch;
-
- for (i=0;i<NUMTILE8;i++)
- {
- VL_MemToLatch (src,8,8,destoff);
- src += 64;
- destoff +=16;
- }
-
-//
-// pics
-//
- start = LATCHPICS_LUMP_START;
- end = LATCHPICS_LUMP_END;
-
- for (i=start;i<=end;i++)
- {
- latchpics[2+i-start] = destoff;
- width = pictable[i-STARTPICS].width;
- height = pictable[i-STARTPICS].height;
- VL_MemToLatch (grsegs[i],width,height,destoff);
- destoff += width/4 *height;
- }
-
- EGAMAPMASK(15);
-}
--- a/vl.asm
+++ /dev/null
@@ -1,124 +1,0 @@
-SCREENSEG = 0a000h
-
- DATASEG
-
- EXTRN TimeCount:WORD ; incremented every 70th of a second
- EXTRN linewidth:WORD
-
-starttime dw ?
-
- CODESEG
-
-;==============
-;
-; VL_SetCRTC
-;
-;==============
-
-PROC VL_SetCRTC crtc:WORD
-PUBLIC VL_SetCRTC
-
-;
-; wait for a display signal to make sure the raster isn't in the middle
-; of a sync
-;
- cli
-
- mov dx,STATUS_REGISTER_1
-
-@@waitdisplay:
- in al,dx
- test al,1 ;1 = display is disabled (HBL / VBL)
- jnz @@waitdisplay
-
-
-;
-; set CRTC start
-;
-; for some reason, my XT's EGA card doesn't like word outs to the CRTC
-; index...
-;
- mov cx,[crtc]
- mov dx,CRTC_INDEX
- mov al,0ch ;start address high register
- out dx,al
- inc dx
- mov al,ch
- out dx,al
- dec dx
- mov al,0dh ;start address low register
- out dx,al
- mov al,cl
- inc dx
- out dx,al
-
-
- sti
-
- ret
-
-ENDP
-
-;============================================================================
-;
-; VL_ScreenToScreen
-;
-; Basic block copy routine. Copies one block of screen memory to another,
-; using write mode 1 (sets it and returns with write mode 0). bufferofs is
-; NOT accounted for.
-;
-;============================================================================
-
-PROC VL_ScreenToScreen source:WORD, dest:WORD, wide:WORD, height:WORD
-PUBLIC VL_ScreenToScreen
-USES SI,DI
-
- pushf
- cli
-
- mov dx,SC_INDEX
- mov ax,SC_MAPMASK+15*256
- out dx,ax
- mov dx,GC_INDEX
- mov al,GC_MODE
- out dx,al
- inc dx
- in al,dx
- and al,NOT 3
- or al,1
- out dx,al
-
- popf
-
- mov bx,[linewidth]
- sub bx,[wide]
-
- mov ax,SCREENSEG
- mov es,ax
- mov ds,ax
-
- mov si,[source]
- mov di,[dest] ;start at same place in all planes
- mov dx,[height] ;scan lines to draw
- mov ax,[wide]
-
-@@lineloop:
- mov cx,ax
- rep movsb
- add si,bx
- add di,bx
-
- dec dx
- jnz @@lineloop
-
- mov dx,GC_INDEX+1
- in al,dx
- and al,NOT 3
- out dx,al
-
- mov ax,ss
- mov ds,ax ;restore turbo's data segment
-
- ret
-
-ENDP
--- a/vl.c
+++ /dev/null
@@ -1,243 +1,0 @@
-u16int bufferofs;
-u16int displayofs,pelpan;
-
-#define SC_INDEX 0x3C4
-#define SC_RESET 0
-#define SC_CLOCK 1
-#define SC_MAPMASK 2
-#define SC_CHARMAP 3
-#define SC_MEMMODE 4
-
-#define CRTC_INDEX 0x3D4
-#define CRTC_H_TOTAL 0
-#define CRTC_H_DISPEND 1
-#define CRTC_H_BLANK 2
-#define CRTC_H_ENDBLANK 3
-#define CRTC_H_RETRACE 4
-#define CRTC_H_ENDRETRACE 5
-#define CRTC_V_TOTAL 6
-#define CRTC_OVERFLOW 7
-#define CRTC_ROWSCAN 8
-#define CRTC_MAXSCANLINE 9
-#define CRTC_CURSORSTART 10
-#define CRTC_CURSOREND 11
-#define CRTC_STARTHIGH 12
-#define CRTC_STARTLOW 13
-#define CRTC_CURSORHIGH 14
-#define CRTC_CURSORLOW 15
-#define CRTC_V_RETRACE 16
-#define CRTC_V_ENDRETRACE 17
-#define CRTC_V_DISPEND 18
-#define CRTC_OFFSET 19
-#define CRTC_UNDERLINE 20
-#define CRTC_V_BLANK 21
-#define CRTC_V_ENDBLANK 22
-#define CRTC_MODE 23
-#define CRTC_LINECOMPARE 24
-
-
-#define GC_INDEX 0x3CE
-#define GC_SETRESET 0
-#define GC_ENABLESETRESET 1
-#define GC_COLORCOMPARE 2
-#define GC_DATAROTATE 3
-#define GC_READMAP 4
-#define GC_MODE 5
-#define GC_MISCELLANEOUS 6
-#define GC_COLORDONTCARE 7
-#define GC_BITMASK 8
-
-#define ATR_INDEX 0x3c0
-#define ATR_MODE 16
-#define ATR_OVERSCAN 17
-#define ATR_COLORPLANEENABLE 18
-#define ATR_PELPAN 19
-#define ATR_COLORSELECT 20
-
-#define STATUS_REGISTER_1 0x3da
-
-#define PEL_WRITE_ADR 0x3c8
-#define PEL_READ_ADR 0x3c7
-#define PEL_DATA 0x3c9
-
-#define SCREENSEG 0xa000
-
-#define SCREENWIDTH 80 // default screen width in bytes
-#define MAXSCANLINES 200 // size of ylookup table
-
-#define TILEWIDTH 4
-
-extern u16int bufferofs; // all drawing is reletive to this
-extern u16int displayofs,pelpan; // last setscreen coordinates
-
-extern u16int screenseg; // set to 0xa000 for asm convenience
-
-extern u16int linewidth;
-extern u16int ylookup[MAXSCANLINES];
-
-extern int screenfaded;
-extern u16int bordercolor;
-
-#define VGAWRITEMODE(x) asm{\
-cli;\
-mov dx,GC_INDEX;\
-mov al,GC_MODE;\
-out dx,al;\
-inc dx;\
-in al,dx;\
-and al,252;\
-or al,x;\
-out dx,al;\
-sti;}
-
-#define VGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov al,SC_MAPMASK;mov ah,x;out dx,ax;sti;}
-#define VGAREADMAP(x) asm{cli;mov dx,GC_INDEX;mov al,GC_READMAP;mov ah,x;out dx,ax;sti;}
-
-u16int screenseg=SCREENSEG; // set to 0xa000 for asm convenience
-
-u16int linewidth;
-u16int ylookup[MAXSCANLINES];
-
-int screenfaded;
-u16int bordercolor;
-
-int fastpalette; // if true, use outsb to set
-
-u8int pixmasks[4] = {1,2,4,8};
-u8int leftmasks[4] = {15,14,12,8};
-u8int rightmasks[4] = {1,3,7,15};
-
-void VL_Plot (s16int x, s16int y, s16int color)
-{
- u8int mask;
-
- mask = pixmasks[x&3];
- VGAMAPMASK(mask);
- *(u8int far *)MK_FP(SCREENSEG,bufferofs+(ylookup[y]+(x>>2))) = color;
- VGAMAPMASK(15);
-}
-
-void VL_Vlin (s16int x, s16int y, s16int height, s16int color)
-{
- u8int far *dest,mask;
-
- mask = pixmasks[x&3];
- VGAMAPMASK(mask);
-
- dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));
-
- while (height--)
- {
- *dest = color;
- dest += linewidth;
- }
-
- VGAMAPMASK(15);
-}
-
-void VL_MemToLatch (u8int far *source, s16int width, s16int height, u16int dest)
-{
- u16int count;
- u8int plane,mask;
-
- count = ((width+3)/4)*height;
- mask = 1;
- for (plane = 0; plane<4 ; plane++)
- {
- VGAMAPMASK(mask);
- mask <<= 1;
-
-asm mov cx,count
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm mov di,[dest]
-asm lds si,[source]
-asm rep movsb
-asm mov ax,ss
-asm mov ds,ax
-
- source+= count;
- }
-}
-
-void VL_MemToScreen (u8int far *source, s16int width, s16int height, s16int x, s16int y)
-{
- u8int far *screen,far *dest,mask;
- s16int plane;
-
- width>>=2;
- dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
- mask = 1 << (x&3);
-
- for (plane = 0; plane<4; plane++)
- {
- VGAMAPMASK(mask);
- mask <<= 1;
- if (mask == 16)
- mask = 1;
-
- screen = dest;
- for (y=0;y<height;y++,screen+=linewidth,source+=width)
- _fmemcpy (screen,source,width);
- }
-}
-
-void VL_MaskedToScreen (u8int far *source, s16int width, s16int height, s16int x, s16int y)
-{
- u8int far *screen,far *dest,mask;
- u8int far *maskptr;
- s16int plane;
-
- width>>=2;
- dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
-// mask = 1 << (x&3);
-
-// maskptr = source;
-
- for (plane = 0; plane<4; plane++)
- {
- VGAMAPMASK(mask);
- mask <<= 1;
- if (mask == 16)
- mask = 1;
-
- screen = dest;
- for (y=0;y<height;y++,screen+=linewidth,source+=width)
- _fmemcpy (screen,source,width);
- }
-}
-
-void VL_LatchToScreen (u16int source, s16int width, s16int height, s16int x, s16int y)
-{
- VGAWRITEMODE(1);
- VGAMAPMASK(15);
-
-asm mov di,[y] // dest = bufferofs+ylookup[y]+(x>>2)
-asm shl di,1
-asm mov di,[WORD PTR ylookup+di]
-asm add di,[bufferofs]
-asm mov ax,[x]
-asm shr ax,2
-asm add di,ax
-
-asm mov si,[source]
-asm mov ax,[width]
-asm mov bx,[linewidth]
-asm sub bx,ax
-asm mov dx,[height]
-asm mov cx,SCREENSEG
-asm mov ds,cx
-asm mov es,cx
-
-drawline:
-asm mov cx,ax
-asm rep movsb
-asm add di,bx
-asm dec dx
-asm jnz drawline
-
-asm mov ax,ss
-asm mov ds,ax
-
- VGAWRITEMODE(0);
-}
--- a/wl3d.c
+++ b/wl3d.c
@@ -11,12 +11,13 @@
char *ext = "wl6";
int ver;
int grabon;
-int kbon, mson;
-int kb, mΔx, mΔy, mΔb;
+int kbon;
+int kb, mΔx, mΔy, mb;
int demexit;
void (*step)(void);
int Δtc;
int nosleep;
+int autorun;
Channel *csc;
QLock inlck;
@@ -29,12 +30,12 @@
static Rectangle fbr, grabr;
static Image *fb;
static Channel *reszc;
-static int cson;
+static int cson, mson, fixms;
static void
mproc(void *)
{
- int n, fd, nerr;
+ int n, b, fd, nerr;
char buf[1+5*12], *px, *py, *pb;
Point o, p;
@@ -62,14 +63,20 @@
case 'm':
if(!mson)
break;
+ if(fixms){
+ fixms = 0;
+ goto res;
+ }
p.x = strtol(px, nil, 10);
p.y = strtol(py, nil, 10);
+ b = strtol(pb, nil, 10);
qlock(&inlck);
mΔx += p.x - o.x;
- mΔy += o.y - p.y;
- mΔb = *pb;
+ mΔy += p.y - o.y;
+ mb = b;
qunlock(&inlck);
if(!ptinrect(p, grabr)){
+ res:
fprint(fd, "m%d %d", p0.x, p0.y);
p = p0;
}
@@ -106,7 +113,7 @@
chartorune(&r, buf+1);
nbsend(csc, &r);
}
- if(c != 'k' || c != 'K' || !kbon)
+ if(c != 'k' && c != 'K' || !kbon)
continue;
s = buf+1;
k = 0;
@@ -157,7 +164,7 @@
croak(void *, char *s)
{
if(strncmp(s, "sys:", 4) == 0)
- mson = 0;
+ grab(0);
noted(NDFLT);
}
@@ -164,7 +171,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-23dopqs] [-f demo] [-m dir] [-w map] [-x difficulty]\n", argv0);
+ fprint(2, "usage: %s [-23dopqs] [-f demo] [-m dir] [-w map difc]\n", argv0);
threadexits("usage");
}
@@ -176,18 +183,10 @@
p = mallocz(n, 1);
if(p == nil)
sysfatal("emalloc: %r");
+ setmalloctag(p, getcallerpc(&n));
return p;
}
-void *
-erealloc(void *p, ulong n)
-{
- p = realloc(p, n);
- if(p == nil)
- sysfatal("erealloc: %r");
- return p;
-}
-
void
grab(int on)
{
@@ -203,6 +202,7 @@
return;
}
write(fd, nocurs, sizeof nocurs);
+ fixms++;
}else if(fd >= 0){
close(fd);
fd = -1;
@@ -242,13 +242,14 @@
void
threadmain(int argc, char **argv)
{
- int tc;
+ int tc, m, d;
vlong t0, t, dt;
char *datdir, *df;
datdir = "/sys/games/lib/wl3d/";
df = nil;
- step = mstep;
+ m = -1;
+ d = 0;
ARGBEGIN{
case '2': ext = "sd2"; ver = SOD; break;
case '3': ext = "sd3"; ver = SOD; break;
@@ -259,8 +260,7 @@
case 'p': nosleep++; break;
case 'q': demexit++; break;
case 's': ext = "sod"; ver = SOD; break;
- case 'w': /* TODO: warp to ep, level */ break;
- case 'x': /* TODO: set difficulty for warp */ break;
+ case 'w': m = strtoul(EARGF(usage()), nil, 0); d = strtoul(EARGF(usage()), nil, 0); break;
default:
usage();
}ARGEND;
@@ -270,7 +270,6 @@
pal = pals[C0];
resetfb();
dat(datdir);
- initsnd();
csc = chancreate(sizeof(Rune), 20);
reszc = chancreate(sizeof(int), 2);
if(csc == nil | reszc == nil)
@@ -277,11 +276,13 @@
sysfatal("chancreate: %r");
if(proccreate(kproc, nil, 8192) < 0 || proccreate(mproc, nil, 8192) < 0)
sysfatal("proccreate: %r");
-
- init(df);
+ tab();
+ initsnd();
+ init(df, m, d);
cson++;
t0 = nsec();
Δtc = 1;
+ step = qstep;
for(;;){
if(nbrecv(reszc, nil) != 0){
if(getwindow(display, Refnone) < 0)
@@ -298,8 +299,6 @@
tc = 10;
Δtc = tc;
t0 += tc * Td;
- if(onestep)
- t0 += Td;
dt = (t0 - t) / Te6;
if(dt > 0 && !nosleep)
sleep(dt);