ref: ddcaa37baf64e0fc44f8ebf051005a0b0a1fd29b
parent: 7d1bc4ab95db2a1199150eb91cc0d7b1a5dd1128
author: Konstantinn Bonnet <[email protected]>
date: Sun Dec 4 22:15:07 EST 2016
add scaled walls and sprites, misc fixes - fs: use more appropriate types for vswap data, interpret sprite data partially on load - fs: fix stt sprites set based on sprs before it's allocated - fs: fix pcm number and placement for wl1/sdm - gm: use mtc as tic count for cam sprite display - gm: constant time checks in gm only, not in main loop - gm: fix demo and deathcam sprites placements - hub: slow fadeout after demof end - map: fix blocking static objects being set as pickable bonus items - map: fix sod sprite offsets - rend: remove bullshit special shape check - rend: fix viss sorting in scaleall - snd: fix extra pcm clipping/cracking; the remainder seems similar to reference
--- a/dat.h
+++ b/dat.h
@@ -2,6 +2,8 @@
typedef int s32int;
typedef struct Col Col;
typedef struct Dat Dat;
+typedef struct Sprc Sprc;
+typedef struct Spr Spr;
typedef struct Pic Pic;
typedef struct Fnt Fnt;
typedef struct Sfx Sfx;
@@ -82,8 +84,22 @@
uchar *p;
uchar *e;
};
-extern Dat *wals, *sprs, *imfs;
-extern uchar **exts, **dems, **epis;
+extern Dat *imfs;
+struct Sprc{
+ uchar *p;
+ int s;
+ int e;
+};
+struct Spr{
+ int lx;
+ int rx;
+ Sprc **cs;
+ Sprc **ce;
+ uchar *sp;
+};
+extern Spr *sprs;
+extern uchar **exts, **dems, **epis, **wals;
+extern int drofs;
struct Pic{
int x;
@@ -1096,6 +1112,7 @@
GSspark2,
GSspark3,
GSspark4,
+ GSe,
θE = 0,
θNE = 45,
@@ -1123,9 +1140,10 @@
void (*up)(Obj *);
void (*act)(Obj *);
int dt;
- Dat *spr;
+ int sprn;
State *n;
int rot;
+ Spr *spr;
};
extern State stt[];
struct Obj{
@@ -1164,7 +1182,7 @@
extern Door doors[], *doore, pusher;
struct Static{
Tile *tl;
- Dat *spr;
+ Spr *spr;
int f;
int item;
};
@@ -1243,7 +1261,6 @@
int demo;
int record;
int load;
- int fizz;
};
extern Game gm;
extern int god, noclip, onestep;
--- a/debug.c
+++ b/debug.c
@@ -1,326 +1,10 @@
-// WL_DEBUG.C
-
-#include "WL_DEF.H"
-#pragma hdrstop
-#include <BIOS.H>
-
-/*
-=============================================================================
-
- LOCAL CONSTANTS
-
-=============================================================================
-*/
-
#define VIEWTILEX (vw.dx/16)
#define VIEWTILEY (vw.dy/16)
-/*
-=============================================================================
-
- GLOBAL VARIABLES
-
-=============================================================================
-*/
-
-
-s16int DebugKeys (void);
-
-/*
-=============================================================================
-
- LOCAL VARIABLES
-
-=============================================================================
-*/
-
-
s16int maporgx;
s16int maporgy;
enum {mapview,tilemapview,actoratview,visview} viewtype;
-void ViewMap (void);
-
-//===========================================================================
-
-/*
-==================
-=
-= DebugMemory
-=
-==================
-*/
-
-void DebugMemory (void)
-{
- s16int i;
- char scratch[80],str[10];
- s32int mem;
-
- CenterWindow (16,7);
-
- US_CPrint ("Memory Usage");
- US_CPrint ("------------");
- US_Print ("Total :");
- US_PrintUnsigned (mminfo.mainmem/1024);
- US_Print ("k\nFree :");
- US_PrintUnsigned (MM_UnusedMemory()/1024);
- US_Print ("k\nWith purge:");
- US_PrintUnsigned (MM_TotalFree()/1024);
- US_Print ("k\n");
- VW_UpdateScreen();
- IN_Ack ();
-}
-
-//===========================================================================
-
-/*
-==================
-=
-= CountObjects
-=
-==================
-*/
-
-void CountObjects (void)
-{
- s16int i,total,count,active,inactive,doors;
- objtype *obj;
-
- CenterWindow (16,7);
- active = inactive = count = doors = 0;
-
- US_Print ("Total statics :");
- total = laststatobj-&statobjlist[0];
- US_PrintUnsigned (total);
-
- US_Print ("\nIn use statics:");
- for (i=0;i<total;i++)
- if (statobjlist[i].shapenum != -1)
- count++;
- else
- doors++; //debug
- US_PrintUnsigned (count);
-
- US_Print ("\nDoors :");
- US_PrintUnsigned (doornum);
-
- for (obj=player->next;obj;obj=obj->next)
- {
- if (obj->active)
- active++;
- else
- inactive++;
- }
-
- US_Print ("\nTotal actors :");
- US_PrintUnsigned (active+inactive);
-
- US_Print ("\nActive actors :");
- US_PrintUnsigned (active);
-
- VW_UpdateScreen();
- IN_Ack ();
-}
-
-void ShapeTest (void)
-{
-extern u16int NumDigi;
-extern u16int _seg *DigiList;
-static char buf[10];
-
- int done;
- u8int scan;
- s16int i,j,k,x;
- u32int l;
- uchar *addr;
- PageListStruct far *page;
-
- CenterWindow(20,16);
- VW_UpdateScreen();
- for (i = 0,done = false;!done;)
- {
- US_ClearWindow();
-// sound = -1;
-
- page = &PMPages[i];
- US_Print(" Page #");
- US_PrintUnsigned(i);
- if (i < PMSpriteStart)
- US_Print(" (Wall)");
- else if (i < PMSoundStart)
- US_Print(" (Sprite)");
- else if (i == ChunksInFile - 1)
- US_Print(" (Sound Info)");
- else
- US_Print(" (Sound)");
-
- US_Print("\n XMS: ");
- if (page->xmsPage != -1)
- US_PrintUnsigned(page->xmsPage);
- else
- US_Print("No");
-
- US_Print("\n Main: ");
- if (page->mainPage != -1)
- US_PrintUnsigned(page->mainPage);
- else if (page->emsPage != -1)
- {
- US_Print("EMS ");
- US_PrintUnsigned(page->emsPage);
- }
- else
- US_Print("No");
-
- US_Print("\n Last hit: ");
- US_PrintUnsigned(page->lastHit);
-
- US_Print("\n Address: ");
- addr = PM_GetPageAddress(i);
- sprintf(buf,"0x%04x",(u16int)addr);
- US_Print(buf);
-
- if (addr)
- {
- if (i < PMSpriteStart)
- {
- //
- // draw the wall
- //
- bufferofs += 32*SCREENWIDTH;
- postx = 128;
- postwidth = 1;
- postsource = ((s32int)((u16int)addr))<<16;
- for (x=0;x<64;x++,postx++,postsource+=64)
- {
- wallheight[postx] = 256;
- ScalePost ();
- }
- bufferofs -= 32*SCREENWIDTH;
- }
- else if (i < PMSoundStart)
- {
- //
- // draw the sprite
- //
- bufferofs += 32*SCREENWIDTH;
- scalespr (160, i-PMSpriteStart, 64);
- bufferofs -= 32*SCREENWIDTH;
- }
- else if (i == ChunksInFile - 1)
- {
- US_Print("\n\n Number of sounds: ");
- US_PrintUnsigned(NumDigi);
- for (l = j = k = 0;j < NumDigi;j++)
- {
- l += DigiList[(j * 2) + 1];
- k += (DigiList[(j * 2) + 1] + (PMPageSize - 1)) / PMPageSize;
- }
- US_Print("\n Total bytes: ");
- US_PrintUnsigned(l);
- US_Print("\n Total pages: ");
- US_PrintUnsigned(k);
- }
- else
- {
- u8int far *dp = (u8int far *)MK_FP(addr,0);
- for (j = 0;j < NumDigi;j++)
- {
- k = (DigiList[(j * 2) + 1] + (PMPageSize - 1)) / PMPageSize;
- if
- (
- (i >= PMSoundStart + DigiList[j * 2])
- && (i < PMSoundStart + DigiList[j * 2] + k)
- )
- break;
- }
- if (j < NumDigi)
- {
-// sound = j;
- US_Print("\n Sound #");
- US_PrintUnsigned(j);
- US_Print("\n Segment #");
- US_PrintUnsigned(i - PMSoundStart - DigiList[j * 2]);
- }
- for (j = 0;j < page->length;j += 32)
- {
- u8int v = dp[j];
- s16int v2 = (u16int)v;
- v2 -= 128;
- v2 /= 4;
- if (v2 < 0)
- VWB_Vlin(WindowY + WindowH - 32 + v2,
- WindowY + WindowH - 32,
- WindowX + 8 + (j / 32),BLACK);
- else
- VWB_Vlin(WindowY + WindowH - 32,
- WindowY + WindowH - 32 + v2,
- WindowX + 8 + (j / 32),BLACK);
- }
- }
- }
-
- VW_UpdateScreen();
-
- while (!(scan = LastScan))
- SD_Poll();
-
- IN_ClearKey(scan);
- switch (scan)
- {
- case sc_LeftArrow:
- if (i)
- i--;
- break;
- case sc_RightArrow:
- if (++i >= ChunksInFile)
- i--;
- break;
- case sc_W: // Walls
- i = 0;
- break;
- case sc_S: // Sprites
- i = PMSpriteStart;
- break;
- case sc_D: // Digitized
- i = PMSoundStart;
- break;
- case sc_I: // Digitized info
- i = ChunksInFile - 1;
- break;
- case sc_L: // Load all pages
- for (j = 0;j < ChunksInFile;j++)
- PM_GetPage(j);
- break;
- case sc_P:
-// if (sound != -1)
-// SD_PlayDigitized(sound);
- break;
- case sc_Escape:
- done = true;
- break;
- case sc_Enter:
- PM_GetPage(i);
- break;
- }
- }
- SD_StopDigitized();
-}
-#pragma warn +pia
-
-
-
-//===========================================================================
-
-
-/*
-================
-=
-= DebugKeys
-=
-================
-*/
-
s16int DebugKeys (void)
{
int esc;
@@ -342,12 +26,6 @@
return 1;
}
- if (Keyboard[sc_C]) // C = count objects
- {
- CountObjects();
- return 1;
- }
-
if (Keyboard[sc_E]) // E = quit level
{
if (tedlevel)
@@ -401,11 +79,6 @@
gamestate.ammo = 99;
huda ();
IN_Ack ();
- return 1;
- }
- else if (Keyboard[sc_M]) // M = memory info
- {
- DebugMemory();
return 1;
}
#ifdef SPEAR
--- a/def.h
+++ b/def.h
@@ -161,7 +161,7 @@
// refresh variables
extern s32int postsource;
-extern u16int postx;
+extern u16int scx;
extern u16int postwidth;
extern dirtype opposite[9];
--- a/drw.c
+++ b/drw.c
@@ -5,8 +5,8 @@
Fnt fnts[2], *fnt;
Pic *pics;
-uchar **exts, **dems, **epis;
-Dat *wals, *sprs;
+uchar **exts, **dems, **epis, **wals;
+Spr *sprs;
int scale, npx;
uchar *px, pxb[Va], fzb[Vw*Vhud];
--- a/fns.h
+++ b/fns.h
@@ -31,6 +31,7 @@
void hudw(void);
void hudp(void);
void clear(void);
+void scalspr(int, int, int);
s32int ffs(s32int, s32int);
void render(void);
void initscal(void);
@@ -50,6 +51,7 @@
void mapmus(void);
void initmap(void);
void sodmap(void);
+void camwarp(void);
void bonus(Static*);
int rnd(void);
void gstep(void);
--- a/fs.c
+++ b/fs.c
@@ -4,6 +4,7 @@
#include "dat.h"
#include "fns.h"
+int drofs;
u32int *pal, pals[Cend][256]={ {
0x000000, 0x0000aa, 0x00aa00, 0x00aaaa, 0xaa0000, 0xaa00aa, 0xaa5500,
0xaaaaaa, 0x555555, 0x5555ff, 0x55ff55, 0x55ffff, 0xff5555, 0xff55ff,
@@ -446,8 +447,7 @@
Mapsz = Planesz * Nplane
};
static Dat *pcms;
-static uchar *swpb;
-static int alofs;
+static int alofs, npcm;
static u16int rlewtag;
static u32int *mapofs, *mape;
@@ -628,66 +628,132 @@
}
static void
-packpcm(Biobuf *bf, Dat *e, u16int so, u16int po)
+walls(Biobuf *bf, int n, u16int *sz, u32int *of)
{
- u16int n;
- Dat *p, *s;
+ uchar **d, **e;
- p = s = wals+po;
- while(++p < e){
+ drofs = n - 8;
+ wals = emalloc(n * sizeof *wals);
+ e = wals + n;
+ for(d=wals; d<e; d++, of++){
+ n = *sz++;
+ if(n == 0)
+ continue;
+ Bseek(bf, *of, 0);
+ *d = emalloc(n);
+ eread(bf, *d, n);
+ }
+}
+
+static void
+sprites(Biobuf *bf, int n, u16int *sz, u32int *of)
+{
+ uchar *hu, *u;
+ Spr *s, *e;
+ Sprc **c, *ap, a[65];
+
+ sprs = emalloc(n * sizeof *sprs);
+ e = sprs + n;
+ for(s=sprs; s<e; s++, of++){
+ n = *sz++;
+ if(n == 0)
+ continue;
+ Bseek(bf, *of, 0);
+ s->lx = get16(bf);
+ s->rx = get16(bf);
+ n -= 4;
+ s->sp = emalloc(n);
+ eread(bf, s->sp, n);
+ n = s->rx - s->lx + 1;
+ s->cs = emalloc(n * sizeof *s->cs);
+ s->ce = s->cs + n;
+ hu = s->sp;
+ c = s->cs;
+ while(n-- > 0){
+ u = s->sp + GBIT16(hu) - 4;
+ hu += 2;
+ ap = a;
+ ap->e = GBIT16(u) / 2, u+=2;
+ while(ap->e != 0){
+ ap->p = s->sp + (s16int)GBIT16(u) - 4, u+=2;
+ ap->s = GBIT16(u) / 2, u+=2;
+ ap->p += ap->s;
+ ap++;
+ ap->e = GBIT16(u) / 2, u+=2;
+ }
+ ap++;
+ *c = emalloc((ap-a) * sizeof **c);
+ memcpy(*c, a, (ap-a) * sizeof **c);
+ c++;
+ }
+ }
+}
+
+static void
+pcmpak(Biobuf *bf, int n, u16int *sz, u32int *of)
+{
+ u16int *csz, *cp, *ce;
+ uchar *u;
+ vlong sof;
+ Dat *d, *e;
+
+ sof = Bseek(bf, 0, 1);
+ Bseek(bf, of[n], 0);
+ n = sz[n] / 4;
+ csz = emalloc(n * sizeof *csz);
+ cp = csz;
+ ce = csz + n;
+ while(cp < ce){
Bseek(bf, 2, 1);
- n = get16(bf);
- while(s->e < s->p + n)
- s->e = p++->e;
- while(p->p == nil && p < e-1)
- p++;
- s++;
- s->p = p->p;
- s->e = p->e;
+ *cp++ = get16(bf);
}
- n = s-wals;
- wals = erealloc(wals, n * sizeof *wals);
- sprs = wals + so;
- pcms = wals + po;
+ npcm = n;
+ pcms = emalloc(n * sizeof *pcms);
+ Bseek(bf, sof, 0);
+ for(d=pcms, e=pcms+n, cp=csz; d<e; d++){
+ n = *cp++;
+ if(*sz == 0){
+ n = (n-1) / 4096 + 1;
+ sz += n;
+ of += n;
+ continue;
+ }
+ d->p = emalloc(n * sizeof *d->p);
+ d->e = d->p + n;
+ u = d->p;
+ while(u < d->e){
+ Bseek(bf, *of++, 0);
+ u += eread(bf, u, *sz++);
+ }
+ }
+ free(csz);
}
static void
vswap(void)
{
- u16int n, v, w;
- u32int *o, *p;
- uchar *u;
- Dat *s, *e;
+ int n, so, po;
+ u32int *ofs, *ofp;
+ u16int *szs, *szp;
Biobuf *bf;
bf = bopen("vswap.", OREAD);
n = get16(bf);
- s = wals = emalloc((n-1) * sizeof *wals);
- e = s + n-1;
- v = get16(bf);
- w = get16(bf);
- p = o = emalloc(n * sizeof *o);
-
- while(p < o+n)
- *p++ = get32(bf);
- while(s < e)
- s++->e = (uchar*)(uintptr)get16(bf);
- u = swpb = emalloc(bsize(bf) - Bseek(bf, 0, 1));
- Bseek(bf, 2, 1);
- for(p=o, s=wals; s<e; s++, p++){
- n = (uintptr)s->e;
- if(n == 0)
- continue;
- Bseek(bf, *p, 0);
- s->p = u;
- s->e = u + n;
- u += eread(bf, u, n);
- }
- Bseek(bf, *p, 0);
- free(o);
- swpb = erealloc(swpb, u-swpb);
-
- packpcm(bf, e-1, v, w);
+ so = get16(bf);
+ po = get16(bf);
+ ofs = emalloc(n * sizeof *ofs);
+ szs = emalloc(n * sizeof *szs);
+ ofp = ofs;
+ while(ofp < ofs + n)
+ *ofp++ = get32(bf);
+ szp = szs;
+ while(szp < szs + n)
+ *szp++ = get16(bf);
+ walls(bf, so, szs, ofs);
+ sprites(bf, po - so, szs + so, ofs + so);
+ pcmpak(bf, n - po - 1, szs + po, ofs + po);
+ free(ofs);
+ free(szs);
Bterm(bf);
}
@@ -737,7 +803,7 @@
swap(sfxs+Sscream9, sfxs+Sschbdie);
}
p = pcmt[ver<SDM ? 0 : 1];
- e = p + (ver==WL6 ? 46 : ver==WL1 ? 21 : ver==SDM ? 26 : 40);
+ e = p + npcm;
for(pcm=pcms; p<e; p++, pcm++)
if(*p != Send)
sfxs[*p].pcm = pcm;
@@ -951,6 +1017,16 @@
}
static void
+sttspr(void)
+{
+ State *s;
+
+ for(s=stt; s<stt+GSe; s++)
+ if(s->sprn != 0)
+ s->spr = sprs + s->sprn;
+}
+
+static void
fixpal(void)
{
u32int *p, *s;
@@ -1015,10 +1091,6 @@
if(bind(".", dir, MBEFORE|MCREATE) < 0 || chdir(dir) < 0)
fprint(2, "dat: %r\n");
- if(ver >= SDM){
- fixpal();
- sodmap();
- }
e = ext;
loadscr();
ext = e;
@@ -1028,6 +1100,11 @@
ext = "sod";
audiot();
gfx();
+ sttspr();
+ if(ver >= SDM){
+ fixpal();
+ sodmap();
+ }
ext = e;
cfg();
}
--- a/gm.c
+++ b/gm.c
@@ -65,7 +65,7 @@
static Crm crms[];
static char crs[Ncrm];
static int dmgtc, bonustc, facetc, funtc;
-static Obj *killer;
+static Obj *camobj;
static int bosskillx, bosskilly;
static int gotspear, spearx, speary, spearθ;
static int atk[][4] = {
@@ -473,7 +473,7 @@
if(gm.hp <= 0){
gm.hp = 0;
gm.end = EDdie;
- killer = from;
+ camobj = from;
if(ver >= SDM && from->type == Oneedle)
gm.mut++;
}
@@ -1307,9 +1307,6 @@
static void
cam(Obj *o)
{
- int Δx, Δy, Δr;
- double θ;
-
if(gm.won){
gm.end = EDcam2;
return;
@@ -1316,33 +1313,9 @@
}
gm.won++;
gm.end = EDcam;
+ mtc = 0;
dofizz++;
-
- ostate(oplr, stt+GSplrcam);
- oplr->x = bosskillx;
- oplr->y = bosskilly;
- Δx = o->x - oplr->x;
- Δy = oplr->y - o->y;
- θ = atan2(Δy, Δx);
- if(θ < 0)
- θ = Fpi * 2 + θ;
- oplr->θ = θ / (Fpi * 2) * 360;
- Δr = 0x14000;
- do{
- oplr->x = o->x - ffs(Δr, cost[oplr->θ]);
- oplr->y = o->y + ffs(Δr, sint[oplr->θ]);
- Δr += 0x1000;
- }while(!trymove(oplr, Dplr, 1, 0));
- oplr->tx = oplr->x >> Dtlshift;
- oplr->ty = oplr->y >> Dtlshift;
- oplr->tl = tiles + oplr->ty * Mapdxy + oplr->tx;
-
- switch(o->type){
- case Oschb: ostate(o, stt+GSschbcam); break;
- case Ootto: ostate(o, stt+GSottocam); break;
- case Ofett: ostate(o, stt+GSfettcam); break;
- case Ohitler: ostate(o, stt+GShitlercam); break;
- }
+ camobj = o;
}
static void
@@ -1941,444 +1914,444 @@
}
State stt[] = {
- [GSplr] {uplr, nil, 0, nil, nil, 0},
- [GSplrcam] {nil, nil, 0, nil, nil, 0},
- [GSblaz1] {urun, nil, 12, sprs+SPbjwalk1, stt+GSblaz2, 0},
- [GSblaz2] {nil, nil, 3, sprs+SPbjwalk1, stt+GSblaz3, 0},
- [GSblaz3] {urun, nil, 8, sprs+SPbjwalk2, stt+GSblaz4, 0},
- [GSblaz4] {urun, nil, 12, sprs+SPbjwalk3, stt+GSblaz5, 0},
- [GSblaz5] {nil, nil, 3, sprs+SPbjwalk3, stt+GSblaz6, 0},
- [GSblaz6] {urun, nil, 8, sprs+SPbjwalk4, stt+GSblaz1, 0},
- [GSjump1] {ujump, nil, 14, sprs+SPbjjump1, stt+GSjump2, 0},
- [GSjump2] {ujump, runyell, 14, sprs+SPbjjump2, stt+GSjump3, 0},
- [GSjump3] {ujump, nil, 14, sprs+SPbjjump3, stt+GSjump4, 0},
- [GSjump4] {nil, victory, 300, sprs+SPbjjump4, stt+GSjump4, 0},
- [GSgd] {uwait, nil, 0, sprs+SPgd, stt+GSgd, 1},
- [GSgdwalk1] {uwalk, nil, 20, sprs+SPgdwalk1, stt+GSgdwalk2, 1},
- [GSgdwalk2] {nil, nil, 5, sprs+SPgdwalk1, stt+GSgdwalk3, 1},
- [GSgdwalk3] {uwalk, nil, 15, sprs+SPgdwalk2, stt+GSgdwalk4, 1},
- [GSgdwalk4] {uwalk, nil, 20, sprs+SPgdwalk3, stt+GSgdwalk5, 1},
- [GSgdwalk5] {nil, nil, 5, sprs+SPgdwalk3, stt+GSgdwalk6, 1},
- [GSgdwalk6] {uwalk, nil, 15, sprs+SPgdwalk4, stt+GSgdwalk1, 1},
- [GSgdpain1] {nil, nil, 10, sprs+SPgdpain1, stt+GSgdchase1, 2},
- [GSgdpain2] {nil, nil, 10, sprs+SPgdpain2, stt+GSgdchase1, 2},
- [GSgdchase1] {uchase, nil, 10, sprs+SPgdwalk1, stt+GSgdchase2, 1},
- [GSgdchase2] {nil, nil, 3, sprs+SPgdwalk1, stt+GSgdchase3, 1},
- [GSgdchase3] {uchase, nil, 8, sprs+SPgdwalk2, stt+GSgdchase4, 1},
- [GSgdchase4] {uchase, nil, 10, sprs+SPgdwalk3, stt+GSgdchase5, 1},
- [GSgdchase5] {nil, nil, 3, sprs+SPgdwalk3, stt+GSgdchase6, 1},
- [GSgdchase6] {uchase, nil, 8, sprs+SPgdwalk4, stt+GSgdchase1, 1},
- [GSgdfire1] {nil, nil, 20, sprs+SPgdfire1, stt+GSgdfire2, 0},
- [GSgdfire2] {nil, fire, 20, sprs+SPgdfire2, stt+GSgdfire3, 0},
- [GSgdfire3] {nil, nil, 20, sprs+SPgdfire3, stt+GSgdchase1, 0},
- [GSgddie1] {nil, yelp, 15, sprs+SPgddie1, stt+GSgddie2, 0},
- [GSgddie2] {nil, nil, 15, sprs+SPgddie2, stt+GSgddie3, 0},
- [GSgddie3] {nil, nil, 15, sprs+SPgddie3, stt+GSgddie4, 0},
- [GSgddie4] {nil, nil, 0, sprs+SPgddead, stt+GSgddie4, 0},
- [GSss] {uwait, nil, 0, sprs+SPss, stt+GSss, 1},
- [GSsswalk1] {uwalk, nil, 20, sprs+SPsswalk1, stt+GSsswalk2, 1},
- [GSsswalk2] {nil, nil, 5, sprs+SPsswalk1, stt+GSsswalk3, 1},
- [GSsswalk3] {uwalk, nil, 15, sprs+SPsswalk2, stt+GSsswalk4, 1},
- [GSsswalk4] {uwalk, nil, 20, sprs+SPsswalk3, stt+GSsswalk5, 1},
- [GSsswalk5] {nil, nil, 5, sprs+SPsswalk3, stt+GSsswalk6, 1},
- [GSsswalk6] {uwalk, nil, 15, sprs+SPsswalk4, stt+GSsswalk1, 1},
- [GSsspain1] {nil, nil, 10, sprs+SPsspain1, stt+GSsschase1, 2},
- [GSsspain2] {nil, nil, 10, sprs+SPsspain2, stt+GSsschase1, 2},
- [GSsschase1] {uchase, nil, 10, sprs+SPsswalk1, stt+GSsschase2, 1},
- [GSsschase2] {nil, nil, 3, sprs+SPsswalk1, stt+GSsschase3, 1},
- [GSsschase3] {uchase, nil, 8, sprs+SPsswalk2, stt+GSsschase4, 1},
- [GSsschase4] {uchase, nil, 10, sprs+SPsswalk3, stt+GSsschase5, 1},
- [GSsschase5] {nil, nil, 3, sprs+SPsswalk3, stt+GSsschase6, 1},
- [GSsschase6] {uchase, nil, 8, sprs+SPsswalk4, stt+GSsschase1, 1},
- [GSssfire1] {nil, nil, 20, sprs+SPssfire1, stt+GSssfire2, 0},
- [GSssfire2] {nil, fire, 20, sprs+SPssfire2, stt+GSssfire3, 0},
- [GSssfire3] {nil, nil, 10, sprs+SPssfire3, stt+GSssfire4, 0},
- [GSssfire4] {nil, fire, 10, sprs+SPssfire2, stt+GSssfire5, 0},
- [GSssfire5] {nil, nil, 10, sprs+SPssfire3, stt+GSssfire6, 0},
- [GSssfire6] {nil, fire, 10, sprs+SPssfire2, stt+GSssfire7, 0},
- [GSssfire7] {nil, nil, 10, sprs+SPssfire3, stt+GSssfire8, 0},
- [GSssfire8] {nil, fire, 10, sprs+SPssfire2, stt+GSssfire9, 0},
- [GSssfire9] {nil, nil, 10, sprs+SPssfire3, stt+GSsschase1, 0},
- [GSssdie1] {nil, yelp, 15, sprs+SPssdie1, stt+GSssdie2, 0},
- [GSssdie2] {nil, nil, 15, sprs+SPssdie2, stt+GSssdie3, 0},
- [GSssdie3] {nil, nil, 15, sprs+SPssdie3, stt+GSssdie4, 0},
- [GSssdie4] {nil, nil, 0, sprs+SPssdead, stt+GSssdie4, 0},
- [GSofc] {uwait, nil, 0, sprs+SPofc, stt+GSofc, 1},
- [GSofcwalk1] {uwalk, nil, 20, sprs+SPofcwalk1, stt+GSofcwalk2, 1},
- [GSofcwalk2] {nil, nil, 5, sprs+SPofcwalk1, stt+GSofcwalk3, 1},
- [GSofcwalk3] {uwalk, nil, 15, sprs+SPofcwalk2, stt+GSofcwalk4, 1},
- [GSofcwalk4] {uwalk, nil, 20, sprs+SPofcwalk3, stt+GSofcwalk5, 1},
- [GSofcwalk5] {nil, nil, 5, sprs+SPofcwalk3, stt+GSofcwalk6, 1},
- [GSofcwalk6] {uwalk, nil, 15, sprs+SPofcwalk4, stt+GSofcwalk1, 1},
- [GSofcpain1] {nil, nil, 10, sprs+SPofcpain1, stt+GSofcchase1, 2},
- [GSofcpain2] {nil, nil, 10, sprs+SPofcpain2, stt+GSofcchase1, 2},
- [GSofcchase1] {uchase, nil, 10, sprs+SPofcwalk1, stt+GSofcchase2, 1},
- [GSofcchase2] {nil, nil, 3, sprs+SPofcwalk1, stt+GSofcchase3, 1},
- [GSofcchase3] {uchase, nil, 8, sprs+SPofcwalk2, stt+GSofcchase4, 1},
- [GSofcchase4] {uchase, nil, 10, sprs+SPofcwalk3, stt+GSofcchase5, 1},
- [GSofcchase5] {nil, nil, 3, sprs+SPofcwalk3, stt+GSofcchase6, 1},
- [GSofcchase6] {uchase, nil, 8, sprs+SPofcwalk4, stt+GSofcchase1, 1},
- [GSofcfire1] {nil, nil, 6, sprs+SPofcfire1, stt+GSofcfire2, 0},
- [GSofcfire2] {nil, fire, 20, sprs+SPofcfire2, stt+GSofcfire3, 0},
- [GSofcfire3] {nil, nil, 10, sprs+SPofcfire3, stt+GSofcchase1, 0},
- [GSofcdie1] {nil, yelp, 11, sprs+SPofcdie1, stt+GSofcdie2, 0},
- [GSofcdie2] {nil, nil, 11, sprs+SPofcdie2, stt+GSofcdie3, 0},
- [GSofcdie3] {nil, nil, 11, sprs+SPofcdie3, stt+GSofcdie4, 0},
- [GSofcdie4] {nil, nil, 11, sprs+SPofcdie4, stt+GSofcdie5, 0},
- [GSofcdie5] {nil, nil, 0, sprs+SPofcdead, stt+GSofcdie5, 0},
- [GSmut] {uwait, nil, 0, sprs+SPmut, stt+GSmut, 1},
- [GSmutwalk1] {uwalk, nil, 20, sprs+SPmutwalk1, stt+GSmutwalk2, 1},
- [GSmutwalk2] {nil, nil, 5, sprs+SPmutwalk1, stt+GSmutwalk3, 1},
- [GSmutwalk3] {uwalk, nil, 15, sprs+SPmutwalk2, stt+GSmutwalk4, 1},
- [GSmutwalk4] {uwalk, nil, 20, sprs+SPmutwalk3, stt+GSmutwalk5, 1},
- [GSmutwalk5] {nil, nil, 5, sprs+SPmutwalk3, stt+GSmutwalk6, 1},
- [GSmutwalk6] {uwalk, nil, 15, sprs+SPmutwalk4, stt+GSmutwalk1, 1},
- [GSmutpain1] {nil, nil, 10, sprs+SPmutpain1, stt+GSmutchase1, 2},
- [GSmutpain2] {nil, nil, 10, sprs+SPmutpain2, stt+GSmutchase1, 2},
- [GSmutchase1] {uchase, nil, 10, sprs+SPmutwalk1, stt+GSmutchase2, 1},
- [GSmutchase2] {nil, nil, 3, sprs+SPmutwalk1, stt+GSmutchase3, 1},
- [GSmutchase3] {uchase, nil, 8, sprs+SPmutwalk2, stt+GSmutchase4, 1},
- [GSmutchase4] {uchase, nil, 10, sprs+SPmutwalk3, stt+GSmutchase5, 1},
- [GSmutchase5] {nil, nil, 3, sprs+SPmutwalk3, stt+GSmutchase6, 1},
- [GSmutchase6] {uchase, nil, 8, sprs+SPmutwalk4, stt+GSmutchase1, 1},
- [GSmutfire1] {nil, fire, 6, sprs+SPmutfire1, stt+GSmutfire2, 0},
- [GSmutfire2] {nil, nil, 20, sprs+SPmutfire2, stt+GSmutfire3, 0},
- [GSmutfire3] {nil, fire, 10, sprs+SPmutfire3, stt+GSmutfire4, 0},
- [GSmutfire4] {nil, nil, 20, sprs+SPmutfire4, stt+GSmutchase1, 0},
- [GSmutdie1] {nil, yelp, 7, sprs+SPmutdie1, stt+GSmutdie2, 0},
- [GSmutdie2] {nil, nil, 7, sprs+SPmutdie2, stt+GSmutdie3, 0},
- [GSmutdie3] {nil, nil, 7, sprs+SPmutdie3, stt+GSmutdie4, 0},
- [GSmutdie4] {nil, nil, 7, sprs+SPmutdie4, stt+GSmutdie5, 0},
- [GSmutdie5] {nil, nil, 0, sprs+SPmutdead, stt+GSmutdie5, 0},
- [GSdogwalk1] {uwalk, nil, 20, sprs+SPdogwalk1, stt+GSdogwalk2, 1},
- [GSdogwalk2] {nil, nil, 5, sprs+SPdogwalk1, stt+GSdogwalk3, 1},
- [GSdogwalk3] {uwalk, nil, 15, sprs+SPdogwalk2, stt+GSdogwalk4, 1},
- [GSdogwalk4] {uwalk, nil, 20, sprs+SPdogwalk3, stt+GSdogwalk5, 1},
- [GSdogwalk5] {nil, nil, 5, sprs+SPdogwalk3, stt+GSdogwalk6, 1},
- [GSdogwalk6] {uwalk, nil, 15, sprs+SPdogwalk4, stt+GSdogwalk1, 1},
- [GSdogchase1] {udogchase, nil, 10, sprs+SPdogwalk1, stt+GSdogchase2, 1},
- [GSdogchase2] {nil, nil, 3, sprs+SPdogwalk1, stt+GSdogchase3, 1},
- [GSdogchase3] {udogchase, nil, 8, sprs+SPdogwalk2, stt+GSdogchase4, 1},
- [GSdogchase4] {udogchase, nil, 10, sprs+SPdogwalk3, stt+GSdogchase5, 1},
- [GSdogchase5] {nil, nil, 3, sprs+SPdogwalk3, stt+GSdogchase6, 1},
- [GSdogchase6] {udogchase, nil, 8, sprs+SPdogwalk4, stt+GSdogchase1, 1},
- [GSdogfire1] {nil, nil, 10, sprs+SPdogfire1, stt+GSdogfire2, 0},
- [GSdogfire2] {nil, bite, 10, sprs+SPdogfire2, stt+GSdogfire3, 0},
- [GSdogfire3] {nil, nil, 10, sprs+SPdogfire3, stt+GSdogfire4, 0},
- [GSdogfire4] {nil, nil, 10, sprs+SPdogfire1, stt+GSdogfire5, 0},
- [GSdogfire5] {nil, nil, 10, sprs+SPdogwalk1, stt+GSdogchase1, 0},
- [GSdogdie1] {nil, yelp, 15, sprs+SPdogdie1, stt+GSdogdie2, 0},
- [GSdogdie2] {nil, nil, 15, sprs+SPdogdie2, stt+GSdogdie3, 0},
- [GSdogdie3] {nil, nil, 15, sprs+SPdogdie3, stt+GSdogdie4, 0},
- [GSdogdie4] {nil, nil, 15, sprs+SPdogdead, stt+GSdogdie4, 0},
- [GShans] {uwait, nil, 0, sprs+SPhanswalk1, stt+GShans, 0},
- [GShanschase1] {uchase, nil, 10, sprs+SPhanswalk1, stt+GShanschase2, 0},
- [GShanschase2] {nil, nil, 3, sprs+SPhanswalk1, stt+GShanschase3, 0},
- [GShanschase3] {uchase, nil, 8, sprs+SPhanswalk2, stt+GShanschase4, 0},
- [GShanschase4] {uchase, nil, 10, sprs+SPhanswalk3, stt+GShanschase5, 0},
- [GShanschase5] {nil, nil, 3, sprs+SPhanswalk3, stt+GShanschase6, 0},
- [GShanschase6] {uchase, nil, 8, sprs+SPhanswalk4, stt+GShanschase1, 0},
- [GShansfire1] {nil, nil, 30, sprs+SPhansfire1, stt+GShansfire2, 0},
- [GShansfire2] {nil, fire, 10, sprs+SPhansfire2, stt+GShansfire3, 0},
- [GShansfire3] {nil, fire, 10, sprs+SPhansfire3, stt+GShansfire4, 0},
- [GShansfire4] {nil, fire, 10, sprs+SPhansfire2, stt+GShansfire5, 0},
- [GShansfire5] {nil, fire, 10, sprs+SPhansfire3, stt+GShansfire6, 0},
- [GShansfire6] {nil, fire, 10, sprs+SPhansfire2, stt+GShansfire7, 0},
- [GShansfire7] {nil, fire, 10, sprs+SPhansfire3, stt+GShansfire8, 0},
- [GShansfire8] {nil, nil, 10, sprs+SPhansfire1, stt+GShanschase1, 0},
- [GShansdie1] {nil, yelp, 15, sprs+SPhansdie1, stt+GShansdie2, 0},
- [GShansdie2] {nil, nil, 15, sprs+SPhansdie2, stt+GShansdie3, 0},
- [GShansdie3] {nil, nil, 15, sprs+SPhansdie3, stt+GShansdie4, 0},
- [GShansdie4] {nil, nil, 0, sprs+SPhansdead, stt+GShansdie4, 0},
- [GSschb] {uwait, nil, 0, sprs+SPschbwalk1, stt+GSschb, 0},
- [GSschbchase1] {uboss, nil, 10, sprs+SPschbwalk1, stt+GSschbchase2, 0},
- [GSschbchase2] {nil, nil, 3, sprs+SPschbwalk1, stt+GSschbchase3, 0},
- [GSschbchase3] {uboss, nil, 8, sprs+SPschbwalk2, stt+GSschbchase4, 0},
- [GSschbchase4] {uboss, nil, 10, sprs+SPschbwalk3, stt+GSschbchase5, 0},
- [GSschbchase5] {nil, nil, 3, sprs+SPschbwalk3, stt+GSschbchase6, 0},
- [GSschbchase6] {uboss, nil, 8, sprs+SPschbwalk4, stt+GSschbchase1, 0},
- [GSschbfire1] {nil, nil, 30, sprs+SPschbfire1, stt+GSschbfire2, 0},
- [GSschbfire2] {nil, launch, 10, sprs+SPschbfire2, stt+GSschbchase1, 0},
- [GSschbcam] {nil, nil, 1, sprs+SPschbwalk1, stt+GSschbdie1, 0},
- [GSschbdie1] {nil, yelp, 10, sprs+SPschbwalk1, stt+GSschbdie2, 0},
- [GSschbdie2] {nil, nil, 10, sprs+SPschbwalk1, stt+GSschbdie3, 0},
- [GSschbdie3] {nil, nil, 10, sprs+SPschbdie1, stt+GSschbdie4, 0},
- [GSschbdie4] {nil, nil, 10, sprs+SPschbdie2, stt+GSschbdie5, 0},
- [GSschbdie5] {nil, nil, 10, sprs+SPschbdie3, stt+GSschbdie6, 0},
- [GSschbdie6] {nil, cam, 20, sprs+SPschbdead, stt+GSschbdie6, 0},
- [GSgretel] {uwait, nil, 0, sprs+SPgretelwalk1, stt+GSgretel, 0},
- [GSgretelchase1] {uchase, nil, 10, sprs+SPgretelwalk1, stt+GSgretelchase2, 0},
- [GSgretelchase2] {nil, nil, 3, sprs+SPgretelwalk1, stt+GSgretelchase3, 0},
- [GSgretelchase3] {uchase, nil, 8, sprs+SPgretelwalk2, stt+GSgretelchase4, 0},
- [GSgretelchase4] {uchase, nil, 10, sprs+SPgretelwalk3, stt+GSgretelchase5, 0},
- [GSgretelchase5] {nil, nil, 3, sprs+SPgretelwalk3, stt+GSgretelchase6, 0},
- [GSgretelchase6] {uchase, nil, 8, sprs+SPgretelwalk4, stt+GSgretelchase1, 0},
- [GSgretelfire1] {nil, nil, 30, sprs+SPgretelfire1, stt+GSgretelfire2, 0},
- [GSgretelfire2] {nil, fire, 10, sprs+SPgretelfire2, stt+GSgretelfire3, 0},
- [GSgretelfire3] {nil, fire, 10, sprs+SPgretelfire3, stt+GSgretelfire4, 0},
- [GSgretelfire4] {nil, fire, 10, sprs+SPgretelfire2, stt+GSgretelfire5, 0},
- [GSgretelfire5] {nil, fire, 10, sprs+SPgretelfire3, stt+GSgretelfire6, 0},
- [GSgretelfire6] {nil, fire, 10, sprs+SPgretelfire2, stt+GSgretelfire7, 0},
- [GSgretelfire7] {nil, fire, 10, sprs+SPgretelfire3, stt+GSgretelfire8, 0},
- [GSgretelfire8] {nil, nil, 10, sprs+SPgretelfire1, stt+GSgretelchase1, 0},
- [GSgreteldie1] {nil, yelp, 15, sprs+SPgreteldie1, stt+GSgreteldie2, 0},
- [GSgreteldie2] {nil, nil, 15, sprs+SPgreteldie2, stt+GSgreteldie3, 0},
- [GSgreteldie3] {nil, nil, 15, sprs+SPgreteldie3, stt+GSgreteldie4, 0},
- [GSgreteldie4] {nil, nil, 0, sprs+SPgreteldead, stt+GSgreteldie4, 0},
- [GSotto] {uwait, nil, 0, sprs+SPottowalk1, stt+GSotto, 0},
- [GSottochase1] {uboss, nil, 10, sprs+SPottowalk1, stt+GSottochase2, 0},
- [GSottochase2] {nil, nil, 3, sprs+SPottowalk1, stt+GSottochase3, 0},
- [GSottochase3] {uboss, nil, 8, sprs+SPottowalk2, stt+GSottochase4, 0},
- [GSottochase4] {uboss, nil, 10, sprs+SPottowalk3, stt+GSottochase5, 0},
- [GSottochase5] {nil, nil, 3, sprs+SPottowalk3, stt+GSottochase6, 0},
- [GSottochase6] {uboss, nil, 8, sprs+SPottowalk4, stt+GSottochase1, 0},
- [GSottofire1] {nil, nil, 30, sprs+SPottofire1, stt+GSottofire2, 0},
- [GSottofire2] {nil, launch, 10, sprs+SPottofire2, stt+GSottochase1, 0},
- [GSottocam] {nil, nil, 1, sprs+SPottowalk1, stt+GSottodie1, 0},
- [GSottodie1] {nil, yelp, 1, sprs+SPottowalk1, stt+GSottodie2, 0},
- [GSottodie2] {nil, nil, 10, sprs+SPottowalk1, stt+GSottodie3, 0},
- [GSottodie3] {nil, nil, 10, sprs+SPottodie1, stt+GSottodie4, 0},
- [GSottodie4] {nil, nil, 10, sprs+SPottodie2, stt+GSottodie5, 0},
- [GSottodie5] {nil, nil, 10, sprs+SPottodie3, stt+GSottodie6, 0},
- [GSottodie6] {nil, cam, 20, sprs+SPottodead, stt+GSottodie6, 0},
- [GSfett] {uwait, nil, 0, sprs+SPfettwalk1, stt+GSfett, 0},
- [GSfettchase1] {uboss, nil, 10, sprs+SPfettwalk1, stt+GSfettchase2, 0},
- [GSfettchase2] {nil, nil, 3, sprs+SPfettwalk1, stt+GSfettchase3, 0},
- [GSfettchase3] {uboss, nil, 8, sprs+SPfettwalk2, stt+GSfettchase4, 0},
- [GSfettchase4] {uboss, nil, 10, sprs+SPfettwalk3, stt+GSfettchase5, 0},
- [GSfettchase5] {nil, nil, 3, sprs+SPfettwalk3, stt+GSfettchase6, 0},
- [GSfettchase6] {uboss, nil, 8, sprs+SPfettwalk4, stt+GSfettchase1, 0},
- [GSfettfire1] {nil, nil, 30, sprs+SPfettfire1, stt+GSfettfire2, 0},
- [GSfettfire2] {nil, launch, 10, sprs+SPfettfire2, stt+GSfettfire3, 0},
- [GSfettfire3] {nil, fire, 10, sprs+SPfettfire3, stt+GSfettfire4, 0},
- [GSfettfire4] {nil, fire, 10, sprs+SPfettfire4, stt+GSfettfire5, 0},
- [GSfettfire5] {nil, fire, 10, sprs+SPfettfire3, stt+GSfettfire6, 0},
- [GSfettfire6] {nil, fire, 10, sprs+SPfettfire4, stt+GSfettchase1, 0},
- [GSfettcam] {nil, nil, 1, sprs+SPfettwalk1, stt+GSfettdie1, 0},
- [GSfettdie1] {nil, yelp, 1, sprs+SPfettwalk1, stt+GSfettdie2, 0},
- [GSfettdie2] {nil, nil, 10, sprs+SPfettwalk1, stt+GSfettdie3, 0},
- [GSfettdie3] {nil, nil, 10, sprs+SPfettdie1, stt+GSfettdie4, 0},
- [GSfettdie4] {nil, nil, 10, sprs+SPfettdie2, stt+GSfettdie5, 0},
- [GSfettdie5] {nil, nil, 10, sprs+SPfettdie3, stt+GSfettdie6, 0},
- [GSfettdie6] {nil, cam, 20, sprs+SPfettdead, stt+GSfettdie6, 0},
- [GSfake] {uwait, nil, 0, sprs+SPfakewalk1, stt+GSfake, 0},
- [GSfakechase1] {ufake, nil, 10, sprs+SPfakewalk1, stt+GSfakechase2, 0},
- [GSfakechase2] {nil, nil, 3, sprs+SPfakewalk1, stt+GSfakechase3, 0},
- [GSfakechase3] {ufake, nil, 8, sprs+SPfakewalk2, stt+GSfakechase4, 0},
- [GSfakechase4] {ufake, nil, 10, sprs+SPfakewalk3, stt+GSfakechase5, 0},
- [GSfakechase5] {nil, nil, 3, sprs+SPfakewalk3, stt+GSfakechase6, 0},
- [GSfakechase6] {ufake, nil, 8, sprs+SPfakewalk4, stt+GSfakechase1, 0},
- [GSfakefire1] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire2, 0},
- [GSfakefire2] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire3, 0},
- [GSfakefire3] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire4, 0},
- [GSfakefire4] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire5, 0},
- [GSfakefire5] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire6, 0},
- [GSfakefire6] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire7, 0},
- [GSfakefire7] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire8, 0},
- [GSfakefire8] {nil, launch, 8, sprs+SPfakefire, stt+GSfakefire9, 0},
- [GSfakefire9] {nil, nil, 8, sprs+SPfakefire, stt+GSfakechase1, 0},
- [GSfakedie1] {nil, yelp, 10, sprs+SPfakedie1, stt+GSfakedie2, 0},
- [GSfakedie2] {nil, nil, 10, sprs+SPfakedie2, stt+GSfakedie3, 0},
- [GSfakedie3] {nil, nil, 10, sprs+SPfakedie3, stt+GSfakedie4, 0},
- [GSfakedie4] {nil, nil, 10, sprs+SPfakedie4, stt+GSfakedie5, 0},
- [GSfakedie5] {nil, nil, 10, sprs+SPfakedie5, stt+GSfakedie6, 0},
- [GSfakedie6] {nil, nil, 0, sprs+SPfakedead, stt+GSfakedie6, 0},
- [GSmech] {uwait, nil, 0, sprs+SPmechwalk1, stt+GSmech, 0},
- [GSmechchase1] {uchase, mechsfx, 10, sprs+SPmechwalk1, stt+GSmechchase2, 0},
- [GSmechchase2] {nil, nil, 6, sprs+SPmechwalk1, stt+GSmechchase3, 0},
- [GSmechchase3] {uchase, nil, 8, sprs+SPmechwalk2, stt+GSmechchase4, 0},
- [GSmechchase4] {uchase, mechsfx, 10, sprs+SPmechwalk3, stt+GSmechchase5, 0},
- [GSmechchase5] {nil, nil, 6, sprs+SPmechwalk3, stt+GSmechchase6, 0},
- [GSmechchase6] {uchase, nil, 8, sprs+SPmechwalk4, stt+GSmechchase1, 0},
- [GSmechfire1] {nil, nil, 30, sprs+SPmechfire1, stt+GSmechfire2, 0},
- [GSmechfire2] {nil, fire, 10, sprs+SPmechfire2, stt+GSmechfire3, 0},
- [GSmechfire3] {nil, fire, 10, sprs+SPmechfire3, stt+GSmechfire4, 0},
- [GSmechfire4] {nil, fire, 10, sprs+SPmechfire2, stt+GSmechfire5, 0},
- [GSmechfire5] {nil, fire, 10, sprs+SPmechfire3, stt+GSmechfire6, 0},
- [GSmechfire6] {nil, fire, 10, sprs+SPmechfire2, stt+GSmechchase1, 0},
- [GSmechdie1] {nil, yelp, 10, sprs+SPmechdie1, stt+GSmechdie2, 0},
- [GSmechdie2] {nil, nil, 10, sprs+SPmechdie2, stt+GSmechdie3, 0},
- [GSmechdie3] {nil, mechblow, 10, sprs+SPmechdie3, stt+GSmechdie4, 0},
- [GSmechdie4] {nil, nil, 0, sprs+SPmechdead, stt+GSmechdie4, 0},
- [GShitlerchase1] {uchase, nil, 6, sprs+SPhitlerwalk1, stt+GShitlerchase2, 0},
- [GShitlerchase2] {nil, nil, 4, sprs+SPhitlerwalk1, stt+GShitlerchase3, 0},
- [GShitlerchase3] {uchase, nil, 2, sprs+SPhitlerwalk2, stt+GShitlerchase4, 0},
- [GShitlerchase4] {uchase, nil, 6, sprs+SPhitlerwalk3, stt+GShitlerchase5, 0},
- [GShitlerchase5] {nil, nil, 4, sprs+SPhitlerwalk3, stt+GShitlerchase6, 0},
- [GShitlerchase6] {uchase, nil, 2, sprs+SPhitlerwalk4, stt+GShitlerchase1, 0},
- [GShitlerfire1] {nil, nil, 30, sprs+SPhitlerfire1, stt+GShitlerfire2, 0},
- [GShitlerfire2] {nil, fire, 10, sprs+SPhitlerfire2, stt+GShitlerfire3, 0},
- [GShitlerfire3] {nil, fire, 10, sprs+SPhitlerfire3, stt+GShitlerfire4, 0},
- [GShitlerfire4] {nil, fire, 10, sprs+SPhitlerfire2, stt+GShitlerfire5, 0},
- [GShitlerfire5] {nil, fire, 10, sprs+SPhitlerfire3, stt+GShitlerfire6, 0},
- [GShitlerfire6] {nil, fire, 10, sprs+SPhitlerfire2, stt+GShitlerchase1, 0},
- [GShitlercam] {nil, nil, 10, sprs+SPhitlerwalk1, stt+GShitlerdie1, 0},
- [GShitlerdie1] {nil, yelp, 1, sprs+SPhitlerwalk1, stt+GShitlerdie2, 0},
- [GShitlerdie2] {nil, nil, 10, sprs+SPhitlerwalk1, stt+GShitlerdie3, 0},
- [GShitlerdie3] {nil, slurp, 10, sprs+SPhitlerdie1, stt+GShitlerdie4, 0},
- [GShitlerdie4] {nil, nil, 10, sprs+SPhitlerdie2, stt+GShitlerdie5, 0},
- [GShitlerdie5] {nil, nil, 10, sprs+SPhitlerdie3, stt+GShitlerdie6, 0},
- [GShitlerdie6] {nil, nil, 10, sprs+SPhitlerdie4, stt+GShitlerdie7, 0},
- [GShitlerdie7] {nil, nil, 10, sprs+SPhitlerdie5, stt+GShitlerdie8, 0},
- [GShitlerdie8] {nil, nil, 10, sprs+SPhitlerdie6, stt+GShitlerdie9, 0},
- [GShitlerdie9] {nil, nil, 10, sprs+SPhitlerdie7, stt+GShitlerdie10, 0},
- [GShitlerdie10] {nil, cam, 20, sprs+SPhitlerdead, stt+GShitlerdie10, 0},
- [GSgh1chase1] {ughost, nil, 10, sprs+SPgh1walk1, stt+GSgh1chase2, 0},
- [GSgh2chase1] {ughost, nil, 10, sprs+SPgh3walk1, stt+GSgh2chase2, 0},
- [GSgh3chase1] {ughost, nil, 10, sprs+SPgh2walk1, stt+GSgh3chase2, 0},
- [GSgh4chase1] {ughost, nil, 10, sprs+SPgh2walk1, stt+GSgh4chase2, 0},
- [GSgh1chase2] {ughost, nil, 10, sprs+SPgh1walk2, stt+GSgh1chase1, 0},
- [GSgh2chase2] {ughost, nil, 10, sprs+SPgh3walk2, stt+GSgh2chase1, 0},
- [GSgh3chase2] {ughost, nil, 10, sprs+SPgh2walk2, stt+GSgh3chase1, 0},
- [GSgh4chase2] {ughost, nil, 10, sprs+SPgh2walk2, stt+GSgh4chase1, 0},
- [GStrans] {uwait, nil, 0, sprs+SPtranswalk1, stt+GStrans, 0},
- [GStranschase1] {uchase, nil, 10, sprs+SPtranswalk1, stt+GStranschase2, 0},
- [GStranschase2] {nil, nil, 3, sprs+SPtranswalk1, stt+GStranschase3, 0},
- [GStranschase3] {uchase, nil, 8, sprs+SPtranswalk2, stt+GStranschase4, 0},
- [GStranschase4] {uchase, nil, 10, sprs+SPtranswalk3, stt+GStranschase5, 0},
- [GStranschase5] {nil, nil, 3, sprs+SPtranswalk3, stt+GStranschase6, 0},
- [GStranschase6] {uchase, nil, 8, sprs+SPtranswalk4, stt+GStranschase1, 0},
- [GStransfire1] {nil, nil, 30, sprs+SPtransfire1, stt+GStransfire2, 0},
- [GStransfire2] {nil, fire, 10, sprs+SPtransfire2, stt+GStransfire3, 0},
- [GStransfire3] {nil, fire, 10, sprs+SPtransfire3, stt+GStransfire4, 0},
- [GStransfire4] {nil, fire, 10, sprs+SPtransfire2, stt+GStransfire5, 0},
- [GStransfire5] {nil, fire, 10, sprs+SPtransfire3, stt+GStransfire6, 0},
- [GStransfire6] {nil, fire, 10, sprs+SPtransfire2, stt+GStransfire7, 0},
- [GStransfire7] {nil, fire, 10, sprs+SPtransfire3, stt+GStransfire8, 0},
- [GStransfire8] {nil, nil, 10, sprs+SPtransfire1, stt+GStranschase1, 0},
- [GStransdie1] {nil, yelp, 1, sprs+SPtranswalk1, stt+GStransdie2, 0},
- [GStransdie2] {nil, nil, 1, sprs+SPtranswalk1, stt+GStransdie3, 0},
- [GStransdie3] {nil, nil, 15, sprs+SPtransdie1, stt+GStransdie4, 0},
- [GStransdie4] {nil, nil, 15, sprs+SPtransdie2, stt+GStransdie5, 0},
- [GStransdie5] {nil, nil, 15, sprs+SPtransdie3, stt+GStransdie6, 0},
- [GStransdie6] {nil, nil, 0, sprs+SPtransdead, stt+GStransdie6, 0},
- [GSwilh] {uwait, nil, 0, sprs+SPwilhwalk1, stt+GSwilh, 0},
- [GSwilhchase1] {uboss, nil, 10, sprs+SPwilhwalk1, stt+GSwilhchase2, 0},
- [GSwilhchase2] {nil, nil, 3, sprs+SPwilhwalk1, stt+GSwilhchase3, 0},
- [GSwilhchase3] {uboss, nil, 8, sprs+SPwilhwalk2, stt+GSwilhchase4, 0},
- [GSwilhchase4] {uboss, nil, 10, sprs+SPwilhwalk3, stt+GSwilhchase5, 0},
- [GSwilhchase5] {nil, nil, 3, sprs+SPwilhwalk3, stt+GSwilhchase6, 0},
- [GSwilhchase6] {uboss, nil, 8, sprs+SPwilhwalk4, stt+GSwilhchase1, 0},
- [GSwilhfire1] {nil, nil, 30, sprs+SPwilhfire1, stt+GSwilhfire2, 0},
- [GSwilhfire2] {nil, launch, 10, sprs+SPwilhfire2, stt+GSwilhfire3, 0},
- [GSwilhfire3] {nil, fire, 10, sprs+SPwilhfire3, stt+GSwilhfire4, 0},
- [GSwilhfire4] {nil, fire, 10, sprs+SPwilhfire4, stt+GSwilhfire5, 0},
- [GSwilhfire5] {nil, fire, 10, sprs+SPwilhfire3, stt+GSwilhfire6, 0},
- [GSwilhfire6] {nil, fire, 10, sprs+SPwilhfire4, stt+GSwilhchase1, 0},
- [GSwilhdie1] {nil, yelp, 1, sprs+SPwilhwalk1, stt+GSwilhdie2, 0},
- [GSwilhdie2] {nil, nil, 10, sprs+SPwilhwalk1, stt+GSwilhdie3, 0},
- [GSwilhdie3] {nil, nil, 10, sprs+SPwilhdie1, stt+GSwilhdie4, 0},
- [GSwilhdie4] {nil, nil, 10, sprs+SPwilhdie2, stt+GSwilhdie5, 0},
- [GSwilhdie5] {nil, nil, 10, sprs+SPwilhdie3, stt+GSwilhdie6, 0},
- [GSwilhdie6] {nil, nil, 20, sprs+SPwilhdead, stt+GSwilhdie6, 0},
- [GSuber] {uwait, nil, 0, sprs+SPuberwalk1, stt+GSuber, 0},
- [GSuberchase1] {uchase, nil, 10, sprs+SPuberwalk1, stt+GSuberchase2, 0},
- [GSuberchase2] {nil, nil, 3, sprs+SPuberwalk1, stt+GSuberchase3, 0},
- [GSuberchase3] {uchase, nil, 8, sprs+SPuberwalk2, stt+GSuberchase4, 0},
- [GSuberchase4] {uchase, nil, 10, sprs+SPuberwalk3, stt+GSuberchase5, 0},
- [GSuberchase5] {nil, nil, 3, sprs+SPuberwalk3, stt+GSuberchase6, 0},
- [GSuberchase6] {uchase, nil, 8, sprs+SPuberwalk4, stt+GSuberchase1, 0},
- [GSuberfire1] {nil, nil, 30, sprs+SPuberfire1, stt+GSuberfire2, 0},
- [GSuberfire2] {nil, uberfire, 12, sprs+SPuberfire2, stt+GSuberfire3, 0},
- [GSuberfire3] {nil, uberfire, 12, sprs+SPuberfire3, stt+GSuberfire4, 0},
- [GSuberfire4] {nil, uberfire, 12, sprs+SPuberfire4, stt+GSuberfire5, 0},
- [GSuberfire5] {nil, uberfire, 12, sprs+SPuberfire3, stt+GSuberfire6, 0},
- [GSuberfire6] {nil, uberfire, 12, sprs+SPuberfire2, stt+GSuberfire7, 0},
- [GSuberfire7] {nil, nil, 12, sprs+SPuberfire1, stt+GSuberchase1, 0},
- [GSuberdie1] {nil, yelp, 1, sprs+SPuberwalk1, stt+GSuberdie2, 0},
- [GSuberdie2] {nil, nil, 1, sprs+SPuberwalk1, stt+GSuberdie3, 0},
- [GSuberdie3] {nil, nil, 15, sprs+SPuberdie1, stt+GSuberdie4, 0},
- [GSuberdie4] {nil, nil, 15, sprs+SPuberdie2, stt+GSuberdie5, 0},
- [GSuberdie5] {nil, nil, 15, sprs+SPuberdie3, stt+GSuberdie6, 0},
- [GSuberdie6] {nil, nil, 15, sprs+SPuberdie4, stt+GSuberdie7, 0},
- [GSuberdie7] {nil, nil, 0, sprs+SPuberdead, stt+GSuberdie7, 0},
- [GSknight] {uwait, nil, 0, sprs+SPknightwalk1, stt+GSknight, 0},
- [GSknightchase1] {uboss, nil, 10, sprs+SPknightwalk1, stt+GSknightchase2, 0},
- [GSknightchase2] {nil, nil, 3, sprs+SPknightwalk1, stt+GSknightchase3, 0},
- [GSknightchase3] {uboss, nil, 8, sprs+SPknightwalk2, stt+GSknightchase4, 0},
- [GSknightchase4] {uboss, nil, 10, sprs+SPknightwalk3, stt+GSknightchase5, 0},
- [GSknightchase5] {nil, nil, 3, sprs+SPknightwalk3, stt+GSknightchase6, 0},
- [GSknightchase6] {uboss, nil, 8, sprs+SPknightwalk4, stt+GSknightchase1, 0},
- [GSknightfire1] {nil, nil, 30, sprs+SPknightfire1, stt+GSknightfire2, 0},
- [GSknightfire2] {nil, launch, 10, sprs+SPknightfire2, stt+GSknightfire3, 0},
- [GSknightfire3] {nil, fire, 10, sprs+SPknightfire4, stt+GSknightfire4, 0},
- [GSknightfire4] {nil, launch, 10, sprs+SPknightfire3, stt+GSknightfire5, 0},
- [GSknightfire5] {nil, fire, 10, sprs+SPknightfire4, stt+GSknightchase1, 0},
- [GSknightdie1] {nil, yelp, 1, sprs+SPknightwalk1, stt+GSknightdie2, 0},
- [GSknightdie2] {nil, nil, 10, sprs+SPknightwalk1, stt+GSknightdie3, 0},
- [GSknightdie3] {nil, nil, 10, sprs+SPknightdie1, stt+GSknightdie4, 0},
- [GSknightdie4] {nil, nil, 10, sprs+SPknightdie2, stt+GSknightdie5, 0},
- [GSknightdie5] {nil, nil, 10, sprs+SPknightdie3, stt+GSknightdie6, 0},
- [GSknightdie6] {nil, nil, 10, sprs+SPknightdie4, stt+GSknightdie7, 0},
- [GSknightdie7] {nil, nil, 10, sprs+SPknightdie5, stt+GSknightdie8, 0},
- [GSknightdie8] {nil, nil, 10, sprs+SPknightdie6, stt+GSknightdie9, 0},
- [GSknightdie9] {nil, nil, 0, sprs+SPknightdead, stt+GSknightdie9, 0},
- [GSspectrewait1] {uwait, nil, 10, sprs+SPspectrewalk1, stt+GSspectrewait2, 0},
- [GSspectrewait2] {uwait, nil, 10, sprs+SPspectrewalk2, stt+GSspectrewait3, 0},
- [GSspectrewait3] {uwait, nil, 10, sprs+SPspectrewalk3, stt+GSspectrewait4, 0},
- [GSspectrewait4] {uwait, nil, 10, sprs+SPspectrewalk4, stt+GSspectrewait1, 0},
- [GSspectrewake] {nil, wake, 10, sprs+SPspectreF4, stt+GSspectrewake, 0},
- [GSspectrechase1] {ughost, nil, 10, sprs+SPspectrewalk1, stt+GSspectrechase2, 0},
- [GSspectrechase2] {ughost, nil, 10, sprs+SPspectrewalk2, stt+GSspectrechase3, 0},
- [GSspectrechase3] {ughost, nil, 10, sprs+SPspectrewalk3, stt+GSspectrechase4, 0},
- [GSspectrechase4] {ughost, nil, 10, sprs+SPspectrewalk4, stt+GSspectrechase1, 0},
- [GSspectredie1] {nil, nil, 10, sprs+SPspectreF1, stt+GSspectredie2, 0},
- [GSspectredie2] {nil, nil, 10, sprs+SPspectreF2, stt+GSspectredie3, 0},
- [GSspectredie3] {nil, nil, 10, sprs+SPspectreF3, stt+GSspectredie4, 0},
- [GSspectredie4] {nil, nil, 300, sprs+SPspectreF4, stt+GSspectrewake, 0},
- [GSangel] {uwait, nil, 0, sprs+SPangelwalk1, stt+GSangel, 0},
- [GSangelchase1] {uboss, nil, 10, sprs+SPangelwalk1, stt+GSangelchase2, 0},
- [GSangelchase2] {nil, nil, 3, sprs+SPangelwalk1, stt+GSangelchase3, 0},
- [GSangelchase3] {uboss, nil, 8, sprs+SPangelwalk2, stt+GSangelchase4, 0},
- [GSangelchase4] {uboss, nil, 10, sprs+SPangelwalk3, stt+GSangelchase5, 0},
- [GSangelchase5] {nil, nil, 3, sprs+SPangelwalk3, stt+GSangelchase6, 0},
- [GSangelchase6] {uboss, nil, 8, sprs+SPangelwalk4, stt+GSangelchase1, 0},
- [GSangelfire1] {nil, prelaunch, 10, sprs+SPangelfire1, stt+GSangelfire2, 0},
- [GSangelfire2] {nil, launch, 20, sprs+SPangelfire2, stt+GSangelfire3, 0},
- [GSangelfire3] {nil, relaunch, 10, sprs+SPangelfire1, stt+GSangelfire2, 0},
- [GSangeldie1] {nil, yelp, 1, sprs+SPangelwalk1, stt+GSangeldie2, 0},
- [GSangeldie2] {nil, nil, 1, sprs+SPangelwalk1, stt+GSangeldie3, 0},
- [GSangeldie3] {nil, slurp, 10, sprs+SPangeldie1, stt+GSangeldie4, 0},
- [GSangeldie4] {nil, nil, 10, sprs+SPangeldie2, stt+GSangeldie5, 0},
- [GSangeldie5] {nil, nil, 10, sprs+SPangeldie3, stt+GSangeldie6, 0},
- [GSangeldie6] {nil, nil, 10, sprs+SPangeldie4, stt+GSangeldie7, 0},
- [GSangeldie7] {nil, nil, 10, sprs+SPangeldie5, stt+GSangeldie8, 0},
- [GSangeldie8] {nil, nil, 10, sprs+SPangeldie6, stt+GSangeldie9, 0},
- [GSangeldie9] {nil, nil, 10, sprs+SPangeldie7, stt+GSangeldie10, 0},
- [GSangeldie10] {nil, victory, 130, sprs+SPangeldead, stt+GSangeldie10, 0},
- [GSangeltired1] {nil, tiredsfx, 40, sprs+SPangeltired1, stt+GSangeltired2, 0},
- [GSangeltired2] {nil, nil, 40, sprs+SPangeltired2, stt+GSangeltired3, 0},
- [GSangeltired3] {nil, tiredsfx, 40, sprs+SPangeltired1, stt+GSangeltired4, 0},
- [GSangeltired4] {nil, nil, 40, sprs+SPangeltired2, stt+GSangeltired5, 0},
- [GSangeltired5] {nil, tiredsfx, 40, sprs+SPangeltired1, stt+GSangeltired6, 0},
- [GSangeltired6] {nil, nil, 40, sprs+SPangeltired2, stt+GSangeltired7, 0},
- [GSangeltired7] {nil, tiredsfx, 40, sprs+SPangeltired1, stt+GSangelchase1, 0},
- [GSmissile] {uprj, smoke, 3, sprs+SPmissile1, stt+GSmissile, 1},
- [GSmsmoke1] {nil, nil, 3, sprs+SPmsmoke1, stt+GSmsmoke2, 0},
- [GSmsmoke2] {nil, nil, 3, sprs+SPmsmoke2, stt+GSmsmoke3, 0},
- [GSmsmoke3] {nil, nil, 3, sprs+SPmsmoke3, stt+GSmsmoke4, 0},
- [GSmsmoke4] {nil, nil, 3, sprs+SPmsmoke4, nil, 0},
- [GSmboom1] {nil, nil, 6, sprs+SPmboom1, stt+GSmboom2, 0},
- [GSmboom2] {nil, nil, 6, sprs+SPmboom2, stt+GSmboom3, 0},
- [GSmboom3] {nil, nil, 6, sprs+SPmboom3, nil, 0},
- [GSrocket] {uprj, smoke, 3, sprs+SProcket1, stt+GSrocket, 1},
- [GSrsmoke1] {nil, nil, 3, sprs+SPrsmoke1, stt+GSrsmoke2, 0},
- [GSrsmoke2] {nil, nil, 3, sprs+SPrsmoke2, stt+GSrsmoke3, 0},
- [GSrsmoke3] {nil, nil, 3, sprs+SPrsmoke3, stt+GSrsmoke4, 0},
- [GSrsmoke4] {nil, nil, 3, sprs+SPrsmoke4, nil, 0},
- [GSrboom1] {nil, nil, 6, sprs+SPrboom1, stt+GSrboom2, 0},
- [GSrboom2] {nil, nil, 6, sprs+SPrboom2, stt+GSrboom3, 0},
- [GSrboom3] {nil, nil, 6, sprs+SPrboom3, nil, 0},
- [GSflame1] {nil, uprj, 6, sprs+SPflame1, stt+GSflame2, 0},
- [GSflame2] {nil, uprj, 6, sprs+SPflame2, stt+GSflame1, 0},
- [GSneedle1] {uprj, nil, 6, sprs+SPneedle1, stt+GSneedle2, 0},
- [GSneedle2] {uprj, nil, 6, sprs+SPneedle2, stt+GSneedle3, 0},
- [GSneedle3] {uprj, nil, 6, sprs+SPneedle3, stt+GSneedle4, 0},
- [GSneedle4] {uprj, nil, 6, sprs+SPneedle4, stt+GSneedle1, 0},
- [GSspark1] {uprj, nil, 6, sprs+SPspark1, stt+GSspark2, 0},
- [GSspark2] {uprj, nil, 6, sprs+SPspark2, stt+GSspark3, 0},
- [GSspark3] {uprj, nil, 6, sprs+SPspark3, stt+GSspark4, 0},
- [GSspark4] {uprj, nil, 6, sprs+SPspark4, stt+GSspark1, 0}
+ [GSplr] {uplr, nil, 0, 0, nil, 0},
+ [GSplrcam] {nil, nil, 0, 0, nil, 0},
+ [GSblaz1] {urun, nil, 12, SPbjwalk1, stt+GSblaz2, 0},
+ [GSblaz2] {nil, nil, 3, SPbjwalk1, stt+GSblaz3, 0},
+ [GSblaz3] {urun, nil, 8, SPbjwalk2, stt+GSblaz4, 0},
+ [GSblaz4] {urun, nil, 12, SPbjwalk3, stt+GSblaz5, 0},
+ [GSblaz5] {nil, nil, 3, SPbjwalk3, stt+GSblaz6, 0},
+ [GSblaz6] {urun, nil, 8, SPbjwalk4, stt+GSblaz1, 0},
+ [GSjump1] {ujump, nil, 14, SPbjjump1, stt+GSjump2, 0},
+ [GSjump2] {ujump, runyell, 14, SPbjjump2, stt+GSjump3, 0},
+ [GSjump3] {ujump, nil, 14, SPbjjump3, stt+GSjump4, 0},
+ [GSjump4] {nil, victory, 300, SPbjjump4, stt+GSjump4, 0},
+ [GSgd] {uwait, nil, 0, SPgd, stt+GSgd, 1},
+ [GSgdwalk1] {uwalk, nil, 20, SPgdwalk1, stt+GSgdwalk2, 1},
+ [GSgdwalk2] {nil, nil, 5, SPgdwalk1, stt+GSgdwalk3, 1},
+ [GSgdwalk3] {uwalk, nil, 15, SPgdwalk2, stt+GSgdwalk4, 1},
+ [GSgdwalk4] {uwalk, nil, 20, SPgdwalk3, stt+GSgdwalk5, 1},
+ [GSgdwalk5] {nil, nil, 5, SPgdwalk3, stt+GSgdwalk6, 1},
+ [GSgdwalk6] {uwalk, nil, 15, SPgdwalk4, stt+GSgdwalk1, 1},
+ [GSgdpain1] {nil, nil, 10, SPgdpain1, stt+GSgdchase1, 2},
+ [GSgdpain2] {nil, nil, 10, SPgdpain2, stt+GSgdchase1, 2},
+ [GSgdchase1] {uchase, nil, 10, SPgdwalk1, stt+GSgdchase2, 1},
+ [GSgdchase2] {nil, nil, 3, SPgdwalk1, stt+GSgdchase3, 1},
+ [GSgdchase3] {uchase, nil, 8, SPgdwalk2, stt+GSgdchase4, 1},
+ [GSgdchase4] {uchase, nil, 10, SPgdwalk3, stt+GSgdchase5, 1},
+ [GSgdchase5] {nil, nil, 3, SPgdwalk3, stt+GSgdchase6, 1},
+ [GSgdchase6] {uchase, nil, 8, SPgdwalk4, stt+GSgdchase1, 1},
+ [GSgdfire1] {nil, nil, 20, SPgdfire1, stt+GSgdfire2, 0},
+ [GSgdfire2] {nil, fire, 20, SPgdfire2, stt+GSgdfire3, 0},
+ [GSgdfire3] {nil, nil, 20, SPgdfire3, stt+GSgdchase1, 0},
+ [GSgddie1] {nil, yelp, 15, SPgddie1, stt+GSgddie2, 0},
+ [GSgddie2] {nil, nil, 15, SPgddie2, stt+GSgddie3, 0},
+ [GSgddie3] {nil, nil, 15, SPgddie3, stt+GSgddie4, 0},
+ [GSgddie4] {nil, nil, 0, SPgddead, stt+GSgddie4, 0},
+ [GSss] {uwait, nil, 0, SPss, stt+GSss, 1},
+ [GSsswalk1] {uwalk, nil, 20, SPsswalk1, stt+GSsswalk2, 1},
+ [GSsswalk2] {nil, nil, 5, SPsswalk1, stt+GSsswalk3, 1},
+ [GSsswalk3] {uwalk, nil, 15, SPsswalk2, stt+GSsswalk4, 1},
+ [GSsswalk4] {uwalk, nil, 20, SPsswalk3, stt+GSsswalk5, 1},
+ [GSsswalk5] {nil, nil, 5, SPsswalk3, stt+GSsswalk6, 1},
+ [GSsswalk6] {uwalk, nil, 15, SPsswalk4, stt+GSsswalk1, 1},
+ [GSsspain1] {nil, nil, 10, SPsspain1, stt+GSsschase1, 2},
+ [GSsspain2] {nil, nil, 10, SPsspain2, stt+GSsschase1, 2},
+ [GSsschase1] {uchase, nil, 10, SPsswalk1, stt+GSsschase2, 1},
+ [GSsschase2] {nil, nil, 3, SPsswalk1, stt+GSsschase3, 1},
+ [GSsschase3] {uchase, nil, 8, SPsswalk2, stt+GSsschase4, 1},
+ [GSsschase4] {uchase, nil, 10, SPsswalk3, stt+GSsschase5, 1},
+ [GSsschase5] {nil, nil, 3, SPsswalk3, stt+GSsschase6, 1},
+ [GSsschase6] {uchase, nil, 8, SPsswalk4, stt+GSsschase1, 1},
+ [GSssfire1] {nil, nil, 20, SPssfire1, stt+GSssfire2, 0},
+ [GSssfire2] {nil, fire, 20, SPssfire2, stt+GSssfire3, 0},
+ [GSssfire3] {nil, nil, 10, SPssfire3, stt+GSssfire4, 0},
+ [GSssfire4] {nil, fire, 10, SPssfire2, stt+GSssfire5, 0},
+ [GSssfire5] {nil, nil, 10, SPssfire3, stt+GSssfire6, 0},
+ [GSssfire6] {nil, fire, 10, SPssfire2, stt+GSssfire7, 0},
+ [GSssfire7] {nil, nil, 10, SPssfire3, stt+GSssfire8, 0},
+ [GSssfire8] {nil, fire, 10, SPssfire2, stt+GSssfire9, 0},
+ [GSssfire9] {nil, nil, 10, SPssfire3, stt+GSsschase1, 0},
+ [GSssdie1] {nil, yelp, 15, SPssdie1, stt+GSssdie2, 0},
+ [GSssdie2] {nil, nil, 15, SPssdie2, stt+GSssdie3, 0},
+ [GSssdie3] {nil, nil, 15, SPssdie3, stt+GSssdie4, 0},
+ [GSssdie4] {nil, nil, 0, SPssdead, stt+GSssdie4, 0},
+ [GSofc] {uwait, nil, 0, SPofc, stt+GSofc, 1},
+ [GSofcwalk1] {uwalk, nil, 20, SPofcwalk1, stt+GSofcwalk2, 1},
+ [GSofcwalk2] {nil, nil, 5, SPofcwalk1, stt+GSofcwalk3, 1},
+ [GSofcwalk3] {uwalk, nil, 15, SPofcwalk2, stt+GSofcwalk4, 1},
+ [GSofcwalk4] {uwalk, nil, 20, SPofcwalk3, stt+GSofcwalk5, 1},
+ [GSofcwalk5] {nil, nil, 5, SPofcwalk3, stt+GSofcwalk6, 1},
+ [GSofcwalk6] {uwalk, nil, 15, SPofcwalk4, stt+GSofcwalk1, 1},
+ [GSofcpain1] {nil, nil, 10, SPofcpain1, stt+GSofcchase1, 2},
+ [GSofcpain2] {nil, nil, 10, SPofcpain2, stt+GSofcchase1, 2},
+ [GSofcchase1] {uchase, nil, 10, SPofcwalk1, stt+GSofcchase2, 1},
+ [GSofcchase2] {nil, nil, 3, SPofcwalk1, stt+GSofcchase3, 1},
+ [GSofcchase3] {uchase, nil, 8, SPofcwalk2, stt+GSofcchase4, 1},
+ [GSofcchase4] {uchase, nil, 10, SPofcwalk3, stt+GSofcchase5, 1},
+ [GSofcchase5] {nil, nil, 3, SPofcwalk3, stt+GSofcchase6, 1},
+ [GSofcchase6] {uchase, nil, 8, SPofcwalk4, stt+GSofcchase1, 1},
+ [GSofcfire1] {nil, nil, 6, SPofcfire1, stt+GSofcfire2, 0},
+ [GSofcfire2] {nil, fire, 20, SPofcfire2, stt+GSofcfire3, 0},
+ [GSofcfire3] {nil, nil, 10, SPofcfire3, stt+GSofcchase1, 0},
+ [GSofcdie1] {nil, yelp, 11, SPofcdie1, stt+GSofcdie2, 0},
+ [GSofcdie2] {nil, nil, 11, SPofcdie2, stt+GSofcdie3, 0},
+ [GSofcdie3] {nil, nil, 11, SPofcdie3, stt+GSofcdie4, 0},
+ [GSofcdie4] {nil, nil, 11, SPofcdie4, stt+GSofcdie5, 0},
+ [GSofcdie5] {nil, nil, 0, SPofcdead, stt+GSofcdie5, 0},
+ [GSmut] {uwait, nil, 0, SPmut, stt+GSmut, 1},
+ [GSmutwalk1] {uwalk, nil, 20, SPmutwalk1, stt+GSmutwalk2, 1},
+ [GSmutwalk2] {nil, nil, 5, SPmutwalk1, stt+GSmutwalk3, 1},
+ [GSmutwalk3] {uwalk, nil, 15, SPmutwalk2, stt+GSmutwalk4, 1},
+ [GSmutwalk4] {uwalk, nil, 20, SPmutwalk3, stt+GSmutwalk5, 1},
+ [GSmutwalk5] {nil, nil, 5, SPmutwalk3, stt+GSmutwalk6, 1},
+ [GSmutwalk6] {uwalk, nil, 15, SPmutwalk4, stt+GSmutwalk1, 1},
+ [GSmutpain1] {nil, nil, 10, SPmutpain1, stt+GSmutchase1, 2},
+ [GSmutpain2] {nil, nil, 10, SPmutpain2, stt+GSmutchase1, 2},
+ [GSmutchase1] {uchase, nil, 10, SPmutwalk1, stt+GSmutchase2, 1},
+ [GSmutchase2] {nil, nil, 3, SPmutwalk1, stt+GSmutchase3, 1},
+ [GSmutchase3] {uchase, nil, 8, SPmutwalk2, stt+GSmutchase4, 1},
+ [GSmutchase4] {uchase, nil, 10, SPmutwalk3, stt+GSmutchase5, 1},
+ [GSmutchase5] {nil, nil, 3, SPmutwalk3, stt+GSmutchase6, 1},
+ [GSmutchase6] {uchase, nil, 8, SPmutwalk4, stt+GSmutchase1, 1},
+ [GSmutfire1] {nil, fire, 6, SPmutfire1, stt+GSmutfire2, 0},
+ [GSmutfire2] {nil, nil, 20, SPmutfire2, stt+GSmutfire3, 0},
+ [GSmutfire3] {nil, fire, 10, SPmutfire3, stt+GSmutfire4, 0},
+ [GSmutfire4] {nil, nil, 20, SPmutfire4, stt+GSmutchase1, 0},
+ [GSmutdie1] {nil, yelp, 7, SPmutdie1, stt+GSmutdie2, 0},
+ [GSmutdie2] {nil, nil, 7, SPmutdie2, stt+GSmutdie3, 0},
+ [GSmutdie3] {nil, nil, 7, SPmutdie3, stt+GSmutdie4, 0},
+ [GSmutdie4] {nil, nil, 7, SPmutdie4, stt+GSmutdie5, 0},
+ [GSmutdie5] {nil, nil, 0, SPmutdead, stt+GSmutdie5, 0},
+ [GSdogwalk1] {uwalk, nil, 20, SPdogwalk1, stt+GSdogwalk2, 1},
+ [GSdogwalk2] {nil, nil, 5, SPdogwalk1, stt+GSdogwalk3, 1},
+ [GSdogwalk3] {uwalk, nil, 15, SPdogwalk2, stt+GSdogwalk4, 1},
+ [GSdogwalk4] {uwalk, nil, 20, SPdogwalk3, stt+GSdogwalk5, 1},
+ [GSdogwalk5] {nil, nil, 5, SPdogwalk3, stt+GSdogwalk6, 1},
+ [GSdogwalk6] {uwalk, nil, 15, SPdogwalk4, stt+GSdogwalk1, 1},
+ [GSdogchase1] {udogchase, nil, 10, SPdogwalk1, stt+GSdogchase2, 1},
+ [GSdogchase2] {nil, nil, 3, SPdogwalk1, stt+GSdogchase3, 1},
+ [GSdogchase3] {udogchase, nil, 8, SPdogwalk2, stt+GSdogchase4, 1},
+ [GSdogchase4] {udogchase, nil, 10, SPdogwalk3, stt+GSdogchase5, 1},
+ [GSdogchase5] {nil, nil, 3, SPdogwalk3, stt+GSdogchase6, 1},
+ [GSdogchase6] {udogchase, nil, 8, SPdogwalk4, stt+GSdogchase1, 1},
+ [GSdogfire1] {nil, nil, 10, SPdogfire1, stt+GSdogfire2, 0},
+ [GSdogfire2] {nil, bite, 10, SPdogfire2, stt+GSdogfire3, 0},
+ [GSdogfire3] {nil, nil, 10, SPdogfire3, stt+GSdogfire4, 0},
+ [GSdogfire4] {nil, nil, 10, SPdogfire1, stt+GSdogfire5, 0},
+ [GSdogfire5] {nil, nil, 10, SPdogwalk1, stt+GSdogchase1, 0},
+ [GSdogdie1] {nil, yelp, 15, SPdogdie1, stt+GSdogdie2, 0},
+ [GSdogdie2] {nil, nil, 15, SPdogdie2, stt+GSdogdie3, 0},
+ [GSdogdie3] {nil, nil, 15, SPdogdie3, stt+GSdogdie4, 0},
+ [GSdogdie4] {nil, nil, 15, SPdogdead, stt+GSdogdie4, 0},
+ [GShans] {uwait, nil, 0, SPhanswalk1, stt+GShans, 0},
+ [GShanschase1] {uchase, nil, 10, SPhanswalk1, stt+GShanschase2, 0},
+ [GShanschase2] {nil, nil, 3, SPhanswalk1, stt+GShanschase3, 0},
+ [GShanschase3] {uchase, nil, 8, SPhanswalk2, stt+GShanschase4, 0},
+ [GShanschase4] {uchase, nil, 10, SPhanswalk3, stt+GShanschase5, 0},
+ [GShanschase5] {nil, nil, 3, SPhanswalk3, stt+GShanschase6, 0},
+ [GShanschase6] {uchase, nil, 8, SPhanswalk4, stt+GShanschase1, 0},
+ [GShansfire1] {nil, nil, 30, SPhansfire1, stt+GShansfire2, 0},
+ [GShansfire2] {nil, fire, 10, SPhansfire2, stt+GShansfire3, 0},
+ [GShansfire3] {nil, fire, 10, SPhansfire3, stt+GShansfire4, 0},
+ [GShansfire4] {nil, fire, 10, SPhansfire2, stt+GShansfire5, 0},
+ [GShansfire5] {nil, fire, 10, SPhansfire3, stt+GShansfire6, 0},
+ [GShansfire6] {nil, fire, 10, SPhansfire2, stt+GShansfire7, 0},
+ [GShansfire7] {nil, fire, 10, SPhansfire3, stt+GShansfire8, 0},
+ [GShansfire8] {nil, nil, 10, SPhansfire1, stt+GShanschase1, 0},
+ [GShansdie1] {nil, yelp, 15, SPhansdie1, stt+GShansdie2, 0},
+ [GShansdie2] {nil, nil, 15, SPhansdie2, stt+GShansdie3, 0},
+ [GShansdie3] {nil, nil, 15, SPhansdie3, stt+GShansdie4, 0},
+ [GShansdie4] {nil, nil, 0, SPhansdead, stt+GShansdie4, 0},
+ [GSschb] {uwait, nil, 0, SPschbwalk1, stt+GSschb, 0},
+ [GSschbchase1] {uboss, nil, 10, SPschbwalk1, stt+GSschbchase2, 0},
+ [GSschbchase2] {nil, nil, 3, SPschbwalk1, stt+GSschbchase3, 0},
+ [GSschbchase3] {uboss, nil, 8, SPschbwalk2, stt+GSschbchase4, 0},
+ [GSschbchase4] {uboss, nil, 10, SPschbwalk3, stt+GSschbchase5, 0},
+ [GSschbchase5] {nil, nil, 3, SPschbwalk3, stt+GSschbchase6, 0},
+ [GSschbchase6] {uboss, nil, 8, SPschbwalk4, stt+GSschbchase1, 0},
+ [GSschbfire1] {nil, nil, 30, SPschbfire1, stt+GSschbfire2, 0},
+ [GSschbfire2] {nil, launch, 10, SPschbfire2, stt+GSschbchase1, 0},
+ [GSschbcam] {nil, nil, 1, SPschbwalk1, stt+GSschbdie1, 0},
+ [GSschbdie1] {nil, yelp, 10, SPschbwalk1, stt+GSschbdie2, 0},
+ [GSschbdie2] {nil, nil, 10, SPschbwalk1, stt+GSschbdie3, 0},
+ [GSschbdie3] {nil, nil, 10, SPschbdie1, stt+GSschbdie4, 0},
+ [GSschbdie4] {nil, nil, 10, SPschbdie2, stt+GSschbdie5, 0},
+ [GSschbdie5] {nil, nil, 10, SPschbdie3, stt+GSschbdie6, 0},
+ [GSschbdie6] {nil, cam, 20, SPschbdead, stt+GSschbdie6, 0},
+ [GSgretel] {uwait, nil, 0, SPgretelwalk1, stt+GSgretel, 0},
+ [GSgretelchase1] {uchase, nil, 10, SPgretelwalk1, stt+GSgretelchase2, 0},
+ [GSgretelchase2] {nil, nil, 3, SPgretelwalk1, stt+GSgretelchase3, 0},
+ [GSgretelchase3] {uchase, nil, 8, SPgretelwalk2, stt+GSgretelchase4, 0},
+ [GSgretelchase4] {uchase, nil, 10, SPgretelwalk3, stt+GSgretelchase5, 0},
+ [GSgretelchase5] {nil, nil, 3, SPgretelwalk3, stt+GSgretelchase6, 0},
+ [GSgretelchase6] {uchase, nil, 8, SPgretelwalk4, stt+GSgretelchase1, 0},
+ [GSgretelfire1] {nil, nil, 30, SPgretelfire1, stt+GSgretelfire2, 0},
+ [GSgretelfire2] {nil, fire, 10, SPgretelfire2, stt+GSgretelfire3, 0},
+ [GSgretelfire3] {nil, fire, 10, SPgretelfire3, stt+GSgretelfire4, 0},
+ [GSgretelfire4] {nil, fire, 10, SPgretelfire2, stt+GSgretelfire5, 0},
+ [GSgretelfire5] {nil, fire, 10, SPgretelfire3, stt+GSgretelfire6, 0},
+ [GSgretelfire6] {nil, fire, 10, SPgretelfire2, stt+GSgretelfire7, 0},
+ [GSgretelfire7] {nil, fire, 10, SPgretelfire3, stt+GSgretelfire8, 0},
+ [GSgretelfire8] {nil, nil, 10, SPgretelfire1, stt+GSgretelchase1, 0},
+ [GSgreteldie1] {nil, yelp, 15, SPgreteldie1, stt+GSgreteldie2, 0},
+ [GSgreteldie2] {nil, nil, 15, SPgreteldie2, stt+GSgreteldie3, 0},
+ [GSgreteldie3] {nil, nil, 15, SPgreteldie3, stt+GSgreteldie4, 0},
+ [GSgreteldie4] {nil, nil, 0, SPgreteldead, stt+GSgreteldie4, 0},
+ [GSotto] {uwait, nil, 0, SPottowalk1, stt+GSotto, 0},
+ [GSottochase1] {uboss, nil, 10, SPottowalk1, stt+GSottochase2, 0},
+ [GSottochase2] {nil, nil, 3, SPottowalk1, stt+GSottochase3, 0},
+ [GSottochase3] {uboss, nil, 8, SPottowalk2, stt+GSottochase4, 0},
+ [GSottochase4] {uboss, nil, 10, SPottowalk3, stt+GSottochase5, 0},
+ [GSottochase5] {nil, nil, 3, SPottowalk3, stt+GSottochase6, 0},
+ [GSottochase6] {uboss, nil, 8, SPottowalk4, stt+GSottochase1, 0},
+ [GSottofire1] {nil, nil, 30, SPottofire1, stt+GSottofire2, 0},
+ [GSottofire2] {nil, launch, 10, SPottofire2, stt+GSottochase1, 0},
+ [GSottocam] {nil, nil, 1, SPottowalk1, stt+GSottodie1, 0},
+ [GSottodie1] {nil, yelp, 1, SPottowalk1, stt+GSottodie2, 0},
+ [GSottodie2] {nil, nil, 10, SPottowalk1, stt+GSottodie3, 0},
+ [GSottodie3] {nil, nil, 10, SPottodie1, stt+GSottodie4, 0},
+ [GSottodie4] {nil, nil, 10, SPottodie2, stt+GSottodie5, 0},
+ [GSottodie5] {nil, nil, 10, SPottodie3, stt+GSottodie6, 0},
+ [GSottodie6] {nil, cam, 20, SPottodead, stt+GSottodie6, 0},
+ [GSfett] {uwait, nil, 0, SPfettwalk1, stt+GSfett, 0},
+ [GSfettchase1] {uboss, nil, 10, SPfettwalk1, stt+GSfettchase2, 0},
+ [GSfettchase2] {nil, nil, 3, SPfettwalk1, stt+GSfettchase3, 0},
+ [GSfettchase3] {uboss, nil, 8, SPfettwalk2, stt+GSfettchase4, 0},
+ [GSfettchase4] {uboss, nil, 10, SPfettwalk3, stt+GSfettchase5, 0},
+ [GSfettchase5] {nil, nil, 3, SPfettwalk3, stt+GSfettchase6, 0},
+ [GSfettchase6] {uboss, nil, 8, SPfettwalk4, stt+GSfettchase1, 0},
+ [GSfettfire1] {nil, nil, 30, SPfettfire1, stt+GSfettfire2, 0},
+ [GSfettfire2] {nil, launch, 10, SPfettfire2, stt+GSfettfire3, 0},
+ [GSfettfire3] {nil, fire, 10, SPfettfire3, stt+GSfettfire4, 0},
+ [GSfettfire4] {nil, fire, 10, SPfettfire4, stt+GSfettfire5, 0},
+ [GSfettfire5] {nil, fire, 10, SPfettfire3, stt+GSfettfire6, 0},
+ [GSfettfire6] {nil, fire, 10, SPfettfire4, stt+GSfettchase1, 0},
+ [GSfettcam] {nil, nil, 1, SPfettwalk1, stt+GSfettdie1, 0},
+ [GSfettdie1] {nil, yelp, 1, SPfettwalk1, stt+GSfettdie2, 0},
+ [GSfettdie2] {nil, nil, 10, SPfettwalk1, stt+GSfettdie3, 0},
+ [GSfettdie3] {nil, nil, 10, SPfettdie1, stt+GSfettdie4, 0},
+ [GSfettdie4] {nil, nil, 10, SPfettdie2, stt+GSfettdie5, 0},
+ [GSfettdie5] {nil, nil, 10, SPfettdie3, stt+GSfettdie6, 0},
+ [GSfettdie6] {nil, cam, 20, SPfettdead, stt+GSfettdie6, 0},
+ [GSfake] {uwait, nil, 0, SPfakewalk1, stt+GSfake, 0},
+ [GSfakechase1] {ufake, nil, 10, SPfakewalk1, stt+GSfakechase2, 0},
+ [GSfakechase2] {nil, nil, 3, SPfakewalk1, stt+GSfakechase3, 0},
+ [GSfakechase3] {ufake, nil, 8, SPfakewalk2, stt+GSfakechase4, 0},
+ [GSfakechase4] {ufake, nil, 10, SPfakewalk3, stt+GSfakechase5, 0},
+ [GSfakechase5] {nil, nil, 3, SPfakewalk3, stt+GSfakechase6, 0},
+ [GSfakechase6] {ufake, nil, 8, SPfakewalk4, stt+GSfakechase1, 0},
+ [GSfakefire1] {nil, launch, 8, SPfakefire, stt+GSfakefire2, 0},
+ [GSfakefire2] {nil, launch, 8, SPfakefire, stt+GSfakefire3, 0},
+ [GSfakefire3] {nil, launch, 8, SPfakefire, stt+GSfakefire4, 0},
+ [GSfakefire4] {nil, launch, 8, SPfakefire, stt+GSfakefire5, 0},
+ [GSfakefire5] {nil, launch, 8, SPfakefire, stt+GSfakefire6, 0},
+ [GSfakefire6] {nil, launch, 8, SPfakefire, stt+GSfakefire7, 0},
+ [GSfakefire7] {nil, launch, 8, SPfakefire, stt+GSfakefire8, 0},
+ [GSfakefire8] {nil, launch, 8, SPfakefire, stt+GSfakefire9, 0},
+ [GSfakefire9] {nil, nil, 8, SPfakefire, stt+GSfakechase1, 0},
+ [GSfakedie1] {nil, yelp, 10, SPfakedie1, stt+GSfakedie2, 0},
+ [GSfakedie2] {nil, nil, 10, SPfakedie2, stt+GSfakedie3, 0},
+ [GSfakedie3] {nil, nil, 10, SPfakedie3, stt+GSfakedie4, 0},
+ [GSfakedie4] {nil, nil, 10, SPfakedie4, stt+GSfakedie5, 0},
+ [GSfakedie5] {nil, nil, 10, SPfakedie5, stt+GSfakedie6, 0},
+ [GSfakedie6] {nil, nil, 0, SPfakedead, stt+GSfakedie6, 0},
+ [GSmech] {uwait, nil, 0, SPmechwalk1, stt+GSmech, 0},
+ [GSmechchase1] {uchase, mechsfx, 10, SPmechwalk1, stt+GSmechchase2, 0},
+ [GSmechchase2] {nil, nil, 6, SPmechwalk1, stt+GSmechchase3, 0},
+ [GSmechchase3] {uchase, nil, 8, SPmechwalk2, stt+GSmechchase4, 0},
+ [GSmechchase4] {uchase, mechsfx, 10, SPmechwalk3, stt+GSmechchase5, 0},
+ [GSmechchase5] {nil, nil, 6, SPmechwalk3, stt+GSmechchase6, 0},
+ [GSmechchase6] {uchase, nil, 8, SPmechwalk4, stt+GSmechchase1, 0},
+ [GSmechfire1] {nil, nil, 30, SPmechfire1, stt+GSmechfire2, 0},
+ [GSmechfire2] {nil, fire, 10, SPmechfire2, stt+GSmechfire3, 0},
+ [GSmechfire3] {nil, fire, 10, SPmechfire3, stt+GSmechfire4, 0},
+ [GSmechfire4] {nil, fire, 10, SPmechfire2, stt+GSmechfire5, 0},
+ [GSmechfire5] {nil, fire, 10, SPmechfire3, stt+GSmechfire6, 0},
+ [GSmechfire6] {nil, fire, 10, SPmechfire2, stt+GSmechchase1, 0},
+ [GSmechdie1] {nil, yelp, 10, SPmechdie1, stt+GSmechdie2, 0},
+ [GSmechdie2] {nil, nil, 10, SPmechdie2, stt+GSmechdie3, 0},
+ [GSmechdie3] {nil, mechblow, 10, SPmechdie3, stt+GSmechdie4, 0},
+ [GSmechdie4] {nil, nil, 0, SPmechdead, stt+GSmechdie4, 0},
+ [GShitlerchase1] {uchase, nil, 6, SPhitlerwalk1, stt+GShitlerchase2, 0},
+ [GShitlerchase2] {nil, nil, 4, SPhitlerwalk1, stt+GShitlerchase3, 0},
+ [GShitlerchase3] {uchase, nil, 2, SPhitlerwalk2, stt+GShitlerchase4, 0},
+ [GShitlerchase4] {uchase, nil, 6, SPhitlerwalk3, stt+GShitlerchase5, 0},
+ [GShitlerchase5] {nil, nil, 4, SPhitlerwalk3, stt+GShitlerchase6, 0},
+ [GShitlerchase6] {uchase, nil, 2, SPhitlerwalk4, stt+GShitlerchase1, 0},
+ [GShitlerfire1] {nil, nil, 30, SPhitlerfire1, stt+GShitlerfire2, 0},
+ [GShitlerfire2] {nil, fire, 10, SPhitlerfire2, stt+GShitlerfire3, 0},
+ [GShitlerfire3] {nil, fire, 10, SPhitlerfire3, stt+GShitlerfire4, 0},
+ [GShitlerfire4] {nil, fire, 10, SPhitlerfire2, stt+GShitlerfire5, 0},
+ [GShitlerfire5] {nil, fire, 10, SPhitlerfire3, stt+GShitlerfire6, 0},
+ [GShitlerfire6] {nil, fire, 10, SPhitlerfire2, stt+GShitlerchase1, 0},
+ [GShitlercam] {nil, nil, 10, SPhitlerwalk1, stt+GShitlerdie1, 0},
+ [GShitlerdie1] {nil, yelp, 1, SPhitlerwalk1, stt+GShitlerdie2, 0},
+ [GShitlerdie2] {nil, nil, 10, SPhitlerwalk1, stt+GShitlerdie3, 0},
+ [GShitlerdie3] {nil, slurp, 10, SPhitlerdie1, stt+GShitlerdie4, 0},
+ [GShitlerdie4] {nil, nil, 10, SPhitlerdie2, stt+GShitlerdie5, 0},
+ [GShitlerdie5] {nil, nil, 10, SPhitlerdie3, stt+GShitlerdie6, 0},
+ [GShitlerdie6] {nil, nil, 10, SPhitlerdie4, stt+GShitlerdie7, 0},
+ [GShitlerdie7] {nil, nil, 10, SPhitlerdie5, stt+GShitlerdie8, 0},
+ [GShitlerdie8] {nil, nil, 10, SPhitlerdie6, stt+GShitlerdie9, 0},
+ [GShitlerdie9] {nil, nil, 10, SPhitlerdie7, stt+GShitlerdie10, 0},
+ [GShitlerdie10] {nil, cam, 20, SPhitlerdead, stt+GShitlerdie10, 0},
+ [GSgh1chase1] {ughost, nil, 10, SPgh1walk1, stt+GSgh1chase2, 0},
+ [GSgh2chase1] {ughost, nil, 10, SPgh3walk1, stt+GSgh2chase2, 0},
+ [GSgh3chase1] {ughost, nil, 10, SPgh2walk1, stt+GSgh3chase2, 0},
+ [GSgh4chase1] {ughost, nil, 10, SPgh2walk1, stt+GSgh4chase2, 0},
+ [GSgh1chase2] {ughost, nil, 10, SPgh1walk2, stt+GSgh1chase1, 0},
+ [GSgh2chase2] {ughost, nil, 10, SPgh3walk2, stt+GSgh2chase1, 0},
+ [GSgh3chase2] {ughost, nil, 10, SPgh2walk2, stt+GSgh3chase1, 0},
+ [GSgh4chase2] {ughost, nil, 10, SPgh2walk2, stt+GSgh4chase1, 0},
+ [GStrans] {uwait, nil, 0, SPtranswalk1, stt+GStrans, 0},
+ [GStranschase1] {uchase, nil, 10, SPtranswalk1, stt+GStranschase2, 0},
+ [GStranschase2] {nil, nil, 3, SPtranswalk1, stt+GStranschase3, 0},
+ [GStranschase3] {uchase, nil, 8, SPtranswalk2, stt+GStranschase4, 0},
+ [GStranschase4] {uchase, nil, 10, SPtranswalk3, stt+GStranschase5, 0},
+ [GStranschase5] {nil, nil, 3, SPtranswalk3, stt+GStranschase6, 0},
+ [GStranschase6] {uchase, nil, 8, SPtranswalk4, stt+GStranschase1, 0},
+ [GStransfire1] {nil, nil, 30, SPtransfire1, stt+GStransfire2, 0},
+ [GStransfire2] {nil, fire, 10, SPtransfire2, stt+GStransfire3, 0},
+ [GStransfire3] {nil, fire, 10, SPtransfire3, stt+GStransfire4, 0},
+ [GStransfire4] {nil, fire, 10, SPtransfire2, stt+GStransfire5, 0},
+ [GStransfire5] {nil, fire, 10, SPtransfire3, stt+GStransfire6, 0},
+ [GStransfire6] {nil, fire, 10, SPtransfire2, stt+GStransfire7, 0},
+ [GStransfire7] {nil, fire, 10, SPtransfire3, stt+GStransfire8, 0},
+ [GStransfire8] {nil, nil, 10, SPtransfire1, stt+GStranschase1, 0},
+ [GStransdie1] {nil, yelp, 1, SPtranswalk1, stt+GStransdie2, 0},
+ [GStransdie2] {nil, nil, 1, SPtranswalk1, stt+GStransdie3, 0},
+ [GStransdie3] {nil, nil, 15, SPtransdie1, stt+GStransdie4, 0},
+ [GStransdie4] {nil, nil, 15, SPtransdie2, stt+GStransdie5, 0},
+ [GStransdie5] {nil, nil, 15, SPtransdie3, stt+GStransdie6, 0},
+ [GStransdie6] {nil, nil, 0, SPtransdead, stt+GStransdie6, 0},
+ [GSwilh] {uwait, nil, 0, SPwilhwalk1, stt+GSwilh, 0},
+ [GSwilhchase1] {uboss, nil, 10, SPwilhwalk1, stt+GSwilhchase2, 0},
+ [GSwilhchase2] {nil, nil, 3, SPwilhwalk1, stt+GSwilhchase3, 0},
+ [GSwilhchase3] {uboss, nil, 8, SPwilhwalk2, stt+GSwilhchase4, 0},
+ [GSwilhchase4] {uboss, nil, 10, SPwilhwalk3, stt+GSwilhchase5, 0},
+ [GSwilhchase5] {nil, nil, 3, SPwilhwalk3, stt+GSwilhchase6, 0},
+ [GSwilhchase6] {uboss, nil, 8, SPwilhwalk4, stt+GSwilhchase1, 0},
+ [GSwilhfire1] {nil, nil, 30, SPwilhfire1, stt+GSwilhfire2, 0},
+ [GSwilhfire2] {nil, launch, 10, SPwilhfire2, stt+GSwilhfire3, 0},
+ [GSwilhfire3] {nil, fire, 10, SPwilhfire3, stt+GSwilhfire4, 0},
+ [GSwilhfire4] {nil, fire, 10, SPwilhfire4, stt+GSwilhfire5, 0},
+ [GSwilhfire5] {nil, fire, 10, SPwilhfire3, stt+GSwilhfire6, 0},
+ [GSwilhfire6] {nil, fire, 10, SPwilhfire4, stt+GSwilhchase1, 0},
+ [GSwilhdie1] {nil, yelp, 1, SPwilhwalk1, stt+GSwilhdie2, 0},
+ [GSwilhdie2] {nil, nil, 10, SPwilhwalk1, stt+GSwilhdie3, 0},
+ [GSwilhdie3] {nil, nil, 10, SPwilhdie1, stt+GSwilhdie4, 0},
+ [GSwilhdie4] {nil, nil, 10, SPwilhdie2, stt+GSwilhdie5, 0},
+ [GSwilhdie5] {nil, nil, 10, SPwilhdie3, stt+GSwilhdie6, 0},
+ [GSwilhdie6] {nil, nil, 20, SPwilhdead, stt+GSwilhdie6, 0},
+ [GSuber] {uwait, nil, 0, SPuberwalk1, stt+GSuber, 0},
+ [GSuberchase1] {uchase, nil, 10, SPuberwalk1, stt+GSuberchase2, 0},
+ [GSuberchase2] {nil, nil, 3, SPuberwalk1, stt+GSuberchase3, 0},
+ [GSuberchase3] {uchase, nil, 8, SPuberwalk2, stt+GSuberchase4, 0},
+ [GSuberchase4] {uchase, nil, 10, SPuberwalk3, stt+GSuberchase5, 0},
+ [GSuberchase5] {nil, nil, 3, SPuberwalk3, stt+GSuberchase6, 0},
+ [GSuberchase6] {uchase, nil, 8, SPuberwalk4, stt+GSuberchase1, 0},
+ [GSuberfire1] {nil, nil, 30, SPuberfire1, stt+GSuberfire2, 0},
+ [GSuberfire2] {nil, uberfire, 12, SPuberfire2, stt+GSuberfire3, 0},
+ [GSuberfire3] {nil, uberfire, 12, SPuberfire3, stt+GSuberfire4, 0},
+ [GSuberfire4] {nil, uberfire, 12, SPuberfire4, stt+GSuberfire5, 0},
+ [GSuberfire5] {nil, uberfire, 12, SPuberfire3, stt+GSuberfire6, 0},
+ [GSuberfire6] {nil, uberfire, 12, SPuberfire2, stt+GSuberfire7, 0},
+ [GSuberfire7] {nil, nil, 12, SPuberfire1, stt+GSuberchase1, 0},
+ [GSuberdie1] {nil, yelp, 1, SPuberwalk1, stt+GSuberdie2, 0},
+ [GSuberdie2] {nil, nil, 1, SPuberwalk1, stt+GSuberdie3, 0},
+ [GSuberdie3] {nil, nil, 15, SPuberdie1, stt+GSuberdie4, 0},
+ [GSuberdie4] {nil, nil, 15, SPuberdie2, stt+GSuberdie5, 0},
+ [GSuberdie5] {nil, nil, 15, SPuberdie3, stt+GSuberdie6, 0},
+ [GSuberdie6] {nil, nil, 15, SPuberdie4, stt+GSuberdie7, 0},
+ [GSuberdie7] {nil, nil, 0, SPuberdead, stt+GSuberdie7, 0},
+ [GSknight] {uwait, nil, 0, SPknightwalk1, stt+GSknight, 0},
+ [GSknightchase1] {uboss, nil, 10, SPknightwalk1, stt+GSknightchase2, 0},
+ [GSknightchase2] {nil, nil, 3, SPknightwalk1, stt+GSknightchase3, 0},
+ [GSknightchase3] {uboss, nil, 8, SPknightwalk2, stt+GSknightchase4, 0},
+ [GSknightchase4] {uboss, nil, 10, SPknightwalk3, stt+GSknightchase5, 0},
+ [GSknightchase5] {nil, nil, 3, SPknightwalk3, stt+GSknightchase6, 0},
+ [GSknightchase6] {uboss, nil, 8, SPknightwalk4, stt+GSknightchase1, 0},
+ [GSknightfire1] {nil, nil, 30, SPknightfire1, stt+GSknightfire2, 0},
+ [GSknightfire2] {nil, launch, 10, SPknightfire2, stt+GSknightfire3, 0},
+ [GSknightfire3] {nil, fire, 10, SPknightfire4, stt+GSknightfire4, 0},
+ [GSknightfire4] {nil, launch, 10, SPknightfire3, stt+GSknightfire5, 0},
+ [GSknightfire5] {nil, fire, 10, SPknightfire4, stt+GSknightchase1, 0},
+ [GSknightdie1] {nil, yelp, 1, SPknightwalk1, stt+GSknightdie2, 0},
+ [GSknightdie2] {nil, nil, 10, SPknightwalk1, stt+GSknightdie3, 0},
+ [GSknightdie3] {nil, nil, 10, SPknightdie1, stt+GSknightdie4, 0},
+ [GSknightdie4] {nil, nil, 10, SPknightdie2, stt+GSknightdie5, 0},
+ [GSknightdie5] {nil, nil, 10, SPknightdie3, stt+GSknightdie6, 0},
+ [GSknightdie6] {nil, nil, 10, SPknightdie4, stt+GSknightdie7, 0},
+ [GSknightdie7] {nil, nil, 10, SPknightdie5, stt+GSknightdie8, 0},
+ [GSknightdie8] {nil, nil, 10, SPknightdie6, stt+GSknightdie9, 0},
+ [GSknightdie9] {nil, nil, 0, SPknightdead, stt+GSknightdie9, 0},
+ [GSspectrewait1] {uwait, nil, 10, SPspectrewalk1, stt+GSspectrewait2, 0},
+ [GSspectrewait2] {uwait, nil, 10, SPspectrewalk2, stt+GSspectrewait3, 0},
+ [GSspectrewait3] {uwait, nil, 10, SPspectrewalk3, stt+GSspectrewait4, 0},
+ [GSspectrewait4] {uwait, nil, 10, SPspectrewalk4, stt+GSspectrewait1, 0},
+ [GSspectrewake] {nil, wake, 10, SPspectreF4, stt+GSspectrewake, 0},
+ [GSspectrechase1] {ughost, nil, 10, SPspectrewalk1, stt+GSspectrechase2, 0},
+ [GSspectrechase2] {ughost, nil, 10, SPspectrewalk2, stt+GSspectrechase3, 0},
+ [GSspectrechase3] {ughost, nil, 10, SPspectrewalk3, stt+GSspectrechase4, 0},
+ [GSspectrechase4] {ughost, nil, 10, SPspectrewalk4, stt+GSspectrechase1, 0},
+ [GSspectredie1] {nil, nil, 10, SPspectreF1, stt+GSspectredie2, 0},
+ [GSspectredie2] {nil, nil, 10, SPspectreF2, stt+GSspectredie3, 0},
+ [GSspectredie3] {nil, nil, 10, SPspectreF3, stt+GSspectredie4, 0},
+ [GSspectredie4] {nil, nil, 300, SPspectreF4, stt+GSspectrewake, 0},
+ [GSangel] {uwait, nil, 0, SPangelwalk1, stt+GSangel, 0},
+ [GSangelchase1] {uboss, nil, 10, SPangelwalk1, stt+GSangelchase2, 0},
+ [GSangelchase2] {nil, nil, 3, SPangelwalk1, stt+GSangelchase3, 0},
+ [GSangelchase3] {uboss, nil, 8, SPangelwalk2, stt+GSangelchase4, 0},
+ [GSangelchase4] {uboss, nil, 10, SPangelwalk3, stt+GSangelchase5, 0},
+ [GSangelchase5] {nil, nil, 3, SPangelwalk3, stt+GSangelchase6, 0},
+ [GSangelchase6] {uboss, nil, 8, SPangelwalk4, stt+GSangelchase1, 0},
+ [GSangelfire1] {nil, prelaunch, 10, SPangelfire1, stt+GSangelfire2, 0},
+ [GSangelfire2] {nil, launch, 20, SPangelfire2, stt+GSangelfire3, 0},
+ [GSangelfire3] {nil, relaunch, 10, SPangelfire1, stt+GSangelfire2, 0},
+ [GSangeldie1] {nil, yelp, 1, SPangelwalk1, stt+GSangeldie2, 0},
+ [GSangeldie2] {nil, nil, 1, SPangelwalk1, stt+GSangeldie3, 0},
+ [GSangeldie3] {nil, slurp, 10, SPangeldie1, stt+GSangeldie4, 0},
+ [GSangeldie4] {nil, nil, 10, SPangeldie2, stt+GSangeldie5, 0},
+ [GSangeldie5] {nil, nil, 10, SPangeldie3, stt+GSangeldie6, 0},
+ [GSangeldie6] {nil, nil, 10, SPangeldie4, stt+GSangeldie7, 0},
+ [GSangeldie7] {nil, nil, 10, SPangeldie5, stt+GSangeldie8, 0},
+ [GSangeldie8] {nil, nil, 10, SPangeldie6, stt+GSangeldie9, 0},
+ [GSangeldie9] {nil, nil, 10, SPangeldie7, stt+GSangeldie10, 0},
+ [GSangeldie10] {nil, victory, 130, SPangeldead, stt+GSangeldie10, 0},
+ [GSangeltired1] {nil, tiredsfx, 40, SPangeltired1, stt+GSangeltired2, 0},
+ [GSangeltired2] {nil, nil, 40, SPangeltired2, stt+GSangeltired3, 0},
+ [GSangeltired3] {nil, tiredsfx, 40, SPangeltired1, stt+GSangeltired4, 0},
+ [GSangeltired4] {nil, nil, 40, SPangeltired2, stt+GSangeltired5, 0},
+ [GSangeltired5] {nil, tiredsfx, 40, SPangeltired1, stt+GSangeltired6, 0},
+ [GSangeltired6] {nil, nil, 40, SPangeltired2, stt+GSangeltired7, 0},
+ [GSangeltired7] {nil, tiredsfx, 40, SPangeltired1, stt+GSangelchase1, 0},
+ [GSmissile] {uprj, smoke, 3, SPmissile1, stt+GSmissile, 1},
+ [GSmsmoke1] {nil, nil, 3, SPmsmoke1, stt+GSmsmoke2, 0},
+ [GSmsmoke2] {nil, nil, 3, SPmsmoke2, stt+GSmsmoke3, 0},
+ [GSmsmoke3] {nil, nil, 3, SPmsmoke3, stt+GSmsmoke4, 0},
+ [GSmsmoke4] {nil, nil, 3, SPmsmoke4, nil, 0},
+ [GSmboom1] {nil, nil, 6, SPmboom1, stt+GSmboom2, 0},
+ [GSmboom2] {nil, nil, 6, SPmboom2, stt+GSmboom3, 0},
+ [GSmboom3] {nil, nil, 6, SPmboom3, nil, 0},
+ [GSrocket] {uprj, smoke, 3, SProcket1, stt+GSrocket, 1},
+ [GSrsmoke1] {nil, nil, 3, SPrsmoke1, stt+GSrsmoke2, 0},
+ [GSrsmoke2] {nil, nil, 3, SPrsmoke2, stt+GSrsmoke3, 0},
+ [GSrsmoke3] {nil, nil, 3, SPrsmoke3, stt+GSrsmoke4, 0},
+ [GSrsmoke4] {nil, nil, 3, SPrsmoke4, nil, 0},
+ [GSrboom1] {nil, nil, 6, SPrboom1, stt+GSrboom2, 0},
+ [GSrboom2] {nil, nil, 6, SPrboom2, stt+GSrboom3, 0},
+ [GSrboom3] {nil, nil, 6, SPrboom3, nil, 0},
+ [GSflame1] {nil, uprj, 6, SPflame1, stt+GSflame2, 0},
+ [GSflame2] {nil, uprj, 6, SPflame2, stt+GSflame1, 0},
+ [GSneedle1] {uprj, nil, 6, SPneedle1, stt+GSneedle2, 0},
+ [GSneedle2] {uprj, nil, 6, SPneedle2, stt+GSneedle3, 0},
+ [GSneedle3] {uprj, nil, 6, SPneedle3, stt+GSneedle4, 0},
+ [GSneedle4] {uprj, nil, 6, SPneedle4, stt+GSneedle1, 0},
+ [GSspark1] {uprj, nil, 6, SPspark1, stt+GSspark2, 0},
+ [GSspark2] {uprj, nil, 6, SPspark2, stt+GSspark3, 0},
+ [GSspark3] {uprj, nil, 6, SPspark3, stt+GSspark4, 0},
+ [GSspark4] {uprj, nil, 6, SPspark4, stt+GSspark1, 0}
};
static void
@@ -2409,6 +2382,38 @@
}
void
+camwarp(void)
+{
+ int Δx, Δy, Δr;
+ double θ;
+
+ oplr->x = bosskillx;
+ oplr->y = bosskilly;
+ Δx = camobj->x - oplr->x;
+ Δy = oplr->y - camobj->y;
+ θ = atan2(Δy, Δx);
+ if(θ < 0)
+ θ = Fpi * 2 + θ;
+ oplr->θ = θ / (Fpi * 2) * 360;
+ Δr = 0x14000;
+ do{
+ oplr->x = camobj->x - ffs(Δr, cost[oplr->θ]);
+ oplr->y = camobj->y + ffs(Δr, sint[oplr->θ]);
+ Δr += 0x1000;
+ }while(!trymove(oplr, Dplr, 1, 0));
+ oplr->tx = oplr->x >> Dtlshift;
+ oplr->ty = oplr->y >> Dtlshift;
+ oplr->tl = tiles + oplr->ty * Mapdxy + oplr->tx;
+ ostate(oplr, stt+GSplrcam);
+ switch(camobj->type){
+ case Oschb: ostate(camobj, stt+GSschbcam); break;
+ case Ootto: ostate(camobj, stt+GSottocam); break;
+ case Ofett: ostate(camobj, stt+GSfettcam); break;
+ case Ohitler: ostate(camobj, stt+GShitlercam); break;
+ }
+}
+
+void
bonus(Static *s)
{
switch(s->item){
@@ -2519,20 +2524,23 @@
void
gstep(void)
{
- if((gm.demo || gm.record) && demfrm-- != 0)
- return;
- demfrm = 3;
+ if(gm.demo || gm.record){
+ if(demfrm-- != 0)
+ return;
+ demfrm = 3;
+ Δtc = 4;
+ }
input();
noise = 0;
uworld();
upal();
render();
+ mtc += Δtc;
gm.lvltc += Δtc;
if(dofizz){
+ dofizz = 0;
if(!gm.end)
gm.end = EDfizz;
- gm.fizz++;
- dofizz = 0;
gend();
return;
}
--- a/hub.c
+++ b/hub.c
@@ -52,7 +52,8 @@
Lmscore,
Lpants,
Lquit,
- Ldie
+ Lmexit,
+ Lexit
};
struct Seq{
int dt;
@@ -241,7 +242,7 @@
return;
if(r == 'y'){
sfx(Sshoot);
- reset(ml+Ldie);
+ reset(ml+Lmexit);
}
else if(r == 'n' || r == Kesc){
sfx(Sesc);
@@ -448,19 +449,21 @@
{
step = gstep;
gm.end = 0;
- gm.fizz = 0;
}
static void
camtxt2(void)
{
- put(0, 56, Vw, 16, 0x7f);
+ camwarp();
+ mtc = 32;
+ render();
+ fizzop(-1, 1);
+ put(0, 0, Vw, Vhud, 0x7f);
viewbox();
}
static void
camtxt(void)
{
- fizzop(-1, 0);
pictxt(0, 56, "LET\'S SEE THAT AGAIN!");
out();
}
@@ -565,7 +568,7 @@
}
static void
-die(void)
+exit(void)
{
threadexitsall(nil);
}
@@ -604,7 +607,8 @@
mscoreq[] = {{10, fadeout}, {0, score}, {10, fadein}},
pantsq[] = {{30, fadeout}, {0, pants}, {30, fadein}},
quitq[] = {{0, blink}, {10, ask}},
- dieq[] = {{10, fadeout}, {1, die}};
+ mexitq[] = {{10, fadeout}},
+ exitq[] = {{1, exit}};
static Menu *mp, ml[] = {
[Lload] {nil, decq, decq+nelem(decq), ml+Lintro, &fblk},
@@ -628,7 +632,8 @@
[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},
- [Ldie] {nil, dieq, dieq+nelem(dieq), nil, &fmenu}
+ [Lmexit] {nil, mexitq, mexitq+nelem(mexitq), ml+Lexit, &fmenu},
+ [Lexit] {nil, exitq, exitq+nelem(exitq)}
};
static void
@@ -637,11 +642,11 @@
gm.demo = gm.record = 0;
pal = pals[Cfad];
if(demf != nil){
- if(demexit)
- threadexitsall(nil);
free(demf);
demf = nil;
demd = dems;
+ if(demexit)
+ mp->m = ml+Lexit;
}
}
void
@@ -655,14 +660,16 @@
break;
enddem:
case EDdem:
- dend();
mp->m = ml+Ltitle;
+ dend();
break;
case EDcam:
- fizzop(0x7f, 1);
+ 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;
- gm.fizz++;
break;
case EDcam2:
if(gm.demo || gm.record)
@@ -669,10 +676,11 @@
dend();
else
pal = pals[Cfad];
+ scalspr(SPcam, vw.dx/2, vw.dy+1);
break;
case EDkey:
- dend();
mp->m = ml+Linctl;
+ dend();
break;
case EDdie:
if(gm.demo || gm.record)
@@ -686,6 +694,7 @@
mp->m = ml+Lsfxwait;
break;
}
+ mtc = 0;
step = mstep;
}
--- a/man/1/wl3d
+++ b/man/1/wl3d
@@ -33,6 +33,42 @@
Now, you must do anything to escape from the belly of a Nazi dungeon - or die trying."
.RE
.PP
+The command line options are:
+.TP \w'\fLf\ \ \ \fIdemo'u
+.B -2
+Set game version to Spear of Destiny Mission 2: Return to Danger.
+.TP
+.B -3
+Set game version to Spear of Destiny Mission 3: The Ultimate Challenge.
+.TP
+.B -d
+Set game version to Wolfenstein 3-D 1.4 shareware.
+.TP
+.BI -f\ demo
+Play demo from file on startup.
+.TP
+.BI -m\ dir
+Set game data directory.
+.TP
+.B -o
+Set game version to Spear of Destiny 1.0 demo.
+.TP
+.B -p
+Run at full speed.
+.TP
+.B -q
+Quit after demofile playback.
+.TP
+.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.
+.PD
+.PP
.I Wl3d
requires several data files to operate, containing sound effects, music, and several types of graphics.
These are detailed in
@@ -51,7 +87,8 @@
.B MBEFORE
and
.B MCREATE
-flags.
+flags (see
+.IR bind (2)).
Data files can thus be contained in a system directory while the config and save files' location, which are user-specific, can be left at the user's discretion.
If these user-specific files exist and
.I wl3d
@@ -68,7 +105,8 @@
.IR map ,
and
.B -x
-optionally sets the game difficulty.
+optionally sets the game difficulty to 1-4, from easiest to hardest,
+the default being 2.
The
.B -p
parameter runs the program at the fastest speed possible for testing purposes.
@@ -81,31 +119,19 @@
The default game version is Wolfenstein 3-D 1.4 retail, and the data files use the
.L wl6
extension.
-Others are set by the following options:
-.TF -2
-.TP
-.B -d
-Wolfenstein 3-D 1.4 shareware
-.TP
-.B -s
-Spear of Destiny 1.0 retail
-.TP
+Others are set by the options
+.BR -2 ,
+.BR -3 ,
+.BR -d ,
.B -o
-Spear of Destiny 1.0 demo
-.TP
-.B -2
-Spear of Destiny Mission 2: Return to Danger
-.TP
-.B -3
-Spear of Destiny Mission 3: The Ultimate Challenge
-.PD
-.PP
+and
+.BR -s .
The respective data file extensions are
+.LR sd2 ,
+.LR sd3 ,
.LR wl1 ,
-.LR sod ,
.LR sdm ,
-.LR sd2 ,
-.LR sd3 .
+.LR sod .
.PD
Other game versions are unsupported.
Note that
@@ -123,7 +149,7 @@
parameter.
The
.B -q
-parameter causes the program to exit after playback instead.
+parameter causes the program to exit after its playback instead.
The filename's extension, if any, is ignored.
Regardless, a corresponding game version must be set using the aforementioned command line parameters.
An incorrect version will cause erroneous playback or a crash.
@@ -147,7 +173,7 @@
.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 4 megabytes, depending on the game version and architecture.
+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.
.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
@@ -156,16 +182,25 @@
.PP
Copy protection code and the Spear of Destiny Jukebox have been excised.
.PP
-Some cosmetic differences exist.
+Menus are implemented differently, and some have been altered in functionality.
.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.
.SH FILES
-.TF /sys/games/lib/wl3d/*
+.TF /sys/games/lib/wl3d/intro.wl6
.TP
-.B /sys/games/lib/wl3d/*
-wl3d data files
+.B /sys/games/lib/wl3d/
+default wl3d data directory
+.TP
+.B /sys/games/lib/wl3d/intro.wl6
+.B wl6/wl1
+intro screen
+.TP
+.B /sys/games/lib/wl3d/intro.sod
+.B sdm/sod
+intro screen
+.PD
.SH "SEE ALSO"
.IR doom (1) ,
.IR opl2 (1) ,
@@ -189,9 +224,9 @@
Little is done in case the program is unable to run at a framerate of 70 Hz.
.PD
.SS Engine bugs
-Correct demo playback depends on the sound settings used during recording.
+Correct demo playback depends on the sound and view size settings used during recording.
Different settings on playback may cause desynchronization.
-.PD
+.PP
Spawned projectiles are not properly cleared when removed and may cause aberrant behavior and demo desynchronization.
.SH HISTORY
id Software's Wolfenstein 3-D was released for
--- a/man/6/wl3d
+++ b/man/6/wl3d
@@ -324,6 +324,8 @@
is used in conjunction with
.B vgadict
to read and uncompress each lump upon retrieval.
+Pixel data is usually encoded as a palette index,
+and is used in conjunction with a 256 color palette.
.SS Vgahead
.RS
.IR off [ np ][3]
@@ -361,7 +363,8 @@
.I np
pictures, retrieved from
.IR pic .
-.I Np can be obtained from
+.I Np
+can be obtained from
.IR pt 's
uncompressed size.
The following sections detail each lump type.
@@ -384,7 +387,7 @@
containing its pixel data.
The data is an array of bytes of size
.I dy
-.L *
+.SM *
.IR dx [ n ],
to be translated to the character's location on the screen.
A pixel's color is overwritten with the engine's current foreground color when a non-zero byte in the character's pixel data occurs.
@@ -473,19 +476,29 @@
contain player input for the duration of the frame
and correspond respectively to pressed game keys, total horizontal movement (turning) and total vertical movement (forward displacement) deltas.
.I Bt
-is a 8-bit array of the main game keys, regardless of input method.
+is an 8-bit array of the main game keys, regardless of input method.
These are, from least to most significant bit:
fire, strafe, run, open, knife, pistol, machine gun and gatling gun.
The movement deltas are bounded from -100 to 100.
.SS Static data
-Some of the graphics data is stored in the executable and thus cannot be altered.
+Some of the graphics data is stored in the executable and thus cannot be altered
+without modifying it or the loaded object files.
These are the base color palette and intro screen.
-The intro screen is a static screen displayed on startup while verifying available memory and hardware, changed depending on the results.
Each have a
.B wl1/wl6
and a
.B sdm/sod
version, but only one is present.
+.PP
+The base color palette is stored as any other palette, and is the one used in most circumstances.
+Several other palettes are generated based on it,
+notably for screen flashes and fade effects.
+.PP
+The intro screen is a static screen displayed on startup while verifying available memory and hardware,
+then changed depending on the results.
+It is an uncompressed 320x200 graphic lump.
+.BR wl3d (1)
+separates the intro screen from the binary as a distinct file formatted as a 320x200 byte array, and loaded on startup.
.SS Palettes
.RS
{
@@ -522,16 +535,80 @@
for file offsets, and
.IR sz ,
for lengths in bytes.
+A chunk of size 0 is skipped.
+This is permitted when the specific lump is never referenced,
+which can occur in the
+.B wl1
+and
+.B sdm
+versions, where only a limited number of maps and resources are used.
+Attempting to load a sparse lump will cause a crash.
.PP
The rest of the file contains section data.
.SS Wall textures
-[words]
+Wall tiles are 64x64 byte arrays of palette indices.
+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.
.SS Sprites
-[words]
+.RS
+.IR lx [2]
+.IR rx [2]
+.IR cofs [ rx-lx+1 ][2]
+.IR data []
+.br
+.BR cmd :
+{
+.IR se [2] po [2] ss [2]
+}[]
+.IR nul [2]
+.RE
+.PP
+Sprites are stored as variable-length arrays of offsets and visible pixel data,
+with an implicit maximal size of 64x64.
+.IR Lx
+and
+.IR rx
+define the 0-indexed left and right-most coloumns containing visible pixels,
+and must respect the following restrictions:
+.PP
+.RS
+.I lx ∈ {0,1,...,63}
+.br
+.I rx ∈ {32,33,...,63}
+.br
+.I 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.
+.PP
+The following variable-length array,
+.IR cofs ,
+contains one offset into sprite data for each visible coloumn.
+Each offset is set from the beginning of the lump, and points to a
+.I cmd
+array.
+.I Ss / 2
+and
+.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
+an offset into the sprite lump pointing to the strip's palette indices.
+The
+.I cmd
+array is terminated by a 16-bit wide zero.
+Since
+.I ss
+and
+.I se
+are used as word table offsets, they are multiplied by two.
.SS Raw pcm
.RS
{
-.IR chunk [ size/4096 ][]
+.IR chunk [ (size-1)/4096+1 ][]
.RI }[ npcm ]
{
.IR index [2]
@@ -551,20 +628,31 @@
.I Size
is the sum in bytes of the lengths of the lump's chunks.
.PP
-The references for each pcm sound effect (different than those for regular sound effects), as well as their number, are hardcoded in the engine:
+The valid references for each pcm sound effect (different than those for regular sound effects), as well as their number, are hardcoded in the engine:
.TF wl1
.TP
.B wl1
-21 pcms
+46 pcms (20 non empty)
.TP
.B wl6
46 pcms
.TP
.B sdm
-26 pcms
+40 pcms (25 non empty)
.TP
.B sod
40 pcms
+.PD
+.PP
+However, neither
+.I npcm
+nor the pcm table actually reflect this number.
+The number in parentheses indicates the actual number of valid pcm lumps for versions
+which may contain empty chunks.
+These are not contiguous,
+and care must be taken to skip all zero-sized chunks referencing each individual sparse
+pcm lump,
+as indicated in the pcm table.
.SH "CONFIGURATION FILE AND HIGHSCORES"
[words]
.SH "SEE ALSO"
--- a/map.c
+++ b/map.c
@@ -41,9 +41,9 @@
case Rclip2:
break;
case Rblock:
- tl->o = nil;
+ tl->o = nil;
tl->to = 1;
- /* wet floor */
+ break;
case Rcross:
case Rchalice:
case Rbible:
@@ -58,7 +58,10 @@
break;
}
stce->tl = tl;
- stce->spr = sprs + (stctype[n] == Rclip2 ? 28 : 2+n);
+ n = stctype[n] == Rclip2 ? 28 : 2+n;
+ stce->spr = sprs + n;
+ if(stce->spr == nil)
+ sysfatal("spawnstc: missing static sprite %d\n", n);
if(++stce == stcs+Nstc)
sysfatal("static object overflow");
}
@@ -720,8 +723,8 @@
void
drop(Tile *tl, int n)
{
+ int sn, *sti;
Static *s;
- int *sti;
for(sti=stctype; sti<stctype+nelem(stctype); sti++)
if(*sti == n)
@@ -737,7 +740,10 @@
if(s >= stcs+nelem(stcs))
return;
s->tl = tl;
- s->spr = sprs + (n == Rclip2 ? 28 : 2+(sti-stctype));
+ sn = n == Rclip2 ? 28 : 2+(sti-stctype);
+ s->spr = sprs + sn;
+ if(s->spr == nil)
+ sysfatal("drop: missing static sprite %d\n", sn);
s->f = OFbonus;
s->item = n;
}
--- a/rend.c
+++ b/rend.c
@@ -6,14 +6,11 @@
s32int sint[360+90], *cost;
typedef struct Vis Vis;
-struct Vis{
- s16int vwdx;
- s16int vwdy;
- Dat *spr;
-};
-
+typedef struct Scaler Scaler;
enum{
Nvis = 50,
+ Nscal = 256+1,
+ Wdxy = 64,
Fineθ = 3600,
Dfoclen = 0x5700,
Dglob = 0x10000,
@@ -20,6 +17,11 @@
Dtile = 0x2000,
Dobj = 0x4000
};
+struct Vis{
+ s16int vwx;
+ s16int vwdy;
+ Spr *spr;
+};
#define Pi 3.141592657
static float Rad = (float)Fineθ / 2 / Pi;
@@ -30,30 +32,159 @@
static s32int xin, yin;
static int dtx, dty;
static u16int ∂xdown, ∂xup, ∂ydown, ∂yup;
-static int lastside;
+struct Scaler{
+ int skip;
+ int ps;
+ int pe;
+ int dx;
+};
+static Scaler scals[Nscal][Wdxy+1], *sce;
+static uchar *scps, *scts;
+static int scx, scdx, scdy;
+static int waldy[Vw];
+static s32int lastin;
+static int lasttile, lastside;
+
static void
-scalespr(int, int, int)
+scalscol(Scaler *ss, Sprc *c, int dx)
{
+ int ps, pe, w;
+ uchar n, *d, *sp, *ds;
+ Scaler *s, *se;
+
+ ds = pxb + vw.ofs + scx;
+ se = ss + c->e;
+ while(se != ss){
+ sp = c->p;
+ s = ss + c->s;
+ for(; s<se; s++, sp++){
+ if(s->skip)
+ continue;
+ n = *sp;
+ for(ps=s->ps, pe=s->pe; ps<pe; ps++){
+ if(ps >= vw.dy)
+ break;
+ if(ps < 0)
+ continue;
+ d = ds + ps * Vw;
+ w = dx;
+ while(w-- > 0)
+ *d++ = n;
+ }
+ }
+ c++;
+ se = ss + c->e;
+ }
}
static void
-scalevis(Vis *)
+scalvis(Vis *v)
{
+ int x, dx, lx, rx, *lw, *rw;
+ Scaler *ss, *s, *se;
+ Spr *spr;
+ Sprc **c;
+
+ ss = scals[v->vwdy >> 3];
+ if(ss == scals[0] || ss > sce)
+ return;
+ spr = v->spr;
+ lx = spr->lx;
+ rx = spr->rx;
+ scx = v->vwx;
+ if(lx < 32){
+ s = ss + lx;
+ se = ss + 32;
+ while(s < se)
+ scx -= s++->dx;
+ }else{
+ s = ss + 32;
+ se = ss + lx;
+ while(s < se)
+ scx += s++->dx;
+ }
+ c = spr->cs;
+ for(s=ss+lx, se=ss+rx+1; s<se && scx<vw.dx; c++, scx+=dx){
+ dx = s++->dx;
+ if(dx == 0)
+ continue;
+ if(dx == 1){
+ if(scx >= 0 && waldy[scx] < v->vwdy)
+ scalscol(ss, *c, 1);
+ continue;
+ }
+ x = scx + dx;
+ if(scx < 0){
+ if(x <= 0)
+ continue;
+ dx = x;
+ scx = 0;
+ }else if(x > vw.dx)
+ dx = vw.dx - scx;
+ lw = waldy + scx;
+ rw = lw + dx - 1;
+ if(*lw < v->vwdy){
+ if(*rw < v->vwdy){
+ scalscol(ss, *c, dx);
+ continue;
+ }
+ while(*rw >= v->vwdy)
+ rw--, dx--;
+ scalscol(ss, *c, dx);
+ break;
+ }else{
+ if(*rw >= v->vwdy)
+ continue;
+ while(*lw >= v->vwdy){
+ lw++, scx++;
+ dx--;
+ }
+ scalscol(ss, *c, dx);
+ }
+ }
}
static void
+scalcol(void)
+{
+ int i, n, x, dx;
+ uchar c, *ds, *d;
+ Scaler *s;
+
+ s = scals[(waldy[scx] & 0xfff8) >> 3];
+ if(s > sce)
+ s = sce;
+ ds = pxb + vw.ofs + scx;
+ for(x=0; x<Wdxy; x++, s++){
+ if(s->skip)
+ continue;
+ c = scps[x];
+ for(i=s->ps, n=s->pe; i<n; i++){
+ if(i >= vw.dy)
+ break;
+ if(i < 0)
+ continue;
+ d = ds + i * Vw;
+ dx = scdx;
+ while(dx-- > 0)
+ *d++ = c;
+ }
+ }
+}
+
+static void
topspr(void)
{
if(ver < SDM && gm.won){
if(oplr->s == stt+GSplrcam && mtc & 32)
- scalespr(SPcam, vw.dx/2, vw.dy+1);
+ scalspr(SPcam, vw.dx/2, vw.dy+1);
return;
}
if(gm.w != -1)
- scalespr(wspr[gm.w] + gm.wfrm, vw.dx/2, vw.dy+1);
+ scalspr(wspr[gm.w] + gm.wfrm, vw.dx/2, vw.dy+1);
if(gm.record || gm.demo)
- scalespr(SPdemo, vw.dx/2, vw.dy+1);
+ scalspr(SPdemo, vw.dx/2, vw.dy+1);
}
static int
@@ -83,7 +214,8 @@
v->vwdy = 0;
return 0;
}
- v->vwdx = vw.mid + cy * prjw / cx;
+ v->vwx = vw.mid + cy * prjw / cx;
+ /* low 3 bits are fractional */
v->vwdy = prjh / (cx >> 8);
return cx < Dtlglobal && abs(cy) < Dtlglobal / 2;
}
@@ -109,12 +241,13 @@
}
static void
-scaleall(void)
+scalobj(void)
{
+ int i, n, min;
Obj *o;
Tile *tl;
Static *st;
- Vis viss[Nvis], *v, *w, *e, *m;
+ Vis viss[Nvis], *v, *e, *m;
memset(viss, 0, sizeof viss);
e = viss;
@@ -149,11 +282,9 @@
if(o->vwdy == 0)
continue;
o->f |= OFvis;
- e->vwdx = o->vwdx;
+ e->vwx = o->vwdx;
e->vwdy = o->vwdy;
e->spr = o->s->spr;
- if(e->spr == nil)
- e->spr = sprs + o->sdt;
if(o->s->rot)
e->spr += rot(o);
if(e < viss + nelem(viss)-1)
@@ -161,20 +292,23 @@
}else
o->f &= ~OFvis;
}
- for(v=viss; v<e; v++){
- for(w=v, m=v; w<=e; w++)
- if(w->vwdy < m->vwdy)
- m = w;
- scalevis(m);
- if(v != m)
- memcpy(m, v, sizeof *m);
+ for(i=0, n=e-viss; i<n; i++){
+ min = 32000;
+ v = m = viss;
+ while(v < e){
+ if(v->vwdy < min){
+ min = v->vwdy;
+ m = v;
+ }
+ v++;
+ }
+ scalvis(m);
+ m->vwdy = 32000;
}
- if(e != viss)
- scalevis(e);
}
static s16int
-walldy(s32int xin, s32int yin)
+walldy(void)
{
s32int cx, dy;
@@ -188,7 +322,7 @@
static void
vwall(int i, int tx, int ty, int tile)
{
- s16int p;
+ int n;
u16int tex;
tex = yin >> 4 & 0xfc0;
@@ -196,50 +330,43 @@
tex = 0xfc0 - tex;
xin += Dtlglobal;
}
- p = 0;
- USED(tex, p, tx, ty, tile, xin, i);
-#ifdef DICKS
- wallheight[i] = walldy();
- if(lastside==1 && lastintercept == tx && lasttilehit == tile){
- /* in the same wall type as last time, so check for
- * optimized draw */
- if(tex == (u16int)postsource){
- // wide scale
- postwidth++;
- wallheight[i] = wallheight[i-1];
+ waldy[i] = walldy();
+ if(lastside == 1 && lastin == tx && lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
return;
}
- /* new wall */
- if(lastside != -1) /* if not the first scaled post */
- ScalePost();
- lastside = true;
- lastintercept = tx;
- lasttilehit = tile;
- postx = i;
- postwidth = 1;
-
- if(tile & 0x40){ /* check for adjacent doors */
- if(tiles[ty][tx-dtx].tl & 0x80)
- p = SPdoor+3;
+ if(lastside != -1)
+ scalcol();
+ lastside = 1;
+ lastin = tx;
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ if(tile & 0x40){
+ if(tiles[ty*Mapdxy + tx-dtx].tl & 0x80)
+ n = drofs + 3;
else
- p = vertwall[tile & ~0x40];
+ n = ((tile & ~0x40) - 1) * 2 + 1;
}else
- p = vertwall[tile];
- *(((u16int *)&postsource)+1) = (u16int)PM_GetPage(p);
- (u16int)postsource = tex;
-#endif
+ n = (tile - 1) * 2 + 1;
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
hwall(int i, int tx, int ty, int tile)
{
- s16int p;
+ int n;
u16int tex;
tex = xin >> 4 & 0xfc0;
@@ -247,141 +374,130 @@
yin += Dtlglobal;
else
tex = 0xfc0 - tex;
- p = 0;
- USED(i, tx, ty, tile, tex, p);
-#ifdef DICKS
- wallheight[i] = walldy();
- if(lastside == 0 && lastintercept == ty && lasttilehit == tile){
- /* in the same wall type as last time, so check for
- * optimized draw */
- if(tex == (u16int)postsource){ /* wide scale */
- postwidth++;
- wallheight[i] = wallheight[i-1];
- return;
+ waldy[i] = walldy();
+ if(lastside == 0 && lastin == ty && lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
- }else{ /* new wall */
- if(lastside != -1) /* if not the first scaled post */
- ScalePost();
-
- lastside = 0;
- lastintercept = ty;
- lasttilehit = tile;
- postx = i;
- postwidth = 1;
- if(tile & 0x40){ /* check for adjacent doors */
- tx = xin >> Dtlshift;
- if(tiles[ty-dty][tx].tl & 0x80)
- p = SPdoor+2;
- else
- p = horizwall[tile & ~0x40];
- }else
- p = horizwall[tile];
- *( ((u16int *)&postsource)+1) = (u16int)PM_GetPage(p);
- (u16int)postsource = tex;
+ return;
}
-#endif
+ if(lastside != -1)
+ scalcol();
+ lastside = 0;
+ lastin = ty;
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ if(tile & 0x40){
+ tx = xin >> Dtlshift;
+ if(tiles[(ty-dty)*Mapdxy + tx].tl & 0x80)
+ n = drofs + 2;
+ else
+ n = ((tile & ~0x40) - 1) * 2;
+ }else
+ n = (tile - 1) * 2;
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
vdoor(int i, int tile)
{
- USED(i, xin, yin, tile);
-#ifdef DICKS
+ int n;
+ u16int tex;
Door *d;
- u16int tex, p;
- wallheight[i] = walldy(xin, yin);
+ waldy[i] = walldy();
d = doors + (tile & 0x7f);
tex = yin - d->dopen >> 4 & 0xfc0;
- if(lasttilehit == tile){
- /* in the same door as last time, so check for optimized draw */
- if(tex == (u16int)postsource){
- /* wide scale */
- postwidth++;
- wallheight[i] = wallheight[i-1];
- return;
+ if(lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost ();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
- }else{
- if (lastside != -1) /* if not the first scaled post */
- ScalePost (); /* draw last post */
- /* first pixel in this door */
- lastside = 2;
- lasttile = tile;
- postx = i;
- postwidth = 1;
- switch(d->lock){
- case DRunlk: p = SPdoor; break;
- case DRlock1:
- case DRlock2:
- case DRlock3:
- case DRlock4: p = SPdoor+6; break;
- case DRup: p = SPdoor+4; break;
- }
- *( ((u16int *)&postsource)+1) = (u16int)PM_GetPage(p+1);
- (u16int)postsource = tex;
+ return;
}
-#endif
+ if(lastside != -1)
+ scalcol();
+ lastside = 2;
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ n = 1;
+ switch(d->lock){
+ case DRunlk: n += drofs; break;
+ case DRlock1:
+ case DRlock2:
+ case DRlock3:
+ case DRlock4: n += drofs + 6; break;
+ case DRup: n += drofs + 4; break;
+ }
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
hdoor(int i, int tile)
{
- USED(i, xin, yin, tile);
-#ifdef DICKS
+ int n;
+ u16int tex;
Door *d;
- u16int tex, p;
- wallheight[i] = walldy(xin, yin);
+ waldy[i] = walldy();
d = doors + (tile & 0x7f);
tex = xin - d->dopen >> 4 & 0xfc0;
- if(lasttilehit == tile){
- /* in the same door as last time, so check for optimized draw */
- if(tex == (u16int)postsource){ /* wide scale */
- postwidth++;
- wallheight[i] = wallheight[i-1];
- return;
+ if(lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
- }else{
- if(lastside != -1) /* if not the first scaled post */
- ScalePost(); /* draw last post */
- /* first pixel in this door */
- lastside = 2;
- lasttile = tile;
- postx = i;
- postwidth = 1;
- switch(d->lock){
- case DRunlk: p = SPdoor; break;
- case DRlock1:
- case DRlock2:
- case DRlock3:
- case DRlock4: p = SPdoor+6; break;
- case DRup: p = SPdoor+4; break;
- }
- *( ((u16int *)&postsource)+1) = (u16int)PM_GetPage(p);
- (u16int)postsource = tex;
+ return;
}
-#endif
+ if(lastside != -1)
+ scalcol();
+ lastside = 2;
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ n = 0;
+ switch(d->lock){
+ case DRunlk: n = drofs; break;
+ case DRlock1:
+ case DRlock2:
+ case DRlock3:
+ case DRlock4: n = drofs + 6; break;
+ case DRup: n = drofs + 4; break;
+ }
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
vpush(int i, int tile)
{
- s16int p;
+ int n;
u16int tex, ofs;
tex = yin >> 4 & 0xfc0;
@@ -391,40 +507,35 @@
tex = 0xfc0 - tex;
}else
xin += ofs;
- p = 0;
- USED(i, xin, tile, p, tex, ofs);
-#ifdef DICKS
- wallheight[i] = walldy(xin, yin);
- if(lasttilehit == tile){
- /* in the same wall type as last time, so check for
- * optimized draw */
- if(tex == (u16int)postsource){ /* wide scale */
- postwidth++;
- wallheight[i] = wallheight[i-1];
- return;
+ waldy[i] = walldy();
+ if(lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
- }else{ /* new wall */
- if(lastside != -1) // if not the first scaled post
- ScalePost ();
- lasttile = tile;
- postx = i;
- postwidth = 1;
- p = vertwall[tile&63];
- *( ((u16int *)&postsource)+1) = (u16int)PM_GetPage(p);
- (u16int)postsource = tex;
+ return;
}
-#endif
+ if(lastside != -1)
+ scalcol();
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ n = ((tile & 63) - 1) * 2 + 1;
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
hpush(int i, int tile)
{
- s16int p;
+ int n;
u16int tex, ofs;
tex = xin >> 4 & 0xfc0;
@@ -435,34 +546,29 @@
tex = 0xfc0 - tex;
yin += ofs;
}
- p = 0;
- USED(i, yin, tile, p, tex, ofs);
-#ifdef DICKS
- wallheight[i] = walldy(xin, yin);
- if(lasttilehit == tile){
- /* in the same wall type as last time, so check for
- * optimized draw */
- if(tex == (u16int)postsource){ /* wide scale */
- postwidth++;
- wallheight[i] = wallheight[i-1];
- return;
+ waldy[i] = walldy();
+ if(lasttile == tile){
+ if(scps == scts + tex){
+ scdx++;
+ waldy[i] = waldy[i-1];
}else{
- ScalePost();
- (u16int)postsource = tex;
- postwidth = 1;
- postx = i;
+ scalcol();
+ scps = scts + tex;
+ scdx = 1;
+ scx = i;
}
- }else{ /* new wall */
- if(lastside != -1) /* if not the first scaled post */
- ScalePost();
- lasttile = tile;
- postx = i;
- postwidth = 1;
- p = horizwall[tile&63];
- *( ((u16int *)&postsource)+1) = (u16int)PM_GetPage(p);
- (u16int)postsource = tex;
+ return;
}
-#endif
+ if(lastside != -1)
+ scalcol();
+ lasttile = tile;
+ scx = i;
+ scdx = 1;
+ n = ((tile & 63) - 1) * 2;
+ scts = wals[n];
+ if(scts == nil)
+ sysfatal("sparse wall %d\n", n);
+ scps = scts + tex;
}
static void
@@ -474,6 +580,19 @@
u16int dr, x, y, ∂x, ∂y, tilehit;
s32int rs, dx, dy;
+ vw.θ = oplr->θ;
+ midθ = vw.θ * (Fineθ / 360);
+ vw.sin = sint[vw.θ];
+ vw.cos = cost[vw.θ];
+ vw.x = oplr->x - ffs(Dfoclen, vw.cos);
+ vw.y = oplr->y + ffs(Dfoclen, vw.sin);
+ vw.tx = vw.x >> Dtlshift;
+ vw.ty = vw.y >> Dtlshift;
+ ∂xdown = vw.x & Dtlglobal - 1;
+ ∂xup = Dtlglobal - ∂xdown;
+ ∂ydown = vw.y & Dtlglobal - 1;
+ ∂yup = Dtlglobal - ∂ydown;
+ lastside = -1;
i = 0;
tilehit = 0;
loop:
@@ -608,84 +727,85 @@
next:
if(++i < vw.dx)
goto loop;
+ scalcol();
}
static void
-ScalePost(void)
+calcscal(Scaler *s, int dy)
{
-#ifdef DICKS
- ax = SCREENSEG;
- es = ax;
- bx = postx >> 1;
+ int i, step, fix, top, ps, pe;
- asm mov bp,WORD PTR [wallheight+bx] // fractional height (low 3 bits frac)
- asm and bp,0xfff8 // bp = heightscaler*4
- asm shr bp,1
- asm cmp bp,[maxscaleshl2]
- asm jle heightok
- asm mov bp,[maxscaleshl2]
-heightok:
- asm add bp,OFFSET fullscalefarcall
+ top = (vw.dy - dy) / 2;
+ step = (dy << 16) / 64;
+ fix = 0;
+ for(i=0; i<nelem(scals[0]); i++, s++){
+ ps = (fix >> 16) + top;
+ fix += step;
+ pe = (fix >> 16) + top;
+ s->dx = pe > ps ? pe - ps : 0;
+ s->skip = ps == pe || pe < 0 || ps >= vw.dy || i == nelem(scals[0])-1;
+ if(s->skip)
+ continue;
+ s->ps = ps;
+ s->pe = pe;
+ }
+}
+static void
+scaltab(int maxdy)
+{
+ int save, dy;
+ Scaler (*s)[nelem(scals[0])];
- // scale a byte wide strip of wall
- asm mov bx,[postx]
- asm mov di,bx
- asm shr di,2 // X in bytes
- asm add di,[bufferofs]
-
- asm and bx,3
- asm shl bx,3 // bx = pixel*8+pixwidth
- asm add bx,[postwidth]
-
- asm mov al,BYTE PTR [mapmasks1-1+bx] // -1 because no widths of 0
- asm mov dx,SC_INDEX+1
- asm out dx,al // set bit mask register
- asm lds si,DWORD PTR [postsource]
- asm call DWORD PTR [bp] // scale the line of pixels
-
- asm mov al,BYTE PTR [ss:mapmasks2-1+bx] // -1 because no widths of 0
- asm or al,al
- asm jz nomore
-
- // draw a second byte for vertical strips that cross two bytes
- asm inc di
- asm out dx,al // set bit mask register
- asm call DWORD PTR [bp] // scale the line of pixels
-
- asm mov al,BYTE PTR [ss:mapmasks3-1+bx] // -1 because no widths of 0
- asm or al,al
- asm jz nomore
-
- // draw a third byte for vertical strips that cross three bytes
- asm inc di
- asm out dx,al // set bit mask register
- asm call DWORD PTR [bp] // scale the line of pixels
-
-nomore:
- asm mov ax,ss
- asm mov ds,ax
-#endif
+ 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++;
+ }
+ memcpy(scals, scals+1, sizeof *scals);
+ sce = scals[dy-1];
}
-static void
-walls(void)
+void
+scalspr(int n, int x, int dy)
{
- vw.θ = oplr->θ;
- midθ = vw.θ * (Fineθ / 360);
- vw.sin = sint[vw.θ];
- vw.cos = cost[vw.θ];
- vw.x = oplr->x - ffs(Dfoclen, vw.cos);
- vw.y = oplr->y + ffs(Dfoclen, vw.sin);
- vw.tx = vw.x >> Dtlshift;
- vw.ty = vw.y >> Dtlshift;
- ∂xdown = vw.x & Dtlglobal - 1;
- ∂xup = Dtlglobal - ∂xdown;
- ∂ydown = vw.y & Dtlglobal - 1;
- ∂yup = Dtlglobal - ∂ydown;
+ int dx, lx, rx;
+ Scaler *ss, *s, *se;
+ Spr *spr;
+ Sprc **c;
- lastside = -1; // the first pixel is on a new wall
- raytrace();
- ScalePost(); // no more optimization on last post
+ spr = sprs + n;
+ if(spr == nil)
+ sysfatal("scalspr: missing sprite %d\n", n);
+ dy >>= 1;
+ ss = scals[dy];
+ lx = spr->lx;
+ rx = spr->rx;
+ scx = x;
+ if(lx < 32){
+ s = ss + lx;
+ se = ss + 32;
+ while(s < se)
+ scx -= s++->dx;
+ }else{
+ s = ss + 32;
+ se = ss + lx;
+ while(s < se)
+ scx += s++->dx;
+ }
+ c = spr->cs;
+ for(s=ss+lx, se=ss+rx+1; s<se; c++, scx+=dx){
+ dx = s++->dx;
+ if(dx != 0)
+ scalscol(ss, *c, dx);
+ }
}
s32int
@@ -717,8 +837,8 @@
for(tl=tiles; tl<tiles+nelem(tiles); tl++)
tl->vis = 0;
clear();
- walls();
- scaleall();
+ raytrace();
+ scalobj();
topspr();
}
@@ -745,7 +865,7 @@
*q-- = an;
}
- //SetupScaling(vw.dx * 1.5);
+ scaltab((vw.dx * 1.5) / 2);
}
void
--- a/scale.c
+++ /dev/null
@@ -1,719 +1,0 @@
-#define OP_RETF 0xcb
-
-/*
-=============================================================================
-
- GLOBALS
-
-=============================================================================
-*/
-
-t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];
-s32int fullscalefarcall[MAXSCALEHEIGHT+1];
-
-s16int maxscale,maxscaleshl2;
-
-/*
-=============================================================================
-
- LOCALS
-
-=============================================================================
-*/
-
-t_compscale _seg *work;
-u16int BuildCompScale (s16int height, uchar **finalspot);
-
-s16int stepbytwo;
-
-//===========================================================================
-
-/*
-==============
-=
-= BadScale
-=
-==============
-*/
-
-void far BadScale (void)
-{
- Quit ("BadScale called!");
-}
-
-
-void SetupScaling (s16int maxscaleheight)
-{
- s16int i,x,y;
- u8int far *dest;
-
-The dynamically compiled scaling routines are now a Bad Thing.
-On uncached machines (the original target) they are the fastest
-possible way to scale walls, but on modern processors you just
-wind up thrashing the code cash and wrecking performance.
-A simple looping texture mapper would be faster on 486+ machines.
-
- maxscaleheight/=2; // one scaler every two pixels
-
- maxscale = maxscaleheight-1;
- maxscaleshl2 = maxscale<<2;
-
-//
-// free up old scalers
-//
- for (i=1;i<MAXSCALEHEIGHT;i++)
- {
- if (scaledirectory[i])
- MM_FreePtr (&(uchar *)scaledirectory[i]);
- if (i>=stepbytwo)
- i += 2;
- }
- memset (scaledirectory,0,sizeof(scaledirectory));
-
-//
-// build the compiled scalers
-//
- stepbytwo = vw.dy/2; // save space by double stepping
- MM_GetPtr (&(uchar *)work,20000);
-
- for (i=1;i<=maxscaleheight;i++)
- {
- BuildCompScale (i*2,&(uchar *)scaledirectory[i]);
- if (i>=stepbytwo)
- i+= 2;
- }
- MM_FreePtr (&(uchar *)work);
-
-//
-// compact memory and lock down scalers
-//
- for (i=1;i<=maxscaleheight;i++)
- {
- MM_SetLock (&(uchar *)scaledirectory[i],true);
- fullscalefarcall[i] = (u16int)scaledirectory[i];
- fullscalefarcall[i] <<=16;
- fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
- if (i>=stepbytwo)
- {
- scaledirectory[i+1] = scaledirectory[i];
- fullscalefarcall[i+1] = fullscalefarcall[i];
- scaledirectory[i+2] = scaledirectory[i];
- fullscalefarcall[i+2] = fullscalefarcall[i];
- i+=2;
- }
- }
- scaledirectory[0] = scaledirectory[1];
- fullscalefarcall[0] = fullscalefarcall[1];
-
-//
-// check for oversize wall drawing
-//
- for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
- fullscalefarcall[i] = (uintptr)BadScale;
-}
-
-//===========================================================================
-
-/*
-========================
-=
-= BuildCompScale
-=
-= Builds a compiled scaler object that will scale a 64 tall object to
-= the given height (centered vertically on the screen)
-=
-= height should be even
-=
-= Call with
-= ---------
-= DS:SI Source for scale
-= ES:DI Dest for scale
-=
-= Calling the compiled scaler only destroys AL
-=
-========================
-*/
-
-u16int BuildCompScale (s16int height, uchar **finalspot)
-{
- a simple looping texture mapper would be better, simpler, faster
-
- u8int far *code;
-
- s16int i;
- s32int fix,step;
- u16int src,totalscaled,totalsize;
- s16int startpix,endpix,toppix;
-
-
- step = ((s32int)height<<16) / 64;
- code = &work->code[0];
- toppix = (vw.dy-height)/2;
- fix = 0;
-
- for (src=0;src<=64;src++)
- {
- startpix = fix>>16;
- fix += step;
- endpix = fix>>16;
-
- if (endpix>startpix)
- work->width[src] = endpix-startpix;
- else
- work->width[src] = 0;
-
-//
-// mark the start of the code
-//
- work->codeofs[src] = FP_OFF(code);
-
-//
-// compile some code if the source pixel generates any screen pixels
-//
- startpix+=toppix;
- endpix+=toppix;
-
- if (startpix == endpix || endpix < 0 || startpix >= vw.dy || src == 64)
- continue;
-
- //
- // mov al,[si+src]
- //
- *code++ = 0x8a;
- *code++ = 0x44;
- *code++ = src;
-
- for (;startpix<endpix;startpix++)
- {
- if (startpix >= vw.dy)
- break; // off the bottom of the view area
- if (startpix < 0)
- continue; // not into the view area
-
- //
- // mov [es:di+heightofs],al
- //
- *code++ = 0x26;
- *code++ = 0x88;
- *code++ = 0x85;
- *((u16int far *)code)++ = startpix*SCREENBWIDE;
- }
-
- }
-
-//
-// retf
-//
- *code++ = 0xcb;
-
- totalsize = FP_OFF(code);
- MM_GetPtr (finalspot,totalsize);
- _fmemcpy ((u8int _seg *)(*finalspot),(u8int _seg *)work,totalsize);
-
- return totalsize;
-}
-
-
-/*
-=======================
-=
-= ScaleLine
-=
-= linescale should have the high word set to the segment of the scaler
-=
-=======================
-*/
-
-extern s16int slinex,slinewidth;
-extern u16int far *linecmds;
-extern s32int linescale;
-extern u16int maskword;
-
-u8int mask1,mask2,mask3;
-
-
-void near ScaleLine (void)
-{
-asm mov cx,WORD PTR [linescale+2]
-asm mov es,cx // segment of scaler
-
-asm mov bp,WORD PTR [linecmds]
-asm mov dx,SC_INDEX+1 // to set SC_MAPMASK
-
-asm mov bx,[slinex]
-asm mov di,bx
-asm shr di,2 // X in bytes
-asm add di,[bufferofs]
-asm and bx,3
-asm shl bx,3
-asm add bx,[slinewidth] // bx = (pixel*8+pixwidth)
-asm mov al,BYTE [mapmasks3-1+bx] // -1 because pixwidth of 1 is first
-asm mov ds,WORD PTR [linecmds+2]
-asm or al,al
-asm jz notthreebyte // scale across three bytes
-asm jmp threebyte
-notthreebyte:
-asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
-asm or al,al
-asm jnz twobyte // scale across two bytes
-
-//
-// one byte scaling
-//
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm out dx,al // set map mask register
-
-scalesingle:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov dl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm call ss:[linescale] // scale the segment of pixels
-
-asm mov es,cx // segment of scaler
-asm mov BYTE PTR es:[bx],dl // unpatch the RETF
-asm jmp scalesingle // do the next segment
-
-
-//
-// done
-//
-linedone:
-asm mov ax,ss
-asm mov ds,ax
-return;
-
-//
-// two byte scaling
-//
-twobyte:
-asm mov ss:[mask2],al
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask1],al
-
-scaledouble:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov cl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm mov al,ss:[mask1]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask2]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm dec di
-
-asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
-asm mov BYTE PTR es:[bx],cl // unpatch the RETF
-asm jmp scaledouble // do the next segment
-
-
-//
-// three byte scaling
-//
-threebyte:
-asm mov ss:[mask3],al
-asm mov al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask2],al
-asm mov al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first
-asm mov ss:[mask1],al
-
-scaletriple:
-
-asm mov bx,[ds:bp] // table location of rtl to patch
-asm or bx,bx
-asm jz linedone // 0 signals end of segment list
-asm mov bx,[es:bx]
-asm mov cl,[es:bx] // save old value
-asm mov BYTE PTR es:[bx],OP_RETF // patch a RETF in
-asm mov si,[ds:bp+4] // table location of entry spot
-asm mov ax,[es:si]
-asm mov WORD PTR ss:[linescale],ax // call here to start scaling
-asm mov si,[ds:bp+2] // corrected top of shape for this segment
-asm add bp,6 // next segment list
-
-asm mov ax,SCREENSEG
-asm mov es,ax
-asm mov al,ss:[mask1]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask2]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm inc di
-asm mov al,ss:[mask3]
-asm out dx,al // set map mask register
-asm call ss:[linescale] // scale the segment of pixels
-asm dec di
-asm dec di
-
-asm mov es,WORD PTR ss:[linescale+2] // segment of scaler
-asm mov BYTE PTR es:[bx],cl // unpatch the RETF
-asm jmp scaletriple // do the next segment
-
-
-}
-
-
-/*
-=======================
-=
-= scalevis
-=
-= Draws a compiled shape at [scale] pixels high
-=
-= each vertical line of the shape has a pointer to segment data:
-= end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
-= top of virtual line with segment in proper place
-= start of segment pixel*2, used to jsl into compiled scaler
-= <repeat>
-=
-= Setup for call
-= --------------
-= GC_MODE read mode 1, write mode 2
-= GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff
-= GC_INDEX pointing at GC_BITMASK
-=
-=======================
-*/
-
-static s32int longtemp;
-
-void scalevis (s16int xcenter, s16int shapenum, u16int height)
-{
- t_compshape _seg *shape;
- t_compscale _seg *comptable;
- u16int scale,srcx,stopx,tempx; /* /!\ scale shadow */
- s16int t;
- u16int far *cmdptr;
- int leftvis,rightvis;
-
-
- shape = PM_GetSpritePage (shapenum);
-
- scale = height>>3; // low three bits are fractional
- if (!scale || scale>maxscale)
- return; // too close or far away
- comptable = scaledirectory[scale];
-
- *(((u16int *)&linescale)+1)=(u16int)comptable; // seg of far call
- *(((u16int *)&linecmds)+1)=(u16int)shape; // seg of shape
-
-//
-// scale to the left (from pixel 31 to shape->leftpix)
-//
- srcx = 32;
- slinex = xcenter;
- stopx = shape->leftpix;
- cmdptr = &shape->dataofs[31-stopx];
-
- while ( --srcx >=stopx && slinex>0)
- {
- (u16int)linecmds = *cmdptr--;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- if (slinewidth == 1)
- {
- slinex--;
- if (slinex<vw.dx)
- {
- if (wallheight[slinex] >= height)
- continue; // obscured by closer wall
- ScaleLine ();
- }
- continue;
- }
-
- //
- // handle multi pixel lines
- //
- if (slinex>vw.dx)
- {
- slinex -= slinewidth;
- slinewidth = vw.dx-slinex;
- if (slinewidth<1)
- continue; // still off the right side
- }
- else
- {
- if (slinewidth>slinex)
- slinewidth = slinex;
- slinex -= slinewidth;
- }
-
-
- leftvis = (wallheight[slinex] < height);
- rightvis = (wallheight[slinex+slinewidth-1] < height);
-
- if (leftvis)
- {
- if (rightvis)
- ScaleLine ();
- else
- {
- while (wallheight[slinex+slinewidth-1] >= height)
- slinewidth--;
- ScaleLine ();
- }
- }
- else
- {
- if (!rightvis)
- continue; // totally obscured
-
- while (wallheight[slinex] >= height)
- {
- slinex++;
- slinewidth--;
- }
- ScaleLine ();
- break; // the rest of the shape is gone
- }
- }
-
-
-//
-// scale to the right
-//
- slinex = xcenter;
- stopx = shape->rightpix;
- if (shape->leftpix<31)
- {
- srcx = 31;
- cmdptr = &shape->dataofs[32-shape->leftpix];
- }
- else
- {
- srcx = shape->leftpix-1;
- cmdptr = &shape->dataofs[0];
- }
- slinewidth = 0;
-
- while ( ++srcx <= stopx && (slinex+=slinewidth)<vw.dx)
- {
- (u16int)linecmds = *cmdptr++;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- if (slinewidth == 1)
- {
- if (slinex>=0 && wallheight[slinex] < height)
- {
- ScaleLine ();
- }
- continue;
- }
-
- //
- // handle multi pixel lines
- //
- if (slinex<0)
- {
- if (slinewidth <= -slinex)
- continue; // still off the left edge
-
- slinewidth += slinex;
- slinex = 0;
- }
- else
- {
- if (slinex + slinewidth > vw.dx)
- slinewidth = vw.dx-slinex;
- }
-
-
- leftvis = (wallheight[slinex] < height);
- rightvis = (wallheight[slinex+slinewidth-1] < height);
-
- if (leftvis)
- {
- if (rightvis)
- {
- ScaleLine ();
- }
- else
- {
- while (wallheight[slinex+slinewidth-1] >= height)
- slinewidth--;
- ScaleLine ();
- break; // the rest of the shape is gone
- }
- }
- else
- {
- if (rightvis)
- {
- while (wallheight[slinex] >= height)
- {
- slinex++;
- slinewidth--;
- }
- ScaleLine ();
- }
- else
- continue; // totally obscured
- }
- }
-}
-
-
-
-/*
-=======================
-=
-= scalespr
-=
-= NO CLIPPING, height in pixels
-=
-= Draws a compiled shape at [scale] pixels high
-=
-= each vertical line of the shape has a pointer to segment data:
-= end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
-= top of virtual line with segment in proper place
-= start of segment pixel*2, used to jsl into compiled scaler
-= <repeat>
-=
-= Setup for call
-= --------------
-= GC_MODE read mode 1, write mode 2
-= GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff
-= GC_INDEX pointing at GC_BITMASK
-=
-=======================
-*/
-
-void scalespr (s16int xcenter, s16int shapenum, u16int height)
-{
- t_compshape _seg *shape;
- t_compscale _seg *comptable;
- u16int scale,srcx,stopx,tempx; /* /!\ scale shadow */
- s16int t;
- u16int far *cmdptr;
- int leftvis,rightvis;
-
-
- shape = PM_GetSpritePage (shapenum);
-
- scale = height>>1;
- comptable = scaledirectory[scale];
-
- *(((u16int *)&linescale)+1)=(u16int)comptable; // seg of far call
- *(((u16int *)&linecmds)+1)=(u16int)shape; // seg of shape
-
-//
-// scale to the left (from pixel 31 to shape->leftpix)
-//
- srcx = 32;
- slinex = xcenter;
- stopx = shape->leftpix;
- cmdptr = &shape->dataofs[31-stopx];
-
- while ( --srcx >=stopx )
- {
- (u16int)linecmds = *cmdptr--;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- slinex -= slinewidth;
- ScaleLine ();
- }
-
-
-//
-// scale to the right
-//
- slinex = xcenter;
- stopx = shape->rightpix;
- if (shape->leftpix<31)
- {
- srcx = 31;
- cmdptr = &shape->dataofs[32-shape->leftpix];
- }
- else
- {
- srcx = shape->leftpix-1;
- cmdptr = &shape->dataofs[0];
- }
- slinewidth = 0;
-
- while ( ++srcx <= stopx )
- {
- (u16int)linecmds = *cmdptr++;
- if ( !(slinewidth = comptable->width[srcx]) )
- continue;
-
- ScaleLine ();
- slinex+=slinewidth;
- }
-}
-
-
-
-
-//
-// bit mask tables for drawing scaled strips up to eight pixels wide
-//
-// down here so the STUPID inline assembler doesn't get confused!
-//
-
-
-u8int mapmasks1[4][8] = {
-{1 ,3 ,7 ,15,15,15,15,15},
-{2 ,6 ,14,14,14,14,14,14},
-{4 ,12,12,12,12,12,12,12},
-{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
-
-u8int mapmasks2[4][8] = {
-{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
-{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
-{0 ,0 ,1 ,3 ,7 ,15,15,15},
-{0 ,1 ,3 ,7 ,15,15,15,15} };
-
-u8int mapmasks3[4][8] = {
-{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
-{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
-{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
-{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
-
-
-u16int wordmasks[8][8] = {
-{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
-{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
-{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
-{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
-{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
-{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
-{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
-{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
-
-s16int slinex,slinewidth;
-u16int far *linecmds;
-s32int linescale;
-u16int maskword;
-
--- a/snd.c
+++ b/snd.c
@@ -14,7 +14,8 @@
PcmHz = 7000,
ImfHz = 700,
SfxHz = 140,
- Nsamp = Rate/ImfHz * 4,
+ Nsamp = Rate / ImfHz * 4,
+ Npsamp = Rate / PcmHz * 4,
Mdiv = ImfHz / Tb,
Pdiv = PcmHz / Tb,
Nbuf = Nsamp * Mdiv,
@@ -282,7 +283,7 @@
/* stolen property cargocult upsampling */
static void
-filter(int *xb, uchar *s)
+filter(uchar *s)
{
ulong l, p, i;
int *x, o, a;
@@ -289,8 +290,6 @@
s16int m;
vlong v;
- if(s >= sbuf + sizeof sbuf)
- return;
v = 0;
x = &xb[xt>>Np]; /* left side */
l = p = xt & (1<<Np)-1;
@@ -339,6 +338,7 @@
ulong e;
b = sbuf;
+more:
do{
for(i=xbi; n>0 && i<Npbuf; n--, i++)
xb[i] = ((uint)*p++ << 24) - 0x7fffffff;
@@ -347,7 +347,11 @@
break;
e = i - Nextra << Np;
while(xt < e){ /* process buffer and mix */
- filter(xb, b);
+ if(b >= sbuf + nelem(sbuf)){
+ n = 0;
+ break;
+ }
+ filter(b);
b += 4;
xt += TΔ;
}
@@ -364,6 +368,11 @@
xbi = s;
}
}while(n > 0);
+ if(b < sbuf + nelem(sbuf) && p < pcme){
+ n += (b - sbuf) / Npsamp;
+ goto more;
+ }
+ pcm = p;
}
static void
@@ -407,7 +416,6 @@
e = p + Pdiv;
setvol();
resample(p, e-p);
- pcm = e;
}
void
--- a/wl3d.c
+++ b/wl3d.c
@@ -296,14 +296,12 @@
tc = 1;
else if(tc > 10)
tc = 10;
- Δtc = (gm.demo || gm.record) && !gm.fizz ? 4 : tc;
+ Δtc = tc;
t0 += tc * Td;
- if(nosleep)
- continue;
if(onestep)
t0 += Td;
dt = (t0 - t) / Te6;
- if(dt > 0)
+ if(dt > 0 && !nosleep)
sleep(dt);
else
t0 = t;