Initial commit

This commit is contained in:
2026-03-12 19:22:23 +01:00
commit daaca5c6ef
52 changed files with 35670 additions and 0 deletions

86
AUDIOC3D.H Normal file
View File

@@ -0,0 +1,86 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/////////////////////////////////////////////////
//
// MUSE Header for .C3D
// Created Wed Oct 30 22:44:13 1991
//
/////////////////////////////////////////////////
#define NUMSOUNDS 30
#define NUMSNDCHUNKS 91
//
// Sound names & indexes
//
typedef enum {
HITWALLSND, // 0
WARPUPSND, // 1
WARPDOWNSND, // 2
GETBOLTSND, // 3
GETNUKESND, // 4
GETPOTIONSND, // 5
GETKEYSND, // 6
GETSCROLLSND, // 7
GETPOINTSSND, // 8
USEBOLTSND, // 9
USENUKESND, // 10
USEPOTIONSND, // 11
USEKEYSND, // 12
NOITEMSND, // 13
WALK1SND, // 14
WALK2SND, // 15
TAKEDAMAGESND, // 16
MONSTERMISSSND, // 17
GAMEOVERSND, // 18
SHOOTSND, // 19
BIGSHOOTSND, // 20
SHOOTWALLSND, // 21
SHOOTMONSTERSND, // 22
TAKEDMGHURTSND, // 23
BALLBOUNCESND, // 24
COMPSCOREDSND, // 25
KEENSCOREDSND, // 26
COMPPADDLESND, // 27
KEENPADDLESND, // 28
NOWAYSND, // 29
LASTSOUND
} soundnames;
//
// Base offsets
//
#define STARTPCSOUNDS 0
#define STARTADLIBSOUNDS 30
#define STARTDIGISOUNDS 60
#define STARTMUSIC 90
//
// Music names & indexes
//
typedef enum {
TOOHOT_MUS, // 0
LASTMUSIC
} musicnames;
/////////////////////////////////////////////////
//
// Thanks for playing with MUSE!
//
/////////////////////////////////////////////////

BIN
C3DADICT.OBJ Normal file

Binary file not shown.

BIN
C3DAHEAD.OBJ Normal file

Binary file not shown.

BIN
C3DEDICT.OBJ Normal file

Binary file not shown.

BIN
C3DEHEAD.OBJ Normal file

Binary file not shown.

BIN
C3DMHEAD.OBJ Normal file

Binary file not shown.

1259
C3_ACT1.C Normal file

File diff suppressed because it is too large Load Diff

197
C3_ASM.ASM Normal file
View File

@@ -0,0 +1,197 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
IDEAL
MODEL MEDIUM,C
VIEWWIDTH = (33*8)
GC_INDEX = 03CEh
DATASEG
EVEN
;=================== Tables filled in by DrawVWall ==========================
;
; wallheight has the height (scale number) of that collumn of scaled wall
; it is pre bounded to 1-MAXSCALE (the actuial height on screen is 2*height)
;
wallheight dw VIEWWIDTH dup (?)
;
; wallwidth has the pixel width (1-7) of that collumn
;
wallwidth dw VIEWWIDTH dup (?)
;
; wallseg has the segment of the wall picture
;
wallseg dw VIEWWIDTH dup (?)
;
; wallofs has the offset of the wall picture
;
wallofs dw VIEWWIDTH dup (?)
;============================================================================
;
; screenbyte is just position/8
;
LABEL screenbyte WORD
pos = 0
REPT VIEWWIDTH
dw pos/8
pos = pos+1
ENDM
;
; screenbit is (position&7)*16
;
LABEL screenbit WORD
pos = 0
REPT VIEWWIDTH
dw (pos AND 7)*16
pos = pos+1
ENDM
;
; Use offset: screenbit[]+pixwidth*2
; acess from bitmasks-2+offset for one biased pixwidth
; the low byte of bitmasks is for the first screen byte, the high byte
; is the bitmask for the second screen byte (if non 0)
;
bitmasks dw 0080h,00c0h,00e0h,00f0h,00f8h,00fch,00feh,00ffh
dw 0040h,0060h,0070h,0078h,007ch,007eh,007fh,807fh
dw 0020h,0030h,0038h,003ch,003eh,003fh,803fh,0c03fh
dw 0010h,0018h,001ch,001eh,001fh,801fh,0c01fh,0e01fh
dw 0008h,000ch,000eh,000fh,800fh,0c00fh,0e00fh,0f00fh
dw 0004h,0006h,0007h,8007h,0c007h,0e007h,0f007h,0f807h
dw 0002h,0003h,8003h,0c003h,0e003h,0f003h,0f803h,0fc03h
dw 0001h,8001h,0c001h,0e001h,0f001h,0f801h,0fc01h,0fe01h
;
; wallscalecall is a far pointer to the start of a compiled scaler
; The low word will never change, while the high word is set to
; compscaledirectory[scale]
;
wallscalecall dd (65*6) ; offset of t_compscale->code[0]
PUBLIC wallheight,wallwidth,wallseg,wallofs,screenbyte,screenbit
PUBLIC bitmasks,wallscalecall
EXTRN scaledirectory:WORD ; array of MAXSCALE segment pointers to
; compiled scalers
EXTRN screenseg:WORD ; basically just 0xa000
EXTRN bufferofs:WORD ; offset of the current work screen
CODESEG
;============================================================================
;
; ScaleWalls
;
; AX AL is scratched in bit mask setting and scaling
; BX table index
; CX pixwidth*2
; DX GC_INDEX
; SI offset into wall data to scale from, allways 0,64,128,...4032
; DI byte at top of screen that the collumn is contained in
; BP x pixel * 2, index into VIEWWIDTH wide tables
; DS segment of the wall data to texture map
; ES screenseg
; SS addressing DGROUP variables
;
;============================================================================
PROC ScaleWalls
PUBLIC ScaleWalls
USES SI,DI,BP
xor bp,bp ; start at location 0 in the tables
mov dx,GC_INDEX+1
mov es,[screenseg]
;
; scale one collumn of data, possibly across two bytes
;
nextcollumn:
mov bx,[wallheight+bp] ; height of walls (1-MAXSCALE)
shl bx,1
mov ax,[ss:scaledirectory+bx] ; segment of the compiled scaler
mov [WORD PTR ss:wallscalecall+2],ax
mov cx,[wallwidth+bp]
or cx,cx
jnz okwidth
mov cx,2
jmp next
okwidth:
shl cx,1
mov ds,[wallseg+bp]
mov si,[wallofs+bp]
mov di,[screenbyte+bp] ; byte at the top of the scaled collumn
add di,[ss:bufferofs] ; offset of current page flip
mov bx,[screenbit+bp] ; 0-7 << 4
add bx,cx
mov ax,[ss:bitmasks-2+bx]
out dx,al ; set bit mask register
call [DWORD PTR ss:wallscalecall] ; scale the line of pixels
or ah,ah ; is there anything in the second byte?
jnz secondbyte
;
; next
;
next:
add bp,cx
cmp bp,VIEWWIDTH*2
jb nextcollumn
jmp done
;
; draw a second byte for vertical strips that cross two bytes
;
secondbyte:
mov al,ah
inc di ; next byte over
out dx,al ; set bit mask register
call [DWORD PTR ss:wallscalecall] ; scale the line of pixels
;
; next
;
add bp,cx
cmp bp,VIEWWIDTH*2
jb nextcollumn
done:
mov ax,ss
mov ds,ax
ret
ENDP
END

606
C3_DEBUG.C Normal file
View File

@@ -0,0 +1,606 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_DEBUG.C
#include "C3_DEF.H"
#pragma hdrstop
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
#define VIEWTILEX 20
#define VIEWTILEY (VIEWHEIGHT/16)
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
int maporgx;
int maporgy;
enum {mapview,tilemapview,actoratview,visview} viewtype;
void ViewMap (void);
//===========================================================================
/*
==================
=
= DebugMemory
=
==================
*/
void DebugMemory (void)
{
int i;
char scratch[80],str[10];
long mem;
spritetype _seg *block;
VW_FixRefreshBuffer ();
US_CenterWindow (16,7);
#if 0
CA_OpenDebug ();
for (i=0;i<NUMCHUNKS;i++)
{
if (grsegs[i])
{
strcpy (scratch,"Chunk:");
itoa (i,str,10);
strcat (scratch,str);
strcat (scratch,"\n");
write (debughandle,scratch,strlen(scratch));
}
}
CA_CloseDebug ();
#endif
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 ();
}
//===========================================================================
/*
================
=
= PicturePause
=
================
*/
void PicturePause (void)
{
int y;
unsigned source;
source = displayofs+panadjust;
VW_ColorBorder (15);
VW_SetLineWidth (40);
VW_SetScreen (0,0);
if (source<0x10000l-200*64)
{
//
// copy top line first
//
for (y=0;y<200;y++)
VW_ScreenToScreen (source+y*64,y*40,40,1);
}
else
{
//
// copy bottom line first
//
for (y=199;y>=0;y--)
VW_ScreenToScreen (source+y*64,y*40,40,1);
}
IN_Shutdown ();
VW_WaitVBL(70);
bioskey(0);
VW_WaitVBL(70);
Quit (NULL);
}
//===========================================================================
/*
================
=
= ShapeTest
=
================
*/
void ShapeTest (void)
{
}
//===========================================================================
#define sc_1 0x02
#define sc_2 0x03
#define sc_3 0x04
#define sc_4 0x05
#define sc_5 0x06
#define sc_6 0x07
#define sc_7 0x08
#define sc_8 0x09
#define sc_9 0x0a
#define sc_0 0x0b
/*
================
=
= DebugKeys
=
================
*/
int DebugKeys (void)
{
boolean esc;
int level,i;
if (Keyboard[sc_B]) // B = border color
{
CenterWindow(24,3);
PrintY+=6;
US_Print(" Border color (0-15):");
VW_UpdateScreen();
esc = !US_LineInput (px,py,str,NULL,true,2,0);
if (!esc)
{
level = atoi (str);
if (level>=0 && level<=15)
VW_ColorBorder (level);
}
return 1;
}
#if 0
if (Keyboard[sc_C]) // C = count objects
{
CountObjects();
return 1;
}
if (Keyboard[sc_D]) // D = start / end demo record
{
if (DemoMode == demo_Off)
StartDemoRecord ();
else if (DemoMode == demo_Record)
{
EndDemoRecord ();
playstate = ex_completed;
}
return 1;
}
#endif
if (Keyboard[sc_E]) // E = quit level
{
if (tedlevel)
TEDDeath();
playstate = ex_warped;
gamestate.mapon++;
}
if (Keyboard[sc_F]) // F = facing spot
{
CenterWindow (12,4);
US_Print ("X:");
US_PrintUnsigned (player->x);
US_Print ("Y:");
US_PrintUnsigned (player->y);
US_Print ("A:");
US_PrintUnsigned (player->angle);
VW_UpdateScreen();
IN_Ack();
return 1;
}
if (Keyboard[sc_G]) // G = god mode
{
CenterWindow (12,2);
if (godmode)
US_PrintCentered ("God mode OFF");
else
US_PrintCentered ("God mode ON");
VW_UpdateScreen();
IN_Ack();
godmode ^= 1;
return 1;
}
if (Keyboard[sc_H]) // H = hurt self
{
TakeDamage (5);
}
else if (Keyboard[sc_I]) // I = item cheat
{
CenterWindow (12,3);
US_PrintCentered ("Free items!");
VW_UpdateScreen();
for (i=0;i<4;i++)
{
GiveBolt ();
GiveNuke ();
GivePotion ();
if (!gamestate.keys[i])
GiveKey (i);
}
for (i=0;i<8;i++)
GiveScroll (i,false);
IN_Ack ();
return 1;
}
else if (Keyboard[sc_M]) // M = memory info
{
DebugMemory();
return 1;
}
else if (Keyboard[sc_O]) // O = overhead
{
ViewMap();
return 1;
}
else if (Keyboard[sc_P]) // P = pause with no screen disruptioon
{
PicturePause ();
return 1;
}
else if (Keyboard[sc_S]) // S = slow motion
{
singlestep^=1;
CenterWindow (18,3);
if (singlestep)
US_PrintCentered ("Slow motion ON");
else
US_PrintCentered ("Slow motion OFF");
VW_UpdateScreen();
IN_Ack ();
return 1;
}
else if (Keyboard[sc_S]) // T = shape test
{
ShapeTest ();
return 1;
}
else if (Keyboard[sc_V]) // V = extra VBLs
{
CenterWindow(30,3);
PrintY+=6;
US_Print(" Add how many extra VBLs(0-8):");
VW_UpdateScreen();
esc = !US_LineInput (px,py,str,NULL,true,2,0);
if (!esc)
{
level = atoi (str);
if (level>=0 && level<=8)
extravbls = level;
}
return 1;
}
else if (Keyboard[sc_W]) // W = warp to level
{
CenterWindow(26,3);
PrintY+=6;
US_Print(" Warp to which level(1-21):");
VW_UpdateScreen();
esc = !US_LineInput (px,py,str,NULL,true,2,0);
if (!esc)
{
level = atoi (str);
if (level>0 && level<21)
{
gamestate.mapon = level-1;
playstate = ex_warped;
}
}
return 1;
}
else if (Keyboard[sc_X]) // X = item cheat
{
CenterWindow (12,3);
US_PrintCentered ("Extra stuff!");
VW_UpdateScreen();
for (i=0;i<4;i++)
{
GiveBolt ();
GiveNuke ();
GivePotion ();
}
IN_Ack ();
return 1;
}
else if (Keyboard[sc_Z]) // Z = game over
{
}
else if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls
{
GiveScroll (LastScan-sc_1,false);
IN_ClearKeysDown ();
}
return 0;
}
/*
=====================
=
= LatchDrawChar
=
=====================
*/
void LatchDrawChar (unsigned x, unsigned y, unsigned picnum)
{
unsigned source, dest;
dest = bufferofs + ylookup[y]+x;
source = latchpics[0]+picnum*8;
EGAWRITEMODE(1);
EGAMAPMASK(15);
asm mov bx,[linewidth]
asm dec bx
asm mov ax,[screenseg]
asm mov es,ax
asm mov ds,ax
asm mov si,[source]
asm mov di,[dest]
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm add di,bx
asm movsb
asm mov ax,ss
asm mov ds,ax // restore turbo's data segment
EGAWRITEMODE(0);
}
/*
=====================
=
= LatchDrawTile
=
=====================
*/
void LatchDrawTile (unsigned x, unsigned y, unsigned picnum)
{
unsigned source, dest;
dest = bufferofs + ylookup[y]+x;
source = tileoffsets[picnum];
EGAWRITEMODE(1);
EGAMAPMASK(15);
asm mov bx,[linewidth]
asm sub bx,2
asm mov ax,[screenseg]
asm mov es,ax
asm mov ds,ax
asm mov si,[source]
asm mov di,[dest]
asm mov dx,16
lineloop:
asm movsb
asm movsb
asm add di,bx
asm dec dx
asm jnz lineloop
asm mov ax,ss
asm mov ds,ax // restore turbo's data segment
EGAWRITEMODE(0);
}
/*
===================
=
= OverheadRefresh
=
===================
*/
void OverheadRefresh (void)
{
unsigned x,y,endx,endy,sx,sy;
unsigned tile;
if (++screenpage == 3)
screenpage = 0;
bufferofs = screenloc[screenpage];
endx = maporgx+VIEWTILEX;
endy = maporgy+VIEWTILEY;
for (y=maporgy;y<endy;y++)
for (x=maporgx;x<endx;x++)
{
sx = (x-maporgx)*2;
sy = (y-maporgy)*16;
switch (viewtype)
{
case mapview:
tile = *(mapsegs[0]+farmapylookup[y]+x);
break;
case tilemapview:
tile = tilemap[x][y];
break;
case actoratview:
tile = (unsigned)actorat[x][y];
break;
case visview:
tile = spotvis[x][y];
break;
}
if (tile<NUMTILE16)
LatchDrawTile(sx,sy,tile);
else
{
LatchDrawChar(sx,sy,NUMBERCHARS+((tile&0xf000)>>12));
LatchDrawChar(sx+1,sy,NUMBERCHARS+((tile&0x0f00)>>8));
LatchDrawChar(sx,sy+8,NUMBERCHARS+((tile&0x00f0)>>4));
LatchDrawChar(sx+1,sy+8,NUMBERCHARS+(tile&0x000f));
}
}
VW_SetScreen (bufferofs,0);
displayofs = bufferofs;
}
/*
===================
=
= ViewMap
=
===================
*/
void ViewMap (void)
{
boolean button0held;
viewtype = actoratview;
button0held = false;
maporgx = player->tilex - VIEWTILEX/2;
if (maporgx<0)
maporgx = 0;
maporgy = player->tiley - VIEWTILEY/2;
if (maporgy<0)
maporgy = 0;
do
{
//
// let user pan around
//
IN_ReadControl(0,&c);
if (c.xaxis == -1 && maporgx>0)
maporgx--;
if (c.xaxis == 1 && maporgx<mapwidth-VIEWTILEX)
maporgx++;
if (c.yaxis == -1 && maporgy>0)
maporgy--;
if (c.yaxis == 1 && maporgy<mapheight-VIEWTILEY)
maporgy++;
if (c.button0 && !button0held)
{
button0held = true;
viewtype++;
if (viewtype>visview)
viewtype = mapview;
}
if (!c.button0)
button0held = false;
OverheadRefresh ();
} while (!Keyboard[sc_Escape]);
IN_ClearKeysDown ();
DrawPlayScreen ();
}

533
C3_DEF.H Normal file
View File

@@ -0,0 +1,533 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "ID_HEADS.H"
#include <MATH.H>
#include <VALUES.H>
//#define PROFILE
/*
=============================================================================
GLOBAL CONSTANTS
=============================================================================
*/
#define NAMESTART 180
#define UNMARKGRCHUNK(chunk) (grneeded[chunk]&=~ca_levelbit)
#define MOUSEINT 0x33
#define EXPWALLSTART 8
#define NUMEXPWALLS 7
#define WALLEXP 15
#define NUMFLOORS 36
#define NUMFLOORS 36
#define NUMLATCHPICS 100
#define NUMSCALEPICS 100
#define NUMSCALEWALLS 30
#define FLASHCOLOR 5
#define FLASHTICS 4
#define NUMLEVELS 20
#define VIEWX 0 // corner of view window
#define VIEWY 0
#define VIEWWIDTH (33*8) // size of view window
#define VIEWHEIGHT (18*8)
#define VIEWXH (VIEWX+VIEWWIDTH-1)
#define VIEWYH (VIEWY+VIEWHEIGHT-1)
#define CENTERX (VIEWX+VIEWWIDTH/2-1) // middle of view window
#define CENTERY (VIEWY+VIEWHEIGHT/2-1)
#define GLOBAL1 (1l<<16)
#define TILEGLOBAL GLOBAL1
#define TILESHIFT 16l
#define MINDIST (2*GLOBAL1/5)
#define FOCALLENGTH (TILEGLOBAL) // in global coordinates
#define ANGLES 360 // must be divisable by 4
#define MAPSIZE 64 // maps are 64*64 max
#define MAXACTORS 150 // max number of tanks, etc / map
#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3
#define SIGN(x) ((x)>0?1:-1)
#define ABS(x) ((int)(x)>0?(x):-(x))
#define LABS(x) ((long)(x)>0?(x):-(x))
#define MAXSCALE (VIEWWIDTH/2)
#define MAXBODY 64
#define MAXSHOTPOWER 56
#define SCREEN1START 0
#define SCREEN2START 8320
#define PAGE1START 0x900
#define PAGE2START 0x2000
#define PAGE3START 0x3700
#define FREESTART 0x4e00
#define PIXRADIUS 512
#define STATUSLINES (200-VIEWHEIGHT)
enum bonusnumbers {B_BOLT,B_NUKE,B_POTION,B_RKEY,B_YKEY,B_GKEY,B_BKEY,B_SCROLL1,
B_SCROLL2,B_SCROLL3,B_SCROLL4,B_SCROLL5,B_SCROLL6,B_SCROLL7,B_SCROLL8,
B_GOAL,B_CHEST};
/*
=============================================================================
GLOBAL TYPES
=============================================================================
*/
enum {BLANKCHAR=9,BOLTCHAR,NUKECHAR,POTIONCHAR,KEYCHARS,SCROLLCHARS=17,
NUMBERCHARS=25};
typedef long fixed;
typedef struct {int x,y;} tilept;
typedef struct {fixed x,y;} globpt;
typedef struct
{
int x1,x2,leftclip,rightclip;// first pixel of wall (may not be visable)
unsigned height1,height2,color,walllength,side;
long planecoord;
} walltype;
typedef enum
{nothing,playerobj,bonusobj,orcobj,batobj,skeletonobj,trollobj,demonobj,
mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj
,gateobj} classtype;
typedef enum {north,east,south,west,northeast,southeast,southwest,
northwest,nodir} dirtype; // a catacombs 2 carryover
typedef struct statestruct
{
int shapenum;
int tictime;
void (*think) ();
struct statestruct *next;
} statetype;
typedef struct objstruct
{
enum {no,yes} active;
int ticcount;
classtype obclass;
statetype *state;
boolean shootable;
boolean tileobject; // true if entirely inside one tile
long distance;
dirtype dir;
fixed x,y;
unsigned tilex,tiley;
int viewx;
unsigned viewheight;
int angle;
int hitpoints;
long speed;
unsigned size; // global radius for hit rect calculation
fixed xl,xh,yl,yh; // hit rectangle
int temp1,temp2;
struct objstruct *next,*prev;
} objtype;
typedef struct
{
int difficulty;
int mapon;
int bolts,nukes,potions,keys[4],scrolls[8];
long score;
int body,shotpower;
} gametype;
typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
,ex_loadedgame,ex_victorious,ex_abort} exittype;
/*
=============================================================================
C3_MAIN DEFINITIONS
=============================================================================
*/
extern char str[80],str2[20];
extern unsigned tedlevelnum;
extern boolean tedlevel;
extern gametype gamestate;
extern exittype playstate;
void NewGame (void);
boolean SaveTheGame(int file);
boolean LoadTheGame(int file);
void ResetGame(void);
void ShutdownId (void);
void InitGame (void);
void Quit (char *error);
void TEDDeath(void);
void DemoLoop (void);
void SetupScalePic (unsigned picnum);
void SetupScaleWall (unsigned picnum);
void SetupScaling (void);
void main (void);
/*
=============================================================================
C3_GAME DEFINITIONS
=============================================================================
*/
extern unsigned latchpics[NUMLATCHPICS];
extern unsigned tileoffsets[NUMTILE16];
extern unsigned textstarts[27];
#define L_CHARS 0
#define L_NOSHOT 1
#define L_SHOTBAR 2
#define L_NOBODY 3
#define L_BODYBAR 4
void ScanInfoPlane (void);
void ScanText (void);
void SetupGameLevel (void);
void Victory (void);
void Died (void);
void NormalScreen (void);
void DrawPlayScreen (void);
void LoadLatchMem (void);
void FizzleFade (unsigned source, unsigned dest,
unsigned width,unsigned height, boolean abortable);
void FizzleOut (int showlevel);
void FreeUpMemory (void);
void GameLoop (void);
/*
=============================================================================
C3_PLAY DEFINITIONS
=============================================================================
*/
extern ControlInfo c;
extern boolean running,slowturn;
extern int bordertime;
extern byte tilemap[MAPSIZE][MAPSIZE];
extern objtype *actorat[MAPSIZE][MAPSIZE];
extern byte spotvis[MAPSIZE][MAPSIZE];
extern objtype objlist[MAXACTORS],*new,*obj,*player;
extern unsigned farmapylookup[MAPSIZE];
extern byte *nearmapylookup[MAPSIZE];
extern byte update[];
extern boolean godmode,singlestep;
extern int extravbls;
extern int mousexmove,mouseymove;
extern int pointcount,pointsleft;
void CenterWindow(word w,word h);
void DebugMemory (void);
void PicturePause (void);
int DebugKeys (void);
void CheckKeys (void);
void InitObjList (void);
void GetNewObj (boolean usedummy);
void RemoveObj (objtype *gone);
void PollControlls (void);
void PlayLoop (void);
/*
=============================================================================
C3_STATE DEFINITIONS
=============================================================================
*/
void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size);
void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size);
boolean CheckHandAttack (objtype *ob);
void T_DoDamage (objtype *ob);
boolean Walk (objtype *ob);
void ChaseThink (objtype *obj, boolean diagonal);
void MoveObj (objtype *ob, long move);
boolean Chase (objtype *ob, boolean diagonal);
extern dirtype opposite[9];
/*
=============================================================================
C3_TRACE DEFINITIONS
=============================================================================
*/
int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
int BackTrace (int finish);
void ForwardTrace (void);
int FinishWall (void);
void InsideCorner (void);
void OutsideCorner (void);
void FollowWalls (void);
extern boolean aborttrace;
/*
=============================================================================
C3_DRAW DEFINITIONS
=============================================================================
*/
#define MAXWALLS 50
#define DANGERHIGH 45
#define MIDWALL (MAXWALLS/2)
//==========================================================================
extern tilept tile,lasttile,focal,left,mid,right;
extern globpt edge,view;
extern unsigned screenloc[3];
extern unsigned freelatch;
extern int screenpage;
extern boolean fizzlein;
extern long lasttimecount;
extern int firstangle,lastangle;
extern fixed prestep;
extern int traceclip,tracetop;
extern fixed sintable[ANGLES+ANGLES/4],*costable;
extern fixed viewx,viewy,viewsin,viewcos; // the focal point
extern int viewangle;
extern fixed scale,scaleglobal;
extern unsigned slideofs;
extern int zbuffer[VIEWXH+1];
extern walltype walls[MAXWALLS],*leftwall,*rightwall;
extern fixed tileglobal;
extern fixed focallength;
extern fixed mindist;
extern int viewheight;
extern fixed scale;
extern int walllight1[NUMFLOORS];
extern int walldark1[NUMFLOORS];
extern int walllight2[NUMFLOORS];
extern int walldark2[NUMFLOORS];
//==========================================================================
void DrawLine (int xl, int xh, int y,int color);
void DrawWall (walltype *wallptr);
void TraceRay (unsigned angle);
fixed FixedByFrac (fixed a, fixed b);
void TransformPoint (fixed gx, fixed gy, int *screenx, unsigned *screenheight);
fixed TransformX (fixed gx, fixed gy);
int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
void ForwardTrace (void);
int FinishWall (void);
int TurnClockwise (void);
int TurnCounterClockwise (void);
void FollowWall (void);
void NewScene (void);
void BuildTables (void);
/*
=============================================================================
C3_SCALE DEFINITIONS
=============================================================================
*/
#define COMPSCALECODESTART (65*6) // offset to start of code in comp scaler
typedef struct
{
unsigned codeofs[65];
unsigned start[65];
unsigned width[65];
byte code[];
} t_compscale;
typedef struct
{
unsigned width;
unsigned codeofs[64];
} t_compshape;
extern unsigned scaleblockwidth,
scaleblockheight,
scaleblockdest;
extern byte plotpix[8];
extern byte bitmasks1[8][8];
extern byte bitmasks2[8][8];
extern t_compscale _seg *scaledirectory[MAXSCALE+1];
extern t_compshape _seg *shapedirectory[NUMSCALEPICS];
extern memptr walldirectory[NUMSCALEWALLS];
extern unsigned shapesize[MAXSCALE+1];
void DeplanePic (int picnum);
void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale);
unsigned BuildCompShape (t_compshape _seg **finalspot);
/*
=============================================================================
C3_ASM DEFINITIONS
=============================================================================
*/
extern unsigned wallheight [VIEWWIDTH];
extern unsigned wallwidth [VIEWWIDTH];
extern unsigned wallseg [VIEWWIDTH];
extern unsigned wallofs [VIEWWIDTH];
extern unsigned screenbyte [VIEWWIDTH];
extern unsigned screenbit [VIEWWIDTH];
extern unsigned bitmasks [64];
extern long wallscalecall;
void ScaleWalls (void);
/*
=============================================================================
C3_WIZ DEFINITIONS
=============================================================================
*/
#define MAXHANDHEIGHT 72
extern long lastnuke;
extern int handheight;
extern int boltsleft;
/*
=============================================================================
C3_ACT1 DEFINITIONS
=============================================================================
*/
extern statetype s_trollouch;
extern statetype s_trolldie1;
extern statetype s_orcpause;
extern statetype s_orc1;
extern statetype s_orc2;
extern statetype s_orc3;
extern statetype s_orc4;
extern statetype s_orcattack1;
extern statetype s_orcattack2;
extern statetype s_orcattack3;
extern statetype s_orcouch;
extern statetype s_orcdie1;
extern statetype s_orcdie2;
extern statetype s_orcdie3;
extern statetype s_demonouch;
extern statetype s_demondie1;
extern statetype s_mageouch;
extern statetype s_magedie1;
extern statetype s_grelouch;
extern statetype s_greldie1;
extern statetype s_batdie1;

1592
C3_DRAW.C Normal file

File diff suppressed because it is too large Load Diff

1199
C3_GAME.C Normal file

File diff suppressed because it is too large Load Diff

756
C3_MAIN.C Normal file
View File

@@ -0,0 +1,756 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_MAIN.C
#include "C3_DEF.H"
#pragma hdrstop
/*
=============================================================================
CATACOMB 3-D
An Id Software production
by John Carmack
=============================================================================
*/
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
memptr scalesegs[NUMPICS];
char str[80],str2[20];
unsigned tedlevelnum;
boolean tedlevel;
gametype gamestate;
exittype playstate;
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
//===========================================================================
// JAB Hack begin
#define MyInterrupt 0x60
void interrupt (*intaddr)();
void interrupt (*oldintaddr)();
char *JHParmStrings[] = {"no386",nil};
void
jabhack(void)
{
extern void far jabhack2(void);
extern int far CheckIs386(void);
int i;
oldintaddr = getvect(MyInterrupt);
for (i = 1;i < _argc;i++)
if (US_CheckParm(_argv[i],JHParmStrings) == 0)
return;
if (CheckIs386())
{
jabhack2();
setvect(MyInterrupt,intaddr);
}
}
void
jabunhack(void)
{
setvect(MyInterrupt,oldintaddr);
}
// JAB Hack end
//===========================================================================
/*
=====================
=
= NewGame
=
= Set up new game to start from the beginning
=
=====================
*/
void NewGame (void)
{
memset (&gamestate,0,sizeof(gamestate));
gamestate.mapon = 0;
gamestate.body = MAXBODY;
}
//===========================================================================
#define RLETAG 0xABCD
/*
==================
=
= SaveTheGame
=
==================
*/
boolean SaveTheGame(int file)
{
word i,compressed,expanded;
objtype *o;
memptr bigbuffer;
if (!CA_FarWrite(file,(void far *)&gamestate,sizeof(gamestate)))
return(false);
expanded = mapwidth * mapheight * 2;
MM_GetPtr (&bigbuffer,expanded);
for (i = 0;i < 3;i+=2) // Write planes 0 and 2
{
//
// leave a word at start of compressed data for compressed length
//
compressed = (unsigned)CA_RLEWCompress ((unsigned huge *)mapsegs[i]
,expanded,((unsigned huge *)bigbuffer)+1,RLETAG);
*(unsigned huge *)bigbuffer = compressed;
if (!CA_FarWrite(file,(void far *)bigbuffer,compressed+2) )
{
MM_FreePtr (&bigbuffer);
return(false);
}
}
for (o = player;o;o = o->next)
if (!CA_FarWrite(file,(void far *)o,sizeof(objtype)))
{
MM_FreePtr (&bigbuffer);
return(false);
}
MM_FreePtr (&bigbuffer);
return(true);
}
//===========================================================================
/*
==================
=
= LoadTheGame
=
==================
*/
boolean LoadTheGame(int file)
{
unsigned i,x,y;
objtype *obj,*prev,*next,*followed;
unsigned compressed,expanded;
unsigned far *map,tile;
memptr bigbuffer;
if (!CA_FarRead(file,(void far *)&gamestate,sizeof(gamestate)))
return(false);
SetupGameLevel (); // load in and cache the base old level
expanded = mapwidth * mapheight * 2;
MM_GetPtr (&bigbuffer,expanded);
for (i = 0;i < 3;i+=2) // Read planes 0 and 2
{
if (!CA_FarRead(file,(void far *)&compressed,sizeof(compressed)) )
{
MM_FreePtr (&bigbuffer);
return(false);
}
if (!CA_FarRead(file,(void far *)bigbuffer,compressed) )
{
MM_FreePtr (&bigbuffer);
return(false);
}
CA_RLEWexpand ((unsigned huge *)bigbuffer,
(unsigned huge *)mapsegs[i],expanded,RLETAG);
}
MM_FreePtr (&bigbuffer);
//
// copy the wall data to a data segment array again, to handle doors and
// bomb walls that are allready opened
//
memset (tilemap,0,sizeof(tilemap));
memset (actorat,0,sizeof(actorat));
map = mapsegs[0];
for (y=0;y<mapheight;y++)
for (x=0;x<mapwidth;x++)
{
tile = *map++;
if (tile<NUMFLOORS)
{
tilemap[x][y] = tile;
if (tile>0)
(unsigned)actorat[x][y] = tile;
}
}
// Read the object list back in - assumes at least one object in list
InitObjList ();
new = player;
while (true)
{
prev = new->prev;
next = new->next;
if (!CA_FarRead(file,(void far *)new,sizeof(objtype)))
return(false);
followed = new->next;
new->prev = prev;
new->next = next;
actorat[new->tilex][new->tiley] = new; // drop a new marker
if (followed)
GetNewObj (false);
else
break;
}
return(true);
}
//===========================================================================
/*
==================
=
= ResetGame
=
==================
*/
void ResetGame(void)
{
NewGame ();
ca_levelnum--;
ca_levelbit>>=1;
CA_ClearMarks();
ca_levelbit<<=1;
ca_levelnum++;
}
//===========================================================================
/*
==========================
=
= ShutdownId
=
= Shuts down all ID_?? managers
=
==========================
*/
void ShutdownId (void)
{
US_Shutdown ();
#ifndef PROFILE
SD_Shutdown ();
IN_Shutdown ();
#endif
VW_Shutdown ();
CA_Shutdown ();
MM_Shutdown ();
}
//===========================================================================
/*
==========================
=
= InitGame
=
= Load a few things right away
=
==========================
*/
void InitGame (void)
{
unsigned segstart,seglength;
int i,x,y;
unsigned *blockstart;
// US_TextScreen();
MM_Startup ();
VW_Startup ();
#ifndef PROFILE
IN_Startup ();
SD_Startup ();
#endif
US_Startup ();
// US_UpdateTextScreen();
CA_Startup ();
US_Setup ();
US_SetLoadSaveHooks(LoadTheGame,SaveTheGame,ResetGame);
//
// load in and lock down some basic chunks
//
CA_ClearMarks ();
CA_MarkGrChunk(STARTFONT);
CA_MarkGrChunk(STARTTILE8);
CA_MarkGrChunk(STARTTILE8M);
CA_MarkGrChunk(HAND1PICM);
CA_MarkGrChunk(HAND2PICM);
CA_MarkGrChunk(ENTERPLAQUEPIC);
CA_CacheMarks (NULL);
MM_SetLock (&grsegs[STARTFONT],true);
MM_SetLock (&grsegs[STARTTILE8],true);
MM_SetLock (&grsegs[STARTTILE8M],true);
MM_SetLock (&grsegs[HAND1PICM],true);
MM_SetLock (&grsegs[HAND2PICM],true);
MM_SetLock (&grsegs[ENTERPLAQUEPIC],true);
fontcolor = WHITE;
//
// build some tables
//
for (i=0;i<MAPSIZE;i++)
nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;
for (i=0;i<PORTTILESHIGH;i++)
uwidthtable[i] = UPDATEWIDE*i;
blockstart = &blockstarts[0];
for (y=0;y<UPDATEHIGH;y++)
for (x=0;x<UPDATEWIDE;x++)
*blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;
BuildTables (); // 3-d tables
SetupScaling ();
#ifndef PROFILE
// US_FinishTextScreen();
#endif
//
// reclaim the memory from the linked in text screen
//
segstart = FP_SEG(&introscn);
seglength = 4000/16;
if (FP_OFF(&introscn))
{
segstart++;
seglength--;
}
MML_UseSpace (segstart,seglength);
VW_SetScreenMode (GRMODE);
VW_ColorBorder (3);
VW_ClearVideo (BLACK);
//
// initialize variables
//
updateptr = &update[0];
*(unsigned *)(updateptr + UPDATEWIDE*PORTTILESHIGH) = UPDATETERMINATE;
bufferofs = 0;
displayofs = 0;
VW_SetLineWidth(SCREENWIDTH);
}
//===========================================================================
void clrscr (void); // can't include CONIO.H because of name conflicts...
/*
==========================
=
= Quit
=
==========================
*/
void Quit (char *error)
{
unsigned finscreen;
#if 0
if (!error)
{
CA_SetAllPurge ();
CA_CacheGrChunk (PIRACY);
finscreen = (unsigned)grsegs[PIRACY];
}
#endif
ShutdownId ();
if (error && *error)
{
puts(error);
exit(1);
}
#if 0
if (!NoWait)
{
movedata (finscreen,0,0xb800,0,4000);
bioskey (0);
clrscr();
}
#endif
exit(0);
}
//===========================================================================
/*
==================
=
= TEDDeath
=
==================
*/
void TEDDeath(void)
{
ShutdownId();
execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL);
}
//===========================================================================
/*
=====================
=
= DemoLoop
=
=====================
*/
static char *ParmStrings[] = {"easy","normal","hard",""};
void DemoLoop (void)
{
int i,level;
//
// check for launch from ted
//
if (tedlevel)
{
NewGame();
gamestate.mapon = tedlevelnum;
restartgame = gd_Normal;
for (i = 1;i < _argc;i++)
{
if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1)
continue;
restartgame = gd_Easy+level;
break;
}
GameLoop();
TEDDeath();
}
//
// main game cycle
//
displayofs = bufferofs = 0;
VW_Bar (0,0,320,200,0);
while (1)
{
CA_CacheGrChunk (TITLEPIC);
bufferofs = SCREEN2START;
displayofs = SCREEN1START;
VWB_DrawPic (0,0,TITLEPIC);
MM_SetPurge (&grsegs[TITLEPIC],3);
UNMARKGRCHUNK(TITLEPIC);
FizzleFade (bufferofs,displayofs,320,200,true);
if (!IN_UserInput(TickBase*3,false))
{
CA_CacheGrChunk (CREDITSPIC);
VWB_DrawPic (0,0,CREDITSPIC);
MM_SetPurge (&grsegs[CREDITSPIC],3);
UNMARKGRCHUNK(CREDITSPIC);
FizzleFade (bufferofs,displayofs,320,200,true);
}
if (!IN_UserInput(TickBase*3,false))
{
highscores:
DrawHighScores ();
FizzleFade (bufferofs,displayofs,320,200,true);
IN_UserInput(TickBase*3,false);
}
if (IN_IsUserInput())
{
US_ControlPanel ();
if (restartgame || loadedgame)
{
GameLoop ();
goto highscores;
}
}
}
}
//===========================================================================
/*
==========================
=
= SetupScalePic
=
==========================
*/
void SetupScalePic (unsigned picnum)
{
unsigned scnum;
scnum = picnum-FIRSTSCALEPIC;
if (shapedirectory[scnum])
{
MM_SetPurge (&(memptr)shapedirectory[scnum],0);
return; // allready in memory
}
CA_CacheGrChunk (picnum);
DeplanePic (picnum);
shapesize[scnum] = BuildCompShape (&shapedirectory[scnum]);
grneeded[picnum]&= ~ca_levelbit;
MM_FreePtr (&grsegs[picnum]);
}
//===========================================================================
/*
==========================
=
= SetupScaleWall
=
==========================
*/
void SetupScaleWall (unsigned picnum)
{
int x,y;
unsigned scnum;
byte far *dest;
scnum = picnum-FIRSTWALLPIC;
if (walldirectory[scnum])
{
MM_SetPurge (&walldirectory[scnum],0);
return; // allready in memory
}
CA_CacheGrChunk (picnum);
DeplanePic (picnum);
MM_GetPtr(&walldirectory[scnum],64*64);
dest = (byte far *)walldirectory[scnum];
for (x=0;x<64;x++)
for (y=0;y<64;y++)
*dest++ = spotvis[y][x];
grneeded[picnum]&= ~ca_levelbit;
MM_FreePtr (&grsegs[picnum]);
}
//===========================================================================
/*
==========================
=
= SetupScaling
=
==========================
*/
void SetupScaling (void)
{
int i,x,y;
byte far *dest;
//
// build the compiled scalers
//
for (i=1;i<=VIEWWIDTH/2;i++)
BuildCompScale (i*2,&scaledirectory[i]);
}
//===========================================================================
int showscorebox;
void RF_FixOfs (void)
{
}
void HelpScreens (void)
{
}
/*
==================
=
= CheckMemory
=
==================
*/
#define MINMEMORY 335000l
void CheckMemory(void)
{
unsigned finscreen;
if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem
>= MINMEMORY)
return;
CA_CacheGrChunk (OUTOFMEM);
finscreen = (unsigned)grsegs[OUTOFMEM];
ShutdownId ();
movedata (finscreen,7,0xb800,0,4000);
gotoxy (1,24);
exit(1);
}
//===========================================================================
/*
==========================
=
= main
=
==========================
*/
void main (void)
{
short i;
if (stricmp(_argv[1], "/VER") == 0)
{
printf("Catacomb 3-D version 1.22 (Rev 1)\n");
printf("Copyright 1991-93 Softdisk Publishing\n");
printf("Developed for use with 100%% IBM compatibles\n");
printf("that have 640K memory and DOS version 3.3 or later\n");
printf("and EGA graphics or better.\n");
exit(0);
}
if (stricmp(_argv[1], "/?") == 0)
{
printf("Catacomb 3-D version 1.22\n");
printf("Copyright 1991-93 Softdisk Publishing\n\n");
printf("Syntax:\n");
printf("CAT3D [/<switch>]\n\n");
printf("Switch What it does\n");
printf("/? This Information\n");
printf("/VER Display Program Version Information\n");
printf("/COMP Fix problems with SVGA screens\n");
printf("/NOAL No AdLib or SoundBlaster detection\n");
printf("/NOJOYS Tell program to ignore joystick\n");
printf("/NOMOUSE Tell program to ignore mouse\n");
printf("/HIDDENCARD Overrides video detection\n\n");
printf("Each switch must include a '/' and multiple switches\n");
printf("must be seperated by at least one space.\n\n");
exit(0);
}
jabhack();
InitGame ();
CheckMemory ();
LoadLatchMem ();
#ifdef PROFILE
NewGame ();
GameLoop ();
#endif
//NewGame ();
//GameLoop ();
DemoLoop();
Quit("Demo loop exited???");
}

584
C3_PLAY.C Normal file
View File

@@ -0,0 +1,584 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_PLAY.C
#include "C3_DEF.H"
#pragma hdrstop
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
#define POINTTICS 6
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
ControlInfo c;
boolean running,slowturn;
int bordertime;
objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist;
unsigned farmapylookup[MAPSIZE];
byte *nearmapylookup[MAPSIZE];
boolean singlestep,godmode;
int extravbls;
//
// replacing refresh manager
//
unsigned mapwidth,mapheight,tics;
boolean compatability;
byte *updateptr;
unsigned mapwidthtable[64];
unsigned uwidthtable[UPDATEHIGH];
unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];
#define UPDATESCREENSIZE (UPDATEWIDE*PORTTILESHIGH+2)
#define UPDATESPARESIZE (UPDATEWIDE*2+4)
#define UPDATESIZE (UPDATESCREENSIZE+2*UPDATESPARESIZE)
byte update[UPDATESIZE];
int mousexmove,mouseymove;
int pointcount,pointsleft;
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
void CalcBounds (objtype *ob);
void DrawPlayScreen (void);
//
// near data map array (wall values only, get text number from far data)
//
byte tilemap[MAPSIZE][MAPSIZE];
byte spotvis[MAPSIZE][MAPSIZE];
objtype *actorat[MAPSIZE][MAPSIZE];
objtype dummyobj;
int bordertime;
int objectcount;
void StopMusic(void);
void StartMusic(void);
//==========================================================================
///////////////////////////////////////////////////////////////////////////
//
// CenterWindow() - Generates a window of a given width & height in the
// middle of the screen
//
///////////////////////////////////////////////////////////////////////////
#define MAXX 264
#define MAXY 146
void CenterWindow(word w,word h)
{
US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h);
}
//===========================================================================
/*
=====================
=
= CheckKeys
=
=====================
*/
void CheckKeys (void)
{
if (screenfaded) // don't do anything with a faded screen
return;
//
// pause key wierdness can't be checked as a scan code
//
if (Paused)
{
CenterWindow (8,3);
US_PrintCentered ("PAUSED");
VW_UpdateScreen ();
SD_MusicOff();
IN_Ack();
SD_MusicOn();
Paused = false;
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
}
//
// F1-F7/ESC to enter control panel
//
if ( (LastScan >= sc_F1 && LastScan <= sc_F7) || LastScan == sc_Escape)
{
StopMusic ();
NormalScreen ();
FreeUpMemory ();
US_CenterWindow (20,8);
US_CPrint ("Loading");
VW_UpdateScreen ();
US_ControlPanel();
if (abortgame)
{
playstate = ex_abort;
return;
}
StartMusic ();
IN_ClearKeysDown();
if (restartgame)
playstate = ex_resetgame;
if (loadedgame)
playstate = ex_loadedgame;
DrawPlayScreen ();
CacheScaleds ();
lasttimecount = TimeCount;
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
}
//
// F10-? debug keys
//
if (Keyboard[sc_F10])
{
DebugKeys();
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
lasttimecount = TimeCount;
}
}
//===========================================================================
/*
#############################################################################
The objlist data structure
#############################################################################
objlist containt structures for every actor currently playing. The structure
is accessed as a linked list starting at *player, ending when ob->next ==
NULL. GetNewObj inserts a new object at the end of the list, meaning that
if an actor spawn another actor, the new one WILL get to think and react the
same frame. RemoveObj unlinks the given object and returns it to the free
list, but does not damage the objects ->next pointer, so if the current object
removes itself, a linked list following loop can still safely get to the
next element.
<backwardly linked free list>
#############################################################################
*/
/*
=========================
=
= InitObjList
=
= Call to clear out the entire object list, returning them all to the free
= list. Allocates a special spot for the player.
=
=========================
*/
void InitObjList (void)
{
int i;
for (i=0;i<MAXACTORS;i++)
{
objlist[i].prev = &objlist[i+1];
objlist[i].next = NULL;
}
objlist[MAXACTORS-1].prev = NULL;
objfreelist = &objlist[0];
lastobj = NULL;
objectcount = 0;
//
// give the player and score the first free spots
//
GetNewObj (false);
player = new;
}
//===========================================================================
/*
=========================
=
= GetNewObj
=
= Sets the global variable new to point to a free spot in objlist.
= The free spot is inserted at the end of the liked list
=
= When the object list is full, the caller can either have it bomb out ot
= return a dummy object pointer that will never get used
=
=========================
*/
void GetNewObj (boolean usedummy)
{
if (!objfreelist)
{
if (usedummy)
{
new = &dummyobj;
return;
}
Quit ("GetNewObj: No free spots in objlist!");
}
new = objfreelist;
objfreelist = new->prev;
memset (new,0,sizeof(*new));
if (lastobj)
lastobj->next = new;
new->prev = lastobj; // new->next is allready NULL from memset
new->active = false;
lastobj = new;
objectcount++;
}
//===========================================================================
/*
=========================
=
= RemoveObj
=
= Add the given object back into the free list, and unlink it from it's
= neighbors
=
=========================
*/
void RemoveObj (objtype *gone)
{
objtype **spotat;
if (gone == player)
Quit ("RemoveObj: Tried to remove the player!");
//
// fix the next object's back link
//
if (gone == lastobj)
lastobj = (objtype *)gone->prev;
else
gone->next->prev = gone->prev;
//
// fix the previous object's forward link
//
gone->prev->next = gone->next;
//
// add it back in to the free list
//
gone->prev = objfreelist;
objfreelist = gone;
}
//==========================================================================
/*
===================
=
= PollControls
=
===================
*/
void PollControls (void)
{
unsigned buttons;
IN_ReadControl(0,&c);
if (MousePresent)
{
Mouse(MButtons);
buttons = _BX;
Mouse(MDelta);
mousexmove = _CX;
mouseymove = _DX;
if (buttons&1)
c.button0 = 1;
if (buttons&2)
c.button1 = 1;
}
if (Controls[0]==ctrl_Joystick)
{
if (c.x>120 || c.x <-120 || c.y>120 || c.y<-120)
running = true;
else
running = false;
if (c.x>-48 && c.x<48)
slowturn = true;
else
slowturn = false;
}
else
{
if (Keyboard[sc_RShift])
running = true;
else
running = false;
if (c.button0)
slowturn = true;
else
slowturn = false;
}
}
//==========================================================================
/*
=================
=
= StopMusic
=
=================
*/
void StopMusic(void)
{
int i;
SD_MusicOff();
for (i = 0;i < LASTMUSIC;i++)
if (audiosegs[STARTMUSIC + i])
{
MM_SetPurge(&((memptr)audiosegs[STARTMUSIC + i]),3);
MM_SetLock(&((memptr)audiosegs[STARTMUSIC + i]),false);
}
}
//==========================================================================
/*
=================
=
= StartMusic
=
=================
*/
// JAB - Cache & start the appropriate music for this level
void StartMusic(void)
{
musicnames chunk;
SD_MusicOff();
chunk = TOOHOT_MUS;
// if ((chunk == -1) || (MusicMode != smm_AdLib))
//DEBUG control panel return;
MM_BombOnError (false);
CA_CacheAudioChunk(STARTMUSIC + chunk);
MM_BombOnError (true);
if (mmerror)
mmerror = false;
else
{
MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true);
SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);
}
}
//==========================================================================
/*
===================
=
= PlayLoop
=
===================
*/
void PlayLoop (void)
{
int give;
void (*think)();
ingame = true;
playstate = TimeCount = 0;
gamestate.shotpower = handheight = 0;
pointcount = pointsleft = 0;
DrawLevelNumber (gamestate.mapon);
DrawBars ();
#ifndef PROFILE
fizzlein = true; // fizzle fade in the first refresh
#endif
TimeCount = lasttimecount = lastnuke = 0;
PollControls (); // center mouse
StartMusic ();
do
{
#ifndef PROFILE
PollControls();
#else
c.xaxis = 1;
if (++TimeCount == 300)
return;
#endif
for (obj = player;obj;obj = obj->next)
if (obj->active)
{
if (obj->ticcount)
{
obj->ticcount-=tics;
while ( obj->ticcount <= 0)
{
think = obj->state->think;
if (think)
{
think (obj);
if (!obj->state)
{
RemoveObj (obj);
goto nextactor;
}
}
obj->state = obj->state->next;
if (!obj->state)
{
RemoveObj (obj);
goto nextactor;
}
if (!obj->state->tictime)
{
obj->ticcount = 0;
goto nextactor;
}
if (obj->state->tictime>0)
obj->ticcount += obj->state->tictime;
}
}
think = obj->state->think;
if (think)
{
think (obj);
if (!obj->state)
RemoveObj (obj);
}
nextactor:;
}
if (bordertime)
{
bordertime -= tics;
if (bordertime<=0)
{
bordertime = 0;
VW_ColorBorder (3);
}
}
if (pointcount)
{
pointcount -= tics;
if (pointcount <= 0)
{
pointcount += POINTTICS;
give = (pointsleft > 1000)? 1000 :
(
(pointsleft > 100)? 100 :
((pointsleft < 20)? pointsleft : 20)
);
SD_PlaySound (GETPOINTSSND);
AddPoints (give);
pointsleft -= give;
if (!pointsleft)
pointcount = 0;
}
}
ThreeDRefresh ();
CheckKeys();
if (singlestep)
{
VW_WaitVBL(14);
lasttimecount = TimeCount;
}
if (extravbls)
VW_WaitVBL(extravbls);
}while (!playstate);
StopMusic ();
ingame = false;
if (bordertime)
{
bordertime = 0;
VW_ColorBorder (3);
}
if (!abortgame)
AddPoints (pointsleft);
else
abortgame = false;
}

690
C3_SCALE.C Normal file
View File

@@ -0,0 +1,690 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_SCALE.C
#include "C3_DEF.H"
#pragma hdrstop
//const unsigned viewheight = 144;
const unsigned screenbwide = 40;
const byte BACKGROUNDPIX = 5;
unsigned shapesize[MAXSCALE+1];
t_compscale _seg *scaledirectory[MAXSCALE+1];
t_compshape _seg *shapedirectory[NUMSCALEPICS];
memptr walldirectory[NUMSCALEWALLS];
/*
===========================
=
= DeplanePic
=
= Takes a raw bit map of width bytes by height and creates a scaleable shape
=
= Returns the length of the shape in bytes
=
= Fills in spotvis (a convenient 64*64 array) with the color values
=
===========================
*/
void DeplanePic (int picnum)
{
byte far *plane0,far *plane1,far *plane2,far *plane3;
byte by0,by1,by2,by3;
unsigned x,y,b,color,shift,width,height;
byte *dest;
//
// convert ega pixels to byte color values in a temp buffer
//
width = pictable[picnum-STARTPICS].width;
height = pictable[picnum-STARTPICS].height;
if (width>64 || height!=64)
Quit ("DePlanePic: Bad size shape");
memset (spotvis,BACKGROUNDPIX,sizeof(spotvis));
plane0 = (byte _seg *)grsegs[picnum];
plane1 = plane0 + width*height;
plane2 = plane1 + width*height;
plane3 = plane2 + width*height;
for (y=0;y<height;y++)
{
dest = &spotvis[y][0];
for (x=0;x<width;x++)
{
by0 = *plane0++;
by1 = *plane1++;
by2 = *plane2++;
by3 = *plane3++;
for (b=0;b<8;b++)
{
shift=8-b;
color = 0;
asm mov cl,[BYTE PTR shift]
asm mov al,[BYTE PTR by3]
asm rcr al,cl;
asm rcl [BYTE PTR color],1;
asm mov cl,[BYTE PTR shift]
asm mov al,[BYTE PTR by2]
asm rcr al,cl;
asm rcl [BYTE PTR color],1;
asm mov cl,[BYTE PTR shift]
asm mov al,[BYTE PTR by1]
asm rcr al,cl;
asm rcl [BYTE PTR color],1;
asm mov cl,[BYTE PTR shift]
asm mov al,[BYTE PTR by0]
asm rcr al,cl;
asm rcl [BYTE PTR color],1;
*dest++ = color;
} // B
} // X
} // Y
}
/*
========================
=
= 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
=
========================
*/
unsigned BuildCompScale (int height, memptr *finalspot)
{
t_compscale _seg *work;
byte far *code;
int i;
long fix,step;
unsigned src,totalscaled,totalsize;
int startpix,endpix,toppix;
MM_GetPtr (&(memptr)work,20000);
step = ((long)height<<16) / 64;
code = &work->code[0];
toppix = (viewheight-height)/2;
fix = 0;
for (src=0;src<=64;src++)
{
startpix = fix>>16;
fix += step;
endpix = fix>>16;
work->start[src] = startpix;
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 >= VIEWHEIGHT || src == 64)
continue;
//
// mov al,[si+src]
//
*code++ = 0x8a;
*code++ = 0x44;
*code++ = src;
for (;startpix<endpix;startpix++)
{
if (startpix >= VIEWHEIGHT)
break; // off the bottom of the view area
if (startpix < 0)
continue; // not into the view area
//
// and [es:di+heightofs],al
//
*code++ = 0x26;
*code++ = 0x20;
*code++ = 0x85;
*((unsigned far *)code)++ = startpix*screenbwide;
}
}
//
// retf
//
*code++ = 0xcb;
totalsize = FP_OFF(code);
MM_GetPtr (finalspot,totalsize);
_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
MM_FreePtr (&(memptr)work);
return totalsize;
}
/*
========================
=
= BuildCompShape
=
= typedef struct
= {
= unsigned width;
= unsigned codeofs[64];
= } t_compshape;
=
= Width is the number of compiled line draws in the shape. The shape
= drawing code will assume that the midpoint of the shape is in the
= middle of the width.
=
= The non background pixel data will start at codeofs[width], so codeofs
= greater than width will be invalid.
=
= Each code offset will draw one vertical line of the shape, consisting
= of 0 or more segments of scaled pixels.
=
= The scaled shapes use ss:0-4 as a scratch variable for the far call to
= the compiled scaler, so zero it back out after the shape is scaled, or
= a "null pointer assignment" will result upon termination.
=
= Setup for a call to a compiled shape
= -----------------------------------
= ax toast
= bx toast
= cx toast
= dx segment of compiled shape
= si toast
= di byte at top of view area to draw the line in
= bp 0
= ss:2 and ds the segment of the compiled scaler to use
= es screenseg
=
= Upon return, ds IS NOT SET to the data segment. Do:
= mov ax,ss
= mov ds,ax
=
=
= GC_BITMASK set to the pixels to be drawn in the row of bytes under DI
= GC_MODE read mode 1, write mode 2
= GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff
=
=
= Code generated for each segment
= -------------------------------
= mov bx,[(segend+1)*2]
= mov cx,[bx]
= mov [BYTE PTR bx],0xc8 // far return
= mov ax,[segstart*2]
= mov [ss:0],ax // entry point into the compiled scaler
= mov ds,dx // (mov ds,cs) the data is after the compiled code
= mov si,ofs data
= call [bp] // scale some pixels
= mov ds,[bp+2]
= mov [bx],cx // un patch return
=
= Code generated after all segments on a line
= -------------------------------------------
= retf
=
========================
*/
unsigned BuildCompShape (t_compshape _seg **finalspot)
{
t_compshape _seg *work;
byte far *code;
int firstline,lastline,x,y;
unsigned firstpix,lastpix,width;
unsigned totalsize,pixelofs;
unsigned buff;
// MM_GetPtr (&(memptr)work,20000);
EGAWRITEMODE(0);
EGAREADMAP(0); // use ega screen memory for temp buffer
EGAMAPMASK(1);
buff = screenloc[1];
work = (t_compshape _seg *)(0xa000+(buff+15)/16);
//
// find the width of the shape
//
firstline = -1;
x=0;
do
{
for (y=0;y<64;y++)
if (spotvis[y][x] != BACKGROUNDPIX)
{
firstline = x;
break;
}
if (++x == 64)
Quit ("BuildCompShape: No shape data!");
} while (firstline == -1);
lastline = -1;
x=63;
do
{
for (y=0;y<64;y++)
if (spotvis[y][x] != BACKGROUNDPIX)
{
lastline = x;
break;
}
x--;
} while (lastline == -1);
width = lastline-firstline+1;
work->width = width;
code = (byte far *)&work->codeofs[width];
//
// copy all non background pixels to the work space
//
pixelofs = FP_OFF(code);
for (x=firstline;x<=lastline;x++)
for (y=0;y<64;y++)
if (spotvis[y][x] != BACKGROUNDPIX)
*code++ = spotvis[y][x];
//
// start compiling the vertical lines
//
for (x=firstline;x<=lastline;x++)
{
work->codeofs[x-firstline] = FP_OFF(code);
y=0;
do
{
//
// scan past black background pixels
//
while (spotvis[y][x] == BACKGROUNDPIX && y<64)
y++;
if (y>63) // no more segments
break;
firstpix = y+1; // +1 because width is before codeofs
//
// scan past scalable pixels
//
while (spotvis[y][x] != BACKGROUNDPIX && y<64)
y++;
if (y>63)
lastpix = 65;
else
lastpix = y+1; // actually one pixel past the last displayed
//
// compile the scale call
//
*code++ = 0x8b; // mov bx,[lastpix*2]
*code++ = 0x1e;
*((unsigned far *)code)++ = lastpix*2;
*code++ = 0x8b; // mov cx,[bx]
*code++ = 0x0f;
*code++ = 0xc6; // move [BYTE bx],0xcb
*code++ = 0x07;
*code++ = 0xcb;
*code++ = 0xa1; // mov ax,[firstpix*2] /*************
*((unsigned far *)code)++ = firstpix*2;
*code++ = 0x36; // mov [ss:0],ax
*code++ = 0xa3;
*code++ = 0x00;
*code++ = 0x00;
*code++ = 0x8e; // mov ds,dx (mov ds,cs)
*code++ = 0xda;
*code++ = 0xbe; // mov si,OFFSET pixelofs-firstpixel
*((unsigned far *)code)++ = pixelofs-firstpix;
*code++ = 0xff; // call [DWORD bp]
*code++ = 0x5e;
*code++ = 0x00;
*code++ = 0x8e; // mov ds,[bp+2]
*code++ = 0x5e;
*code++ = 0x02;
*code++ = 0x89; // mov [bx],cx
*code++ = 0x0f;
pixelofs += (lastpix-firstpix);
} while (y<63);
//
// retf
//
*code++ = 0xcb;
}
//
// copy the final shape to a properly sized buffer
//
totalsize = FP_OFF(code);
MM_GetPtr ((memptr *)finalspot,totalsize);
_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
// MM_FreePtr (&(memptr)work);
return totalsize;
}
/*
=======================
=
= ScaleShape
=
= Draws a compiled shape at [scale] pixels high
=
= 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 long longtemp;
void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
{
t_compscale _seg *comptable;
unsigned width,scalewidth;
int x,pixel,lastpixel,pixwidth,min;
unsigned far *codehandle, far *widthptr;
unsigned badcodeptr;
int rightclip;
if (!compshape)
Quit ("ScaleShape: NULL compshape ptr!");
scale = (scale+1)/2;
if (!scale)
return; // too far away
if (scale>MAXSCALE)
scale = MAXSCALE;
comptable = scaledirectory[scale];
width = compshape->width;
scalewidth = comptable->start[width];
pixel = xcenter - scalewidth/2;
lastpixel = pixel+scalewidth-1;
if (pixel >= VIEWWIDTH || lastpixel < 0)
return; // totally off screen
//
// scan backwards from the right edge until pixels are visable
// rightclip is the first NON VISABLE pixel
//
if (lastpixel>=VIEWWIDTH-1)
rightclip = VIEWWIDTH-1;
else
rightclip = lastpixel;
if (zbuffer[rightclip]>scale)
{
if (pixel>0)
min = pixel;
else
min = 0;
do
{
if (--rightclip < min)
return; // totally covered or before 0
if (zbuffer[rightclip]<=scale)
break;
} while (1);
}
rightclip++;
//
// scan from the left until it is on screen, leaving
// [pixel],[pixwidth],[codehandle],and [widthptr] set correctly
//
*(((unsigned *)&longtemp)+1) = (unsigned)compshape; // seg of shape
codehandle = &compshape->codeofs[0];
badcodeptr = compshape->codeofs[width];
widthptr = &comptable->width[0];
asm mov ax,[comptable]
asm mov WORD PTR [2],ax // ds:0-4 is used as a far call pointer
// by the compiled shapes
pixwidth = *widthptr; // scaled width of this pixel
while (!pixwidth)
{
pixwidth = *++widthptr; // find the first visable pixel
codehandle++;
}
if (pixel<0)
{
do
{
if (pixel+pixwidth>0)
{
pixwidth += pixel;
pixel = 0;
break;
}
do
{
pixwidth = *++widthptr;
codehandle++;
} while (!pixwidth);
pixel+=pixwidth;
} while (1);
}
//
// scan until it is visable, leaving
// [pixel],[pixwidth],[codehandle],and [widthptr] set correctly
//
do
{
if (zbuffer[pixel] <= scale)
break; // start drawing here
pixel++;
if (!--pixwidth)
{
do
{
pixwidth = *++widthptr;
codehandle++;
} while (!pixwidth);
}
} while (1);
if (pixel+pixwidth>rightclip)
pixwidth = rightclip-pixel;
//
// draw lines
//
do // while (1)
{
//
// scale a vertical segment [pixwidth] pixels wide at [pixel]
//
(unsigned)longtemp = *codehandle; // offset of compiled code
if ((unsigned)longtemp == badcodeptr)
Quit ("ScaleShape: codehandle past end!");
asm mov bx,[pixel]
asm mov di,bx
asm shr di,1
asm shr di,1
asm shr di,1 // X in bytes
asm add di,[bufferofs]
asm and bx,7
asm shl bx,1
asm shl bx,1
asm shl bx,1
asm add bx,[pixwidth] // bx = pixel*8+pixwidth-1
asm dec bx
asm push bx
asm mov al,BYTE PTR [bitmasks1+bx]
asm mov dx,GC_INDEX+1
asm out dx,al // set bit mask register
asm mov es,[screenseg]
asm push si
asm push di
asm push bp
asm xor bp,bp
asm mov dx,[WORD PTR longtemp+2]
asm mov ds,[2]
asm call ss:[DWORD PTR longtemp] // scale the line of pixels
asm mov ax,ss
asm mov ds,ax
asm pop bp
asm pop di
asm pop si
asm pop bx
asm mov al,BYTE PTR [bitmasks2+bx]
asm or al,al
asm jz nosecond
//
// draw a second byte for vertical strips that cross two bytes
//
asm inc di
asm mov dx,GC_INDEX+1
asm out dx,al // set bit mask register
asm push si
asm push di
asm push bp
asm xor bp,bp
asm mov dx,[WORD PTR longtemp+2]
asm mov ds,[2]
asm call ss:[DWORD PTR longtemp] // scale the line of pixels
asm mov ax,ss
asm mov ds,ax
asm pop bp
asm pop di
asm pop si
//
// advance to the next drawn line
//
nosecond:;
if ( (pixel+=pixwidth) == rightclip )
{
asm mov WORD PTR [0],0
asm mov WORD PTR [2],0
return; // all done!
}
do
{
pixwidth = *++widthptr;
codehandle++;
} while (!pixwidth);
if (pixel+pixwidth > rightclip)
pixwidth = rightclip-pixel;
} while (1);
}
//
// bit mask tables for drawing scaled strips up to eight pixels wide
//
byte bitmasks1[8][8] = {
{0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff},
{0x40,0x60,0x70,0x78,0x7c,0x7e,0x7f,0x7f},
{0x20,0x30,0x38,0x3c,0x3e,0x3f,0x3f,0x3f},
{0x10,0x18,0x1c,0x1e,0x1f,0x1f,0x1f,0x1f},
{0x8,0xc,0xe,0xf,0xf,0xf,0xf,0xf},
{0x4,0x6,0x7,0x7,0x7,0x7,0x7,0x7},
{0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3},
{0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1} };
byte bitmasks2[8][8] = {
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0x80},
{0,0,0,0,0,0,0x80,0xc0},
{0,0,0,0,0,0x80,0xc0,0xe0},
{0,0,0,0,0x80,0xc0,0xe0,0xf0},
{0,0,0,0x80,0xc0,0xe0,0xf0,0xf8},
{0,0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc},
{0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe} };

153
C3_SCA_A.ASM Normal file
View File

@@ -0,0 +1,153 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
IDEAL
MODEL MEDIUM,C
include "ID_ASM.EQU"
;===========================================================================
;
; SCALING GRAPHICS
;
;===========================================================================
MACRO MAKELAB NUM
lab&NUM:
ENDM
MACRO MAKEREF NUM
dw OFFSET lab&NUM
ENDM
;=========================================================================
MAXSCALES equ 256
DATASEG
EXTRN screenseg:WORD
EXTRN linewidth:WORD
LABEL endtable WORD
labcount = 0
REPT MAXSCALES
MAKEREF %labcount
labcount = labcount + 1
ENDM
CODESEG
;==================================================
;
; void scaleline (int scale, unsigned picseg, unsigned maskseg,
; unsigned screen, unsigned width)
;
;==================================================
PROC ScaleLine pixels:word, scaleptr:dword, picptr:dword, screen:word
USES si,di
PUBLIC ScaleLine
;
; modify doline procedure for proper width
;
mov bx,[pixels]
cmp bx,MAXSCALES
jbe @@scaleok
mov bx,MAXSCALES
@@scaleok:
shl bx,1
mov bx,[endtable+bx]
push [cs:bx] ;save the code that will be modified over
mov [WORD cs:bx],0d18eh ;mov ss,cx
push [cs:bx+2] ;save the code that will be modified over
mov [WORD cs:bx+2],90c3h ;ret / nop
push bx
mov dx,[linewidth]
mov di,[WORD screen]
mov es,[screenseg]
mov si,[WORD scaleptr]
mov ds,[WORD scaleptr+2]
mov bx,[WORD picptr]
mov ax,[WORD picptr+2] ;will be moved into ss after call
mov bp,bx
cli
call doline
sti
;
; restore doline to regular state
;
pop bx ;address of modified code
pop [cs:bx+2]
pop [cs:bx]
mov ax,ss
mov ds,ax
ret
;================
;
; doline
;
; Big unwound scaling routine
;
; ds:si = scale table
; ss:bx = pic data
; es:di = screen location
;
;================
doline:
mov cx,ss
mov ss,ax ;can't call a routine with ss used...
labcount = 0
REPT MAXSCALES
MAKELAB %labcount
labcount = labcount + 1
lodsb ; get scaled pixel number
xlat [ss:bx] ; look it up in the picture
xchg [es:di],al ; load latches and write pixel to screen
add di,dx ; down to next line
ENDM
mov ss,cx
ret
ENDP
END

546
C3_STATE.C Normal file
View File

@@ -0,0 +1,546 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_STATE.C
#include "C3_DEF.H"
#pragma hdrstop
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
dirtype opposite[9] =
{south,west,north,east,southwest,northwest,northeast,southeast,nodir};
//===========================================================================
/*
===================
=
= SpawnNewObj
=
===================
*/
void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size)
{
GetNewObj (false);
new->size = size;
new->state = state;
new->ticcount = random (state->tictime)+1;
new->tilex = x;
new->tiley = y;
new->x = ((long)x<<TILESHIFT)+TILEGLOBAL/2;
new->y = ((long)y<<TILESHIFT)+TILEGLOBAL/2;
CalcBounds(new);
new->dir = nodir;
actorat[new->tilex][new->tiley] = new;
}
void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size)
{
GetNewObj (false);
new->size = size;
new->state = state;
new->ticcount = random (state->tictime)+1;
new->active = true;
new->x = x;
new->y = y;
new->tilex = x>>TILESHIFT;
new->tiley = y>>TILESHIFT;
CalcBounds(new);
new->distance = 100;
new->dir = nodir;
}
/*
===================
=
= CheckHandAttack
=
= If the object can move next to the player, it will return true
=
===================
*/
boolean CheckHandAttack (objtype *ob)
{
long deltax,deltay,size;
size = (long)ob->size + player->size + ob->speed*tics;
deltax = ob->x - player->x;
deltay = ob->y - player->y;
if (deltax > size || deltax < -size || deltay > size || deltay < -size)
return false;
return true;
}
/*
===================
=
= T_DoDamage
=
= Attacks the player if still nearby, then immediately changes to next state
=
===================
*/
void T_DoDamage (objtype *ob)
{
int points;
if (!CheckHandAttack (ob))
{
SD_PlaySound (MONSTERMISSSND);
}
else
{
points = 0;
switch (ob->obclass)
{
case orcobj:
points = 4;
break;
case trollobj:
points = 8;
break;
case demonobj:
points = 15;
break;
}
TakeDamage (points);
}
ob->state = ob->state->next;
}
//==========================================================================
/*
==================================
=
= Walk
=
==================================
*/
boolean Walk (objtype *ob)
{
switch (ob->dir)
{
case north:
if (actorat[ob->tilex][ob->tiley-1])
return false;
ob->tiley--;
ob->distance = TILEGLOBAL;
return true;
case northeast:
if (actorat[ob->tilex+1][ob->tiley-1])
return false;
ob->tilex++;
ob->tiley--;
ob->distance = TILEGLOBAL;
return true;
case east:
if (actorat[ob->tilex+1][ob->tiley])
return false;
ob->tilex++;
ob->distance = TILEGLOBAL;
return true;
case southeast:
if (actorat[ob->tilex+1][ob->tiley+1])
return false;
ob->tilex++;
ob->tiley++;
ob->distance = TILEGLOBAL;
return true;
case south:
if (actorat[ob->tilex][ob->tiley+1])
return false;
ob->tiley++;
ob->distance = TILEGLOBAL;
return true;
case southwest:
if (actorat[ob->tilex-1][ob->tiley+1])
return false;
ob->tilex--;
ob->tiley++;
ob->distance = TILEGLOBAL;
return true;
case west:
if (actorat[ob->tilex-1][ob->tiley])
return false;
ob->tilex--;
ob->distance = TILEGLOBAL;
return true;
case northwest:
if (actorat[ob->tilex-1][ob->tiley-1])
return false;
ob->tilex--;
ob->tiley--;
ob->distance = TILEGLOBAL;
return true;
case nodir:
return false;
}
Quit ("Walk: Bad dir");
return false;
}
/*
==================================
=
= ChaseThink
= have the current monster go after the player,
= either diagonally or straight on
=
==================================
*/
void ChaseThink (objtype *obj, boolean diagonal)
{
int deltax,deltay,i;
dirtype d[3];
dirtype tdir, olddir, turnaround;
olddir=obj->dir;
turnaround=opposite[olddir];
deltax=player->tilex - obj->tilex;
deltay=player->tiley - obj->tiley;
d[1]=nodir;
d[2]=nodir;
if (deltax>0)
d[1]= east;
if (deltax<0)
d[1]= west;
if (deltay>0)
d[2]=south;
if (deltay<0)
d[2]=north;
if (abs(deltay)>abs(deltax))
{
tdir=d[1];
d[1]=d[2];
d[2]=tdir;
}
if (d[1]==turnaround)
d[1]=nodir;
if (d[2]==turnaround)
d[2]=nodir;
if (diagonal)
{ /*ramdiagonals try the best dir first*/
if (d[1]!=nodir)
{
obj->dir=d[1];
if (Walk(obj))
return; /*either moved forward or attacked*/
}
if (d[2]!=nodir)
{
obj->dir=d[2];
if (Walk(obj))
return;
}
}
else
{ /*ramstraights try the second best dir first*/
if (d[2]!=nodir)
{
obj->dir=d[2];
if (Walk(obj))
return;
}
if (d[1]!=nodir)
{
obj->dir=d[1];
if (Walk(obj))
return;
}
}
/* there is no direct path to the player, so pick another direction */
obj->dir=olddir;
if (Walk(obj))
return;
if (US_RndT()>128) /*randomly determine direction of search*/
{
for (tdir=north;tdir<=west;tdir++)
{
if (tdir!=turnaround)
{
obj->dir=tdir;
if (Walk(obj))
return;
}
}
}
else
{
for (tdir=west;tdir>=north;tdir--)
{
if (tdir!=turnaround)
{
obj->dir=tdir;
if (Walk(obj))
return;
}
}
}
obj->dir=turnaround;
Walk(obj); /*last chance, don't worry about returned value*/
}
/*
=================
=
= MoveObj
=
=================
*/
void MoveObj (objtype *ob, long move)
{
ob->distance -=move;
switch (ob->dir)
{
case north:
ob->y -= move;
return;
case northeast:
ob->x += move;
ob->y -= move;
return;
case east:
ob->x += move;
return;
case southeast:
ob->x += move;
ob->y += move;
return;
case south:
ob->y += move;
return;
case southwest:
ob->x -= move;
ob->y += move;
return;
case west:
ob->x -= move;
return;
case northwest:
ob->x -= move;
ob->y -= move;
return;
case nodir:
return;
}
}
/*
=================
=
= Chase
=
= returns true if hand attack range
=
=================
*/
boolean Chase (objtype *ob, boolean diagonal)
{
long move;
long deltax,deltay,size;
move = ob->speed*tics;
size = (long)ob->size + player->size + move;
while (move)
{
deltax = ob->x - player->x;
deltay = ob->y - player->y;
if (deltax <= size && deltax >= -size
&& deltay <= size && deltay >= -size)
{
CalcBounds (ob);
return true;
}
if (move < ob->distance)
{
MoveObj (ob,move);
break;
}
actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
if (ob->dir == nodir)
ob->dir = north;
ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
move -= ob->distance;
ChaseThink (ob,diagonal);
if (!ob->distance)
break; // no possible move
actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
}
CalcBounds (ob);
return false;
}
//===========================================================================
/*
===================
=
= ShootActor
=
===================
*/
void ShootActor (objtype *ob, unsigned damage)
{
ob->hitpoints -= damage;
if (ob->hitpoints<=0)
{
switch (ob->obclass)
{
case orcobj:
ob->state = &s_orcdie1;
GivePoints (100);
break;
case trollobj:
ob->state = &s_trolldie1;
GivePoints (400);
break;
case demonobj:
ob->state = &s_demondie1;
GivePoints (1000);
break;
case mageobj:
ob->state = &s_magedie1;
GivePoints (600);
break;
case batobj:
ob->state = &s_batdie1;
GivePoints (100);
break;
case grelmobj:
ob->state = &s_greldie1;
GivePoints (10000);
break;
}
ob->obclass = inertobj;
ob->shootable = false;
actorat[ob->tilex][ob->tiley] = NULL;
}
else
{
switch (ob->obclass)
{
case orcobj:
ob->state = &s_orcouch;
break;
case trollobj:
ob->state = &s_trollouch;
break;
case demonobj:
ob->state = &s_demonouch;
break;
case mageobj:
ob->state = &s_mageouch;
break;
case grelmobj:
ob->state = &s_grelouch;
break;
}
}
ob->ticcount = ob->state->tictime;
}

872
C3_TRACE.C Normal file
View File

@@ -0,0 +1,872 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// C3_TRACE.C
#include "C3_DEF.H"
#pragma hdrstop
/*
=============================================================================
LOCAL CONSTANTS
=============================================================================
*/
//
// TESTWALLVISABLE will set the global variable wallvisable to 1 or 0
// depending on if tile.x,tile.y,wallon is visable from focal point
//
#define TESTWALLVISABLE { \
if (tile.y<focal.y) \
voffset = 0; \
else if (tile.y==focal.y) \
voffset = 3; \
else \
voffset = 6; \
if (tile.x==focal.x) \
voffset ++; \
else if (tile.x>focal.x) \
voffset += 2; \
wallvisable = visable[voffset][wallon]; }
/*
=============================================================================
GLOBAL VARIABLES
=============================================================================
*/
boolean aborttrace;
/*
=============================================================================
LOCAL VARIABLES
=============================================================================
*/
unsigned wallvisable,voffset;
fixed edgex,edgey;
int wallon;
int basecolor;
walltype *oldwall;
//
// offsets from upper left corner of a tile to the left and right edges of
// a given wall (NORTH-WEST)
//
fixed point1x[4] = {GLOBAL1,GLOBAL1,0 ,0 };
fixed point1y[4] = {0 ,GLOBAL1,GLOBAL1,0 };
fixed point2x[4] = {0 ,GLOBAL1,GLOBAL1,0 };
fixed point2y[4] = {0 ,0 ,GLOBAL1 ,GLOBAL1};
//
// offset from tile.x,tile.y of the tile that shares wallon side
// (side is not visable if it is shared)
//
int sharex[4] = { 0, 1, 0,-1};
int sharey[4] = {-1, 0, 1, 0};
//
// amount to move tile.x,tile.y to follow wallon to another tile
//
int followx[4] = {-1, 0, 1, 0};
int followy[4] = { 0,-1, 0, 1};
//
// cornerwall gives the wall on the same tile to start following when the
// wall ends at an empty tile (go around an edge on same tile)
// turnwall gives the wall on tile.x+sharex,tile.y+sharey to start following
// when the wall hits another tile (right angle corner)
//
int cornerwall[4] = {WEST,NORTH,EAST,SOUTH};
int turnwall[4] = {EAST,SOUTH,WEST,NORTH};
//
// wall visabilities in reletive locations
// -,- 0,- +,-
// -,0 0,0 +,0
// -,+ 0,+ +,+
//
int visable[9][4] =
{
{0,1,1,0}, {0,0,1,0}, {0,0,1,1},
{0,1,0,0}, {0,0,0,0}, {0,0,0,1},
{1,1,0,0}, {1,0,0,0}, {1,0,0,1}
};
int startwall[9] = {2,2,3, 1,0,3, 1,0,0};
int backupwall[9] = {3,3,0, 2,0,0, 2,1,1};
int walllength;
/*
=============================================================================
FUNCTIONS
=============================================================================
*/
/*
========================
=
= FollowTrace
=
========================
*/
int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max)
{
int tx,ty,otx,oty;
long absdx,absdy,xstep,ystep;
tx = tracex>>TILESHIFT;
ty = tracey>>TILESHIFT;
spotvis[tx][ty] = true;
absdx=LABS(deltax);
absdy=LABS(deltay);
if (absdx>absdy)
{
ystep = (deltay<<8)/(absdx>>8);
if (!ystep)
ystep = deltay>0 ? 1 : -1;
oty = (tracey+ystep)>>TILESHIFT;
if (deltax>0)
{
//###############
//
// step x by +1
//
//###############
do
{
tx++;
spotvis[tx][ty] = true;
tracey+=ystep;
ty = tracey>>TILESHIFT;
if (ty!=oty)
{
if (tilemap[tx-1][ty])
{
tile.x = tx-1;
tile.y = ty;
return 1;
}
oty = ty;
}
if (tilemap[tx][ty])
{
tile.x = tx;
tile.y = ty;
return 1;
}
} while (--max);
return 0;
}
else
{
//###############
//
// step x by -1
//
//###############
do
{
tx--;
spotvis[tx][ty] = true;
tracey+=ystep;
ty = tracey>>TILESHIFT;
if (ty!=oty)
{
if (tilemap[tx][oty])
{
tile.x = tx;
tile.y = oty;
return 1;
}
oty = ty;
}
if (tilemap[tx][ty])
{
tile.x = tx;
tile.y = ty;
return 1;
}
} while (--max);
return 0;
}
}
else
{
xstep = (deltax<<8)/(absdy>>8);
if (!xstep)
xstep = deltax>0 ? 1 : -1;
otx = (tracex+xstep)>>TILESHIFT;
if (deltay>0)
{
//###############
//
// step y by +1
//
//###############
do
{
ty++;
spotvis[tx][ty] = true;
tracex+=xstep;
tx = tracex>>TILESHIFT;
if (tx!=otx)
{
if (tilemap[tx][ty-1])
{
tile.x = tx;
tile.y = ty-1;
return 1;
}
otx = tx;
}
if (tilemap[tx][ty])
{
tile.x = tx;
tile.y = ty;
return 1;
}
} while (--max);
return 0;
}
else
{
//###############
//
// step y by -1
//
//###############
do
{
ty--;
spotvis[tx][ty] = true;
tracex+=xstep;
tx = tracex>>TILESHIFT;
if (tx!=otx)
{
if (tilemap[otx][ty])
{
tile.x = otx;
tile.y = ty;
return 1;
}
otx = tx;
}
if (tilemap[tx][ty])
{
tile.x = tx;
tile.y = ty;
return 1;
}
} while (--max);
return 0;
}
}
}
//===========================================================================
/*
=================
=
= BackTrace
=
= Traces backwards from edgex,edgey to viewx,viewy to see if a closer
= tile obscures the given point. If it does, it finishes the wall and
= starts a new one.
= Returns true if a tile is hit.
= Call with a 1 to have it automatically finish the current wall
=
=================
*/
int BackTrace (int finish)
{
fixed tracex,tracey;
long deltax,deltay,absdx,absdy;
int steps,otx,oty,testx,testheight,offset,wall;
deltax = viewx-edgex;
deltay = viewy-edgey;
absdx = LABS(deltax);
absdy = LABS(deltay);
if (absdx>absdy)
steps = ABS(focal.x-(edgex>>TILESHIFT))-1;
else
steps = ABS(focal.y-(edgey>>TILESHIFT))-1;
if (steps<=0)
return 0;
otx = tile.x;
oty = tile.y;
if (!FollowTrace(edgex,edgey,deltax,deltay,steps))
return 0;
//
// if the start wall is behind the focal point, the trace went too far back
//
if (ABS(tile.x-focal.x)<2 && ABS(tile.y-focal.y)<2) // too close
{
if (tile.x == focal.x && tile.y == focal.y)
{
tile.x = otx;
tile.y = oty;
return 0;
}
if (tile.x<focal.x)
{
if (tile.y<focal.y)
wall = SOUTH;
else
wall = EAST;
}
else if (tile.x==focal.x)
{
if (tile.y<focal.y)
wall = SOUTH;
else
wall = NORTH;
}
else
{
if (tile.y<=focal.y)
wall = WEST;
else
wall = NORTH;
}
//
// rotate the X value to see if it is behind the view plane
//
if (TransformX (((long)tile.x<<16)+point1x[wall],
((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)
{
tile.x = otx;
tile.y = oty;
return 0;
}
}
//
// if the old wall is still behind a closer wall, ignore the back trace
// and continue on (dealing with limited precision...)
//
if (finish && !FinishWall ()) // the wall is still behind a forward wall
{
tile.x = otx;
tile.y = oty;
rightwall->x1 = oldwall->x2; // common edge with last wall
rightwall->height1 = oldwall->height2;
return 0;
}
//
// back up along the intersecting face to find the rightmost wall
//
if (tile.y<focal.y)
offset = 0;
else if (tile.y==focal.y)
offset = 3;
else
offset = 6;
if (tile.x==focal.x)
offset ++;
else if (tile.x>focal.x)
offset += 2;
wallon = backupwall[offset];
while (tilemap[tile.x][tile.y])
{
tile.x += followx[wallon];
tile.y += followy[wallon];
};
tile.x -= followx[wallon];
tile.y -= followy[wallon];
wallon = cornerwall[wallon]; // turn to first visable face
edgex = ((long)tile.x<<16);
edgey = ((long)tile.y<<16);
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
&rightwall->x1,&rightwall->height1);
basecolor = tilemap[tile.x][tile.y];
return 1;
}
//===========================================================================
/*
=================
=
= ForwardTrace
=
= Traces forwards from edgex,edgey along the line from viewx,viewy until
= a solid tile is hit. Sets tile.x,tile.y
=
=================
*/
void ForwardTrace (void)
{
int offset;
fixed tracex,tracey;
long deltax,deltay;
deltax = edgex-viewx;
deltay = edgey-viewy;
FollowTrace(edgex,edgey,deltax,deltay,0);
if (tile.y<focal.y)
offset = 0;
else if (tile.y==focal.y)
offset = 3;
else
offset = 6;
if (tile.x==focal.x)
offset ++;
else if (tile.x>focal.x)
offset += 2;
wallon = startwall[offset];
//
// start the new wall
//
edgex = ((long)tile.x<<16);
edgey = ((long)tile.y<<16);
//
// if entire first wall is invisable, corner
//
TransformPoint (edgex+point2x[wallon],edgey+point2y[wallon],
&rightwall->x2,&rightwall->height2);
if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]]
|| rightwall->x2 < (rightwall-1)->x2 )
wallon = cornerwall [wallon];
//
// transform first point
//
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
&rightwall->x1,&rightwall->height1);
basecolor = tilemap[tile.x][tile.y];
}
//===========================================================================
/*
=================
=
= FinishWall
=
= Transforms edgex,edgey as the next point of the current wall
= and sticks it in the wall list
=
=================
*/
int FinishWall (void)
{
char num[20];
oldwall = rightwall;
rightwall->color = basecolor;
TransformPoint (edgex,edgey,&rightwall->x2,&rightwall->height2);
if (rightwall->x2 <= (rightwall-1)->x2+2
&& rightwall->height2 < (rightwall-1)->height2 )
return 0;
rightwall->walllength = walllength;
switch (wallon)
{
case north:
case south:
rightwall->side = 0;
rightwall->planecoord = edgey;
break;
case west:
case east:
rightwall->side = 1;
rightwall->planecoord = edgex;
break;
}
walllength = 1;
rightwall++;
return 1;
}
//===========================================================================
/*
=================
=
= InsideCorner
=
=================
*/
void InsideCorner (void)
{
int offset;
//
// the wall turned -90 degrees, so draw what we have, move to the new tile,
// change wallon, change color, and continue following.
//
FinishWall ();
tile.x += sharex[wallon];
tile.y += sharey[wallon];
wallon = turnwall[wallon];
//
// if the new wall is visable, continue following it. Otherwise
// follow it backwards until it turns
//
TESTWALLVISABLE;
if (wallvisable)
{
//
// just turn to the next wall and continue
//
rightwall->x1 = oldwall->x2; // common edge with last wall
rightwall->height1 = oldwall->height2;
basecolor = tilemap[tile.x][tile.y];
return; // continue from here
}
//
// back follow the invisable wall until it turns, then follow that
//
do
{
tile.x += followx[wallon];
tile.y += followy[wallon];
} while (tilemap[tile.x][tile.y]);
tile.x -= followx[wallon];
tile.y -= followy[wallon];
wallon = cornerwall[wallon]; // turn to first visable face
edgex = ((long)tile.x<<16)+point1x[wallon];
edgey = ((long)tile.y<<16)+point1y[wallon];
if (!BackTrace(0)) // backtrace without finishing a wall
{
TransformPoint (edgex,edgey,&rightwall->x1,&rightwall->height1);
basecolor = tilemap[tile.x][tile.y];
}
}
//===========================================================================
/*
=================
=
= OutsideCorner
=
=================
*/
void OutsideCorner (void)
{
int offset;
//
// edge is the outside edge of a corner, so draw the current wall and
// turn the corner (+90 degrees)
//
FinishWall ();
tile.x -= followx[wallon]; // backup to the real tile
tile.y -= followy[wallon];
wallon = cornerwall[wallon];
//
// if the new wall is visable, continue following it. Otherwise
// trace a ray from the corner to find a wall in the distance to
// follow
//
TESTWALLVISABLE;
if (wallvisable)
{
//
// the new wall is visable, so just continue on
//
rightwall->x1 = oldwall->x2; // common edge with last wall
rightwall->height1 = oldwall->height2;
return; // still on same tile, so color is ok
}
//
// start from a new tile further away
//
ForwardTrace(); // find the next wall further back
}
//===========================================================================
/*
=================
=
= FollowWalls
=
= Starts a wall edge at the leftmost edge of tile.x,tile.y and follows it
= until something else is seen or the entire view area is covered
=
=================
*/
void FollowWalls (void)
{
int height,newcolor,offset,wall;
//####################
//
// figure leftmost wall of new tile
//
//####################
restart:
walllength = 1;
if (tile.y<focal.y)
offset = 0;
else if (tile.y==focal.y)
offset = 3;
else
offset = 6;
if (tile.x==focal.x)
offset ++;
else if (tile.x>focal.x)
offset += 2;
wallon = startwall[offset];
//
// if the start wall is inside a block, skip it by cornering to the second wall
//
if ( tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])
wallon = cornerwall [wallon];
//
// transform first edge to screen coordinates
//
edgex = ((long)tile.x<<16);
edgey = ((long)tile.y<<16);
TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],
&rightwall->x1,&rightwall->height1);
basecolor = tilemap[tile.x][tile.y];
//##################
//
// follow the wall as long as possible
//
//##################
advance:
do // while ( tile.x != right.x || tile.y != right.y)
{
//
// check for conditions that shouldn't happed...
//
if (rightwall->x1 > VIEWXH) // somehow missed right tile...
return;
if (rightwall == &walls[DANGERHIGH])
{
//
// somethiing got messed up! Correct by thrusting ahead...
//
VW_ColorBorder(6);
bordertime = 60;
Thrust(player->angle,TILEGLOBAL/4);
player->angle+=5;
if (player->angle>ANGLES)
player->angle-=ANGLES;
aborttrace = true;
return;
#if 0
strcpy (str,"Wall list overflow at LE:");
itoa(mapon+1,str2,10);
strcat (str,str2);
strcat (str," X:");
ltoa(objlist[0].x,str2,10);
strcat (str,str2);
strcat (str," Y:");
ltoa(objlist[0].y,str2,10);
strcat (str,str2);
strcat (str," AN:");
itoa(objlist[0].angle,str2,10);
strcat (str,str2);
Quit (str);
#endif
}
//
// proceed along wall
//
edgex = ((long)tile.x<<16)+point2x[wallon];
edgey = ((long)tile.y<<16)+point2y[wallon];
if (BackTrace(1)) // went behind a closer wall
continue;
//
// advance to next tile along wall
//
tile.x += followx[wallon];
tile.y += followy[wallon];
if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])
{
InsideCorner (); // turn at a corner
continue;
}
newcolor = tilemap[tile.x][tile.y];
if (!newcolor) // turn around an edge
{
OutsideCorner ();
continue;
}
if (newcolor != basecolor)
{
//
// wall changed color, so draw what we have and continue following
//
FinishWall ();
rightwall->x1 = oldwall->x2; // new wall shares this edge
rightwall->height1 = oldwall->height2;
basecolor = newcolor;
continue;
}
walllength++;
} while (tile.x != right.x || tile.y != right.y);
//######################
//
// draw the last tile
//
//######################
edgex = ((long)tile.x<<16)+point2x[wallon];
edgey = ((long)tile.y<<16)+point2y[wallon];
FinishWall();
wallon = cornerwall[wallon];
//
// if the corner wall is visable, draw it
//
TESTWALLVISABLE;
if (wallvisable)
{
rightwall->x1 = oldwall->x2; // common edge with last wall
rightwall->height1 = oldwall->height2;
edgex = ((long)tile.x<<16)+point2x[wallon];
edgey = ((long)tile.y<<16)+point2y[wallon];
FinishWall();
}
}
//===========================================================================

2046
C3_WIZ.C Normal file

File diff suppressed because it is too large Load Diff

BIN
CAT3D.PRJ Normal file

Binary file not shown.

339
COPYING Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

327
GFXE_C3D.EQU Normal file
View File

@@ -0,0 +1,327 @@
;=====================================
;
; Graphics .EQU file for .C3D
; IGRAB-ed on Tue Dec 21 15:06:11 1993
;
;=====================================
CP_MAINMENUPIC = 5
CP_NEWGAMEMENUPIC = 6
CP_LOADMENUPIC = 7
CP_SAVEMENUPIC = 8
CP_CONFIGMENUPIC = 9
CP_SOUNDMENUPIC = 10
CP_MUSICMENUPIC = 11
CP_KEYBOARDMENUPIC = 12
CP_KEYMOVEMENTPIC = 13
CP_KEYBUTTONPIC = 14
CP_JOYSTICKMENUPIC = 15
CP_OPTIONSMENUPIC = 16
CP_PADDLEWARPIC = 17
CP_QUITPIC = 18
CP_JOYSTICKPIC = 19
CP_MENUSCREENPIC = 20
TITLEPIC = 21
CREDITSPIC = 22
HIGHSCORESPIC = 23
FINALEPIC = 24
STATUSPIC = 25
SIDEBARSPIC = 26
SCROLLTOPPIC = 27
SCROLL1PIC = 28
SCROLL2PIC = 29
SCROLL3PIC = 30
SCROLL4PIC = 31
SCROLL5PIC = 32
SCROLL6PIC = 33
SCROLL7PIC = 34
SCROLL8PIC = 35
FIRSTLATCHPIC = 36
NOSHOTPOWERPIC = 37
SHOTPOWERPIC = 38
NOBODYPIC = 39
BODYPIC = 40
COMPAS1PIC = 41
COMPAS2PIC = 42
COMPAS3PIC = 43
COMPAS4PIC = 44
COMPAS5PIC = 45
COMPAS6PIC = 46
COMPAS7PIC = 47
COMPAS8PIC = 48
COMPAS9PIC = 49
COMPAS10PIC = 50
COMPAS11PIC = 51
COMPAS12PIC = 52
COMPAS13PIC = 53
COMPAS14PIC = 54
COMPAS15PIC = 55
COMPAS16PIC = 56
DEADPIC = 57
FIRSTSCALEPIC = 58
ORC1PIC = 59
ORC2PIC = 60
ORC3PIC = 61
ORC4PIC = 62
ORCATTACK1PIC = 63
ORCATTACK2PIC = 64
ORCOUCHPIC = 65
ORCDIE1PIC = 66
ORCDIE2PIC = 67
ORCDIE3PIC = 68
TROLL1PIC = 69
TROLL2PIC = 70
TROLL3PIC = 71
TROLL4PIC = 72
TROLLOUCHPIC = 73
TROLLATTACK1PIC = 74
TROLLATTACK2PIC = 75
TROLLATTACK3PIC = 76
TROLLDIE1PIC = 77
TROLLDIE2PIC = 78
TROLLDIE3PIC = 79
WARP1PIC = 80
WARP2PIC = 81
WARP3PIC = 82
WARP4PIC = 83
BOLTOBJPIC = 84
BOLTOBJ2PIC = 85
NUKEOBJPIC = 86
NUKEOBJ2PIC = 87
POTIONOBJPIC = 88
RKEYOBJPIC = 89
YKEYOBJPIC = 90
GKEYOBJPIC = 91
BKEYOBJPIC = 92
SCROLLOBJPIC = 93
CHESTOBJPIC = 94
PSHOT1PIC = 95
PSHOT2PIC = 96
BIGPSHOT1PIC = 97
BIGPSHOT2PIC = 98
DEMON1PIC = 99
DEMON2PIC = 100
DEMON3PIC = 101
DEMON4PIC = 102
DEMONATTACK1PIC = 103
DEMONATTACK2PIC = 104
DEMONATTACK3PIC = 105
DEMONOUCHPIC = 106
DEMONDIE1PIC = 107
DEMONDIE2PIC = 108
DEMONDIE3PIC = 109
MAGE1PIC = 110
MAGE2PIC = 111
MAGEOUCHPIC = 112
MAGEATTACKPIC = 113
MAGEDIE1PIC = 114
MAGEDIE2PIC = 115
BAT1PIC = 116
BAT2PIC = 117
BAT3PIC = 118
BAT4PIC = 119
BATDIE1PIC = 120
BATDIE2PIC = 121
GREL1PIC = 122
GREL2PIC = 123
GRELATTACKPIC = 124
GRELHITPIC = 125
GRELDIE1PIC = 126
GRELDIE2PIC = 127
GRELDIE3PIC = 128
GRELDIE4PIC = 129
GRELDIE5PIC = 130
GRELDIE6PIC = 131
NEMESISPIC = 132
FIRSTWALLPIC = 133
EXPWALL1PIC = 134
EXPWALL2PIC = 135
EXPWALL3PIC = 136
WALL1LPIC = 137
WALL1DPIC = 138
WALL2DPIC = 139
WALL2LPIC = 140
WALL3DPIC = 141
WALL3LPIC = 142
WALL4DPIC = 143
WALL4LPIC = 144
WALL5DPIC = 145
WALL5LPIC = 146
WALL6DPIC = 147
WALL6LPIC = 148
WALL7DPIC = 149
WALL7LPIC = 150
RDOOR1PIC = 151
RDOOR2PIC = 152
YDOOR1PIC = 153
YDOOR2PIC = 154
GDOOR1PIC = 155
GDOOR2PIC = 156
BDOOR1PIC = 157
BDOOR2PIC = 158
ENTERPLAQUEPIC = 159
CP_MENUMASKPICM = 160
HAND1PICM = 161
HAND2PICM = 162
PADDLESPR = 163
BALLSPR = 164
BALL1PIXELTOTHERIGHTSPR = 165
LEVEL1TEXT = 456
LEVEL2TEXT = 457
LEVEL3TEXT = 458
LEVEL4TEXT = 459
LEVEL5TEXT = 460
LEVEL6TEXT = 461
LEVEL7TEXT = 462
LEVEL8TEXT = 463
LEVEL9TEXT = 464
LEVEL10TEXT = 465
LEVEL11TEXT = 466
LEVEL12TEXT = 467
LEVEL13TEXT = 468
LEVEL14TEXT = 469
LEVEL15TEXT = 470
LEVEL16TEXT = 471
LEVEL17TEXT = 472
LEVEL18TEXT = 473
LEVEL19TEXT = 474
LEVEL20TEXT = 475
OUTOFMEM = 476
PIRACY = 477
CONTROLS_LUMP_START = 5
CONTROLS_LUMP_END = 20
PADDLE_LUMP_START = 163
PADDLE_LUMP_END = 165
ORC_LUMP_START = 59
ORC_LUMP_END = 68
TROLL_LUMP_START = 69
TROLL_LUMP_END = 79
WARP_LUMP_START = 80
WARP_LUMP_END = 83
BOLT_LUMP_START = 84
BOLT_LUMP_END = 85
NUKE_LUMP_START = 86
NUKE_LUMP_END = 87
POTION_LUMP_START = 88
POTION_LUMP_END = 88
RKEY_LUMP_START = 89
RKEY_LUMP_END = 89
YKEY_LUMP_START = 90
YKEY_LUMP_END = 90
GKEY_LUMP_START = 91
GKEY_LUMP_END = 91
BKEY_LUMP_START = 92
BKEY_LUMP_END = 92
SCROLL_LUMP_START = 93
SCROLL_LUMP_END = 93
CHEST_LUMP_START = 94
CHEST_LUMP_END = 94
PLAYER_LUMP_START = 95
PLAYER_LUMP_END = 98
DEMON_LUMP_START = 99
DEMON_LUMP_END = 109
MAGE_LUMP_START = 110
MAGE_LUMP_END = 115
BAT_LUMP_START = 116
BAT_LUMP_END = 121
GREL_LUMP_START = 122
GREL_LUMP_END = 132
EXPWALL_LUMP_START = 134
EXPWALL_LUMP_END = 136
WALL1_LUMP_START = 137
WALL1_LUMP_END = 138
WALL2_LUMP_START = 139
WALL2_LUMP_END = 140
WALL3_LUMP_START = 141
WALL3_LUMP_END = 142
WALL4_LUMP_START = 143
WALL4_LUMP_END = 144
WALL5_LUMP_START = 145
WALL5_LUMP_END = 146
WALL6_LUMP_START = 147
WALL6_LUMP_END = 148
WALL7_LUMP_START = 149
WALL7_LUMP_END = 150
RDOOR_LUMP_START = 151
RDOOR_LUMP_END = 152
YDOOR_LUMP_START = 153
YDOOR_LUMP_END = 154
GDOOR_LUMP_START = 155
GDOOR_LUMP_END = 156
BDOOR_LUMP_START = 157
BDOOR_LUMP_END = 158
;
; Amount of each data item
;
NUMCHUNKS = 478
NUMFONT = 2
NUMFONTM = 0
NUMPICS = 155
NUMPICM = 3
NUMSPRITES = 3
NUMTILE8 = 108
NUMTILE8M = 36
NUMTILE16 = 216
NUMTILE16M = 72
NUMTILE32 = 0
NUMTILE32M = 0
NUMEXTERN = 22
;
; File offsets for data items
;
STRUCTPIC = 0
STRUCTPICM = 1
STRUCTSPRITE = 2
STARTFONT = 3
STARTFONTM = 5
STARTPICS = 5
STARTPICM = 160
STARTSPRITES = 163
STARTTILE8 = 166
STARTTILE8M = 167
STARTTILE16 = 168
STARTTILE16M = 384
STARTTILE32 = 456
STARTTILE32M = 456
STARTEXTERN = 456
;
; Thank you for using IGRAB!
;

353
GFXE_C3D.H Normal file
View File

@@ -0,0 +1,353 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//////////////////////////////////////
//
// Graphics .H file for .C3D
// IGRAB-ed on Tue Dec 21 15:06:10 1993
//
//////////////////////////////////////
typedef enum {
// Lump Start
CP_MAINMENUPIC=5,
CP_NEWGAMEMENUPIC, // 6
CP_LOADMENUPIC, // 7
CP_SAVEMENUPIC, // 8
CP_CONFIGMENUPIC, // 9
CP_SOUNDMENUPIC, // 10
CP_MUSICMENUPIC, // 11
CP_KEYBOARDMENUPIC, // 12
CP_KEYMOVEMENTPIC, // 13
CP_KEYBUTTONPIC, // 14
CP_JOYSTICKMENUPIC, // 15
CP_OPTIONSMENUPIC, // 16
CP_PADDLEWARPIC, // 17
CP_QUITPIC, // 18
CP_JOYSTICKPIC, // 19
CP_MENUSCREENPIC, // 20
TITLEPIC, // 21
CREDITSPIC, // 22
HIGHSCORESPIC, // 23
FINALEPIC, // 24
STATUSPIC, // 25
SIDEBARSPIC, // 26
SCROLLTOPPIC, // 27
SCROLL1PIC, // 28
SCROLL2PIC, // 29
SCROLL3PIC, // 30
SCROLL4PIC, // 31
SCROLL5PIC, // 32
SCROLL6PIC, // 33
SCROLL7PIC, // 34
SCROLL8PIC, // 35
FIRSTLATCHPIC, // 36
NOSHOTPOWERPIC, // 37
SHOTPOWERPIC, // 38
NOBODYPIC, // 39
BODYPIC, // 40
COMPAS1PIC, // 41
COMPAS2PIC, // 42
COMPAS3PIC, // 43
COMPAS4PIC, // 44
COMPAS5PIC, // 45
COMPAS6PIC, // 46
COMPAS7PIC, // 47
COMPAS8PIC, // 48
COMPAS9PIC, // 49
COMPAS10PIC, // 50
COMPAS11PIC, // 51
COMPAS12PIC, // 52
COMPAS13PIC, // 53
COMPAS14PIC, // 54
COMPAS15PIC, // 55
COMPAS16PIC, // 56
DEADPIC, // 57
FIRSTSCALEPIC, // 58
ORC1PIC, // 59
ORC2PIC, // 60
ORC3PIC, // 61
ORC4PIC, // 62
ORCATTACK1PIC, // 63
ORCATTACK2PIC, // 64
ORCOUCHPIC, // 65
ORCDIE1PIC, // 66
ORCDIE2PIC, // 67
ORCDIE3PIC, // 68
TROLL1PIC, // 69
TROLL2PIC, // 70
TROLL3PIC, // 71
TROLL4PIC, // 72
TROLLOUCHPIC, // 73
TROLLATTACK1PIC, // 74
TROLLATTACK2PIC, // 75
TROLLATTACK3PIC, // 76
TROLLDIE1PIC, // 77
TROLLDIE2PIC, // 78
TROLLDIE3PIC, // 79
WARP1PIC, // 80
WARP2PIC, // 81
WARP3PIC, // 82
WARP4PIC, // 83
BOLTOBJPIC, // 84
BOLTOBJ2PIC, // 85
NUKEOBJPIC, // 86
NUKEOBJ2PIC, // 87
POTIONOBJPIC, // 88
RKEYOBJPIC, // 89
YKEYOBJPIC, // 90
GKEYOBJPIC, // 91
BKEYOBJPIC, // 92
SCROLLOBJPIC, // 93
CHESTOBJPIC, // 94
PSHOT1PIC, // 95
PSHOT2PIC, // 96
BIGPSHOT1PIC, // 97
BIGPSHOT2PIC, // 98
DEMON1PIC, // 99
DEMON2PIC, // 100
DEMON3PIC, // 101
DEMON4PIC, // 102
DEMONATTACK1PIC, // 103
DEMONATTACK2PIC, // 104
DEMONATTACK3PIC, // 105
DEMONOUCHPIC, // 106
DEMONDIE1PIC, // 107
DEMONDIE2PIC, // 108
DEMONDIE3PIC, // 109
MAGE1PIC, // 110
MAGE2PIC, // 111
MAGEOUCHPIC, // 112
MAGEATTACKPIC, // 113
MAGEDIE1PIC, // 114
MAGEDIE2PIC, // 115
BAT1PIC, // 116
BAT2PIC, // 117
BAT3PIC, // 118
BAT4PIC, // 119
BATDIE1PIC, // 120
BATDIE2PIC, // 121
GREL1PIC, // 122
GREL2PIC, // 123
GRELATTACKPIC, // 124
GRELHITPIC, // 125
GRELDIE1PIC, // 126
GRELDIE2PIC, // 127
GRELDIE3PIC, // 128
GRELDIE4PIC, // 129
GRELDIE5PIC, // 130
GRELDIE6PIC, // 131
NEMESISPIC, // 132
FIRSTWALLPIC, // 133
EXPWALL1PIC, // 134
EXPWALL2PIC, // 135
EXPWALL3PIC, // 136
WALL1LPIC, // 137
WALL1DPIC, // 138
WALL2DPIC, // 139
WALL2LPIC, // 140
WALL3DPIC, // 141
WALL3LPIC, // 142
WALL4DPIC, // 143
WALL4LPIC, // 144
WALL5DPIC, // 145
WALL5LPIC, // 146
WALL6DPIC, // 147
WALL6LPIC, // 148
WALL7DPIC, // 149
WALL7LPIC, // 150
RDOOR1PIC, // 151
RDOOR2PIC, // 152
YDOOR1PIC, // 153
YDOOR2PIC, // 154
GDOOR1PIC, // 155
GDOOR2PIC, // 156
BDOOR1PIC, // 157
BDOOR2PIC, // 158
ENTERPLAQUEPIC, // 159
CP_MENUMASKPICM=160,
HAND1PICM, // 161
HAND2PICM, // 162
// Lump Start
PADDLESPR=163,
BALLSPR, // 164
BALL1PIXELTOTHERIGHTSPR, // 165
LEVEL1TEXT=456,
LEVEL2TEXT, // 457
LEVEL3TEXT, // 458
LEVEL4TEXT, // 459
LEVEL5TEXT, // 460
LEVEL6TEXT, // 461
LEVEL7TEXT, // 462
LEVEL8TEXT, // 463
LEVEL9TEXT, // 464
LEVEL10TEXT, // 465
LEVEL11TEXT, // 466
LEVEL12TEXT, // 467
LEVEL13TEXT, // 468
LEVEL14TEXT, // 469
LEVEL15TEXT, // 470
LEVEL16TEXT, // 471
LEVEL17TEXT, // 472
LEVEL18TEXT, // 473
LEVEL19TEXT, // 474
LEVEL20TEXT, // 475
OUTOFMEM, // 476
PIRACY, // 477
ENUMEND
} graphicnums;
//
// Data LUMPs
//
#define CONTROLS_LUMP_START 5
#define CONTROLS_LUMP_END 20
#define PADDLE_LUMP_START 163
#define PADDLE_LUMP_END 165
#define ORC_LUMP_START 59
#define ORC_LUMP_END 68
#define TROLL_LUMP_START 69
#define TROLL_LUMP_END 79
#define WARP_LUMP_START 80
#define WARP_LUMP_END 83
#define BOLT_LUMP_START 84
#define BOLT_LUMP_END 85
#define NUKE_LUMP_START 86
#define NUKE_LUMP_END 87
#define POTION_LUMP_START 88
#define POTION_LUMP_END 88
#define RKEY_LUMP_START 89
#define RKEY_LUMP_END 89
#define YKEY_LUMP_START 90
#define YKEY_LUMP_END 90
#define GKEY_LUMP_START 91
#define GKEY_LUMP_END 91
#define BKEY_LUMP_START 92
#define BKEY_LUMP_END 92
#define SCROLL_LUMP_START 93
#define SCROLL_LUMP_END 93
#define CHEST_LUMP_START 94
#define CHEST_LUMP_END 94
#define PLAYER_LUMP_START 95
#define PLAYER_LUMP_END 98
#define DEMON_LUMP_START 99
#define DEMON_LUMP_END 109
#define MAGE_LUMP_START 110
#define MAGE_LUMP_END 115
#define BAT_LUMP_START 116
#define BAT_LUMP_END 121
#define GREL_LUMP_START 122
#define GREL_LUMP_END 132
#define EXPWALL_LUMP_START 134
#define EXPWALL_LUMP_END 136
#define WALL1_LUMP_START 137
#define WALL1_LUMP_END 138
#define WALL2_LUMP_START 139
#define WALL2_LUMP_END 140
#define WALL3_LUMP_START 141
#define WALL3_LUMP_END 142
#define WALL4_LUMP_START 143
#define WALL4_LUMP_END 144
#define WALL5_LUMP_START 145
#define WALL5_LUMP_END 146
#define WALL6_LUMP_START 147
#define WALL6_LUMP_END 148
#define WALL7_LUMP_START 149
#define WALL7_LUMP_END 150
#define RDOOR_LUMP_START 151
#define RDOOR_LUMP_END 152
#define YDOOR_LUMP_START 153
#define YDOOR_LUMP_END 154
#define GDOOR_LUMP_START 155
#define GDOOR_LUMP_END 156
#define BDOOR_LUMP_START 157
#define BDOOR_LUMP_END 158
//
// Amount of each data item
//
#define NUMCHUNKS 478
#define NUMFONT 2
#define NUMFONTM 0
#define NUMPICS 155
#define NUMPICM 3
#define NUMSPRITES 3
#define NUMTILE8 108
#define NUMTILE8M 36
#define NUMTILE16 216
#define NUMTILE16M 72
#define NUMTILE32 0
#define NUMTILE32M 0
#define NUMEXTERNS 22
//
// File offsets for data items
//
#define STRUCTPIC 0
#define STRUCTPICM 1
#define STRUCTSPRITE 2
#define STARTFONT 3
#define STARTFONTM 5
#define STARTPICS 5
#define STARTPICM 160
#define STARTSPRITES 163
#define STARTTILE8 166
#define STARTTILE8M 167
#define STARTTILE16 168
#define STARTTILE16M 384
#define STARTTILE32 456
#define STARTTILE32M 456
#define STARTEXTERNS 456
//
// Thank you for using IGRAB!
//

114
ID_ASM.EQU Normal file
View File

@@ -0,0 +1,114 @@
;
; Equates for all .ASM files
;
;----------------------------------------------------------------------------
INCLUDE "GFXE_C3D.EQU"
;----------------------------------------------------------------------------
CGAGR = 1
EGAGR = 2
VGAGR = 3
GRMODE = EGAGR
PROFILE = 0 ; 1=keep stats on tile drawing
SC_INDEX = 03C4h
SC_RESET = 0
SC_CLOCK = 1
SC_MAPMASK = 2
SC_CHARMAP = 3
SC_MEMMODE = 4
CRTC_INDEX = 03D4h
CRTC_H_TOTAL = 0
CRTC_H_DISPEND = 1
CRTC_H_BLANK = 2
CRTC_H_ENDBLANK = 3
CRTC_H_RETRACE = 4
CRTC_H_ENDRETRACE = 5
CRTC_V_TOTAL = 6
CRTC_OVERFLOW = 7
CRTC_ROWSCAN = 8
CRTC_MAXSCANLINE = 9
CRTC_CURSORSTART = 10
CRTC_CURSOREND = 11
CRTC_STARTHIGH = 12
CRTC_STARTLOW = 13
CRTC_CURSORHIGH = 14
CRTC_CURSORLOW = 15
CRTC_V_RETRACE = 16
CRTC_V_ENDRETRACE = 17
CRTC_V_DISPEND = 18
CRTC_OFFSET = 19
CRTC_UNDERLINE = 20
CRTC_V_BLANK = 21
CRTC_V_ENDBLANK = 22
CRTC_MODE = 23
CRTC_LINECOMPARE = 24
GC_INDEX = 03CEh
GC_SETRESET = 0
GC_ENABLESETRESET = 1
GC_COLORCOMPARE = 2
GC_DATAROTATE = 3
GC_READMAP = 4
GC_MODE = 5
GC_MISCELLANEOUS = 6
GC_COLORDONTCARE = 7
GC_BITMASK = 8
ATR_INDEX = 03c0h
ATR_MODE = 16
ATR_OVERSCAN = 17
ATR_COLORPLANEENABLE = 18
ATR_PELPAN = 19
ATR_COLORSELECT = 20
STATUS_REGISTER_1 = 03dah
MACRO WORDOUT
out dx,ax
ENDM
if 0
MACRO WORDOUT
out dx,al
inc dx
xchg al,ah
out dx,al
dec dx
xchg al,ah
ENDM
endif
UPDATEWIDE = 22
UPDATEHIGH = 13 ; hack for catacombs
;
; tile info offsets from segment tinf
;
SPEED = 402
ANIM = (SPEED+NUMTILE16)
NORTHWALL = (ANIM+NUMTILE16)
EASTWALL = (NORTHWALL+NUMTILE16M)
SOUTHWALL = (EASTWALL+NUMTILE16M)
WESTWALL = (SOUTHWALL+NUMTILE16M)
MANIM = (WESTWALL+NUMTILE16M)
INTILE = (MANIM+NUMTILE16M)
MSPEED = (INTILE+NUMTILE16M)
IFE GRMODE-EGAGR
SCREENWIDTH = 40
ENDIF
IFE GRMODE-CGAGR
SCREENWIDTH = 128
ENDIF

2133
ID_CA.C Normal file

File diff suppressed because it is too large Load Diff

124
ID_CA.H Normal file
View File

@@ -0,0 +1,124 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// ID_CA.H
#ifndef __TYPES__
#include "ID_TYPES.H"
#endif
#ifndef __ID_MM__
#include "ID_MM.H"
#endif
#ifndef __ID_GLOB__
#include "ID_GLOB.H"
#endif
#define __ID_CA__
//===========================================================================
//#define NOMAPS
//#define NOGRAPHICS
//#define NOAUDIO
#define MAPHEADERLINKED
#define GRHEADERLINKED
#define AUDIOHEADERLINKED
#define NUMMAPS 30
#define MAPPLANES 3
//===========================================================================
typedef struct
{
long planestart[3];
unsigned planelength[3];
unsigned width,height;
char name[16];
} maptype;
//===========================================================================
extern byte _seg *tinf;
extern int mapon;
extern unsigned _seg *mapsegs[3];
extern maptype _seg *mapheaderseg[NUMMAPS];
extern byte _seg *audiosegs[NUMSNDCHUNKS];
extern void _seg *grsegs[NUMCHUNKS];
extern byte far grneeded[NUMCHUNKS];
extern byte ca_levelbit,ca_levelnum;
extern char *titleptr[8];
extern int profilehandle,debughandle;
//
// hooks for custom cache dialogs
//
extern void (*drawcachebox) (char *title, unsigned numcache);
extern void (*updatecachebox) (void);
extern void (*finishcachebox) (void);
//===========================================================================
// just for the score box reshifting
void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,
unsigned width, unsigned height, unsigned pixshift);
//===========================================================================
void CA_OpenDebug (void);
void CA_CloseDebug (void);
boolean CA_FarRead (int handle, byte far *dest, long length);
boolean CA_FarWrite (int handle, byte far *source, long length);
boolean CA_ReadFile (char *filename, memptr *ptr);
boolean CA_LoadFile (char *filename, memptr *ptr);
long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,
unsigned rlewtag);
void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,
unsigned rlewtag);
void CA_Startup (void);
void CA_Shutdown (void);
void CA_CacheAudioChunk (int chunk);
void CA_LoadAllSounds (void);
void CA_UpLevel (void);
void CA_DownLevel (void);
void CA_SetAllPurge (void);
void CA_ClearMarks (void);
void CA_ClearAllMarks (void);
#define CA_MarkGrChunk(chunk) grneeded[chunk]|=ca_levelbit
void CA_CacheGrChunk (int chunk);
void CA_CacheMap (int mapnum);
void CA_CacheMarks (char *title);

124
ID_HEADS.H Normal file
View File

@@ -0,0 +1,124 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// ID_GLOB.H
#include <ALLOC.H>
#include <CTYPE.H>
#include <DOS.H>
#include <ERRNO.H>
#include <FCNTL.H>
#include <IO.H>
#include <MEM.H>
#include <PROCESS.H>
#include <STDIO.H>
#include <STDLIB.H>
#include <STRING.H>
#include <SYS\STAT.H>
#define __ID_GLOB__
//--------------------------------------------------------------------------
#define EXTENSION "C3D"
extern char far introscn;
#include "GFXE_C3D.H"
#include "AUDIOC3D.H"
//--------------------------------------------------------------------------
#define CAT3D
#define TEXTGR 0
#define CGAGR 1
#define EGAGR 2
#define VGAGR 3
#define GRMODE EGAGR
#if GRMODE == EGAGR
#define GREXT "EGA"
#endif
#if GRMODE == CGAGR
#define GREXT "CGA"
#endif
//#define PROFILE
//
// ID Engine
// Types.h - Generic types, #defines, etc.
// v1.0d1
//
#ifndef __TYPES__
#define __TYPES__
typedef enum {false,true} boolean;
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long longword;
typedef byte * Ptr;
typedef struct
{
int x,y;
} Point;
typedef struct
{
Point ul,lr;
} Rect;
#define nil ((void *)0)
#endif
#include "ID_MM.H"
#include "ID_CA.H"
#include "ID_VW.H"
#include "ID_IN.H"
#include "ID_SD.H"
#include "ID_US.H"
void Quit (char *error); // defined in user program
//
// replacing refresh manager with custom routines
//
#define PORTTILESWIDE 21 // all drawing takes place inside a
#define PORTTILESHIGH 14 // non displayed port of this size
#define UPDATEWIDE (PORTTILESWIDE+1)
#define UPDATEHIGH PORTTILESHIGH
#define MAXTICS 6
#define DEMOTICS 3
#define UPDATETERMINATE 0x0301
extern unsigned mapwidth,mapheight,tics;
extern boolean compatability;
extern byte *updateptr;
extern unsigned uwidthtable[UPDATEHIGH];
extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];

1112
ID_IN.C Normal file

File diff suppressed because it is too large Load Diff

208
ID_IN.H Normal file
View File

@@ -0,0 +1,208 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//
// ID Engine
// ID_IN.h - Header file for Input Manager
// v1.0d1
// By Jason Blochowiak
//
#ifndef __TYPES__
#include "ID_Types.h"
#endif
#ifndef __ID_IN__
#define __ID_IN__
#ifdef __DEBUG__
#define __DEBUG_InputMgr__
#endif
#define MaxPlayers 4
#define MaxKbds 2
#define MaxJoys 2
#define NumCodes 128
typedef byte ScanCode;
#define sc_None 0
#define sc_Bad 0xff
#define sc_Return 0x1c
#define sc_Enter sc_Return
#define sc_Escape 0x01
#define sc_Space 0x39
#define sc_BackSpace 0x0e
#define sc_Tab 0x0f
#define sc_Alt 0x38
#define sc_Control 0x1d
#define sc_CapsLock 0x3a
#define sc_LShift 0x2a
#define sc_RShift 0x36
#define sc_UpArrow 0x48
#define sc_DownArrow 0x50
#define sc_LeftArrow 0x4b
#define sc_RightArrow 0x4d
#define sc_Insert 0x52
#define sc_Delete 0x53
#define sc_Home 0x47
#define sc_End 0x4f
#define sc_PgUp 0x49
#define sc_PgDn 0x51
#define sc_F1 0x3b
#define sc_F2 0x3c
#define sc_F3 0x3d
#define sc_F4 0x3e
#define sc_F5 0x3f
#define sc_F6 0x40
#define sc_F7 0x41
#define sc_F8 0x42
#define sc_F9 0x43
#define sc_F10 0x44
#define sc_F11 0x57
#define sc_F12 0x59
#define sc_A 0x1e
#define sc_B 0x30
#define sc_C 0x2e
#define sc_D 0x20
#define sc_E 0x12
#define sc_F 0x21
#define sc_G 0x22
#define sc_H 0x23
#define sc_I 0x17
#define sc_J 0x24
#define sc_K 0x25
#define sc_L 0x26
#define sc_M 0x32
#define sc_N 0x31
#define sc_O 0x18
#define sc_P 0x19
#define sc_Q 0x10
#define sc_R 0x13
#define sc_S 0x1f
#define sc_T 0x14
#define sc_U 0x16
#define sc_V 0x2f
#define sc_W 0x11
#define sc_X 0x2d
#define sc_Y 0x15
#define sc_Z 0x2c
#define key_None 0
#define key_Return 0x0d
#define key_Enter key_Return
#define key_Escape 0x1b
#define key_Space 0x20
#define key_BackSpace 0x08
#define key_Tab 0x09
#define key_Delete 0x7f
// Stuff for the mouse
#define MReset 0
#define MButtons 3
#define MDelta 11
#define MouseInt 0x33
#define Mouse(x) _AX = x,geninterrupt(MouseInt)
typedef enum {
demo_Off,demo_Record,demo_Playback,demo_PlayDone
} Demo;
typedef enum {
ctrl_Keyboard,
ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2,
ctrl_Joystick,
ctrl_Joystick1 = ctrl_Joystick,ctrl_Joystick2,
ctrl_Mouse
} ControlType;
typedef enum {
motion_Left = -1,motion_Up = -1,
motion_None = 0,
motion_Right = 1,motion_Down = 1
} Motion;
typedef enum {
dir_North,dir_NorthEast,
dir_East,dir_SouthEast,
dir_South,dir_SouthWest,
dir_West,dir_NorthWest,
dir_None
} Direction;
typedef struct {
boolean button0,button1;
int x,y;
Motion xaxis,yaxis;
Direction dir;
} CursorInfo;
typedef CursorInfo ControlInfo;
typedef struct {
ScanCode button0,button1,
upleft, up, upright,
left, right,
downleft, down, downright;
} KeyboardDef;
typedef struct {
word joyMinX,joyMinY,
threshMinX,threshMinY,
threshMaxX,threshMaxY,
joyMaxX,joyMaxY,
joyMultXL,joyMultYL,
joyMultXH,joyMultYH;
} JoystickDef;
// Global variables
extern boolean Keyboard[],
MousePresent,
JoysPresent[];
extern boolean Paused;
extern char LastASCII;
extern ScanCode LastScan;
extern KeyboardDef KbdDefs[];
extern JoystickDef JoyDefs[];
extern ControlType Controls[MaxPlayers];
extern Demo DemoMode;
extern byte _seg *DemoBuffer;
extern word DemoOffset,DemoSize;
// Function prototypes
#define IN_KeyDown(code) (Keyboard[(code)])
#define IN_ClearKey(code) {Keyboard[code] = false;\
if (code == LastScan) LastScan = sc_None;}
// DEBUG - put names in prototypes
extern void IN_Startup(void),IN_Shutdown(void),
IN_Default(boolean gotit,ControlType in),
IN_SetKeyHook(void (*)()),
IN_ClearKeysDown(void),
IN_ReadCursor(CursorInfo *),
IN_ReadControl(int,ControlInfo *),
IN_SetControlType(int,ControlType),
IN_GetJoyAbs(word joy,word *xp,word *yp),
IN_SetupJoy(word joy,word minx,word maxx,
word miny,word maxy),
IN_StartDemoPlayback(byte _seg *buffer,word bufsize),
IN_StopDemo(void),IN_FreeDemoBuffer(void),
IN_Ack(void),IN_AckBack(void);
extern boolean IN_UserInput(longword delay,boolean clear),
IN_IsUserInput(void),
IN_StartDemoRecord(word bufsize);
extern byte *IN_GetScanName(ScanCode);
extern char IN_WaitForASCII(void);
extern ScanCode IN_WaitForKey(void);
extern word IN_GetJoyButtonsDB(word joy);
#endif

1130
ID_MM.C Normal file

File diff suppressed because it is too large Load Diff

108
ID_MM.H Normal file
View File

@@ -0,0 +1,108 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// ID_MM.H
#ifndef __ID_CA__
#define __ID_CA__
#define SAVENEARHEAP 0x400 // space to leave in data segment
#define SAVEFARHEAP 0 // space to leave in far heap
#define BUFFERSIZE 0x1000 // miscelanious, allways available buffer
#define MAXBLOCKS 600
//--------
#define EMS_INT 0x67
#define EMS_STATUS 0x40
#define EMS_GETFRAME 0x41
#define EMS_GETPAGES 0x42
#define EMS_ALLOCPAGES 0x43
#define EMS_MAPPAGE 0x44
#define EMS_FREEPAGES 0x45
#define EMS_VERSION 0x46
//--------
#define XMS_VERSION 0x00
#define XMS_ALLOCHMA 0x01
#define XMS_FREEHMA 0x02
#define XMS_GENABLEA20 0x03
#define XMS_GDISABLEA20 0x04
#define XMS_LENABLEA20 0x05
#define XMS_LDISABLEA20 0x06
#define XMS_QUERYA20 0x07
#define XMS_QUERYREE 0x08
#define XMS_ALLOC 0x09
#define XMS_FREE 0x0A
#define XMS_MOVE 0x0B
#define XMS_LOCK 0x0C
#define XMS_UNLOCK 0x0D
#define XMS_GETINFO 0x0E
#define XMS_RESIZE 0x0F
#define XMS_ALLOCUMB 0x10
#define XMS_FREEUMB 0x11
//==========================================================================
typedef void _seg * memptr;
typedef struct
{
long nearheap,farheap,EMSmem,XMSmem,mainmem;
} mminfotype;
//==========================================================================
extern mminfotype mminfo;
extern memptr bufferseg;
extern boolean mmerror;
extern void (* beforesort) (void);
extern void (* aftersort) (void);
//==========================================================================
void MM_Startup (void);
void MM_Shutdown (void);
void MM_MapEMS (void);
void MM_GetPtr (memptr *baseptr,unsigned long size);
void MM_FreePtr (memptr *baseptr);
void MM_SetPurge (memptr *baseptr, int purge);
void MM_SetLock (memptr *baseptr, boolean locked);
void MM_SortMem (void);
void MM_ShowMemory (void);
long MM_UnusedMemory (void);
long MM_TotalFree (void);
void MM_BombOnError (boolean bomb);
#endif

2845
ID_RF.C Normal file

File diff suppressed because it is too large Load Diff

153
ID_RF.H Normal file
View File

@@ -0,0 +1,153 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// ID_RF.H
#define __ID_RF__
#ifndef __ID_MM__
#include "ID_MM.H"
#endif
/*
=============================================================================
CONSTANTS
=============================================================================
*/
#define MINTICS 2
#define MAXTICS 6
#define DEMOTICS 3
#define MAPBORDER 2 // map border must be at least 1
#define MAXSPRITES 50 // max tracked sprites
#define MAXANIMTILES 90 // max animating tiles on screen
#define MAXANIMTYPES 50 // max different unique anim tiles on map
#define MAXMAPHEIGHT 200
#define PRIORITIES 4
#define MASKEDTILEPRIORITY 3 // planes go: 0,1,2,MTILES,3
#define TILEGLOBAL 256
#define PIXGLOBAL 16
#define G_T_SHIFT 8 // global >> ?? = tile
#define G_P_SHIFT 4 // global >> ?? = pixels
#define P_T_SHIFT 4 // pixels >> ?? = tile
#define PORTTILESWIDE 21 // all drawing takes place inside a
#define PORTTILESHIGH 14 // non displayed port of this size
//#define PORTGLOBALWIDE (21*TILEGLOBAL)
//#define PORTGLOBALHIGH (14*TILEGLOBAL)
#define UPDATEWIDE (PORTTILESWIDE+1)
#define UPDATEHIGH PORTTILESHIGH
//===========================================================================
typedef enum {spritedraw,maskdraw} drawtype;
/*
=============================================================================
PUBLIC VARIABLES
=============================================================================
*/
extern boolean compatability; // crippled refresh for wierdo SVGAs
extern unsigned tics;
extern long lasttimecount;
extern unsigned originxglobal,originyglobal;
extern unsigned originxtile,originytile;
extern unsigned originxscreen,originyscreen;
extern unsigned mapwidth,mapheight,mapbyteswide,mapwordswide
,mapbytesextra,mapwordsextra;
extern unsigned mapbwidthtable[MAXMAPHEIGHT];
extern unsigned originxmin,originxmax,originymin,originymax;
extern unsigned masterofs;
//
// the floating update window is also used by the view manager for
// double buffer tracking
//
extern byte *updateptr; // current start of update window
#if GRMODE == CGAGR
extern byte *baseupdateptr;
#endif
extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];
extern unsigned updatemapofs[UPDATEWIDE*UPDATEHIGH];
extern unsigned uwidthtable[UPDATEHIGH]; // lookup instead of multiple
#define UPDATETERMINATE 0x0301
/*
=============================================================================
PUBLIC FUNCTIONS
=============================================================================
*/
void RF_Startup (void);
void RF_Shutdown (void);
void RF_FixOfs (void);
void RF_NewMap (void);
void RF_MarkTileGraphics (void);
void RF_SetScrollBlock (int x, int y, boolean horizontal);
void RF_NewPosition (unsigned x, unsigned y);
void RF_Scroll (int x, int y);
void RF_MapToMap (unsigned srcx, unsigned srcy,
unsigned destx, unsigned desty,
unsigned width, unsigned height);
void RF_MemToMap (unsigned far *source, unsigned plane,
unsigned destx, unsigned desty,
unsigned width, unsigned height);
void RF_ClearBlock (int x, int y, int width, int height);
void RF_RedrawBlock (int x, int y, int width, int height);
void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly,
unsigned spritenumber, drawtype draw, int priority);
void RF_RemoveSprite (void **user);
void RF_CalcTics (void);
void RF_Refresh (void);
void RF_ForceRefresh (void);
void RF_SetRefreshHook (void (*func) (void) );
unsigned RF_FindFreeBuffer (void);

690
ID_RF_A.ASM Normal file
View File

@@ -0,0 +1,690 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
; ID_RF_A.ASM
IDEAL
MODEL MEDIUM,C
INCLUDE "ID_ASM.EQU"
;============================================================================
TILESWIDE = 21
TILESHIGH = 14
UPDATESIZE = (TILESWIDE+1)*TILESHIGH+1
DATASEG
EXTRN screenseg:WORD
EXTRN updateptr:WORD
EXTRN updatestart:WORD
EXTRN masterofs:WORD ;start of master tile port
EXTRN bufferofs:WORD ;start of current buffer port
EXTRN screenstart:WORD ;starts of three screens (0/1/master) in EGA mem
EXTRN grsegs:WORD
EXTRN mapsegs:WORD
EXTRN originmap:WORD
EXTRN updatemapofs:WORD
EXTRN tinf:WORD ;seg pointer to map header and tile info
EXTRN blockstarts:WORD ;offsets from bufferofs for each update block
planemask db ?
planenum db ?
CODESEG
screenstartcs dw ? ;in code segment for accesability
IFE GRMODE-CGAGR
;============================================================================
;
; CGA refresh routines
;
;============================================================================
TILEWIDTH = 4
;=================
;
; RFL_NewTile
;
; Draws a composit two plane tile to the master screen and sets the update
; spot to 1 in both update pages, forcing the tile to be copied to the
; view pages the next two refreshes
;
; Called to draw newlly scrolled on strips and animating tiles
;
;=================
PROC RFL_NewTile updateoffset:WORD
PUBLIC RFL_NewTile
USES SI,DI
;
; mark both update lists at this spot
;
mov di,[updateoffset]
mov bx,[updateptr] ;start of update matrix
mov [BYTE bx+di],1
mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line
;
; set di to the location in screenseg to draw the tile
;
shl di,1
mov si,[updatemapofs+di] ;offset in map from origin
add si,[originmap]
mov di,[blockstarts+di] ;screen location for tile
add di,[masterofs]
;
; set BX to the foreground tile number and SI to the background number
; If either BX or SI = 0xFFFF, the tile does not need to be masked together
; as one of the planes totally eclipses the other
;
mov es,[mapsegs+2] ;foreground plane
mov bx,[es:si]
mov es,[mapsegs] ;background plane
mov si,[es:si]
mov es,[screenseg]
or bx,bx
jz @@singletile
jmp @@maskeddraw ;draw both together
;=============
;
; Draw single background tile from main memory
;
;=============
@@singletile:
shl si,1
mov ds,[grsegs+STARTTILE16*2+si]
xor si,si ;block is segment aligned
REPT 15
movsw
movsw
add di,dx
ENDM
movsw
movsw
mov ax,ss
mov ds,ax ;restore turbo's data segment
ret
;=========
;
; Draw a masked tile combo
; Interupts are disabled and the stack segment is reassigned
;
;=========
@@maskeddraw:
cli ; don't allow ints when SS is set
shl bx,1
mov ss,[grsegs+STARTTILE16M*2+bx]
shl si,1
mov ds,[grsegs+STARTTILE16*2+si]
xor si,si ;first word of tile data
REPT 16
mov ax,[si] ;background tile
and ax,[ss:si] ;mask
or ax,[ss:si+64] ;masked data
stosw
mov ax,[si+2] ;background tile
and ax,[ss:si+2] ;mask
or ax,[ss:si+66] ;masked data
stosw
add si,4
add di,dx
ENDM
mov ax,@DATA
mov ss,ax
sti
mov ds,ax
ret
ENDP
ENDIF
IFE GRMODE-EGAGR
;===========================================================================
;
; EGA refresh routines
;
;===========================================================================
TILEWIDTH = 2
;=================
;
; RFL_NewTile
;
; Draws a composit two plane tile to the master screen and sets the update
; spot to 1 in both update pages, forcing the tile to be copied to the
; view pages the next two refreshes
;
; Called to draw newlly scrolled on strips and animating tiles
;
; Assumes write mode 0
;
;=================
PROC RFL_NewTile updateoffset:WORD
PUBLIC RFL_NewTile
USES SI,DI
;
; mark both update lists at this spot
;
mov di,[updateoffset]
mov bx,[updatestart] ;page 0 pointer
mov [BYTE bx+di],1
mov bx,[updatestart+2] ;page 1 pointer
mov [BYTE bx+di],1
;
; set screenstartcs to the location in screenseg to draw the tile
;
shl di,1
mov si,[updatemapofs+di] ;offset in map from origin
add si,[originmap]
mov di,[blockstarts+di] ;screen location for tile
add di,[masterofs]
mov [cs:screenstartcs],di
;
; set BX to the foreground tile number and SI to the background number
; If either BX or SI = 0xFFFF, the tile does not need to be masked together
; as one of the planes totally eclipses the other
;
mov es,[mapsegs+2] ;foreground plane
mov bx,[es:si]
mov es,[mapsegs] ;background plane
mov si,[es:si]
mov es,[screenseg]
mov dx,SC_INDEX ;for stepping through map mask planes
or bx,bx
jz @@singletile
jmp @@maskeddraw ;draw both together
;=========
;
; No foreground tile, so draw a single background tile.
;
;=========
@@singletile:
mov bx,SCREENWIDTH-2 ;add to get to start of next line
shl si,1
mov ax,[cs:screenstartcs]
mov ds,[grsegs+STARTTILE16*2+si]
xor si,si ;block is segment aligned
mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
mov cx,4 ;draw four planes
@@planeloop:
mov dx,SC_INDEX
WORDOUT
mov di,[cs:screenstartcs] ;start at same place in all planes
REPT 15
movsw
add di,bx
ENDM
movsw
shl ah,1 ;shift plane mask over for next plane
loop @@planeloop
mov ax,ss
mov ds,ax ;restore turbo's data segment
ret
;=========
;
; Draw a masked tile combo
; Interupts are disabled and the stack segment is reassigned
;
;=========
@@maskeddraw:
cli ; don't allow ints when SS is set
shl bx,1
mov ss,[grsegs+STARTTILE16M*2+bx]
shl si,1
mov ds,[grsegs+STARTTILE16*2+si]
xor si,si ;first word of tile data
mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
mov di,[cs:screenstartcs]
@@planeloopm:
WORDOUT
tileofs = 0
lineoffset = 0
REPT 16
mov bx,[si+tileofs] ;background tile
and bx,[ss:tileofs] ;mask
or bx,[ss:si+tileofs+32] ;masked data
mov [es:di+lineoffset],bx
tileofs = tileofs + 2
lineoffset = lineoffset + SCREENWIDTH
ENDM
add si,32
shl ah,1 ;shift plane mask over for next plane
cmp ah,10000b
je @@done ;drawn all four planes
jmp @@planeloopm
@@done:
mov ax,@DATA
mov ss,ax
sti
mov ds,ax
ret
ENDP
ENDIF
IFE GRMODE-VGAGR
;============================================================================
;
; VGA refresh routines
;
;============================================================================
ENDIF
;============================================================================
;
; reasonably common refresh routines
;
;============================================================================
;=================
;
; RFL_UpdateTiles
;
; Scans through the update matrix pointed to by updateptr, looking for 1s.
; A 1 represents a tile that needs to be copied from the master screen to the
; current screen (a new row or an animated tiled). If more than one adjacent
; tile in a horizontal row needs to be copied, they will be copied as a group.
;
; Assumes write mode 1
;
;=================
; AX 0/1 for scasb, temp for segment register transfers
; BX width for block copies
; CX REP counter
; DX line width deltas
; SI source for copies
; DI scas dest / movsb dest
; BP pointer to UPDATETERMINATE
;
; DS
; ES
; SS
PROC RFL_UpdateTiles
PUBLIC RFL_UpdateTiles
USES SI,DI,BP
jmp SHORT @@realstart
@@done:
;
; all tiles have been scanned
;
ret
@@realstart:
mov di,[updateptr]
mov bp,(TILESWIDE+1)*TILESHIGH+1
add bp,di ; when di = bx, all tiles have been scanned
push di
mov cx,-1 ; definately scan the entire thing
;
; scan for a 1 in the update list, meaning a tile needs to be copied
; from the master screen to the current screen
;
@@findtile:
pop di ; place to continue scaning from
mov ax,ss
mov es,ax ; search in the data segment
mov ds,ax
mov al,1
repne scasb
cmp di,bp
je @@done
cmp [BYTE di],al
jne @@singletile
jmp @@tileblock
;============
;
; copy a single tile
;
;============
EVEN
@@singletile:
inc di ; we know the next tile is nothing
push di ; save off the spot being scanned
sub di,[updateptr]
shl di,1
mov di,[blockstarts-4+di] ; start of tile location on screen
mov si,di
add di,[bufferofs] ; dest in current screen
add si,[masterofs] ; source in master screen
mov dx,SCREENWIDTH-TILEWIDTH
mov ax,[screenseg]
mov ds,ax
mov es,ax
;--------------------------
IFE GRMODE-CGAGR
REPT 15
movsw
movsw
add si,dx
add di,dx
ENDM
movsw
movsw
ENDIF
;--------------------------
IFE GRMODE-EGAGR
REPT 15
movsb
movsb
add si,dx
add di,dx
ENDM
movsb
movsb
ENDIF
;--------------------------
jmp @@findtile
;============
;
; more than one tile in a row needs to be updated, so do it as a group
;
;============
EVEN
@@tileblock:
mov dx,di ; hold starting position + 1 in dx
inc di ; we know the next tile also gets updated
repe scasb ; see how many more in a row
push di ; save off the spot being scanned
mov bx,di
sub bx,dx ; number of tiles in a row
shl bx,1 ; number of bytes / row
mov di,dx ; lookup position of start tile
sub di,[updateptr]
shl di,1
mov di,[blockstarts-2+di] ; start of tile location
mov si,di
add di,[bufferofs] ; dest in current screen
add si,[masterofs] ; source in master screen
mov dx,SCREENWIDTH
sub dx,bx ; offset to next line on screen
IFE GRMODE-CGAGR
sub dx,bx ; bx is words wide in CGA tiles
ENDIF
mov ax,[screenseg]
mov ds,ax
mov es,ax
REPT 15
mov cx,bx
IFE GRMODE-CGAGR
rep movsw
ENDIF
IFE GRMODE-EGAGR
rep movsb
ENDIF
add si,dx
add di,dx
ENDM
mov cx,bx
IFE GRMODE-CGAGR
rep movsw
ENDIF
IFE GRMODE-EGAGR
rep movsb
ENDIF
dec cx ; was 0 from last rep movsb, now $ffff for scasb
jmp @@findtile
ENDP
;============================================================================
;=================
;
; RFL_MaskForegroundTiles
;
; Scan through update looking for 3's. If the foreground tile there is a
; masked foreground tile, draw it to the screen
;
;=================
PROC RFL_MaskForegroundTiles
PUBLIC RFL_MaskForegroundTiles
USES SI,DI,BP
jmp SHORT @@realstart
@@done:
;
; all tiles have been scanned
;
ret
@@realstart:
mov di,[updateptr]
mov bp,(TILESWIDE+1)*TILESHIGH+2
add bp,di ; when di = bx, all tiles have been scanned
push di
mov cx,-1 ; definately scan the entire thing
;
; scan for a 3 in the update list
;
@@findtile:
mov ax,ss
mov es,ax ; scan in the data segment
mov al,3
pop di ; place to continue scaning from
repne scasb
cmp di,bp
je @@done
;============
;
; found a tile, see if it needs to be masked on
;
;============
push di
sub di,[updateptr]
shl di,1
mov si,[updatemapofs-2+di] ; offset from originmap
add si,[originmap]
mov es,[mapsegs+2] ; foreground map plane segment
mov si,[es:si] ; foreground tile number
or si,si
jz @@findtile ; 0 = no foreground tile
mov bx,si
add bx,INTILE ;INTILE tile info table
mov es,[tinf]
test [BYTE PTR es:bx],80h ;high bit = masked tile
jz @@findtile
;-------------------
IFE GRMODE-CGAGR
;=================
;
; mask the tile CGA
;
;=================
mov di,[blockstarts-2+di]
add di,[bufferofs]
mov es,[screenseg]
shl si,1
mov ds,[grsegs+STARTTILE16M*2+si]
mov bx,64 ;data starts 64 bytes after mask
xor si,si
lineoffset = 0
REPT 16
mov ax,[es:di+lineoffset] ;background
and ax,[si] ;mask
or ax,[si+bx] ;masked data
mov [es:di+lineoffset],ax ;background
inc si
inc si
mov ax,[es:di+lineoffset+2] ;background
and ax,[si] ;mask
or ax,[si+bx] ;masked data
mov [es:di+lineoffset+2],ax ;background
inc si
inc si
lineoffset = lineoffset + SCREENWIDTH
ENDM
ENDIF
;-------------------
IFE GRMODE-EGAGR
;=================
;
; mask the tile
;
;=================
mov [BYTE planemask],1
mov [BYTE planenum],0
mov di,[blockstarts-2+di]
add di,[bufferofs]
mov [cs:screenstartcs],di
mov es,[screenseg]
shl si,1
mov ds,[grsegs+STARTTILE16M*2+si]
mov bx,32 ;data starts 32 bytes after mask
@@planeloopm:
mov dx,SC_INDEX
mov al,SC_MAPMASK
mov ah,[ss:planemask]
WORDOUT
mov dx,GC_INDEX
mov al,GC_READMAP
mov ah,[ss:planenum]
WORDOUT
xor si,si
mov di,[cs:screenstartcs]
lineoffset = 0
REPT 16
mov cx,[es:di+lineoffset] ;background
and cx,[si] ;mask
or cx,[si+bx] ;masked data
inc si
inc si
mov [es:di+lineoffset],cx
lineoffset = lineoffset + SCREENWIDTH
ENDM
add bx,32 ;the mask is now further away
inc [ss:planenum]
shl [ss:planemask],1 ;shift plane mask over for next plane
cmp [ss:planemask],10000b ;done all four planes?
je @@drawn ;drawn all four planes
jmp @@planeloopm
@@drawn:
ENDIF
;-------------------
mov ax,ss
mov ds,ax
mov cx,-1 ;definately scan the entire thing
jmp @@findtile
ENDP
END

1295
ID_SD.C Normal file

File diff suppressed because it is too large Load Diff

205
ID_SD.H Normal file
View File

@@ -0,0 +1,205 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//
// ID Engine
// ID_SD.h - Sound Manager Header
// v1.0d1
// By Jason Blochowiak
//
#ifndef __TYPES__
#include "ID_Types.h"
#endif
#ifndef __ID_SD__
#define __ID_SD__
#ifdef __DEBUG__
#define __DEBUG_SoundMgr__
#endif
#define TickBase 70 // 70Hz per tick - used as a base for timer 0
typedef enum {
sdm_Off,
sdm_PC,sdm_AdLib,
} SDMode;
typedef enum {
smm_Off,smm_AdLib
} SMMode;
typedef struct
{
longword length;
word priority;
} SoundCommon;
// PC Sound stuff
#define pcTimer 0x42
#define pcTAccess 0x43
#define pcSpeaker 0x61
#define pcSpkBits 3
typedef struct
{
SoundCommon common;
byte data[1];
} PCSound;
// Registers for the Sound Blaster card - needs to be offset by n0
#define sbReset 0x206
#define sbReadData 0x20a
#define sbWriteCmd 0x20c
#define sbWriteData 0x20c
#define sbWriteStat 0x20c
#define sbDataAvail 0x20e
typedef struct
{
SoundCommon common;
word hertz;
byte bits,
reference,
data[1];
} SampledSound;
// Registers for the AdLib card
// Operator stuff
#define alChar 0x20
#define alScale 0x40
#define alAttack 0x60
#define alSus 0x80
#define alWave 0xe0
// Channel stuff
#define alFreqL 0xa0
#define alFreqH 0xb0
#define alFeedCon 0xc0
// Global stuff
#define alEffects 0xbd
typedef struct
{
byte mChar,cChar,
mScale,cScale,
mAttack,cAttack,
mSus,cSus,
mWave,cWave,
nConn,
// These are only for Muse - these bytes are really unused
voice,
mode,
unused[3];
} Instrument;
typedef struct
{
SoundCommon common;
Instrument inst;
byte block,
data[1];
} AdLibSound;
//
// Sequencing stuff
//
#define sqMaxTracks 10
#define sqMaxMoods 1 // DEBUG
#define sev_Null 0 // Does nothing
#define sev_NoteOff 1 // Turns a note off
#define sev_NoteOn 2 // Turns a note on
#define sev_NotePitch 3 // Sets the pitch of a currently playing note
#define sev_NewInst 4 // Installs a new instrument
#define sev_NewPerc 5 // Installs a new percussive instrument
#define sev_PercOn 6 // Turns a percussive note on
#define sev_PercOff 7 // Turns a percussive note off
#define sev_SeqEnd -1 // Terminates a sequence
// Flags for MusicGroup.flags
#define sf_Melodic 0
#define sf_Percussive 1
#if 1
typedef struct
{
word length,
values[1];
} MusicGroup;
#else
typedef struct
{
word flags,
count,
offsets[1];
} MusicGroup;
#endif
typedef struct
{
/* This part needs to be set up by the user */
word mood,far *moods[sqMaxMoods];
/* The rest is set up by the code */
Instrument inst;
boolean percussive;
word far *seq;
longword nextevent;
} ActiveTrack;
#define sqmode_Normal 0
#define sqmode_FadeIn 1
#define sqmode_FadeOut 2
#define sqMaxFade 64 // DEBUG
// Global variables
extern boolean AdLibPresent,
NeedsMusic; // For Caching Mgr
extern SDMode SoundMode;
extern SMMode MusicMode;
extern longword TimeCount; // Global time in ticks
// Function prototypes
extern void SD_Startup(void),
SD_Shutdown(void),
SD_Default(boolean gotit,SDMode sd,SMMode sm),
SD_PlaySound(soundnames sound),
SD_StopSound(void),
SD_WaitSoundDone(void),
SD_StartMusic(MusicGroup far *music),
SD_MusicOn(void),
SD_MusicOff(void),
SD_FadeOutMusic(void),
SD_SetUserHook(void (*hook)(void));
extern boolean SD_MusicPlaying(void),
SD_SetSoundMode(SDMode mode),
SD_SetMusicMode(SMMode mode);
extern word SD_SoundPlaying(void);
#ifdef _MUSE_ // MUSE Goes directly to the lower level routines
extern void SDL_PCPlaySound(PCSound far *sound),
SDL_PCStopSound(void),
SDL_ALPlaySound(AdLibSound far *sound),
SDL_ALStopSound(void);
#endif
#endif

128
ID_STRS.H Normal file
View File

@@ -0,0 +1,128 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define S_LOADING "Loading"
#define S_EMPTYSPOT "Empty"
#define S_SVGACOMP "SVGA Compatibility Mode Enabled."
#define S_READYPRESS " Ready - Press a Key "
#define S_NOSFX "NO SOUND EFFECTS"
#define S_PCSPKR "PC SPEAKER"
#define S_ALSB "ADLIB/SOUNDBLASTER"
#define S_QUIET "QUIET ADLIB/SOUNDBLASTER"
#define S_NOMUSIC "NO MUSIC"
#define S_BEGINE "BEGIN EASY GAME"
#define S_BEGINN "BEGIN NORMAL GAME"
#define S_BEGINH "BEGIN HARD GAME"
#define S_UPLEFT "UP & LEFT"
#define S_UP "UP"
#define S_UPRIGHT "UP & RIGHT"
#define S_RIGHT "RIGHT"
#define S_DNRIGHT "DOWN & RIGHT"
#define S_DN "DOWN"
#define S_DNLEFT "DOWN & LEFT"
#define S_LEFT "LEFT"
#define S_JUMP "JUMP"
#define S_POGO "POGO"
#define S_FIRE "FIRE"
#define S_MOVEMENT "MOVEMENT"
#define S_BUTTONS "BUTTONS"
#define S_SOUND "SOUND"
#define S_MUSIC "MUSIC"
#define S_OPTIONS "OPTIONS"
#define S_USEKB "USE KEYBOARD"
#define S_USEJOY1 "USE JOYSTICK #1"
#define S_USEJOY2 "USE JOYSTICK #2"
#define S_NEWGAME "NEW GAME"
#define S_LOADGAME "LOAD GAME"
#define S_SAVEGAME "SAVE GAME"
#define S_CONFIG "CONFIGURE"
#define S_ENDGAME "END GAME"
#define S_PADDLEWAR "PADDLE WAR"
#define S_QUIT "QUIT"
#define S_ESCBACK "ESC TO BACK OUT"
#define S_ESCBACK1 "ESC to back out"
#define S_ESCQUIT "ESC to quit"
#define S_F1HELP "F1 for help"
#define S_REALLYEND "REALLY END CURRENT GAME?"
#define S_PRESSY "PRESS Y TO END IT"
#define S_REALLYQUIT "REALLY QUIT?"
#define S_PRESSYQ "PRESS Y TO QUIT"
#define S_INAGAME "YOU'RE IN A GAME"
#define S_PRESSY2L "PRESS Y TO LOAD GAME"
#define S_PRESSY4N "PRESS Y FOR NEW GAME"
#define S_USLERROR "Error: "
#define S_USLUNKNOWN "Unknown"
#define S_USLDISKFULL "Disk is Full"
#define S_USLFILEINC "File is Incomplete"
#define S_PRESSKEY "PRESS ANY KEY"
#define S_PRESSKEY1 "Press any key"
#define S_SBOXON "SCORE BOX (ON)"
#define S_SBOXOFF "SCORE BOX (OFF)"
#define S_SVGAON "SVGA COMPATIBILITY (ON)"
#define S_SVGAOFF "SVGA COMPATIBILITY (OFF)"
#define S_2BON "TWO-BUTTON FIRING (ON)"
#define S_2BOFF "TWO-BUTTON FIRING (OFF)"
#define S_SBOXNOWON "Score box now on"
#define S_SBOXNOWOFF "Score box now off"
#define S_SVGANOWON "SVGA compatibility now on"
#define S_SVGANOWOFF "SVGA compatibility now off"
#define S_2BNOWON "Two-button firing now on"
#define S_2BNOWOFF "Two-button firing now off"
#define S_KEYBOARD "KEYBOARD"
#define S_JOY1 "JOYSTICK #1"
#define S_JOY2 "JOYSTICK #2"
#define S_MOUSE "MOUSE"
#define S_CONTROL "CONTROL: "
#define S_KEYUSED "Key already used"
#define S_PB1 "and press button #1"
#define S_PB2 "and press button #2"
#define S_MJUL "Move Joystick to upper left"
#define S_MJLR "Move Joystick to lower right"
#define S_USINGJ1 "USING "S_JOY1
#define S_USINGJ2 "USING "S_JOY2
#define S_TYPENAME "Type name"
#define S_ENTERACC "Enter accepts"
#define S_UNTITLED "Untitled"
#define S_SAVING "Saving"
#define S_YOULOST "You lost!"
#define S_YOUWON "You won!"
#define S_ARRMOVE "Arrows move"
#define S_ENTERSEL "Enter selects"
#define S_RETGAME "RETURN TO GAME"
#define S_RETDEMO "RETURN TO DEMO"
#define S_CTRLPANEL "Control Panel"
#define S_QUITTING "Quitting..."
#define S_WHATNAME "What is the name of this creature?"
#define S_SORRY "Sorry, that's not quite right."
#define S_CHECKMAN "Please check your manual and try again."
#define S_BADCARD "Improper video card! If you really have an EGA/VGA card that I am not\n"\
"detecting, use the -HIDDENCARD command line parameter!"
#define S_BADCARD1 "Improper video card! If you really have a CGA card that I am not\n"\
"detecting, use the -HIDDENCARD command line parameter!"

3691
ID_US.C Normal file

File diff suppressed because it is too large Load Diff

147
ID_US.H Normal file
View File

@@ -0,0 +1,147 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//
// ID Engine
// ID_US.h - Header file for the User Manager
// v1.0d1
// By Jason Blochowiak
//
#ifndef __TYPES__
#include "ID_Types.h"
#endif
#ifndef __ID_US__
#define __ID_US__
#ifdef __DEBUG__
#define __DEBUG_UserMgr__
#endif
//#define HELPTEXTLINKED
#define MaxX 320
#define MaxY 200
#define MaxHelpLines 500
#define MaxHighName 57
#define MaxScores 7
typedef struct
{
char name[MaxHighName + 1];
long score;
word completed;
} HighScore;
#define MaxGameName 32
#define MaxSaveGames 6
typedef struct
{
char signature[4];
word *oldtest;
boolean present;
char name[MaxGameName + 1];
} SaveGame;
#define MaxString 128 // Maximum input string size
typedef struct
{
int x,y,
w,h,
px,py;
} WindowRec; // Record used to save & restore screen windows
typedef enum
{
gd_Continue,
gd_Easy,
gd_Normal,
gd_Hard
} GameDiff;
// Hack import for TED launch support
extern boolean tedlevel;
extern word tedlevelnum;
extern void TEDDeath(void);
extern boolean ingame, // Set by game code if a game is in progress
abortgame, // Set if a game load failed
loadedgame, // Set if the current game was loaded
NoWait,
HighScoresDirty;
extern char *abortprogram; // Set to error msg if program is dying
extern GameDiff restartgame; // Normally gd_Continue, else starts game
extern word PrintX,PrintY; // Current printing location in the window
extern word WindowX,WindowY,// Current location of window
WindowW,WindowH;// Current size of window
extern boolean Button0,Button1,
CursorBad;
extern int CursorX,CursorY;
extern void (*USL_MeasureString)(char far *,word *,word *),
(*USL_DrawString)(char far *);
extern boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int);
extern void (*USL_ResetGame)(void);
extern SaveGame Games[MaxSaveGames];
extern HighScore Scores[];
#define US_HomeWindow() {PrintX = WindowX; PrintY = WindowY;}
extern void US_Startup(void),
US_Setup(void),
US_Shutdown(void),
US_InitRndT(boolean randomize),
US_SetLoadSaveHooks(boolean (*load)(int),
boolean (*save)(int),
void (*reset)(void)),
US_TextScreen(void),
US_UpdateTextScreen(void),
US_FinishTextScreen(void),
US_ControlPanel(void),
US_DrawWindow(word x,word y,word w,word h),
US_CenterWindow(word,word),
US_SaveWindow(WindowRec *win),
US_RestoreWindow(WindowRec *win),
US_ClearWindow(void),
US_SetPrintRoutines(void (*measure)(char far *,word *,word *),
void (*print)(char far *)),
US_PrintCentered(char *s),
US_CPrint(char *s),
US_CPrintLine(char *s),
US_Print(char *s),
US_PrintUnsigned(longword n),
US_PrintSigned(long n),
US_StartCursor(void),
US_ShutCursor(void),
US_ControlPanel(void),
US_CheckHighScore(long score,word other),
US_DisplayHighScores(int which);
extern boolean US_UpdateCursor(void),
US_LineInput(int x,int y,char *buf,char *def,boolean escok,
int maxchars,int maxwidth);
extern int US_CheckParm(char *parm,char **strings),
US_RndT(void);
void USL_PrintInCenter(char *s,Rect r);
char *USL_GiveSaveName(word game);
#endif

1285
ID_US_1.C Normal file

File diff suppressed because it is too large Load Diff

1818
ID_US_2.C Normal file

File diff suppressed because it is too large Load Diff

117
ID_US_A.ASM Normal file
View File

@@ -0,0 +1,117 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
IDEAL
MODEL MEDIUM,C
; Assembly portion of the User Mgr. This is just John Carmack's table
; driven pseudo-random number generator, and we put it in the User Mgr
; because we couldn't figure out where it should go
;============================================================================
;
; RANDOM ROUTINES
;
;============================================================================
FARDATA
rndindex dw ?
rndtable db 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66
db 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36
db 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188
db 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224
db 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242
db 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0
db 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235
db 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113
db 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75
db 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196
db 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113
db 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241
db 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224
db 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95
db 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226
db 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36
db 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106
db 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136
db 120, 163, 236, 249
CODESEG
LastRnd dw ?
;=================================================
;
; void US_InitRndT (boolean randomize)
; Init table based RND generator
; if randomize is false, the counter is set to 0
;
;=================================================
PROC US_InitRndT randomize:word
uses si,di
public US_InitRndT
mov ax,SEG rndtable
mov es,ax
mov ax,[randomize]
or ax,ax
jne @@timeit ;if randomize is true, really random
mov dx,0 ;set to a definite value
jmp @@setit
@@timeit:
mov ah,2ch
int 21h ;GetSystemTime
and dx,0ffh
@@setit:
mov [es:rndindex],dx
ret
ENDP
;=================================================
;
; int US_RndT (void)
; Return a random # between 0-255
; Exit : AX = value
;
;=================================================
PROC US_RndT
public US_RndT
mov ax,SEG rndtable
mov es,ax
mov bx,[es:rndindex]
inc bx
and bx,0ffh
mov [es:rndindex],bx
mov al,[es:rndtable+BX]
xor ah,ah
ret
ENDP
END

1541
ID_VW.C Normal file

File diff suppressed because it is too large Load Diff

370
ID_VW.H Normal file
View File

@@ -0,0 +1,370 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// ID_VW.H
#ifndef __TYPES__
#include "ID_TYPES.H"
#endif
#ifndef __ID_MM__
#include "ID_MM.H"
#endif
#ifndef __ID_GLOB__
#include "ID_GLOB.H"
#endif
#define __ID_VW__
//===========================================================================
#define G_P_SHIFT 4 // global >> ?? = pixels
#if GRMODE == EGAGR
#define SCREENWIDTH 40
#define CHARWIDTH 1
#define TILEWIDTH 2
#define GRPLANES 4
#define BYTEPIXELS 8
#endif
#if GRMODE == CGAGR
#define SCREENWIDTH 128
#define CHARWIDTH 2
#define TILEWIDTH 4
#define GRPLANES 1
#define BYTEPIXELS 4
#endif
#define VIRTUALHEIGHT 300
#define VIRTUALWIDTH 512
#if GRMODE == CGAGR
#define MAXSHIFTS 1
#define WHITE 3 // graphics mode independant colors
#define BLACK 0
#define FIRSTCOLOR 1
#define SECONDCOLOR 2
#define F_WHITE 0 // for XOR font drawing
#define F_BLACK 3
#define F_FIRSTCOLOR 2
#define F_SECONDCOLOR 1
#endif
#if GRMODE == EGAGR
#define MAXSHIFTS 4
#define WHITE 15 // graphics mode independant colors
#define BLACK 0
#define FIRSTCOLOR 1
#define SECONDCOLOR 12
#define F_WHITE 0 // for XOR font drawing
#define F_BLACK 15
#define F_FIRSTCOLOR 14
#define F_SECONDCOLOR 3
#endif
#if GRMODE == EGAGR
#define SCREENXMASK (~7)
#define SCREENXPLUS (7)
#define SCREENXDIV (8)
#endif
#if GRMODE == CGAGR
#define SCREENXMASK (~3)
#define SCREENXDIV (4)
#endif
//===========================================================================
#define SC_INDEX 0x3C4
#define SC_RESET 0
#define SC_CLOCK 1
#define SC_MAPMASK 2
#define SC_CHARMAP 3
#define SC_MEMMODE 4
#define CRTC_INDEX 0x3D4
#define CRTC_H_TOTAL 0
#define CRTC_H_DISPEND 1
#define CRTC_H_BLANK 2
#define CRTC_H_ENDBLANK 3
#define CRTC_H_RETRACE 4
#define CRTC_H_ENDRETRACE 5
#define CRTC_V_TOTAL 6
#define CRTC_OVERFLOW 7
#define CRTC_ROWSCAN 8
#define CRTC_MAXSCANLINE 9
#define CRTC_CURSORSTART 10
#define CRTC_CURSOREND 11
#define CRTC_STARTHIGH 12
#define CRTC_STARTLOW 13
#define CRTC_CURSORHIGH 14
#define CRTC_CURSORLOW 15
#define CRTC_V_RETRACE 16
#define CRTC_V_ENDRETRACE 17
#define CRTC_V_DISPEND 18
#define CRTC_OFFSET 19
#define CRTC_UNDERLINE 20
#define CRTC_V_BLANK 21
#define CRTC_V_ENDBLANK 22
#define CRTC_MODE 23
#define CRTC_LINECOMPARE 24
#define GC_INDEX 0x3CE
#define GC_SETRESET 0
#define GC_ENABLESETRESET 1
#define GC_COLORCOMPARE 2
#define GC_DATAROTATE 3
#define GC_READMAP 4
#define GC_MODE 5
#define GC_MISCELLANEOUS 6
#define GC_COLORDONTCARE 7
#define GC_BITMASK 8
#define ATR_INDEX 0x3c0
#define ATR_MODE 16
#define ATR_OVERSCAN 17
#define ATR_COLORPLANEENABLE 18
#define ATR_PELPAN 19
#define ATR_COLORSELECT 20
#define STATUS_REGISTER_1 0x3da
//===========================================================================
typedef enum {NOcard,MDAcard,CGAcard,EGAcard,MCGAcard,VGAcard,
HGCcard=0x80,HGCPcard,HICcard} cardtype;
typedef struct
{
int width,
height,
orgx,orgy,
xl,yl,xh,yh,
shifts;
} spritetabletype;
typedef struct
{
unsigned sourceoffset[MAXSHIFTS];
unsigned planesize[MAXSHIFTS];
unsigned width[MAXSHIFTS];
byte data[];
} spritetype; // the memptr for each sprite points to this
typedef struct
{
int width,height;
} pictabletype;
typedef struct
{
int height;
int location[256];
char width[256];
} fontstruct;
typedef enum {CGAgr,EGAgr,VGAgr} grtype;
//===========================================================================
extern cardtype videocard; // set by VW_Startup
extern grtype grmode; // CGAgr, EGAgr, VGAgr
extern unsigned bufferofs; // hidden port to draw to before displaying
extern unsigned displayofs; // origin of port on visable screen
extern unsigned panx,pany; // panning adjustments inside port in pixels
extern unsigned pansx,pansy;
extern unsigned panadjust; // panx/pany adjusted by screen resolution
extern unsigned screenseg; // normally 0xa000 or buffer segment
extern unsigned linewidth;
extern unsigned ylookup[VIRTUALHEIGHT];
extern boolean screenfaded;
extern char colors[7][17]; // pallets for fades
extern pictabletype _seg *pictable;
extern pictabletype _seg *picmtable;
extern spritetabletype _seg *spritetable;
extern unsigned fontnumber; // 0 based font number for drawing
extern int px,py;
extern byte pdrawmode,fontcolor;
extern int bordercolor;
//
// asm globals
//
extern unsigned *shifttabletable[8];
extern unsigned bufferwidth,bufferheight,screenspot; // used by font drawing stuff
//===========================================================================
void VW_Startup (void);
void VW_Shutdown (void);
cardtype VW_VideoID (void);
//
// EGA hardware routines
//
#define EGAWRITEMODE(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_MODE+256*x;out dx,ax;sti;}
#define EGABITMASK(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_BITMASK+256*x;out dx,ax;sti;}
#define EGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov ax,SC_MAPMASK+x*256;out dx,ax;sti;}
#define EGAREADMAP(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_READMAP+x*256;out dx,ax;sti;}
void VW_SetLineWidth(int width);
void VW_SetSplitScreen(int width);
void VW_SetScreen (unsigned CRTC, unsigned pelpan);
void VW_SetScreenMode (int grmode);
void VW_ClearVideo (int color);
void VW_WaitVBL (int number);
void VW_ColorBorder (int color);
void VW_SetPalette(byte *palette);
void VW_SetDefaultColors(void);
void VW_FadeOut(void);
void VW_FadeIn(void);
void VW_FadeUp(void);
void VW_FadeDown(void);
void VW_SetAtrReg (int reg, int value);
//
// block primitives
//
void VW_MaskBlock(memptr segm,unsigned ofs,unsigned dest,
unsigned wide,unsigned height,unsigned planesize);
void VW_MemToScreen(memptr source,unsigned dest,unsigned width,unsigned height);
void VW_ScreenToMem(unsigned source,memptr dest,unsigned width,unsigned height);
void VW_ScreenToScreen(unsigned source,unsigned dest,unsigned width,unsigned height);
//
// block addressable routines
//
void VW_DrawTile8(unsigned x, unsigned y, unsigned tile);
#if GRMODE == EGAGR
#define VW_DrawTile8M(x,y,t) \
VW_MaskBlock(grsegs[STARTTILE8M],(t)*40,bufferofs+ylookup[y]+(x),1,8,8)
#define VW_DrawTile16(x,y,t) \
VW_MemToScreen(grsegs[STARTTILE16+t],bufferofs+ylookup[y]+(x),2,16)
#define VW_DrawTile16M(x,y,t) \
VW_MaskBlock(grsegs[STARTTILE16M],(t)*160,bufferofs+ylookup[y]+(x),2,16,32)
#endif
#if GRMODE == CGAGR
#define VW_DrawTile8M(x,y,t) \
VW_MaskBlock(grsegs[STARTTILE8M],(t)*32,bufferofs+ylookup[y]+(x),2,8,16)
#define VW_DrawTile16(x,y,t) \
VW_MemToScreen(grsegs[STARTTILE16+t],bufferofs+ylookup[y]+(x),4,16)
#define VW_DrawTile16M(x,y,t) \
VW_MaskBlock(grsegs[STARTTILE16M],(t)*128,bufferofs+ylookup[y]+(x),4,16,64)
#endif
void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum);
void VW_DrawMPic(unsigned x, unsigned y, unsigned chunknum);
void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum);
//
// pixel addressable routines
//
void VW_MeasurePropString (char far *string, word *width, word *height);
void VW_MeasureMPropString (char far *string, word *width, word *height);
void VW_DrawPropString (char far *string);
void VW_DrawMPropString (char far *string);
void VW_DrawSprite(int x, int y, unsigned sprite);
void VW_Plot(unsigned x, unsigned y, unsigned color);
void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color);
void VW_Vlin(unsigned yl, unsigned yh, unsigned x, unsigned color);
void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height,
unsigned color);
//===========================================================================
//
// Double buffer management routines
//
void VW_InitDoubleBuffer (void);
void VW_FixRefreshBuffer (void);
int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2);
void VW_UpdateScreen (void);
void VW_CGAFullUpdate (void);
//
// cursor
//
void VW_ShowCursor (void);
void VW_HideCursor (void);
void VW_MoveCursor (int x, int y);
void VW_SetCursor (int spritenum);
void VW_FreeCursor (void);
//
// mode independant routines
// coordinates in pixels, rounded to best screen res
// regions marked in double buffer
//
void VWB_DrawTile8 (int x, int y, int tile);
void VWB_DrawTile8M (int x, int y, int tile);
void VWB_DrawTile16 (int x, int y, int tile);
void VWB_DrawTile16M (int x, int y, int tile);
void VWB_DrawPic (int x, int y, int chunknum);
void VWB_DrawMPic(int x, int y, int chunknum);
void VWB_Bar (int x, int y, int width, int height, int color);
void VWB_DrawPropString (char far *string);
void VWB_DrawMPropString (char far *string);
void VWB_DrawSprite (int x, int y, int chunknum);
void VWB_Plot (int x, int y, int color);
void VWB_Hlin (int x1, int x2, int y, int color);
void VWB_Vlin (int y1, int y2, int x, int color);
//===========================================================================

732
ID_VW_A.ASM Normal file
View File

@@ -0,0 +1,732 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
; ID_VW_A.ASM
IDEAL
MODEL MEDIUM,C
INCLUDE "ID_ASM.EQU"
WAITFORVBL = 1 ; setting to 0 causes setscreen and waitvbl
; to skip waiting for VBL (for timing things)
;============================================================================
DATASEG
EXTRN screenseg :WORD
EXTRN drawofs :WORD
EXTRN bufferofs :WORD
EXTRN displayofs :WORD
EXTRN drawofs :WORD
EXTRN panadjust :WORD
EXTRN ylookup :WORD
EXTRN linewidth :WORD
EXTRN grsegs :WORD
EXTRN updateptr :WORD
EXTRN blockstarts :WORD ;offsets from drawofs for each update block
EXTRN fontspace :WORD
EXTRN fontnumber :WORD
planemask db ?
planenum db ?
screendest dw ?
linedelta dw ?
LABEL shiftdata0 WORD
dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
dw 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
dw 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41
dw 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55
dw 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69
dw 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83
dw 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
dw 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111
dw 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125
dw 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139
dw 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153
dw 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167
dw 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181
dw 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195
dw 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209
dw 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223
dw 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237
dw 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251
dw 252, 253, 254, 255
LABEL shiftdata1 WORD
dw 0,32768, 1,32769, 2,32770, 3,32771, 4,32772, 5,32773, 6,32774
dw 7,32775, 8,32776, 9,32777, 10,32778, 11,32779, 12,32780, 13,32781
dw 14,32782, 15,32783, 16,32784, 17,32785, 18,32786, 19,32787, 20,32788
dw 21,32789, 22,32790, 23,32791, 24,32792, 25,32793, 26,32794, 27,32795
dw 28,32796, 29,32797, 30,32798, 31,32799, 32,32800, 33,32801, 34,32802
dw 35,32803, 36,32804, 37,32805, 38,32806, 39,32807, 40,32808, 41,32809
dw 42,32810, 43,32811, 44,32812, 45,32813, 46,32814, 47,32815, 48,32816
dw 49,32817, 50,32818, 51,32819, 52,32820, 53,32821, 54,32822, 55,32823
dw 56,32824, 57,32825, 58,32826, 59,32827, 60,32828, 61,32829, 62,32830
dw 63,32831, 64,32832, 65,32833, 66,32834, 67,32835, 68,32836, 69,32837
dw 70,32838, 71,32839, 72,32840, 73,32841, 74,32842, 75,32843, 76,32844
dw 77,32845, 78,32846, 79,32847, 80,32848, 81,32849, 82,32850, 83,32851
dw 84,32852, 85,32853, 86,32854, 87,32855, 88,32856, 89,32857, 90,32858
dw 91,32859, 92,32860, 93,32861, 94,32862, 95,32863, 96,32864, 97,32865
dw 98,32866, 99,32867, 100,32868, 101,32869, 102,32870, 103,32871, 104,32872
dw 105,32873, 106,32874, 107,32875, 108,32876, 109,32877, 110,32878, 111,32879
dw 112,32880, 113,32881, 114,32882, 115,32883, 116,32884, 117,32885, 118,32886
dw 119,32887, 120,32888, 121,32889, 122,32890, 123,32891, 124,32892, 125,32893
dw 126,32894, 127,32895
LABEL shiftdata2 WORD
dw 0,16384,32768,49152, 1,16385,32769,49153, 2,16386,32770,49154, 3,16387
dw 32771,49155, 4,16388,32772,49156, 5,16389,32773,49157, 6,16390,32774,49158
dw 7,16391,32775,49159, 8,16392,32776,49160, 9,16393,32777,49161, 10,16394
dw 32778,49162, 11,16395,32779,49163, 12,16396,32780,49164, 13,16397,32781,49165
dw 14,16398,32782,49166, 15,16399,32783,49167, 16,16400,32784,49168, 17,16401
dw 32785,49169, 18,16402,32786,49170, 19,16403,32787,49171, 20,16404,32788,49172
dw 21,16405,32789,49173, 22,16406,32790,49174, 23,16407,32791,49175, 24,16408
dw 32792,49176, 25,16409,32793,49177, 26,16410,32794,49178, 27,16411,32795,49179
dw 28,16412,32796,49180, 29,16413,32797,49181, 30,16414,32798,49182, 31,16415
dw 32799,49183, 32,16416,32800,49184, 33,16417,32801,49185, 34,16418,32802,49186
dw 35,16419,32803,49187, 36,16420,32804,49188, 37,16421,32805,49189, 38,16422
dw 32806,49190, 39,16423,32807,49191, 40,16424,32808,49192, 41,16425,32809,49193
dw 42,16426,32810,49194, 43,16427,32811,49195, 44,16428,32812,49196, 45,16429
dw 32813,49197, 46,16430,32814,49198, 47,16431,32815,49199, 48,16432,32816,49200
dw 49,16433,32817,49201, 50,16434,32818,49202, 51,16435,32819,49203, 52,16436
dw 32820,49204, 53,16437,32821,49205, 54,16438,32822,49206, 55,16439,32823,49207
dw 56,16440,32824,49208, 57,16441,32825,49209, 58,16442,32826,49210, 59,16443
dw 32827,49211, 60,16444,32828,49212, 61,16445,32829,49213, 62,16446,32830,49214
dw 63,16447,32831,49215
LABEL shiftdata3 WORD
dw 0, 8192,16384,24576,32768,40960,49152,57344, 1, 8193,16385,24577,32769,40961
dw 49153,57345, 2, 8194,16386,24578,32770,40962,49154,57346, 3, 8195,16387,24579
dw 32771,40963,49155,57347, 4, 8196,16388,24580,32772,40964,49156,57348, 5, 8197
dw 16389,24581,32773,40965,49157,57349, 6, 8198,16390,24582,32774,40966,49158,57350
dw 7, 8199,16391,24583,32775,40967,49159,57351, 8, 8200,16392,24584,32776,40968
dw 49160,57352, 9, 8201,16393,24585,32777,40969,49161,57353, 10, 8202,16394,24586
dw 32778,40970,49162,57354, 11, 8203,16395,24587,32779,40971,49163,57355, 12, 8204
dw 16396,24588,32780,40972,49164,57356, 13, 8205,16397,24589,32781,40973,49165,57357
dw 14, 8206,16398,24590,32782,40974,49166,57358, 15, 8207,16399,24591,32783,40975
dw 49167,57359, 16, 8208,16400,24592,32784,40976,49168,57360, 17, 8209,16401,24593
dw 32785,40977,49169,57361, 18, 8210,16402,24594,32786,40978,49170,57362, 19, 8211
dw 16403,24595,32787,40979,49171,57363, 20, 8212,16404,24596,32788,40980,49172,57364
dw 21, 8213,16405,24597,32789,40981,49173,57365, 22, 8214,16406,24598,32790,40982
dw 49174,57366, 23, 8215,16407,24599,32791,40983,49175,57367, 24, 8216,16408,24600
dw 32792,40984,49176,57368, 25, 8217,16409,24601,32793,40985,49177,57369, 26, 8218
dw 16410,24602,32794,40986,49178,57370, 27, 8219,16411,24603,32795,40987,49179,57371
dw 28, 8220,16412,24604,32796,40988,49180,57372, 29, 8221,16413,24605,32797,40989
dw 49181,57373, 30, 8222,16414,24606,32798,40990,49182,57374, 31, 8223,16415,24607
dw 32799,40991,49183,57375
LABEL shiftdata4 WORD
dw 0, 4096, 8192,12288,16384,20480,24576,28672,32768,36864,40960,45056,49152,53248
dw 57344,61440, 1, 4097, 8193,12289,16385,20481,24577,28673,32769,36865,40961,45057
dw 49153,53249,57345,61441, 2, 4098, 8194,12290,16386,20482,24578,28674,32770,36866
dw 40962,45058,49154,53250,57346,61442, 3, 4099, 8195,12291,16387,20483,24579,28675
dw 32771,36867,40963,45059,49155,53251,57347,61443, 4, 4100, 8196,12292,16388,20484
dw 24580,28676,32772,36868,40964,45060,49156,53252,57348,61444, 5, 4101, 8197,12293
dw 16389,20485,24581,28677,32773,36869,40965,45061,49157,53253,57349,61445, 6, 4102
dw 8198,12294,16390,20486,24582,28678,32774,36870,40966,45062,49158,53254,57350,61446
dw 7, 4103, 8199,12295,16391,20487,24583,28679,32775,36871,40967,45063,49159,53255
dw 57351,61447, 8, 4104, 8200,12296,16392,20488,24584,28680,32776,36872,40968,45064
dw 49160,53256,57352,61448, 9, 4105, 8201,12297,16393,20489,24585,28681,32777,36873
dw 40969,45065,49161,53257,57353,61449, 10, 4106, 8202,12298,16394,20490,24586,28682
dw 32778,36874,40970,45066,49162,53258,57354,61450, 11, 4107, 8203,12299,16395,20491
dw 24587,28683,32779,36875,40971,45067,49163,53259,57355,61451, 12, 4108, 8204,12300
dw 16396,20492,24588,28684,32780,36876,40972,45068,49164,53260,57356,61452, 13, 4109
dw 8205,12301,16397,20493,24589,28685,32781,36877,40973,45069,49165,53261,57357,61453
dw 14, 4110, 8206,12302,16398,20494,24590,28686,32782,36878,40974,45070,49166,53262
dw 57358,61454, 15, 4111, 8207,12303,16399,20495,24591,28687,32783,36879,40975,45071
dw 49167,53263,57359,61455
LABEL shiftdata5 WORD
dw 0, 2048, 4096, 6144, 8192,10240,12288,14336,16384,18432,20480,22528,24576,26624
dw 28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152,51200,53248,55296
dw 57344,59392,61440,63488, 1, 2049, 4097, 6145, 8193,10241,12289,14337,16385,18433
dw 20481,22529,24577,26625,28673,30721,32769,34817,36865,38913,40961,43009,45057,47105
dw 49153,51201,53249,55297,57345,59393,61441,63489, 2, 2050, 4098, 6146, 8194,10242
dw 12290,14338,16386,18434,20482,22530,24578,26626,28674,30722,32770,34818,36866,38914
dw 40962,43010,45058,47106,49154,51202,53250,55298,57346,59394,61442,63490, 3, 2051
dw 4099, 6147, 8195,10243,12291,14339,16387,18435,20483,22531,24579,26627,28675,30723
dw 32771,34819,36867,38915,40963,43011,45059,47107,49155,51203,53251,55299,57347,59395
dw 61443,63491, 4, 2052, 4100, 6148, 8196,10244,12292,14340,16388,18436,20484,22532
dw 24580,26628,28676,30724,32772,34820,36868,38916,40964,43012,45060,47108,49156,51204
dw 53252,55300,57348,59396,61444,63492, 5, 2053, 4101, 6149, 8197,10245,12293,14341
dw 16389,18437,20485,22533,24581,26629,28677,30725,32773,34821,36869,38917,40965,43013
dw 45061,47109,49157,51205,53253,55301,57349,59397,61445,63493, 6, 2054, 4102, 6150
dw 8198,10246,12294,14342,16390,18438,20486,22534,24582,26630,28678,30726,32774,34822
dw 36870,38918,40966,43014,45062,47110,49158,51206,53254,55302,57350,59398,61446,63494
dw 7, 2055, 4103, 6151, 8199,10247,12295,14343,16391,18439,20487,22535,24583,26631
dw 28679,30727,32775,34823,36871,38919,40967,43015,45063,47111,49159,51207,53255,55303
dw 57351,59399,61447,63495
LABEL shiftdata6 WORD
dw 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,10240,11264,12288,13312
dw 14336,15360,16384,17408,18432,19456,20480,21504,22528,23552,24576,25600,26624,27648
dw 28672,29696,30720,31744,32768,33792,34816,35840,36864,37888,38912,39936,40960,41984
dw 43008,44032,45056,46080,47104,48128,49152,50176,51200,52224,53248,54272,55296,56320
dw 57344,58368,59392,60416,61440,62464,63488,64512, 1, 1025, 2049, 3073, 4097, 5121
dw 6145, 7169, 8193, 9217,10241,11265,12289,13313,14337,15361,16385,17409,18433,19457
dw 20481,21505,22529,23553,24577,25601,26625,27649,28673,29697,30721,31745,32769,33793
dw 34817,35841,36865,37889,38913,39937,40961,41985,43009,44033,45057,46081,47105,48129
dw 49153,50177,51201,52225,53249,54273,55297,56321,57345,58369,59393,60417,61441,62465
dw 63489,64513, 2, 1026, 2050, 3074, 4098, 5122, 6146, 7170, 8194, 9218,10242,11266
dw 12290,13314,14338,15362,16386,17410,18434,19458,20482,21506,22530,23554,24578,25602
dw 26626,27650,28674,29698,30722,31746,32770,33794,34818,35842,36866,37890,38914,39938
dw 40962,41986,43010,44034,45058,46082,47106,48130,49154,50178,51202,52226,53250,54274
dw 55298,56322,57346,58370,59394,60418,61442,62466,63490,64514, 3, 1027, 2051, 3075
dw 4099, 5123, 6147, 7171, 8195, 9219,10243,11267,12291,13315,14339,15363,16387,17411
dw 18435,19459,20483,21507,22531,23555,24579,25603,26627,27651,28675,29699,30723,31747
dw 32771,33795,34819,35843,36867,37891,38915,39939,40963,41987,43011,44035,45059,46083
dw 47107,48131,49155,50179,51203,52227,53251,54275,55299,56323,57347,58371,59395,60419
dw 61443,62467,63491,64515
LABEL shiftdata7 WORD
dw 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656
dw 7168, 7680, 8192, 8704, 9216, 9728,10240,10752,11264,11776,12288,12800,13312,13824
dw 14336,14848,15360,15872,16384,16896,17408,17920,18432,18944,19456,19968,20480,20992
dw 21504,22016,22528,23040,23552,24064,24576,25088,25600,26112,26624,27136,27648,28160
dw 28672,29184,29696,30208,30720,31232,31744,32256,32768,33280,33792,34304,34816,35328
dw 35840,36352,36864,37376,37888,38400,38912,39424,39936,40448,40960,41472,41984,42496
dw 43008,43520,44032,44544,45056,45568,46080,46592,47104,47616,48128,48640,49152,49664
dw 50176,50688,51200,51712,52224,52736,53248,53760,54272,54784,55296,55808,56320,56832
dw 57344,57856,58368,58880,59392,59904,60416,60928,61440,61952,62464,62976,63488,64000
dw 64512,65024, 1, 513, 1025, 1537, 2049, 2561, 3073, 3585, 4097, 4609, 5121, 5633
dw 6145, 6657, 7169, 7681, 8193, 8705, 9217, 9729,10241,10753,11265,11777,12289,12801
dw 13313,13825,14337,14849,15361,15873,16385,16897,17409,17921,18433,18945,19457,19969
dw 20481,20993,21505,22017,22529,23041,23553,24065,24577,25089,25601,26113,26625,27137
dw 27649,28161,28673,29185,29697,30209,30721,31233,31745,32257,32769,33281,33793,34305
dw 34817,35329,35841,36353,36865,37377,37889,38401,38913,39425,39937,40449,40961,41473
dw 41985,42497,43009,43521,44033,44545,45057,45569,46081,46593,47105,47617,48129,48641
dw 49153,49665,50177,50689,51201,51713,52225,52737,53249,53761,54273,54785,55297,55809
dw 56321,56833,57345,57857,58369,58881,59393,59905,60417,60929,61441,61953,62465,62977
dw 63489,64001,64513,65025
shifttabletable dw shiftdata0,shiftdata1,shiftdata2,shiftdata3
dw shiftdata4,shiftdata5,shiftdata6,shiftdata7
PUBLIC shifttabletable
;============================================================================
CODESEG
IFE GRMODE-CGAGR
INCLUDE "ID_VW_AC.ASM"
ENDIF
IFE GRMODE-EGAGR
INCLUDE "ID_VW_AE.ASM"
ENDIF
IFE GRMODE-VGAGR
INCLUDE "ID_VW_AV.ASM"
ENDIF
;============================================================================
;
; MISC VIDEO ROUTINES
;
;============================================================================
;========
;
; VW_WaitVBL (int number)
;
;========
PROC VW_WaitVBL number:WORD
PUBLIC VW_WaitVBL
if WAITFORVBL ; skip wait if profiling
mov dx,STATUS_REGISTER_1
mov cx,[number]
waitvbl1:
in al,dx
test al,00001000b ;look for vbl
jnz waitvbl1
waitvbl2:
in al,dx
test al,00001000b ;look for vbl
jz waitvbl2
loop waitvbl1
endif
ret
ENDP
;===========================================================================
MASM
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;
; Name: VW_VideoID
;
; Function: Detects the presence of various video subsystems
;
; int VideoID;
;
; Subsystem ID values:
; 0 = (none)
; 1 = MDA
; 2 = CGA
; 3 = EGA
; 4 = MCGA
; 5 = VGA
; 80h = HGC
; 81h = HGC+
; 82h = Hercules InColor
;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;
; Equates
;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
VIDstruct STRUC ; corresponds to C data structure
Video0Type DB ? ; first subsystem type
Display0Type DB ? ; display attached to first subsystem
Video1Type DB ? ; second subsystem type
Display1Type DB ? ; display attached to second subsystem
VIDstruct ENDS
Device0 EQU word ptr Video0Type[di]
Device1 EQU word ptr Video1Type[di]
MDA EQU 1 ; subsystem types
CGA EQU 2
EGA EQU 3
MCGA EQU 4
VGA EQU 5
HGC EQU 80h
HGCPlus EQU 81h
InColor EQU 82h
MDADisplay EQU 1 ; display types
CGADisplay EQU 2
EGAColorDisplay EQU 3
PS2MonoDisplay EQU 4
PS2ColorDisplay EQU 5
TRUE EQU 1
FALSE EQU 0
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;
; Program
;
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Results VIDstruct <> ;results go here!
EGADisplays DB CGADisplay ; 0000b, 0001b (EGA switch values)
DB EGAColorDisplay ; 0010b, 0011b
DB MDADisplay ; 0100b, 0101b
DB CGADisplay ; 0110b, 0111b
DB EGAColorDisplay ; 1000b, 1001b
DB MDADisplay ; 1010b, 1011b
DCCtable DB 0,0 ; translate table for INT 10h func 1Ah
DB MDA,MDADisplay
DB CGA,CGADisplay
DB 0,0
DB EGA,EGAColorDisplay
DB EGA,MDADisplay
DB 0,0
DB VGA,PS2MonoDisplay
DB VGA,PS2ColorDisplay
DB 0,0
DB MCGA,EGAColorDisplay
DB MCGA,PS2MonoDisplay
DB MCGA,PS2ColorDisplay
TestSequence DB TRUE ; this list of flags and addresses
DW FindPS2 ; determines the order in which this
; program looks for the various
EGAflag DB ? ; subsystems
DW FindEGA
CGAflag DB ?
DW FindCGA
Monoflag DB ?
DW FindMono
NumberOfTests EQU ($-TestSequence)/3
PUBLIC VW_VideoID
VW_VideoID PROC
push bp ; preserve caller registers
mov bp,sp
push ds
push si
push di
push cs
pop ds
ASSUME DS:@Code
; initialize the data structure that will contain the results
lea di,Results ; DS:DI -> start of data structure
mov Device0,0 ; zero these variables
mov Device1,0
; look for the various subsystems using the subroutines whose addresses are
; tabulated in TestSequence; each subroutine sets flags in TestSequence
; to indicate whether subsequent subroutines need to be called
mov byte ptr CGAflag,TRUE
mov byte ptr EGAflag,TRUE
mov byte ptr Monoflag,TRUE
mov cx,NumberOfTests
mov si,offset TestSequence
@@L01: lodsb ; AL := flag
test al,al
lodsw ; AX := subroutine address
jz @@L02 ; skip subroutine if flag is false
push si
push cx
call ax ; call subroutine to detect subsystem
pop cx
pop si
@@L02: loop @@L01
; determine which subsystem is active
call FindActive
mov al,Results.Video0Type
mov ah,0 ; was: Results.Display0Type
pop di ; restore caller registers and return
pop si
pop ds
mov sp,bp
pop bp
ret
VW_VideoID ENDP
;
; FindPS2
;
; This subroutine uses INT 10H function 1Ah to determine the video BIOS
; Display Combination Code (DCC) for each video subsystem present.
;
FindPS2 PROC near
mov ax,1A00h
int 10h ; call video BIOS for info
cmp al,1Ah
jne @@L13 ; exit if function not supported (i.e.,
; no MCGA or VGA in system)
; convert BIOS DCCs into specific subsystems & displays
mov cx,bx
xor bh,bh ; BX := DCC for active subsystem
or ch,ch
jz @@L11 ; jump if only one subsystem present
mov bl,ch ; BX := inactive DCC
add bx,bx
mov ax,[bx+offset DCCtable]
mov Device1,ax
mov bl,cl
xor bh,bh ; BX := active DCC
@@L11: add bx,bx
mov ax,[bx+offset DCCtable]
mov Device0,ax
; reset flags for subsystems that have been ruled out
mov byte ptr CGAflag,FALSE
mov byte ptr EGAflag,FALSE
mov byte ptr Monoflag,FALSE
lea bx,Video0Type[di] ; if the BIOS reported an MDA ...
cmp byte ptr [bx],MDA
je @@L12
lea bx,Video1Type[di]
cmp byte ptr [bx],MDA
jne @@L13
@@L12: mov word ptr [bx],0 ; ... Hercules can't be ruled out
mov byte ptr Monoflag,TRUE
@@L13: ret
FindPS2 ENDP
;
; FindEGA
;
; Look for an EGA. This is done by making a call to an EGA BIOS function
; which doesn't exist in the default (MDA, CGA) BIOS.
FindEGA PROC near ; Caller: AH = flags
; Returns: AH = flags
; Video0Type and
; Display0Type updated
mov bl,10h ; BL := 10h (return EGA info)
mov ah,12h ; AH := INT 10H function number
int 10h ; call EGA BIOS for info
; if EGA BIOS is present,
; BL <> 10H
; CL = switch setting
cmp bl,10h
je @@L22 ; jump if EGA BIOS not present
mov al,cl
shr al,1 ; AL := switches/2
mov bx,offset EGADisplays
xlat ; determine display type from switches
mov ah,al ; AH := display type
mov al,EGA ; AL := subystem type
call FoundDevice
cmp ah,MDADisplay
je @@L21 ; jump if EGA has a monochrome display
mov CGAflag,FALSE ; no CGA if EGA has color display
jmp short @@L22
@@L21: mov Monoflag,FALSE ; EGA has a mono display, so MDA and
; Hercules are ruled out
@@L22: ret
FindEGA ENDP
;
; FindCGA
;
; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
;
FindCGA PROC near ; Returns: VIDstruct updated
mov dx,3D4h ; DX := CRTC address port
call Find6845
jc @@L31 ; jump if not present
mov al,CGA
mov ah,CGADisplay
call FoundDevice
@@L31: ret
FindCGA ENDP
;
; FindMono
;
; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H. If
; a 6845 is found, the subroutine distinguishes between an MDA
; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
; This bit changes on Hercules adapters but does not change on an MDA.
;
; The various Hercules adapters are identified by bits 4 through 6 of
; the CRT Status value:
;
; 000b = HGC
; 001b = HGC+
; 101b = InColor card
;
FindMono PROC near ; Returns: VIDstruct updated
mov dx,3B4h ; DX := CRTC address port
call Find6845
jc @@L44 ; jump if not present
mov dl,0BAh ; DX := 3BAh (status port)
in al,dx
and al,80h
mov ah,al ; AH := bit 7 (vertical sync on HGC)
mov cx,8000h ; do this 32768 times
@@L41: in al,dx
and al,80h ; isolate bit 7
cmp ah,al
loope @@L41 ; wait for bit 7 to change
jne @@L42 ; if bit 7 changed, it's a Hercules
mov al,MDA ; if bit 7 didn't change, it's an MDA
mov ah,MDADisplay
call FoundDevice
jmp short @@L44
@@L42: in al,dx
mov dl,al ; DL := value from status port
and dl,01110000b ; mask bits 4 thru 6
mov ah,MDADisplay ; assume it's a monochrome display
mov al,HGCPlus ; look for an HGC+
cmp dl,00010000b
je @@L43 ; jump if it's an HGC+
mov al,HGC ; look for an InColor card or HGC
cmp dl,01010000b
jne @@L43 ; jump if it's not an InColor card
mov al,InColor ; it's an InColor card
mov ah,EGAColorDisplay
@@L43: call FoundDevice
@@L44: ret
FindMono ENDP
;
; Find6845
;
; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
; The technique is to write and read register 0Fh of the chip (cursor
; low). If the same value is read as written, assume the chip is
; present at the specified port addr.
;
Find6845 PROC near ; Caller: DX = port addr
; Returns: cf set if not present
mov al,0Fh
out dx,al ; select 6845 reg 0Fh (Cursor Low)
inc dx
in al,dx ; AL := current Cursor Low value
mov ah,al ; preserve in AH
mov al,66h ; AL := arbitrary value
out dx,al ; try to write to 6845
mov cx,100h
@@L51: loop @@L51 ; wait for 6845 to respond
in al,dx
xchg ah,al ; AH := returned value
; AL := original value
out dx,al ; restore original value
cmp ah,66h ; test whether 6845 responded
je @@L52 ; jump if it did (cf is reset)
stc ; set carry flag if no 6845 present
@@L52: ret
Find6845 ENDP
;
; FindActive
;
; This subroutine stores the currently active device as Device0. The
; current video mode determines which subsystem is active.
;
FindActive PROC near
cmp word ptr Device1,0
je @@L63 ; exit if only one subsystem
cmp Video0Type[di],4 ; exit if MCGA or VGA present
jge @@L63 ; (INT 10H function 1AH
cmp Video1Type[di],4 ; already did the work)
jge @@L63
mov ah,0Fh
int 10h ; AL := current BIOS video mode
and al,7
cmp al,7 ; jump if monochrome
je @@L61 ; (mode 7 or 0Fh)
cmp Display0Type[di],MDADisplay
jne @@L63 ; exit if Display0 is color
jmp short @@L62
@@L61: cmp Display0Type[di],MDADisplay
je @@L63 ; exit if Display0 is monochrome
@@L62: mov ax,Device0 ; make Device0 currently active
xchg ax,Device1
mov Device0,ax
@@L63: ret
FindActive ENDP
;
; FoundDevice
;
; This routine updates the list of subsystems.
;
FoundDevice PROC near ; Caller: AH = display #
; AL = subsystem #
; Destroys: BX
lea bx,Video0Type[di]
cmp byte ptr [bx],0
je @@L71 ; jump if 1st subsystem
lea bx,Video1Type[di] ; must be 2nd subsystem
@@L71: mov [bx],ax ; update list entry
ret
FoundDevice ENDP
IDEAL
END

1485
ID_VW_AC.ASM Normal file

File diff suppressed because it is too large Load Diff

1752
ID_VW_AE.ASM Normal file

File diff suppressed because it is too large Load Diff

BIN
INTROSCN.OBJ Normal file

Binary file not shown.

115
JABHACK.ASM Normal file
View File

@@ -0,0 +1,115 @@
; Catacomb 3-D Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License along
; with this program; if not, write to the Free Software Foundation, Inc.,
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
; JABHACK.ASM
.386C
IDEAL
MODEL MEDIUM
EXTRN LDIV@:far
;============================================================================
DATASEG
EXTRN _intaddr:word
;============================================================================
CODESEG
; Hacked up Juan Jimenez's code a bit to just return 386/not 386
PROC _CheckIs386
PUBLIC _CheckIs386
pushf ; Save flag registers, we use them here
xor ax,ax ; Clear AX and...
push ax ; ...push it onto the stack
popf ; Pop 0 into flag registers (all bits to 0),
pushf ; attempting to set bits 12-15 of flags to 0's
pop ax ; Recover the save flags
and ax,08000h ; If bits 12-15 of flags are set to
cmp ax,08000h ; zero then it's 8088/86 or 80188/186
jz not386
mov ax,07000h ; Try to set flag bits 12-14 to 1's
push ax ; Push the test value onto the stack
popf ; Pop it into the flag register
pushf ; Push it back onto the stack
pop ax ; Pop it into AX for check
and ax,07000h ; if bits 12-14 are cleared then
jz not386 ; the chip is an 80286
mov ax,1 ; We now assume it's a 80386 or better
popf
retf
not386:
xor ax,ax
popf
retf
ENDP
PROC _jabhack2
PUBLIC _jabhack2
jmp @@skip
@@where:
int 060h
retf
@@skip:
push es
mov ax,seg LDIV@
mov es,ax
mov ax,[WORD PTR @@where]
mov [WORD FAR es:LDIV@],ax
mov ax,[WORD PTR @@where+2]
mov [WORD FAR es:LDIV@+2],ax
mov ax,offset @@jabdiv
mov [_intaddr],ax
mov ax,seg @@jabdiv
mov [_intaddr+2],ax
pop es
retf
@@jabdiv:
add sp,4 ;Nuke IRET address, but leave flags
push bp
mov bp,sp ;Save BP, and set it equal to stack
cli
mov eax,[bp+8]
cdq
idiv [DWORD PTR bp+12]
mov edx,eax
shr edx,16
pop bp ;Restore BP
popf ;Restore flags (from INT)
retf 8 ;Return to original caller
ENDP
END

55
MAPSC3D.H Normal file
View File

@@ -0,0 +1,55 @@
/* Catacomb 3-D Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
///////////////////////////////////////
//
// TED5 Map Header for C3D
//
///////////////////////////////////////
//
// Map Names
//
typedef enum {
APPROACH_MAP, // 0
ENTRANCE_MAP, // 1
GROUND_FLOOR_MAP, // 2
SECOND_FLOOR_MAP, // 3
THIRD_FLOOR_MAP, // 4
TOWER_1_MAP, // 5
TOWER_2_MAP, // 6
SECRET_HALLS_MAP, // 7
ACCESS_FLOOR_MAP, // 8
DUNGEON_MAP, // 9
LOWER_DUNGEON_MAP, // 10
CATACOMB_MAP, // 11
LOWER_REACHES_MAP, // 12
WARRENS_MAP, // 13
HIDDEN_CAVERNS_MAP, // 14
FENSOFINSANITY_MAP, // 15
CHAOSCORRIDORS_MAP, // 16
LABYRINTH_MAP, // 17
HALLS_OF_BLOOD_MAP, // 18
NEMESISSLAIR_MAP, // 19
LASTMAP
} mapnames;
//
// TILEINFO offsets
//
#define ANIM 402

42
NOTES.TXT Normal file
View File

@@ -0,0 +1,42 @@
589: No mention of Id software has been removed. I thought this was
cleared up last project. I am proud of CAT3D, and I would have a problem
with the removal of credit to the development team.
591: The version number is on the intro screen
592: The new piracy screen is in
660: The map view is a debugging tool, not a feature.
682,694,695: The hang is fixed. Whenever a monster had no viable move it
went into a loop (the trolls were all added at the last minute). Good
catch.
697: The graphic screw up was fixed by adding two blocks to the map
Everything else: The single lines are a result of roundoff error between
two transformations. When a wall segment disapears it is a result of a
back trace hitting a side that should by invisable. The objects showing up
through walls is a result of the z buffer being kept in pixels (a poor
design decision). Not mentioned by you: The thick bar shown when you look
almost straight down a long wall is a result of the tangent table maxing out
in 16 bits, causing the texture mapping to think it can optimize the wall
drawing. The fish eye view when you turn right next to a wall is a result of
not having enough compiled scaler routines (memory constraints) to scale
thinks closer than the view plane. These problems are understood, but the
corrective measures are not really feasable. I think CAT3D still stands well
even with these warts. Over the past several days I have developed a ray
tracing/intersecting 3-D refresh to replace the image based system from
CAT3D, and it has addressed all of these problems. I would put it in CAT3D
except for: it uses 286 specific code in a few places, but no big deal
to replace. It is designed to work with a demand paged graphics caching
system, still no big deal. I am unsure of its memory requirements,
potentially a terminal problem. I haven't tested it with scaled sprites
yet, this would require one or two additional days.
If gamer's edge ever gets an ok to do a hard drive installable game you will
probably see the new system.
John Carmack

13
README.md Normal file
View File

@@ -0,0 +1,13 @@
Catacomb 3-D: The Descent
=========================
This repository contains the source code for Catacomb 3-D (also known as
Catacombs 3 or Catacomb 3-D: A New Dimension). The source code is designed for
Borland C++ 2.0, but compiled fine with Borland C++ 3.1 at the time of this
release.
It is released under the GNU GPLv2. Please see COPYING for license details.
This release does not affect the licensing for the game data files. You will
need to legally acquire the game data in order to use the exe built from this
source code.