├── CAT3D.PRJ ├── ID_VW_A.ASM ├── C3DADICT.OBJ ├── C3DAHEAD.OBJ ├── C3DEDICT.OBJ ├── C3DEHEAD.OBJ ├── C3DMHEAD.OBJ ├── INTROSCN.OBJ ├── README.md ├── MAPSC3D.H ├── NOTES.TXT ├── ID_ASM.EQU ├── AUDIOC3D.H ├── JABHACK.ASM ├── ID_MM.H ├── ID_HEADS.H ├── C3_SCA_A.ASM ├── ID_CA.H ├── ID_US_A.ASM ├── ID_US.H ├── ID_STRS.H ├── ID_RF.H ├── ID_SD.H ├── C3_ASM.ASM ├── ID_IN.H ├── GFXE_C3D.EQU ├── ID_VW.H ├── GFXE_C3D.H ├── C3_STATE.C ├── C3_DEBUG.C ├── C3_PLAY.C ├── C3_DEF.H ├── ID_RF_A.ASM ├── C3_MAIN.C ├── C3_SCALE.C └── COPYING /CAT3D.PRJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/CAT3D.PRJ -------------------------------------------------------------------------------- /ID_VW_A.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/ID_VW_A.ASM -------------------------------------------------------------------------------- /C3DADICT.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/C3DADICT.OBJ -------------------------------------------------------------------------------- /C3DAHEAD.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/C3DAHEAD.OBJ -------------------------------------------------------------------------------- /C3DEDICT.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/C3DEDICT.OBJ -------------------------------------------------------------------------------- /C3DEHEAD.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/C3DEHEAD.OBJ -------------------------------------------------------------------------------- /C3DMHEAD.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/C3DMHEAD.OBJ -------------------------------------------------------------------------------- /INTROSCN.OBJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatacombGames/Catacomb3D/HEAD/INTROSCN.OBJ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Catacomb 3-D: The Descent 2 | ========================= 3 | 4 | This repository contains the source code for Catacomb 3-D (also known as 5 | Catacombs 3 or Catacomb 3-D: A New Dimension). The source code is designed for 6 | Borland C++ 2.0, but compiled fine with Borland C++ 3.1 at the time of this 7 | release. 8 | 9 | It is released under the GNU GPLv2. Please see COPYING for license details. 10 | 11 | This release does not affect the licensing for the game data files. You will 12 | need to legally acquire the game data in order to use the exe built from this 13 | source code. 14 | -------------------------------------------------------------------------------- /MAPSC3D.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | /////////////////////////////////////// 20 | // 21 | // TED5 Map Header for C3D 22 | // 23 | /////////////////////////////////////// 24 | 25 | // 26 | // Map Names 27 | // 28 | typedef enum { 29 | APPROACH_MAP, // 0 30 | ENTRANCE_MAP, // 1 31 | GROUND_FLOOR_MAP, // 2 32 | SECOND_FLOOR_MAP, // 3 33 | THIRD_FLOOR_MAP, // 4 34 | TOWER_1_MAP, // 5 35 | TOWER_2_MAP, // 6 36 | SECRET_HALLS_MAP, // 7 37 | ACCESS_FLOOR_MAP, // 8 38 | DUNGEON_MAP, // 9 39 | LOWER_DUNGEON_MAP, // 10 40 | CATACOMB_MAP, // 11 41 | LOWER_REACHES_MAP, // 12 42 | WARRENS_MAP, // 13 43 | HIDDEN_CAVERNS_MAP, // 14 44 | FENSOFINSANITY_MAP, // 15 45 | CHAOSCORRIDORS_MAP, // 16 46 | LABYRINTH_MAP, // 17 47 | HALLS_OF_BLOOD_MAP, // 18 48 | NEMESISSLAIR_MAP, // 19 49 | LASTMAP 50 | } mapnames; 51 | 52 | // 53 | // TILEINFO offsets 54 | // 55 | #define ANIM 402 56 | -------------------------------------------------------------------------------- /NOTES.TXT: -------------------------------------------------------------------------------- 1 | 589: No mention of Id software has been removed. I thought this was 2 | cleared up last project. I am proud of CAT3D, and I would have a problem 3 | with the removal of credit to the development team. 4 | 5 | 591: The version number is on the intro screen 6 | 7 | 592: The new piracy screen is in 8 | 9 | 660: The map view is a debugging tool, not a feature. 10 | 11 | 682,694,695: The hang is fixed. Whenever a monster had no viable move it 12 | went into a loop (the trolls were all added at the last minute). Good 13 | catch. 14 | 15 | 697: The graphic screw up was fixed by adding two blocks to the map 16 | 17 | Everything else: The single lines are a result of roundoff error between 18 | two transformations. When a wall segment disapears it is a result of a 19 | back trace hitting a side that should by invisable. The objects showing up 20 | through walls is a result of the z buffer being kept in pixels (a poor 21 | design decision). Not mentioned by you: The thick bar shown when you look 22 | almost straight down a long wall is a result of the tangent table maxing out 23 | in 16 bits, causing the texture mapping to think it can optimize the wall 24 | drawing. The fish eye view when you turn right next to a wall is a result of 25 | not having enough compiled scaler routines (memory constraints) to scale 26 | thinks closer than the view plane. These problems are understood, but the 27 | corrective measures are not really feasable. I think CAT3D still stands well 28 | even with these warts. Over the past several days I have developed a ray 29 | tracing/intersecting 3-D refresh to replace the image based system from 30 | CAT3D, and it has addressed all of these problems. I would put it in CAT3D 31 | except for: it uses 286 specific code in a few places, but no big deal 32 | to replace. It is designed to work with a demand paged graphics caching 33 | system, still no big deal. I am unsure of its memory requirements, 34 | potentially a terminal problem. I haven't tested it with scaled sprites 35 | yet, this would require one or two additional days. 36 | 37 | If gamer's edge ever gets an ok to do a hard drive installable game you will 38 | probably see the new system. 39 | 40 | 41 | John Carmack 42 | 43 | -------------------------------------------------------------------------------- /ID_ASM.EQU: -------------------------------------------------------------------------------- 1 | ; 2 | ; Equates for all .ASM files 3 | ; 4 | 5 | ;---------------------------------------------------------------------------- 6 | 7 | INCLUDE "GFXE_C3D.EQU" 8 | 9 | ;---------------------------------------------------------------------------- 10 | 11 | CGAGR = 1 12 | EGAGR = 2 13 | VGAGR = 3 14 | 15 | GRMODE = EGAGR 16 | PROFILE = 0 ; 1=keep stats on tile drawing 17 | 18 | SC_INDEX = 03C4h 19 | SC_RESET = 0 20 | SC_CLOCK = 1 21 | SC_MAPMASK = 2 22 | SC_CHARMAP = 3 23 | SC_MEMMODE = 4 24 | 25 | CRTC_INDEX = 03D4h 26 | CRTC_H_TOTAL = 0 27 | CRTC_H_DISPEND = 1 28 | CRTC_H_BLANK = 2 29 | CRTC_H_ENDBLANK = 3 30 | CRTC_H_RETRACE = 4 31 | CRTC_H_ENDRETRACE = 5 32 | CRTC_V_TOTAL = 6 33 | CRTC_OVERFLOW = 7 34 | CRTC_ROWSCAN = 8 35 | CRTC_MAXSCANLINE = 9 36 | CRTC_CURSORSTART = 10 37 | CRTC_CURSOREND = 11 38 | CRTC_STARTHIGH = 12 39 | CRTC_STARTLOW = 13 40 | CRTC_CURSORHIGH = 14 41 | CRTC_CURSORLOW = 15 42 | CRTC_V_RETRACE = 16 43 | CRTC_V_ENDRETRACE = 17 44 | CRTC_V_DISPEND = 18 45 | CRTC_OFFSET = 19 46 | CRTC_UNDERLINE = 20 47 | CRTC_V_BLANK = 21 48 | CRTC_V_ENDBLANK = 22 49 | CRTC_MODE = 23 50 | CRTC_LINECOMPARE = 24 51 | 52 | 53 | GC_INDEX = 03CEh 54 | GC_SETRESET = 0 55 | GC_ENABLESETRESET = 1 56 | GC_COLORCOMPARE = 2 57 | GC_DATAROTATE = 3 58 | GC_READMAP = 4 59 | GC_MODE = 5 60 | GC_MISCELLANEOUS = 6 61 | GC_COLORDONTCARE = 7 62 | GC_BITMASK = 8 63 | 64 | ATR_INDEX = 03c0h 65 | ATR_MODE = 16 66 | ATR_OVERSCAN = 17 67 | ATR_COLORPLANEENABLE = 18 68 | ATR_PELPAN = 19 69 | ATR_COLORSELECT = 20 70 | 71 | STATUS_REGISTER_1 = 03dah 72 | 73 | 74 | MACRO WORDOUT 75 | out dx,ax 76 | ENDM 77 | 78 | if 0 79 | 80 | MACRO WORDOUT 81 | out dx,al 82 | inc dx 83 | xchg al,ah 84 | out dx,al 85 | dec dx 86 | xchg al,ah 87 | ENDM 88 | 89 | endif 90 | 91 | UPDATEWIDE = 22 92 | UPDATEHIGH = 13 ; hack for catacombs 93 | 94 | ; 95 | ; tile info offsets from segment tinf 96 | ; 97 | 98 | SPEED = 402 99 | ANIM = (SPEED+NUMTILE16) 100 | 101 | NORTHWALL = (ANIM+NUMTILE16) 102 | EASTWALL = (NORTHWALL+NUMTILE16M) 103 | SOUTHWALL = (EASTWALL+NUMTILE16M) 104 | WESTWALL = (SOUTHWALL+NUMTILE16M) 105 | MANIM = (WESTWALL+NUMTILE16M) 106 | INTILE = (MANIM+NUMTILE16M) 107 | MSPEED = (INTILE+NUMTILE16M) 108 | 109 | IFE GRMODE-EGAGR 110 | SCREENWIDTH = 40 111 | ENDIF 112 | IFE GRMODE-CGAGR 113 | SCREENWIDTH = 128 114 | ENDIF 115 | -------------------------------------------------------------------------------- /AUDIOC3D.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | ///////////////////////////////////////////////// 20 | // 21 | // MUSE Header for .C3D 22 | // Created Wed Oct 30 22:44:13 1991 23 | // 24 | ///////////////////////////////////////////////// 25 | 26 | #define NUMSOUNDS 30 27 | #define NUMSNDCHUNKS 91 28 | 29 | // 30 | // Sound names & indexes 31 | // 32 | typedef enum { 33 | HITWALLSND, // 0 34 | WARPUPSND, // 1 35 | WARPDOWNSND, // 2 36 | GETBOLTSND, // 3 37 | GETNUKESND, // 4 38 | GETPOTIONSND, // 5 39 | GETKEYSND, // 6 40 | GETSCROLLSND, // 7 41 | GETPOINTSSND, // 8 42 | USEBOLTSND, // 9 43 | USENUKESND, // 10 44 | USEPOTIONSND, // 11 45 | USEKEYSND, // 12 46 | NOITEMSND, // 13 47 | WALK1SND, // 14 48 | WALK2SND, // 15 49 | TAKEDAMAGESND, // 16 50 | MONSTERMISSSND, // 17 51 | GAMEOVERSND, // 18 52 | SHOOTSND, // 19 53 | BIGSHOOTSND, // 20 54 | SHOOTWALLSND, // 21 55 | SHOOTMONSTERSND, // 22 56 | TAKEDMGHURTSND, // 23 57 | BALLBOUNCESND, // 24 58 | COMPSCOREDSND, // 25 59 | KEENSCOREDSND, // 26 60 | COMPPADDLESND, // 27 61 | KEENPADDLESND, // 28 62 | NOWAYSND, // 29 63 | LASTSOUND 64 | } soundnames; 65 | 66 | // 67 | // Base offsets 68 | // 69 | #define STARTPCSOUNDS 0 70 | #define STARTADLIBSOUNDS 30 71 | #define STARTDIGISOUNDS 60 72 | #define STARTMUSIC 90 73 | 74 | // 75 | // Music names & indexes 76 | // 77 | typedef enum { 78 | TOOHOT_MUS, // 0 79 | LASTMUSIC 80 | } musicnames; 81 | 82 | ///////////////////////////////////////////////// 83 | // 84 | // Thanks for playing with MUSE! 85 | // 86 | ///////////////////////////////////////////////// 87 | -------------------------------------------------------------------------------- /JABHACK.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | ; JABHACK.ASM 19 | 20 | .386C 21 | IDEAL 22 | MODEL MEDIUM 23 | 24 | EXTRN LDIV@:far 25 | 26 | ;============================================================================ 27 | 28 | DATASEG 29 | 30 | EXTRN _intaddr:word 31 | 32 | ;============================================================================ 33 | 34 | CODESEG 35 | 36 | ; Hacked up Juan Jimenez's code a bit to just return 386/not 386 37 | PROC _CheckIs386 38 | PUBLIC _CheckIs386 39 | 40 | pushf ; Save flag registers, we use them here 41 | xor ax,ax ; Clear AX and... 42 | push ax ; ...push it onto the stack 43 | popf ; Pop 0 into flag registers (all bits to 0), 44 | pushf ; attempting to set bits 12-15 of flags to 0's 45 | pop ax ; Recover the save flags 46 | and ax,08000h ; If bits 12-15 of flags are set to 47 | cmp ax,08000h ; zero then it's 8088/86 or 80188/186 48 | jz not386 49 | 50 | mov ax,07000h ; Try to set flag bits 12-14 to 1's 51 | push ax ; Push the test value onto the stack 52 | popf ; Pop it into the flag register 53 | pushf ; Push it back onto the stack 54 | pop ax ; Pop it into AX for check 55 | and ax,07000h ; if bits 12-14 are cleared then 56 | jz not386 ; the chip is an 80286 57 | 58 | mov ax,1 ; We now assume it's a 80386 or better 59 | popf 60 | retf 61 | 62 | not386: 63 | xor ax,ax 64 | popf 65 | retf 66 | 67 | ENDP 68 | 69 | 70 | PROC _jabhack2 71 | PUBLIC _jabhack2 72 | 73 | jmp @@skip 74 | 75 | @@where: 76 | int 060h 77 | retf 78 | 79 | @@skip: 80 | push es 81 | 82 | mov ax,seg LDIV@ 83 | mov es,ax 84 | mov ax,[WORD PTR @@where] 85 | mov [WORD FAR es:LDIV@],ax 86 | mov ax,[WORD PTR @@where+2] 87 | mov [WORD FAR es:LDIV@+2],ax 88 | 89 | mov ax,offset @@jabdiv 90 | mov [_intaddr],ax 91 | mov ax,seg @@jabdiv 92 | mov [_intaddr+2],ax 93 | 94 | pop es 95 | retf 96 | 97 | @@jabdiv: 98 | add sp,4 ;Nuke IRET address, but leave flags 99 | push bp 100 | mov bp,sp ;Save BP, and set it equal to stack 101 | cli 102 | 103 | mov eax,[bp+8] 104 | cdq 105 | idiv [DWORD PTR bp+12] 106 | mov edx,eax 107 | shr edx,16 108 | 109 | pop bp ;Restore BP 110 | popf ;Restore flags (from INT) 111 | retf 8 ;Return to original caller 112 | 113 | ENDP 114 | 115 | END 116 | -------------------------------------------------------------------------------- /ID_MM.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // ID_MM.H 20 | 21 | #ifndef __ID_CA__ 22 | 23 | #define __ID_CA__ 24 | 25 | #define SAVENEARHEAP 0x400 // space to leave in data segment 26 | #define SAVEFARHEAP 0 // space to leave in far heap 27 | 28 | #define BUFFERSIZE 0x1000 // miscelanious, allways available buffer 29 | 30 | #define MAXBLOCKS 600 31 | 32 | 33 | //-------- 34 | 35 | #define EMS_INT 0x67 36 | 37 | #define EMS_STATUS 0x40 38 | #define EMS_GETFRAME 0x41 39 | #define EMS_GETPAGES 0x42 40 | #define EMS_ALLOCPAGES 0x43 41 | #define EMS_MAPPAGE 0x44 42 | #define EMS_FREEPAGES 0x45 43 | #define EMS_VERSION 0x46 44 | 45 | //-------- 46 | 47 | #define XMS_VERSION 0x00 48 | 49 | #define XMS_ALLOCHMA 0x01 50 | #define XMS_FREEHMA 0x02 51 | 52 | #define XMS_GENABLEA20 0x03 53 | #define XMS_GDISABLEA20 0x04 54 | #define XMS_LENABLEA20 0x05 55 | #define XMS_LDISABLEA20 0x06 56 | #define XMS_QUERYA20 0x07 57 | 58 | #define XMS_QUERYREE 0x08 59 | #define XMS_ALLOC 0x09 60 | #define XMS_FREE 0x0A 61 | #define XMS_MOVE 0x0B 62 | #define XMS_LOCK 0x0C 63 | #define XMS_UNLOCK 0x0D 64 | #define XMS_GETINFO 0x0E 65 | #define XMS_RESIZE 0x0F 66 | 67 | #define XMS_ALLOCUMB 0x10 68 | #define XMS_FREEUMB 0x11 69 | 70 | //========================================================================== 71 | 72 | typedef void _seg * memptr; 73 | 74 | typedef struct 75 | { 76 | long nearheap,farheap,EMSmem,XMSmem,mainmem; 77 | } mminfotype; 78 | 79 | //========================================================================== 80 | 81 | extern mminfotype mminfo; 82 | extern memptr bufferseg; 83 | extern boolean mmerror; 84 | 85 | extern void (* beforesort) (void); 86 | extern void (* aftersort) (void); 87 | 88 | //========================================================================== 89 | 90 | void MM_Startup (void); 91 | void MM_Shutdown (void); 92 | void MM_MapEMS (void); 93 | 94 | void MM_GetPtr (memptr *baseptr,unsigned long size); 95 | void MM_FreePtr (memptr *baseptr); 96 | 97 | void MM_SetPurge (memptr *baseptr, int purge); 98 | void MM_SetLock (memptr *baseptr, boolean locked); 99 | void MM_SortMem (void); 100 | 101 | void MM_ShowMemory (void); 102 | 103 | long MM_UnusedMemory (void); 104 | long MM_TotalFree (void); 105 | 106 | void MM_BombOnError (boolean bomb); 107 | 108 | #endif -------------------------------------------------------------------------------- /ID_HEADS.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // ID_GLOB.H 20 | 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #define __ID_GLOB__ 36 | 37 | //-------------------------------------------------------------------------- 38 | 39 | #define EXTENSION "C3D" 40 | 41 | extern char far introscn; 42 | 43 | #include "GFXE_C3D.H" 44 | #include "AUDIOC3D.H" 45 | 46 | //-------------------------------------------------------------------------- 47 | 48 | #define CAT3D 49 | 50 | #define TEXTGR 0 51 | #define CGAGR 1 52 | #define EGAGR 2 53 | #define VGAGR 3 54 | 55 | #define GRMODE EGAGR 56 | 57 | #if GRMODE == EGAGR 58 | #define GREXT "EGA" 59 | #endif 60 | #if GRMODE == CGAGR 61 | #define GREXT "CGA" 62 | #endif 63 | 64 | //#define PROFILE 65 | 66 | // 67 | // ID Engine 68 | // Types.h - Generic types, #defines, etc. 69 | // v1.0d1 70 | // 71 | 72 | #ifndef __TYPES__ 73 | #define __TYPES__ 74 | 75 | typedef enum {false,true} boolean; 76 | typedef unsigned char byte; 77 | typedef unsigned int word; 78 | typedef unsigned long longword; 79 | typedef byte * Ptr; 80 | 81 | typedef struct 82 | { 83 | int x,y; 84 | } Point; 85 | typedef struct 86 | { 87 | Point ul,lr; 88 | } Rect; 89 | 90 | #define nil ((void *)0) 91 | 92 | #endif 93 | 94 | #include "ID_MM.H" 95 | #include "ID_CA.H" 96 | #include "ID_VW.H" 97 | #include "ID_IN.H" 98 | #include "ID_SD.H" 99 | #include "ID_US.H" 100 | 101 | 102 | void Quit (char *error); // defined in user program 103 | 104 | // 105 | // replacing refresh manager with custom routines 106 | // 107 | 108 | #define PORTTILESWIDE 21 // all drawing takes place inside a 109 | #define PORTTILESHIGH 14 // non displayed port of this size 110 | 111 | #define UPDATEWIDE (PORTTILESWIDE+1) 112 | #define UPDATEHIGH PORTTILESHIGH 113 | 114 | #define MAXTICS 6 115 | #define DEMOTICS 3 116 | 117 | #define UPDATETERMINATE 0x0301 118 | 119 | extern unsigned mapwidth,mapheight,tics; 120 | extern boolean compatability; 121 | 122 | extern byte *updateptr; 123 | extern unsigned uwidthtable[UPDATEHIGH]; 124 | extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH]; 125 | -------------------------------------------------------------------------------- /C3_SCA_A.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | IDEAL 19 | MODEL MEDIUM,C 20 | 21 | include "ID_ASM.EQU" 22 | 23 | ;=========================================================================== 24 | ; 25 | ; SCALING GRAPHICS 26 | ; 27 | ;=========================================================================== 28 | 29 | 30 | 31 | MACRO MAKELAB NUM 32 | 33 | lab&NUM: 34 | 35 | ENDM 36 | 37 | MACRO MAKEREF NUM 38 | 39 | dw OFFSET lab&NUM 40 | 41 | ENDM 42 | 43 | 44 | ;========================================================================= 45 | 46 | MAXSCALES equ 256 47 | 48 | DATASEG 49 | 50 | EXTRN screenseg:WORD 51 | EXTRN linewidth:WORD 52 | 53 | LABEL endtable WORD 54 | labcount = 0 55 | REPT MAXSCALES 56 | MAKEREF %labcount 57 | labcount = labcount + 1 58 | ENDM 59 | 60 | 61 | CODESEG 62 | 63 | ;================================================== 64 | ; 65 | ; void scaleline (int scale, unsigned picseg, unsigned maskseg, 66 | ; unsigned screen, unsigned width) 67 | ; 68 | ;================================================== 69 | 70 | PROC ScaleLine pixels:word, scaleptr:dword, picptr:dword, screen:word 71 | USES si,di 72 | PUBLIC ScaleLine 73 | 74 | ; 75 | ; modify doline procedure for proper width 76 | ; 77 | mov bx,[pixels] 78 | cmp bx,MAXSCALES 79 | jbe @@scaleok 80 | mov bx,MAXSCALES 81 | @@scaleok: 82 | shl bx,1 83 | mov bx,[endtable+bx] 84 | push [cs:bx] ;save the code that will be modified over 85 | mov [WORD cs:bx],0d18eh ;mov ss,cx 86 | push [cs:bx+2] ;save the code that will be modified over 87 | mov [WORD cs:bx+2],90c3h ;ret / nop 88 | push bx 89 | 90 | mov dx,[linewidth] 91 | 92 | mov di,[WORD screen] 93 | mov es,[screenseg] 94 | 95 | mov si,[WORD scaleptr] 96 | mov ds,[WORD scaleptr+2] 97 | 98 | mov bx,[WORD picptr] 99 | mov ax,[WORD picptr+2] ;will be moved into ss after call 100 | 101 | mov bp,bx 102 | 103 | cli 104 | call doline 105 | sti 106 | ; 107 | ; restore doline to regular state 108 | ; 109 | pop bx ;address of modified code 110 | pop [cs:bx+2] 111 | pop [cs:bx] 112 | 113 | mov ax,ss 114 | mov ds,ax 115 | ret 116 | 117 | ;================ 118 | ; 119 | ; doline 120 | ; 121 | ; Big unwound scaling routine 122 | ; 123 | ; ds:si = scale table 124 | ; ss:bx = pic data 125 | ; es:di = screen location 126 | ; 127 | ;================ 128 | 129 | doline: 130 | 131 | mov cx,ss 132 | mov ss,ax ;can't call a routine with ss used... 133 | 134 | labcount = 0 135 | 136 | REPT MAXSCALES 137 | 138 | MAKELAB %labcount 139 | labcount = labcount + 1 140 | 141 | lodsb ; get scaled pixel number 142 | xlat [ss:bx] ; look it up in the picture 143 | xchg [es:di],al ; load latches and write pixel to screen 144 | add di,dx ; down to next line 145 | 146 | ENDM 147 | 148 | mov ss,cx 149 | ret 150 | 151 | ENDP 152 | 153 | END -------------------------------------------------------------------------------- /ID_CA.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // ID_CA.H 20 | 21 | #ifndef __TYPES__ 22 | #include "ID_TYPES.H" 23 | #endif 24 | 25 | #ifndef __ID_MM__ 26 | #include "ID_MM.H" 27 | #endif 28 | 29 | #ifndef __ID_GLOB__ 30 | #include "ID_GLOB.H" 31 | #endif 32 | 33 | #define __ID_CA__ 34 | 35 | //=========================================================================== 36 | 37 | //#define NOMAPS 38 | //#define NOGRAPHICS 39 | //#define NOAUDIO 40 | 41 | #define MAPHEADERLINKED 42 | #define GRHEADERLINKED 43 | #define AUDIOHEADERLINKED 44 | 45 | #define NUMMAPS 30 46 | #define MAPPLANES 3 47 | 48 | //=========================================================================== 49 | 50 | typedef struct 51 | { 52 | long planestart[3]; 53 | unsigned planelength[3]; 54 | unsigned width,height; 55 | char name[16]; 56 | } maptype; 57 | 58 | //=========================================================================== 59 | 60 | extern byte _seg *tinf; 61 | extern int mapon; 62 | 63 | extern unsigned _seg *mapsegs[3]; 64 | extern maptype _seg *mapheaderseg[NUMMAPS]; 65 | extern byte _seg *audiosegs[NUMSNDCHUNKS]; 66 | extern void _seg *grsegs[NUMCHUNKS]; 67 | 68 | extern byte far grneeded[NUMCHUNKS]; 69 | extern byte ca_levelbit,ca_levelnum; 70 | 71 | extern char *titleptr[8]; 72 | 73 | extern int profilehandle,debughandle; 74 | 75 | // 76 | // hooks for custom cache dialogs 77 | // 78 | extern void (*drawcachebox) (char *title, unsigned numcache); 79 | extern void (*updatecachebox) (void); 80 | extern void (*finishcachebox) (void); 81 | 82 | //=========================================================================== 83 | 84 | // just for the score box reshifting 85 | 86 | void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest, 87 | unsigned width, unsigned height, unsigned pixshift); 88 | 89 | //=========================================================================== 90 | 91 | void CA_OpenDebug (void); 92 | void CA_CloseDebug (void); 93 | boolean CA_FarRead (int handle, byte far *dest, long length); 94 | boolean CA_FarWrite (int handle, byte far *source, long length); 95 | boolean CA_ReadFile (char *filename, memptr *ptr); 96 | boolean CA_LoadFile (char *filename, memptr *ptr); 97 | 98 | long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest, 99 | unsigned rlewtag); 100 | 101 | void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length, 102 | unsigned rlewtag); 103 | 104 | void CA_Startup (void); 105 | void CA_Shutdown (void); 106 | 107 | void CA_CacheAudioChunk (int chunk); 108 | void CA_LoadAllSounds (void); 109 | 110 | void CA_UpLevel (void); 111 | void CA_DownLevel (void); 112 | 113 | void CA_SetAllPurge (void); 114 | 115 | void CA_ClearMarks (void); 116 | void CA_ClearAllMarks (void); 117 | 118 | #define CA_MarkGrChunk(chunk) grneeded[chunk]|=ca_levelbit 119 | 120 | void CA_CacheGrChunk (int chunk); 121 | void CA_CacheMap (int mapnum); 122 | 123 | void CA_CacheMarks (char *title); 124 | 125 | -------------------------------------------------------------------------------- /ID_US_A.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | IDEAL 19 | MODEL MEDIUM,C 20 | 21 | ; Assembly portion of the User Mgr. This is just John Carmack's table 22 | ; driven pseudo-random number generator, and we put it in the User Mgr 23 | ; because we couldn't figure out where it should go 24 | 25 | 26 | ;============================================================================ 27 | ; 28 | ; RANDOM ROUTINES 29 | ; 30 | ;============================================================================ 31 | 32 | FARDATA 33 | 34 | rndindex dw ? 35 | 36 | rndtable db 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66 37 | db 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36 38 | db 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188 39 | db 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224 40 | db 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242 41 | db 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0 42 | db 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235 43 | db 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113 44 | db 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75 45 | db 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196 46 | db 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113 47 | db 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241 48 | db 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224 49 | db 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95 50 | db 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226 51 | db 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36 52 | db 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106 53 | db 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136 54 | db 120, 163, 236, 249 55 | 56 | 57 | CODESEG 58 | 59 | LastRnd dw ? 60 | 61 | ;================================================= 62 | ; 63 | ; void US_InitRndT (boolean randomize) 64 | ; Init table based RND generator 65 | ; if randomize is false, the counter is set to 0 66 | ; 67 | ;================================================= 68 | 69 | PROC US_InitRndT randomize:word 70 | uses si,di 71 | public US_InitRndT 72 | 73 | mov ax,SEG rndtable 74 | mov es,ax 75 | mov ax,[randomize] 76 | or ax,ax 77 | jne @@timeit ;if randomize is true, really random 78 | 79 | mov dx,0 ;set to a definite value 80 | jmp @@setit 81 | 82 | @@timeit: 83 | mov ah,2ch 84 | int 21h ;GetSystemTime 85 | and dx,0ffh 86 | 87 | @@setit: 88 | mov [es:rndindex],dx 89 | ret 90 | 91 | ENDP 92 | 93 | ;================================================= 94 | ; 95 | ; int US_RndT (void) 96 | ; Return a random # between 0-255 97 | ; Exit : AX = value 98 | ; 99 | ;================================================= 100 | PROC US_RndT 101 | public US_RndT 102 | 103 | mov ax,SEG rndtable 104 | mov es,ax 105 | mov bx,[es:rndindex] 106 | inc bx 107 | and bx,0ffh 108 | mov [es:rndindex],bx 109 | mov al,[es:rndtable+BX] 110 | xor ah,ah 111 | 112 | ret 113 | 114 | ENDP 115 | 116 | END 117 | 118 | -------------------------------------------------------------------------------- /ID_US.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // 20 | // ID Engine 21 | // ID_US.h - Header file for the User Manager 22 | // v1.0d1 23 | // By Jason Blochowiak 24 | // 25 | 26 | #ifndef __TYPES__ 27 | #include "ID_Types.h" 28 | #endif 29 | 30 | #ifndef __ID_US__ 31 | #define __ID_US__ 32 | 33 | #ifdef __DEBUG__ 34 | #define __DEBUG_UserMgr__ 35 | #endif 36 | 37 | //#define HELPTEXTLINKED 38 | 39 | #define MaxX 320 40 | #define MaxY 200 41 | 42 | #define MaxHelpLines 500 43 | 44 | #define MaxHighName 57 45 | #define MaxScores 7 46 | typedef struct 47 | { 48 | char name[MaxHighName + 1]; 49 | long score; 50 | word completed; 51 | } HighScore; 52 | 53 | #define MaxGameName 32 54 | #define MaxSaveGames 6 55 | typedef struct 56 | { 57 | char signature[4]; 58 | word *oldtest; 59 | boolean present; 60 | char name[MaxGameName + 1]; 61 | } SaveGame; 62 | 63 | #define MaxString 128 // Maximum input string size 64 | 65 | typedef struct 66 | { 67 | int x,y, 68 | w,h, 69 | px,py; 70 | } WindowRec; // Record used to save & restore screen windows 71 | 72 | typedef enum 73 | { 74 | gd_Continue, 75 | gd_Easy, 76 | gd_Normal, 77 | gd_Hard 78 | } GameDiff; 79 | 80 | // Hack import for TED launch support 81 | extern boolean tedlevel; 82 | extern word tedlevelnum; 83 | extern void TEDDeath(void); 84 | 85 | extern boolean ingame, // Set by game code if a game is in progress 86 | abortgame, // Set if a game load failed 87 | loadedgame, // Set if the current game was loaded 88 | NoWait, 89 | HighScoresDirty; 90 | extern char *abortprogram; // Set to error msg if program is dying 91 | extern GameDiff restartgame; // Normally gd_Continue, else starts game 92 | extern word PrintX,PrintY; // Current printing location in the window 93 | extern word WindowX,WindowY,// Current location of window 94 | WindowW,WindowH;// Current size of window 95 | 96 | extern boolean Button0,Button1, 97 | CursorBad; 98 | extern int CursorX,CursorY; 99 | 100 | extern void (*USL_MeasureString)(char far *,word *,word *), 101 | (*USL_DrawString)(char far *); 102 | 103 | extern boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int); 104 | extern void (*USL_ResetGame)(void); 105 | extern SaveGame Games[MaxSaveGames]; 106 | extern HighScore Scores[]; 107 | 108 | #define US_HomeWindow() {PrintX = WindowX; PrintY = WindowY;} 109 | 110 | extern void US_Startup(void), 111 | US_Setup(void), 112 | US_Shutdown(void), 113 | US_InitRndT(boolean randomize), 114 | US_SetLoadSaveHooks(boolean (*load)(int), 115 | boolean (*save)(int), 116 | void (*reset)(void)), 117 | US_TextScreen(void), 118 | US_UpdateTextScreen(void), 119 | US_FinishTextScreen(void), 120 | US_ControlPanel(void), 121 | US_DrawWindow(word x,word y,word w,word h), 122 | US_CenterWindow(word,word), 123 | US_SaveWindow(WindowRec *win), 124 | US_RestoreWindow(WindowRec *win), 125 | US_ClearWindow(void), 126 | US_SetPrintRoutines(void (*measure)(char far *,word *,word *), 127 | void (*print)(char far *)), 128 | US_PrintCentered(char *s), 129 | US_CPrint(char *s), 130 | US_CPrintLine(char *s), 131 | US_Print(char *s), 132 | US_PrintUnsigned(longword n), 133 | US_PrintSigned(long n), 134 | US_StartCursor(void), 135 | US_ShutCursor(void), 136 | US_ControlPanel(void), 137 | US_CheckHighScore(long score,word other), 138 | US_DisplayHighScores(int which); 139 | extern boolean US_UpdateCursor(void), 140 | US_LineInput(int x,int y,char *buf,char *def,boolean escok, 141 | int maxchars,int maxwidth); 142 | extern int US_CheckParm(char *parm,char **strings), 143 | US_RndT(void); 144 | 145 | void USL_PrintInCenter(char *s,Rect r); 146 | char *USL_GiveSaveName(word game); 147 | #endif 148 | -------------------------------------------------------------------------------- /ID_STRS.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #define S_LOADING "Loading" 20 | #define S_EMPTYSPOT "Empty" 21 | #define S_SVGACOMP "SVGA Compatibility Mode Enabled." 22 | #define S_READYPRESS " Ready - Press a Key " 23 | #define S_NOSFX "NO SOUND EFFECTS" 24 | #define S_PCSPKR "PC SPEAKER" 25 | #define S_ALSB "ADLIB/SOUNDBLASTER" 26 | #define S_QUIET "QUIET ADLIB/SOUNDBLASTER" 27 | #define S_NOMUSIC "NO MUSIC" 28 | #define S_BEGINE "BEGIN EASY GAME" 29 | #define S_BEGINN "BEGIN NORMAL GAME" 30 | #define S_BEGINH "BEGIN HARD GAME" 31 | #define S_UPLEFT "UP & LEFT" 32 | #define S_UP "UP" 33 | #define S_UPRIGHT "UP & RIGHT" 34 | #define S_RIGHT "RIGHT" 35 | #define S_DNRIGHT "DOWN & RIGHT" 36 | #define S_DN "DOWN" 37 | #define S_DNLEFT "DOWN & LEFT" 38 | #define S_LEFT "LEFT" 39 | 40 | #define S_JUMP "JUMP" 41 | #define S_POGO "POGO" 42 | #define S_FIRE "FIRE" 43 | #define S_MOVEMENT "MOVEMENT" 44 | #define S_BUTTONS "BUTTONS" 45 | 46 | #define S_SOUND "SOUND" 47 | #define S_MUSIC "MUSIC" 48 | #define S_OPTIONS "OPTIONS" 49 | #define S_USEKB "USE KEYBOARD" 50 | #define S_USEJOY1 "USE JOYSTICK #1" 51 | #define S_USEJOY2 "USE JOYSTICK #2" 52 | #define S_NEWGAME "NEW GAME" 53 | #define S_LOADGAME "LOAD GAME" 54 | #define S_SAVEGAME "SAVE GAME" 55 | #define S_CONFIG "CONFIGURE" 56 | #define S_ENDGAME "END GAME" 57 | #define S_PADDLEWAR "PADDLE WAR" 58 | #define S_QUIT "QUIT" 59 | 60 | #define S_ESCBACK "ESC TO BACK OUT" 61 | #define S_ESCBACK1 "ESC to back out" 62 | #define S_ESCQUIT "ESC to quit" 63 | #define S_F1HELP "F1 for help" 64 | #define S_REALLYEND "REALLY END CURRENT GAME?" 65 | #define S_PRESSY "PRESS Y TO END IT" 66 | #define S_REALLYQUIT "REALLY QUIT?" 67 | #define S_PRESSYQ "PRESS Y TO QUIT" 68 | #define S_INAGAME "YOU'RE IN A GAME" 69 | #define S_PRESSY2L "PRESS Y TO LOAD GAME" 70 | #define S_PRESSY4N "PRESS Y FOR NEW GAME" 71 | 72 | #define S_USLERROR "Error: " 73 | #define S_USLUNKNOWN "Unknown" 74 | #define S_USLDISKFULL "Disk is Full" 75 | #define S_USLFILEINC "File is Incomplete" 76 | #define S_PRESSKEY "PRESS ANY KEY" 77 | #define S_PRESSKEY1 "Press any key" 78 | 79 | #define S_SBOXON "SCORE BOX (ON)" 80 | #define S_SBOXOFF "SCORE BOX (OFF)" 81 | #define S_SVGAON "SVGA COMPATIBILITY (ON)" 82 | #define S_SVGAOFF "SVGA COMPATIBILITY (OFF)" 83 | #define S_2BON "TWO-BUTTON FIRING (ON)" 84 | #define S_2BOFF "TWO-BUTTON FIRING (OFF)" 85 | 86 | #define S_SBOXNOWON "Score box now on" 87 | #define S_SBOXNOWOFF "Score box now off" 88 | #define S_SVGANOWON "SVGA compatibility now on" 89 | #define S_SVGANOWOFF "SVGA compatibility now off" 90 | #define S_2BNOWON "Two-button firing now on" 91 | #define S_2BNOWOFF "Two-button firing now off" 92 | 93 | #define S_KEYBOARD "KEYBOARD" 94 | #define S_JOY1 "JOYSTICK #1" 95 | #define S_JOY2 "JOYSTICK #2" 96 | #define S_MOUSE "MOUSE" 97 | #define S_CONTROL "CONTROL: " 98 | #define S_KEYUSED "Key already used" 99 | #define S_PB1 "and press button #1" 100 | #define S_PB2 "and press button #2" 101 | #define S_MJUL "Move Joystick to upper left" 102 | #define S_MJLR "Move Joystick to lower right" 103 | 104 | #define S_USINGJ1 "USING "S_JOY1 105 | #define S_USINGJ2 "USING "S_JOY2 106 | #define S_TYPENAME "Type name" 107 | #define S_ENTERACC "Enter accepts" 108 | #define S_UNTITLED "Untitled" 109 | #define S_SAVING "Saving" 110 | #define S_YOULOST "You lost!" 111 | #define S_YOUWON "You won!" 112 | #define S_ARRMOVE "Arrows move" 113 | #define S_ENTERSEL "Enter selects" 114 | 115 | #define S_RETGAME "RETURN TO GAME" 116 | #define S_RETDEMO "RETURN TO DEMO" 117 | #define S_CTRLPANEL "Control Panel" 118 | #define S_QUITTING "Quitting..." 119 | 120 | #define S_WHATNAME "What is the name of this creature?" 121 | #define S_SORRY "Sorry, that's not quite right." 122 | #define S_CHECKMAN "Please check your manual and try again." 123 | 124 | #define S_BADCARD "Improper video card! If you really have an EGA/VGA card that I am not\n"\ 125 | "detecting, use the -HIDDENCARD command line parameter!" 126 | #define S_BADCARD1 "Improper video card! If you really have a CGA card that I am not\n"\ 127 | "detecting, use the -HIDDENCARD command line parameter!" 128 | 129 | -------------------------------------------------------------------------------- /ID_RF.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // ID_RF.H 20 | 21 | #define __ID_RF__ 22 | 23 | #ifndef __ID_MM__ 24 | #include "ID_MM.H" 25 | #endif 26 | 27 | /* 28 | ============================================================================= 29 | 30 | CONSTANTS 31 | 32 | ============================================================================= 33 | */ 34 | 35 | #define MINTICS 2 36 | #define MAXTICS 6 37 | #define DEMOTICS 3 38 | 39 | #define MAPBORDER 2 // map border must be at least 1 40 | 41 | #define MAXSPRITES 50 // max tracked sprites 42 | #define MAXANIMTILES 90 // max animating tiles on screen 43 | #define MAXANIMTYPES 50 // max different unique anim tiles on map 44 | 45 | #define MAXMAPHEIGHT 200 46 | 47 | #define PRIORITIES 4 48 | #define MASKEDTILEPRIORITY 3 // planes go: 0,1,2,MTILES,3 49 | 50 | #define TILEGLOBAL 256 51 | #define PIXGLOBAL 16 52 | 53 | #define G_T_SHIFT 8 // global >> ?? = tile 54 | #define G_P_SHIFT 4 // global >> ?? = pixels 55 | #define P_T_SHIFT 4 // pixels >> ?? = tile 56 | 57 | #define PORTTILESWIDE 21 // all drawing takes place inside a 58 | #define PORTTILESHIGH 14 // non displayed port of this size 59 | 60 | //#define PORTGLOBALWIDE (21*TILEGLOBAL) 61 | //#define PORTGLOBALHIGH (14*TILEGLOBAL) 62 | 63 | #define UPDATEWIDE (PORTTILESWIDE+1) 64 | #define UPDATEHIGH PORTTILESHIGH 65 | 66 | 67 | //=========================================================================== 68 | 69 | typedef enum {spritedraw,maskdraw} drawtype; 70 | 71 | /* 72 | ============================================================================= 73 | 74 | PUBLIC VARIABLES 75 | 76 | ============================================================================= 77 | */ 78 | 79 | 80 | extern boolean compatability; // crippled refresh for wierdo SVGAs 81 | 82 | extern unsigned tics; 83 | extern long lasttimecount; 84 | 85 | extern unsigned originxglobal,originyglobal; 86 | extern unsigned originxtile,originytile; 87 | extern unsigned originxscreen,originyscreen; 88 | 89 | extern unsigned mapwidth,mapheight,mapbyteswide,mapwordswide 90 | ,mapbytesextra,mapwordsextra; 91 | extern unsigned mapbwidthtable[MAXMAPHEIGHT]; 92 | 93 | extern unsigned originxmin,originxmax,originymin,originymax; 94 | 95 | extern unsigned masterofs; 96 | 97 | // 98 | // the floating update window is also used by the view manager for 99 | // double buffer tracking 100 | // 101 | 102 | extern byte *updateptr; // current start of update window 103 | 104 | #if GRMODE == CGAGR 105 | extern byte *baseupdateptr; 106 | #endif 107 | 108 | extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH]; 109 | extern unsigned updatemapofs[UPDATEWIDE*UPDATEHIGH]; 110 | extern unsigned uwidthtable[UPDATEHIGH]; // lookup instead of multiple 111 | 112 | #define UPDATETERMINATE 0x0301 113 | 114 | /* 115 | ============================================================================= 116 | 117 | PUBLIC FUNCTIONS 118 | 119 | ============================================================================= 120 | */ 121 | 122 | void RF_Startup (void); 123 | void RF_Shutdown (void); 124 | 125 | void RF_FixOfs (void); 126 | void RF_NewMap (void); 127 | void RF_MarkTileGraphics (void); 128 | void RF_SetScrollBlock (int x, int y, boolean horizontal); 129 | void RF_NewPosition (unsigned x, unsigned y); 130 | void RF_Scroll (int x, int y); 131 | 132 | void RF_MapToMap (unsigned srcx, unsigned srcy, 133 | unsigned destx, unsigned desty, 134 | unsigned width, unsigned height); 135 | void RF_MemToMap (unsigned far *source, unsigned plane, 136 | unsigned destx, unsigned desty, 137 | unsigned width, unsigned height); 138 | 139 | void RF_ClearBlock (int x, int y, int width, int height); 140 | void RF_RedrawBlock (int x, int y, int width, int height); 141 | 142 | void RF_PlaceSprite (void **user,unsigned globalx,unsigned globaly, 143 | unsigned spritenumber, drawtype draw, int priority); 144 | void RF_RemoveSprite (void **user); 145 | 146 | void RF_CalcTics (void); 147 | 148 | void RF_Refresh (void); 149 | void RF_ForceRefresh (void); 150 | void RF_SetRefreshHook (void (*func) (void) ); 151 | 152 | unsigned RF_FindFreeBuffer (void); 153 | 154 | -------------------------------------------------------------------------------- /ID_SD.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // 20 | // ID Engine 21 | // ID_SD.h - Sound Manager Header 22 | // v1.0d1 23 | // By Jason Blochowiak 24 | // 25 | 26 | #ifndef __TYPES__ 27 | #include "ID_Types.h" 28 | #endif 29 | 30 | #ifndef __ID_SD__ 31 | #define __ID_SD__ 32 | 33 | #ifdef __DEBUG__ 34 | #define __DEBUG_SoundMgr__ 35 | #endif 36 | 37 | #define TickBase 70 // 70Hz per tick - used as a base for timer 0 38 | 39 | typedef enum { 40 | sdm_Off, 41 | sdm_PC,sdm_AdLib, 42 | } SDMode; 43 | typedef enum { 44 | smm_Off,smm_AdLib 45 | } SMMode; 46 | 47 | typedef struct 48 | { 49 | longword length; 50 | word priority; 51 | } SoundCommon; 52 | 53 | // PC Sound stuff 54 | #define pcTimer 0x42 55 | #define pcTAccess 0x43 56 | #define pcSpeaker 0x61 57 | 58 | #define pcSpkBits 3 59 | 60 | typedef struct 61 | { 62 | SoundCommon common; 63 | byte data[1]; 64 | } PCSound; 65 | 66 | // Registers for the Sound Blaster card - needs to be offset by n0 67 | #define sbReset 0x206 68 | #define sbReadData 0x20a 69 | #define sbWriteCmd 0x20c 70 | #define sbWriteData 0x20c 71 | #define sbWriteStat 0x20c 72 | #define sbDataAvail 0x20e 73 | 74 | typedef struct 75 | { 76 | SoundCommon common; 77 | word hertz; 78 | byte bits, 79 | reference, 80 | data[1]; 81 | } SampledSound; 82 | 83 | // Registers for the AdLib card 84 | // Operator stuff 85 | #define alChar 0x20 86 | #define alScale 0x40 87 | #define alAttack 0x60 88 | #define alSus 0x80 89 | #define alWave 0xe0 90 | // Channel stuff 91 | #define alFreqL 0xa0 92 | #define alFreqH 0xb0 93 | #define alFeedCon 0xc0 94 | // Global stuff 95 | #define alEffects 0xbd 96 | 97 | typedef struct 98 | { 99 | byte mChar,cChar, 100 | mScale,cScale, 101 | mAttack,cAttack, 102 | mSus,cSus, 103 | mWave,cWave, 104 | nConn, 105 | 106 | // These are only for Muse - these bytes are really unused 107 | voice, 108 | mode, 109 | unused[3]; 110 | } Instrument; 111 | 112 | typedef struct 113 | { 114 | SoundCommon common; 115 | Instrument inst; 116 | byte block, 117 | data[1]; 118 | } AdLibSound; 119 | 120 | // 121 | // Sequencing stuff 122 | // 123 | #define sqMaxTracks 10 124 | #define sqMaxMoods 1 // DEBUG 125 | 126 | #define sev_Null 0 // Does nothing 127 | #define sev_NoteOff 1 // Turns a note off 128 | #define sev_NoteOn 2 // Turns a note on 129 | #define sev_NotePitch 3 // Sets the pitch of a currently playing note 130 | #define sev_NewInst 4 // Installs a new instrument 131 | #define sev_NewPerc 5 // Installs a new percussive instrument 132 | #define sev_PercOn 6 // Turns a percussive note on 133 | #define sev_PercOff 7 // Turns a percussive note off 134 | #define sev_SeqEnd -1 // Terminates a sequence 135 | 136 | // Flags for MusicGroup.flags 137 | #define sf_Melodic 0 138 | #define sf_Percussive 1 139 | 140 | #if 1 141 | typedef struct 142 | { 143 | word length, 144 | values[1]; 145 | } MusicGroup; 146 | #else 147 | typedef struct 148 | { 149 | word flags, 150 | count, 151 | offsets[1]; 152 | } MusicGroup; 153 | #endif 154 | 155 | typedef struct 156 | { 157 | /* This part needs to be set up by the user */ 158 | word mood,far *moods[sqMaxMoods]; 159 | 160 | /* The rest is set up by the code */ 161 | Instrument inst; 162 | boolean percussive; 163 | word far *seq; 164 | longword nextevent; 165 | } ActiveTrack; 166 | 167 | #define sqmode_Normal 0 168 | #define sqmode_FadeIn 1 169 | #define sqmode_FadeOut 2 170 | 171 | #define sqMaxFade 64 // DEBUG 172 | 173 | 174 | // Global variables 175 | extern boolean AdLibPresent, 176 | NeedsMusic; // For Caching Mgr 177 | extern SDMode SoundMode; 178 | extern SMMode MusicMode; 179 | extern longword TimeCount; // Global time in ticks 180 | 181 | // Function prototypes 182 | extern void SD_Startup(void), 183 | SD_Shutdown(void), 184 | SD_Default(boolean gotit,SDMode sd,SMMode sm), 185 | SD_PlaySound(soundnames sound), 186 | SD_StopSound(void), 187 | SD_WaitSoundDone(void), 188 | SD_StartMusic(MusicGroup far *music), 189 | SD_MusicOn(void), 190 | SD_MusicOff(void), 191 | SD_FadeOutMusic(void), 192 | SD_SetUserHook(void (*hook)(void)); 193 | extern boolean SD_MusicPlaying(void), 194 | SD_SetSoundMode(SDMode mode), 195 | SD_SetMusicMode(SMMode mode); 196 | extern word SD_SoundPlaying(void); 197 | 198 | #ifdef _MUSE_ // MUSE Goes directly to the lower level routines 199 | extern void SDL_PCPlaySound(PCSound far *sound), 200 | SDL_PCStopSound(void), 201 | SDL_ALPlaySound(AdLibSound far *sound), 202 | SDL_ALStopSound(void); 203 | #endif 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /C3_ASM.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | IDEAL 19 | 20 | MODEL MEDIUM,C 21 | 22 | VIEWWIDTH = (33*8) 23 | GC_INDEX = 03CEh 24 | 25 | DATASEG 26 | EVEN 27 | 28 | ;=================== Tables filled in by DrawVWall ========================== 29 | 30 | ; 31 | ; wallheight has the height (scale number) of that collumn of scaled wall 32 | ; it is pre bounded to 1-MAXSCALE (the actuial height on screen is 2*height) 33 | ; 34 | wallheight dw VIEWWIDTH dup (?) 35 | 36 | ; 37 | ; wallwidth has the pixel width (1-7) of that collumn 38 | ; 39 | wallwidth dw VIEWWIDTH dup (?) 40 | 41 | ; 42 | ; wallseg has the segment of the wall picture 43 | ; 44 | wallseg dw VIEWWIDTH dup (?) 45 | 46 | ; 47 | ; wallofs has the offset of the wall picture 48 | ; 49 | wallofs dw VIEWWIDTH dup (?) 50 | 51 | ;============================================================================ 52 | 53 | ; 54 | ; screenbyte is just position/8 55 | ; 56 | LABEL screenbyte WORD 57 | pos = 0 58 | REPT VIEWWIDTH 59 | dw pos/8 60 | pos = pos+1 61 | ENDM 62 | 63 | ; 64 | ; screenbit is (position&7)*16 65 | ; 66 | LABEL screenbit WORD 67 | pos = 0 68 | REPT VIEWWIDTH 69 | dw (pos AND 7)*16 70 | pos = pos+1 71 | ENDM 72 | 73 | ; 74 | ; Use offset: screenbit[]+pixwidth*2 75 | ; acess from bitmasks-2+offset for one biased pixwidth 76 | ; the low byte of bitmasks is for the first screen byte, the high byte 77 | ; is the bitmask for the second screen byte (if non 0) 78 | ; 79 | 80 | bitmasks dw 0080h,00c0h,00e0h,00f0h,00f8h,00fch,00feh,00ffh 81 | dw 0040h,0060h,0070h,0078h,007ch,007eh,007fh,807fh 82 | dw 0020h,0030h,0038h,003ch,003eh,003fh,803fh,0c03fh 83 | dw 0010h,0018h,001ch,001eh,001fh,801fh,0c01fh,0e01fh 84 | dw 0008h,000ch,000eh,000fh,800fh,0c00fh,0e00fh,0f00fh 85 | dw 0004h,0006h,0007h,8007h,0c007h,0e007h,0f007h,0f807h 86 | dw 0002h,0003h,8003h,0c003h,0e003h,0f003h,0f803h,0fc03h 87 | dw 0001h,8001h,0c001h,0e001h,0f001h,0f801h,0fc01h,0fe01h 88 | 89 | 90 | ; 91 | ; wallscalecall is a far pointer to the start of a compiled scaler 92 | ; The low word will never change, while the high word is set to 93 | ; compscaledirectory[scale] 94 | ; 95 | wallscalecall dd (65*6) ; offset of t_compscale->code[0] 96 | 97 | 98 | PUBLIC wallheight,wallwidth,wallseg,wallofs,screenbyte,screenbit 99 | PUBLIC bitmasks,wallscalecall 100 | 101 | 102 | EXTRN scaledirectory:WORD ; array of MAXSCALE segment pointers to 103 | ; compiled scalers 104 | EXTRN screenseg:WORD ; basically just 0xa000 105 | EXTRN bufferofs:WORD ; offset of the current work screen 106 | 107 | CODESEG 108 | 109 | ;============================================================================ 110 | ; 111 | ; ScaleWalls 112 | ; 113 | ; AX AL is scratched in bit mask setting and scaling 114 | ; BX table index 115 | ; CX pixwidth*2 116 | ; DX GC_INDEX 117 | ; SI offset into wall data to scale from, allways 0,64,128,...4032 118 | ; DI byte at top of screen that the collumn is contained in 119 | ; BP x pixel * 2, index into VIEWWIDTH wide tables 120 | ; DS segment of the wall data to texture map 121 | ; ES screenseg 122 | ; SS addressing DGROUP variables 123 | ; 124 | ;============================================================================ 125 | 126 | PROC ScaleWalls 127 | PUBLIC ScaleWalls 128 | USES SI,DI,BP 129 | 130 | xor bp,bp ; start at location 0 in the tables 131 | mov dx,GC_INDEX+1 132 | mov es,[screenseg] 133 | 134 | ; 135 | ; scale one collumn of data, possibly across two bytes 136 | ; 137 | nextcollumn: 138 | 139 | mov bx,[wallheight+bp] ; height of walls (1-MAXSCALE) 140 | shl bx,1 141 | mov ax,[ss:scaledirectory+bx] ; segment of the compiled scaler 142 | mov [WORD PTR ss:wallscalecall+2],ax 143 | 144 | mov cx,[wallwidth+bp] 145 | or cx,cx 146 | jnz okwidth 147 | mov cx,2 148 | jmp next 149 | 150 | okwidth: 151 | shl cx,1 152 | mov ds,[wallseg+bp] 153 | mov si,[wallofs+bp] 154 | 155 | mov di,[screenbyte+bp] ; byte at the top of the scaled collumn 156 | add di,[ss:bufferofs] ; offset of current page flip 157 | mov bx,[screenbit+bp] ; 0-7 << 4 158 | add bx,cx 159 | mov ax,[ss:bitmasks-2+bx] 160 | out dx,al ; set bit mask register 161 | call [DWORD PTR ss:wallscalecall] ; scale the line of pixels 162 | or ah,ah ; is there anything in the second byte? 163 | jnz secondbyte 164 | ; 165 | ; next 166 | ; 167 | next: 168 | add bp,cx 169 | cmp bp,VIEWWIDTH*2 170 | jb nextcollumn 171 | jmp done 172 | 173 | ; 174 | ; draw a second byte for vertical strips that cross two bytes 175 | ; 176 | secondbyte: 177 | mov al,ah 178 | inc di ; next byte over 179 | out dx,al ; set bit mask register 180 | call [DWORD PTR ss:wallscalecall] ; scale the line of pixels 181 | ; 182 | ; next 183 | ; 184 | add bp,cx 185 | cmp bp,VIEWWIDTH*2 186 | jb nextcollumn 187 | 188 | done: 189 | mov ax,ss 190 | mov ds,ax 191 | ret 192 | 193 | ENDP 194 | 195 | 196 | END 197 | 198 | -------------------------------------------------------------------------------- /ID_IN.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // 20 | // ID Engine 21 | // ID_IN.h - Header file for Input Manager 22 | // v1.0d1 23 | // By Jason Blochowiak 24 | // 25 | 26 | #ifndef __TYPES__ 27 | #include "ID_Types.h" 28 | #endif 29 | 30 | #ifndef __ID_IN__ 31 | #define __ID_IN__ 32 | 33 | #ifdef __DEBUG__ 34 | #define __DEBUG_InputMgr__ 35 | #endif 36 | 37 | #define MaxPlayers 4 38 | #define MaxKbds 2 39 | #define MaxJoys 2 40 | #define NumCodes 128 41 | 42 | typedef byte ScanCode; 43 | #define sc_None 0 44 | #define sc_Bad 0xff 45 | #define sc_Return 0x1c 46 | #define sc_Enter sc_Return 47 | #define sc_Escape 0x01 48 | #define sc_Space 0x39 49 | #define sc_BackSpace 0x0e 50 | #define sc_Tab 0x0f 51 | #define sc_Alt 0x38 52 | #define sc_Control 0x1d 53 | #define sc_CapsLock 0x3a 54 | #define sc_LShift 0x2a 55 | #define sc_RShift 0x36 56 | #define sc_UpArrow 0x48 57 | #define sc_DownArrow 0x50 58 | #define sc_LeftArrow 0x4b 59 | #define sc_RightArrow 0x4d 60 | #define sc_Insert 0x52 61 | #define sc_Delete 0x53 62 | #define sc_Home 0x47 63 | #define sc_End 0x4f 64 | #define sc_PgUp 0x49 65 | #define sc_PgDn 0x51 66 | #define sc_F1 0x3b 67 | #define sc_F2 0x3c 68 | #define sc_F3 0x3d 69 | #define sc_F4 0x3e 70 | #define sc_F5 0x3f 71 | #define sc_F6 0x40 72 | #define sc_F7 0x41 73 | #define sc_F8 0x42 74 | #define sc_F9 0x43 75 | #define sc_F10 0x44 76 | #define sc_F11 0x57 77 | #define sc_F12 0x59 78 | 79 | #define sc_A 0x1e 80 | #define sc_B 0x30 81 | #define sc_C 0x2e 82 | #define sc_D 0x20 83 | #define sc_E 0x12 84 | #define sc_F 0x21 85 | #define sc_G 0x22 86 | #define sc_H 0x23 87 | #define sc_I 0x17 88 | #define sc_J 0x24 89 | #define sc_K 0x25 90 | #define sc_L 0x26 91 | #define sc_M 0x32 92 | #define sc_N 0x31 93 | #define sc_O 0x18 94 | #define sc_P 0x19 95 | #define sc_Q 0x10 96 | #define sc_R 0x13 97 | #define sc_S 0x1f 98 | #define sc_T 0x14 99 | #define sc_U 0x16 100 | #define sc_V 0x2f 101 | #define sc_W 0x11 102 | #define sc_X 0x2d 103 | #define sc_Y 0x15 104 | #define sc_Z 0x2c 105 | 106 | #define key_None 0 107 | #define key_Return 0x0d 108 | #define key_Enter key_Return 109 | #define key_Escape 0x1b 110 | #define key_Space 0x20 111 | #define key_BackSpace 0x08 112 | #define key_Tab 0x09 113 | #define key_Delete 0x7f 114 | 115 | // Stuff for the mouse 116 | #define MReset 0 117 | #define MButtons 3 118 | #define MDelta 11 119 | 120 | #define MouseInt 0x33 121 | #define Mouse(x) _AX = x,geninterrupt(MouseInt) 122 | 123 | typedef enum { 124 | demo_Off,demo_Record,demo_Playback,demo_PlayDone 125 | } Demo; 126 | typedef enum { 127 | ctrl_Keyboard, 128 | ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2, 129 | ctrl_Joystick, 130 | ctrl_Joystick1 = ctrl_Joystick,ctrl_Joystick2, 131 | ctrl_Mouse 132 | } ControlType; 133 | typedef enum { 134 | motion_Left = -1,motion_Up = -1, 135 | motion_None = 0, 136 | motion_Right = 1,motion_Down = 1 137 | } Motion; 138 | typedef enum { 139 | dir_North,dir_NorthEast, 140 | dir_East,dir_SouthEast, 141 | dir_South,dir_SouthWest, 142 | dir_West,dir_NorthWest, 143 | dir_None 144 | } Direction; 145 | typedef struct { 146 | boolean button0,button1; 147 | int x,y; 148 | Motion xaxis,yaxis; 149 | Direction dir; 150 | } CursorInfo; 151 | typedef CursorInfo ControlInfo; 152 | typedef struct { 153 | ScanCode button0,button1, 154 | upleft, up, upright, 155 | left, right, 156 | downleft, down, downright; 157 | } KeyboardDef; 158 | typedef struct { 159 | word joyMinX,joyMinY, 160 | threshMinX,threshMinY, 161 | threshMaxX,threshMaxY, 162 | joyMaxX,joyMaxY, 163 | joyMultXL,joyMultYL, 164 | joyMultXH,joyMultYH; 165 | } JoystickDef; 166 | // Global variables 167 | extern boolean Keyboard[], 168 | MousePresent, 169 | JoysPresent[]; 170 | extern boolean Paused; 171 | extern char LastASCII; 172 | extern ScanCode LastScan; 173 | extern KeyboardDef KbdDefs[]; 174 | extern JoystickDef JoyDefs[]; 175 | extern ControlType Controls[MaxPlayers]; 176 | 177 | extern Demo DemoMode; 178 | extern byte _seg *DemoBuffer; 179 | extern word DemoOffset,DemoSize; 180 | 181 | // Function prototypes 182 | #define IN_KeyDown(code) (Keyboard[(code)]) 183 | #define IN_ClearKey(code) {Keyboard[code] = false;\ 184 | if (code == LastScan) LastScan = sc_None;} 185 | 186 | // DEBUG - put names in prototypes 187 | extern void IN_Startup(void),IN_Shutdown(void), 188 | IN_Default(boolean gotit,ControlType in), 189 | IN_SetKeyHook(void (*)()), 190 | IN_ClearKeysDown(void), 191 | IN_ReadCursor(CursorInfo *), 192 | IN_ReadControl(int,ControlInfo *), 193 | IN_SetControlType(int,ControlType), 194 | IN_GetJoyAbs(word joy,word *xp,word *yp), 195 | IN_SetupJoy(word joy,word minx,word maxx, 196 | word miny,word maxy), 197 | IN_StartDemoPlayback(byte _seg *buffer,word bufsize), 198 | IN_StopDemo(void),IN_FreeDemoBuffer(void), 199 | IN_Ack(void),IN_AckBack(void); 200 | extern boolean IN_UserInput(longword delay,boolean clear), 201 | IN_IsUserInput(void), 202 | IN_StartDemoRecord(word bufsize); 203 | extern byte *IN_GetScanName(ScanCode); 204 | extern char IN_WaitForASCII(void); 205 | extern ScanCode IN_WaitForKey(void); 206 | extern word IN_GetJoyButtonsDB(word joy); 207 | 208 | #endif 209 | -------------------------------------------------------------------------------- /GFXE_C3D.EQU: -------------------------------------------------------------------------------- 1 | ;===================================== 2 | ; 3 | ; Graphics .EQU file for .C3D 4 | ; IGRAB-ed on Tue Dec 21 15:06:11 1993 5 | ; 6 | ;===================================== 7 | 8 | CP_MAINMENUPIC = 5 9 | CP_NEWGAMEMENUPIC = 6 10 | CP_LOADMENUPIC = 7 11 | CP_SAVEMENUPIC = 8 12 | CP_CONFIGMENUPIC = 9 13 | CP_SOUNDMENUPIC = 10 14 | CP_MUSICMENUPIC = 11 15 | CP_KEYBOARDMENUPIC = 12 16 | CP_KEYMOVEMENTPIC = 13 17 | CP_KEYBUTTONPIC = 14 18 | CP_JOYSTICKMENUPIC = 15 19 | CP_OPTIONSMENUPIC = 16 20 | CP_PADDLEWARPIC = 17 21 | CP_QUITPIC = 18 22 | CP_JOYSTICKPIC = 19 23 | CP_MENUSCREENPIC = 20 24 | TITLEPIC = 21 25 | CREDITSPIC = 22 26 | HIGHSCORESPIC = 23 27 | FINALEPIC = 24 28 | STATUSPIC = 25 29 | SIDEBARSPIC = 26 30 | SCROLLTOPPIC = 27 31 | SCROLL1PIC = 28 32 | SCROLL2PIC = 29 33 | SCROLL3PIC = 30 34 | SCROLL4PIC = 31 35 | SCROLL5PIC = 32 36 | SCROLL6PIC = 33 37 | SCROLL7PIC = 34 38 | SCROLL8PIC = 35 39 | FIRSTLATCHPIC = 36 40 | NOSHOTPOWERPIC = 37 41 | SHOTPOWERPIC = 38 42 | NOBODYPIC = 39 43 | BODYPIC = 40 44 | COMPAS1PIC = 41 45 | COMPAS2PIC = 42 46 | COMPAS3PIC = 43 47 | COMPAS4PIC = 44 48 | COMPAS5PIC = 45 49 | COMPAS6PIC = 46 50 | COMPAS7PIC = 47 51 | COMPAS8PIC = 48 52 | COMPAS9PIC = 49 53 | COMPAS10PIC = 50 54 | COMPAS11PIC = 51 55 | COMPAS12PIC = 52 56 | COMPAS13PIC = 53 57 | COMPAS14PIC = 54 58 | COMPAS15PIC = 55 59 | COMPAS16PIC = 56 60 | DEADPIC = 57 61 | FIRSTSCALEPIC = 58 62 | ORC1PIC = 59 63 | ORC2PIC = 60 64 | ORC3PIC = 61 65 | ORC4PIC = 62 66 | ORCATTACK1PIC = 63 67 | ORCATTACK2PIC = 64 68 | ORCOUCHPIC = 65 69 | ORCDIE1PIC = 66 70 | ORCDIE2PIC = 67 71 | ORCDIE3PIC = 68 72 | TROLL1PIC = 69 73 | TROLL2PIC = 70 74 | TROLL3PIC = 71 75 | TROLL4PIC = 72 76 | TROLLOUCHPIC = 73 77 | TROLLATTACK1PIC = 74 78 | TROLLATTACK2PIC = 75 79 | TROLLATTACK3PIC = 76 80 | TROLLDIE1PIC = 77 81 | TROLLDIE2PIC = 78 82 | TROLLDIE3PIC = 79 83 | WARP1PIC = 80 84 | WARP2PIC = 81 85 | WARP3PIC = 82 86 | WARP4PIC = 83 87 | BOLTOBJPIC = 84 88 | BOLTOBJ2PIC = 85 89 | NUKEOBJPIC = 86 90 | NUKEOBJ2PIC = 87 91 | POTIONOBJPIC = 88 92 | RKEYOBJPIC = 89 93 | YKEYOBJPIC = 90 94 | GKEYOBJPIC = 91 95 | BKEYOBJPIC = 92 96 | SCROLLOBJPIC = 93 97 | CHESTOBJPIC = 94 98 | PSHOT1PIC = 95 99 | PSHOT2PIC = 96 100 | BIGPSHOT1PIC = 97 101 | BIGPSHOT2PIC = 98 102 | DEMON1PIC = 99 103 | DEMON2PIC = 100 104 | DEMON3PIC = 101 105 | DEMON4PIC = 102 106 | DEMONATTACK1PIC = 103 107 | DEMONATTACK2PIC = 104 108 | DEMONATTACK3PIC = 105 109 | DEMONOUCHPIC = 106 110 | DEMONDIE1PIC = 107 111 | DEMONDIE2PIC = 108 112 | DEMONDIE3PIC = 109 113 | MAGE1PIC = 110 114 | MAGE2PIC = 111 115 | MAGEOUCHPIC = 112 116 | MAGEATTACKPIC = 113 117 | MAGEDIE1PIC = 114 118 | MAGEDIE2PIC = 115 119 | BAT1PIC = 116 120 | BAT2PIC = 117 121 | BAT3PIC = 118 122 | BAT4PIC = 119 123 | BATDIE1PIC = 120 124 | BATDIE2PIC = 121 125 | GREL1PIC = 122 126 | GREL2PIC = 123 127 | GRELATTACKPIC = 124 128 | GRELHITPIC = 125 129 | GRELDIE1PIC = 126 130 | GRELDIE2PIC = 127 131 | GRELDIE3PIC = 128 132 | GRELDIE4PIC = 129 133 | GRELDIE5PIC = 130 134 | GRELDIE6PIC = 131 135 | NEMESISPIC = 132 136 | FIRSTWALLPIC = 133 137 | EXPWALL1PIC = 134 138 | EXPWALL2PIC = 135 139 | EXPWALL3PIC = 136 140 | WALL1LPIC = 137 141 | WALL1DPIC = 138 142 | WALL2DPIC = 139 143 | WALL2LPIC = 140 144 | WALL3DPIC = 141 145 | WALL3LPIC = 142 146 | WALL4DPIC = 143 147 | WALL4LPIC = 144 148 | WALL5DPIC = 145 149 | WALL5LPIC = 146 150 | WALL6DPIC = 147 151 | WALL6LPIC = 148 152 | WALL7DPIC = 149 153 | WALL7LPIC = 150 154 | RDOOR1PIC = 151 155 | RDOOR2PIC = 152 156 | YDOOR1PIC = 153 157 | YDOOR2PIC = 154 158 | GDOOR1PIC = 155 159 | GDOOR2PIC = 156 160 | BDOOR1PIC = 157 161 | BDOOR2PIC = 158 162 | ENTERPLAQUEPIC = 159 163 | 164 | CP_MENUMASKPICM = 160 165 | HAND1PICM = 161 166 | HAND2PICM = 162 167 | 168 | PADDLESPR = 163 169 | BALLSPR = 164 170 | BALL1PIXELTOTHERIGHTSPR = 165 171 | 172 | LEVEL1TEXT = 456 173 | LEVEL2TEXT = 457 174 | LEVEL3TEXT = 458 175 | LEVEL4TEXT = 459 176 | LEVEL5TEXT = 460 177 | LEVEL6TEXT = 461 178 | LEVEL7TEXT = 462 179 | LEVEL8TEXT = 463 180 | LEVEL9TEXT = 464 181 | LEVEL10TEXT = 465 182 | LEVEL11TEXT = 466 183 | LEVEL12TEXT = 467 184 | LEVEL13TEXT = 468 185 | LEVEL14TEXT = 469 186 | LEVEL15TEXT = 470 187 | LEVEL16TEXT = 471 188 | LEVEL17TEXT = 472 189 | LEVEL18TEXT = 473 190 | LEVEL19TEXT = 474 191 | LEVEL20TEXT = 475 192 | OUTOFMEM = 476 193 | PIRACY = 477 194 | 195 | CONTROLS_LUMP_START = 5 196 | CONTROLS_LUMP_END = 20 197 | 198 | PADDLE_LUMP_START = 163 199 | PADDLE_LUMP_END = 165 200 | 201 | ORC_LUMP_START = 59 202 | ORC_LUMP_END = 68 203 | 204 | TROLL_LUMP_START = 69 205 | TROLL_LUMP_END = 79 206 | 207 | WARP_LUMP_START = 80 208 | WARP_LUMP_END = 83 209 | 210 | BOLT_LUMP_START = 84 211 | BOLT_LUMP_END = 85 212 | 213 | NUKE_LUMP_START = 86 214 | NUKE_LUMP_END = 87 215 | 216 | POTION_LUMP_START = 88 217 | POTION_LUMP_END = 88 218 | 219 | RKEY_LUMP_START = 89 220 | RKEY_LUMP_END = 89 221 | 222 | YKEY_LUMP_START = 90 223 | YKEY_LUMP_END = 90 224 | 225 | GKEY_LUMP_START = 91 226 | GKEY_LUMP_END = 91 227 | 228 | BKEY_LUMP_START = 92 229 | BKEY_LUMP_END = 92 230 | 231 | SCROLL_LUMP_START = 93 232 | SCROLL_LUMP_END = 93 233 | 234 | CHEST_LUMP_START = 94 235 | CHEST_LUMP_END = 94 236 | 237 | PLAYER_LUMP_START = 95 238 | PLAYER_LUMP_END = 98 239 | 240 | DEMON_LUMP_START = 99 241 | DEMON_LUMP_END = 109 242 | 243 | MAGE_LUMP_START = 110 244 | MAGE_LUMP_END = 115 245 | 246 | BAT_LUMP_START = 116 247 | BAT_LUMP_END = 121 248 | 249 | GREL_LUMP_START = 122 250 | GREL_LUMP_END = 132 251 | 252 | EXPWALL_LUMP_START = 134 253 | EXPWALL_LUMP_END = 136 254 | 255 | WALL1_LUMP_START = 137 256 | WALL1_LUMP_END = 138 257 | 258 | WALL2_LUMP_START = 139 259 | WALL2_LUMP_END = 140 260 | 261 | WALL3_LUMP_START = 141 262 | WALL3_LUMP_END = 142 263 | 264 | WALL4_LUMP_START = 143 265 | WALL4_LUMP_END = 144 266 | 267 | WALL5_LUMP_START = 145 268 | WALL5_LUMP_END = 146 269 | 270 | WALL6_LUMP_START = 147 271 | WALL6_LUMP_END = 148 272 | 273 | WALL7_LUMP_START = 149 274 | WALL7_LUMP_END = 150 275 | 276 | RDOOR_LUMP_START = 151 277 | RDOOR_LUMP_END = 152 278 | 279 | YDOOR_LUMP_START = 153 280 | YDOOR_LUMP_END = 154 281 | 282 | GDOOR_LUMP_START = 155 283 | GDOOR_LUMP_END = 156 284 | 285 | BDOOR_LUMP_START = 157 286 | BDOOR_LUMP_END = 158 287 | 288 | 289 | ; 290 | ; Amount of each data item 291 | ; 292 | NUMCHUNKS = 478 293 | NUMFONT = 2 294 | NUMFONTM = 0 295 | NUMPICS = 155 296 | NUMPICM = 3 297 | NUMSPRITES = 3 298 | NUMTILE8 = 108 299 | NUMTILE8M = 36 300 | NUMTILE16 = 216 301 | NUMTILE16M = 72 302 | NUMTILE32 = 0 303 | NUMTILE32M = 0 304 | NUMEXTERN = 22 305 | ; 306 | ; File offsets for data items 307 | ; 308 | STRUCTPIC = 0 309 | STRUCTPICM = 1 310 | STRUCTSPRITE = 2 311 | 312 | STARTFONT = 3 313 | STARTFONTM = 5 314 | STARTPICS = 5 315 | STARTPICM = 160 316 | STARTSPRITES = 163 317 | STARTTILE8 = 166 318 | STARTTILE8M = 167 319 | STARTTILE16 = 168 320 | STARTTILE16M = 384 321 | STARTTILE32 = 456 322 | STARTTILE32M = 456 323 | STARTEXTERN = 456 324 | 325 | ; 326 | ; Thank you for using IGRAB! 327 | ; 328 | -------------------------------------------------------------------------------- /ID_VW.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // ID_VW.H 20 | 21 | #ifndef __TYPES__ 22 | #include "ID_TYPES.H" 23 | #endif 24 | 25 | #ifndef __ID_MM__ 26 | #include "ID_MM.H" 27 | #endif 28 | 29 | #ifndef __ID_GLOB__ 30 | #include "ID_GLOB.H" 31 | #endif 32 | 33 | #define __ID_VW__ 34 | 35 | //=========================================================================== 36 | 37 | #define G_P_SHIFT 4 // global >> ?? = pixels 38 | 39 | #if GRMODE == EGAGR 40 | #define SCREENWIDTH 40 41 | #define CHARWIDTH 1 42 | #define TILEWIDTH 2 43 | #define GRPLANES 4 44 | #define BYTEPIXELS 8 45 | #endif 46 | 47 | #if GRMODE == CGAGR 48 | #define SCREENWIDTH 128 49 | #define CHARWIDTH 2 50 | #define TILEWIDTH 4 51 | #define GRPLANES 1 52 | #define BYTEPIXELS 4 53 | #endif 54 | 55 | #define VIRTUALHEIGHT 300 56 | #define VIRTUALWIDTH 512 57 | 58 | 59 | #if GRMODE == CGAGR 60 | 61 | #define MAXSHIFTS 1 62 | 63 | #define WHITE 3 // graphics mode independant colors 64 | #define BLACK 0 65 | #define FIRSTCOLOR 1 66 | #define SECONDCOLOR 2 67 | #define F_WHITE 0 // for XOR font drawing 68 | #define F_BLACK 3 69 | #define F_FIRSTCOLOR 2 70 | #define F_SECONDCOLOR 1 71 | 72 | #endif 73 | 74 | #if GRMODE == EGAGR 75 | 76 | #define MAXSHIFTS 4 77 | 78 | #define WHITE 15 // graphics mode independant colors 79 | #define BLACK 0 80 | #define FIRSTCOLOR 1 81 | #define SECONDCOLOR 12 82 | #define F_WHITE 0 // for XOR font drawing 83 | #define F_BLACK 15 84 | #define F_FIRSTCOLOR 14 85 | #define F_SECONDCOLOR 3 86 | 87 | #endif 88 | 89 | #if GRMODE == EGAGR 90 | #define SCREENXMASK (~7) 91 | #define SCREENXPLUS (7) 92 | #define SCREENXDIV (8) 93 | #endif 94 | 95 | #if GRMODE == CGAGR 96 | #define SCREENXMASK (~3) 97 | #define SCREENXDIV (4) 98 | #endif 99 | 100 | //=========================================================================== 101 | 102 | 103 | #define SC_INDEX 0x3C4 104 | #define SC_RESET 0 105 | #define SC_CLOCK 1 106 | #define SC_MAPMASK 2 107 | #define SC_CHARMAP 3 108 | #define SC_MEMMODE 4 109 | 110 | #define CRTC_INDEX 0x3D4 111 | #define CRTC_H_TOTAL 0 112 | #define CRTC_H_DISPEND 1 113 | #define CRTC_H_BLANK 2 114 | #define CRTC_H_ENDBLANK 3 115 | #define CRTC_H_RETRACE 4 116 | #define CRTC_H_ENDRETRACE 5 117 | #define CRTC_V_TOTAL 6 118 | #define CRTC_OVERFLOW 7 119 | #define CRTC_ROWSCAN 8 120 | #define CRTC_MAXSCANLINE 9 121 | #define CRTC_CURSORSTART 10 122 | #define CRTC_CURSOREND 11 123 | #define CRTC_STARTHIGH 12 124 | #define CRTC_STARTLOW 13 125 | #define CRTC_CURSORHIGH 14 126 | #define CRTC_CURSORLOW 15 127 | #define CRTC_V_RETRACE 16 128 | #define CRTC_V_ENDRETRACE 17 129 | #define CRTC_V_DISPEND 18 130 | #define CRTC_OFFSET 19 131 | #define CRTC_UNDERLINE 20 132 | #define CRTC_V_BLANK 21 133 | #define CRTC_V_ENDBLANK 22 134 | #define CRTC_MODE 23 135 | #define CRTC_LINECOMPARE 24 136 | 137 | 138 | #define GC_INDEX 0x3CE 139 | #define GC_SETRESET 0 140 | #define GC_ENABLESETRESET 1 141 | #define GC_COLORCOMPARE 2 142 | #define GC_DATAROTATE 3 143 | #define GC_READMAP 4 144 | #define GC_MODE 5 145 | #define GC_MISCELLANEOUS 6 146 | #define GC_COLORDONTCARE 7 147 | #define GC_BITMASK 8 148 | 149 | #define ATR_INDEX 0x3c0 150 | #define ATR_MODE 16 151 | #define ATR_OVERSCAN 17 152 | #define ATR_COLORPLANEENABLE 18 153 | #define ATR_PELPAN 19 154 | #define ATR_COLORSELECT 20 155 | 156 | #define STATUS_REGISTER_1 0x3da 157 | 158 | //=========================================================================== 159 | 160 | typedef enum {NOcard,MDAcard,CGAcard,EGAcard,MCGAcard,VGAcard, 161 | HGCcard=0x80,HGCPcard,HICcard} cardtype; 162 | 163 | typedef struct 164 | { 165 | int width, 166 | height, 167 | orgx,orgy, 168 | xl,yl,xh,yh, 169 | shifts; 170 | } spritetabletype; 171 | 172 | typedef struct 173 | { 174 | unsigned sourceoffset[MAXSHIFTS]; 175 | unsigned planesize[MAXSHIFTS]; 176 | unsigned width[MAXSHIFTS]; 177 | byte data[]; 178 | } spritetype; // the memptr for each sprite points to this 179 | 180 | typedef struct 181 | { 182 | int width,height; 183 | } pictabletype; 184 | 185 | 186 | typedef struct 187 | { 188 | int height; 189 | int location[256]; 190 | char width[256]; 191 | } fontstruct; 192 | 193 | 194 | typedef enum {CGAgr,EGAgr,VGAgr} grtype; 195 | 196 | //=========================================================================== 197 | 198 | extern cardtype videocard; // set by VW_Startup 199 | extern grtype grmode; // CGAgr, EGAgr, VGAgr 200 | 201 | extern unsigned bufferofs; // hidden port to draw to before displaying 202 | extern unsigned displayofs; // origin of port on visable screen 203 | extern unsigned panx,pany; // panning adjustments inside port in pixels 204 | extern unsigned pansx,pansy; 205 | extern unsigned panadjust; // panx/pany adjusted by screen resolution 206 | 207 | extern unsigned screenseg; // normally 0xa000 or buffer segment 208 | 209 | extern unsigned linewidth; 210 | extern unsigned ylookup[VIRTUALHEIGHT]; 211 | 212 | extern boolean screenfaded; 213 | extern char colors[7][17]; // pallets for fades 214 | 215 | extern pictabletype _seg *pictable; 216 | extern pictabletype _seg *picmtable; 217 | extern spritetabletype _seg *spritetable; 218 | 219 | extern unsigned fontnumber; // 0 based font number for drawing 220 | extern int px,py; 221 | extern byte pdrawmode,fontcolor; 222 | 223 | extern int bordercolor; 224 | 225 | // 226 | // asm globals 227 | // 228 | 229 | extern unsigned *shifttabletable[8]; 230 | extern unsigned bufferwidth,bufferheight,screenspot; // used by font drawing stuff 231 | 232 | 233 | 234 | //=========================================================================== 235 | 236 | 237 | void VW_Startup (void); 238 | void VW_Shutdown (void); 239 | 240 | cardtype VW_VideoID (void); 241 | 242 | // 243 | // EGA hardware routines 244 | // 245 | 246 | #define EGAWRITEMODE(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_MODE+256*x;out dx,ax;sti;} 247 | #define EGABITMASK(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_BITMASK+256*x;out dx,ax;sti;} 248 | #define EGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov ax,SC_MAPMASK+x*256;out dx,ax;sti;} 249 | #define EGAREADMAP(x) asm{cli;mov dx,GC_INDEX;mov ax,GC_READMAP+x*256;out dx,ax;sti;} 250 | 251 | void VW_SetLineWidth(int width); 252 | void VW_SetSplitScreen(int width); 253 | void VW_SetScreen (unsigned CRTC, unsigned pelpan); 254 | 255 | void VW_SetScreenMode (int grmode); 256 | void VW_ClearVideo (int color); 257 | void VW_WaitVBL (int number); 258 | 259 | void VW_ColorBorder (int color); 260 | void VW_SetPalette(byte *palette); 261 | void VW_SetDefaultColors(void); 262 | void VW_FadeOut(void); 263 | void VW_FadeIn(void); 264 | void VW_FadeUp(void); 265 | void VW_FadeDown(void); 266 | 267 | void VW_SetAtrReg (int reg, int value); 268 | 269 | // 270 | // block primitives 271 | // 272 | 273 | void VW_MaskBlock(memptr segm,unsigned ofs,unsigned dest, 274 | unsigned wide,unsigned height,unsigned planesize); 275 | void VW_MemToScreen(memptr source,unsigned dest,unsigned width,unsigned height); 276 | void VW_ScreenToMem(unsigned source,memptr dest,unsigned width,unsigned height); 277 | void VW_ScreenToScreen(unsigned source,unsigned dest,unsigned width,unsigned height); 278 | 279 | 280 | // 281 | // block addressable routines 282 | // 283 | 284 | void VW_DrawTile8(unsigned x, unsigned y, unsigned tile); 285 | 286 | #if GRMODE == EGAGR 287 | 288 | #define VW_DrawTile8M(x,y,t) \ 289 | VW_MaskBlock(grsegs[STARTTILE8M],(t)*40,bufferofs+ylookup[y]+(x),1,8,8) 290 | #define VW_DrawTile16(x,y,t) \ 291 | VW_MemToScreen(grsegs[STARTTILE16+t],bufferofs+ylookup[y]+(x),2,16) 292 | #define VW_DrawTile16M(x,y,t) \ 293 | VW_MaskBlock(grsegs[STARTTILE16M],(t)*160,bufferofs+ylookup[y]+(x),2,16,32) 294 | 295 | #endif 296 | 297 | #if GRMODE == CGAGR 298 | 299 | #define VW_DrawTile8M(x,y,t) \ 300 | VW_MaskBlock(grsegs[STARTTILE8M],(t)*32,bufferofs+ylookup[y]+(x),2,8,16) 301 | #define VW_DrawTile16(x,y,t) \ 302 | VW_MemToScreen(grsegs[STARTTILE16+t],bufferofs+ylookup[y]+(x),4,16) 303 | #define VW_DrawTile16M(x,y,t) \ 304 | VW_MaskBlock(grsegs[STARTTILE16M],(t)*128,bufferofs+ylookup[y]+(x),4,16,64) 305 | 306 | #endif 307 | 308 | void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum); 309 | void VW_DrawMPic(unsigned x, unsigned y, unsigned chunknum); 310 | void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum); 311 | 312 | // 313 | // pixel addressable routines 314 | // 315 | void VW_MeasurePropString (char far *string, word *width, word *height); 316 | void VW_MeasureMPropString (char far *string, word *width, word *height); 317 | 318 | void VW_DrawPropString (char far *string); 319 | void VW_DrawMPropString (char far *string); 320 | void VW_DrawSprite(int x, int y, unsigned sprite); 321 | void VW_Plot(unsigned x, unsigned y, unsigned color); 322 | void VW_Hlin(unsigned xl, unsigned xh, unsigned y, unsigned color); 323 | void VW_Vlin(unsigned yl, unsigned yh, unsigned x, unsigned color); 324 | void VW_Bar (unsigned x, unsigned y, unsigned width, unsigned height, 325 | unsigned color); 326 | 327 | //=========================================================================== 328 | 329 | // 330 | // Double buffer management routines 331 | // 332 | 333 | void VW_InitDoubleBuffer (void); 334 | void VW_FixRefreshBuffer (void); 335 | int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2); 336 | void VW_UpdateScreen (void); 337 | void VW_CGAFullUpdate (void); 338 | 339 | // 340 | // cursor 341 | // 342 | 343 | void VW_ShowCursor (void); 344 | void VW_HideCursor (void); 345 | void VW_MoveCursor (int x, int y); 346 | void VW_SetCursor (int spritenum); 347 | void VW_FreeCursor (void); 348 | 349 | // 350 | // mode independant routines 351 | // coordinates in pixels, rounded to best screen res 352 | // regions marked in double buffer 353 | // 354 | 355 | void VWB_DrawTile8 (int x, int y, int tile); 356 | void VWB_DrawTile8M (int x, int y, int tile); 357 | void VWB_DrawTile16 (int x, int y, int tile); 358 | void VWB_DrawTile16M (int x, int y, int tile); 359 | void VWB_DrawPic (int x, int y, int chunknum); 360 | void VWB_DrawMPic(int x, int y, int chunknum); 361 | void VWB_Bar (int x, int y, int width, int height, int color); 362 | 363 | void VWB_DrawPropString (char far *string); 364 | void VWB_DrawMPropString (char far *string); 365 | void VWB_DrawSprite (int x, int y, int chunknum); 366 | void VWB_Plot (int x, int y, int color); 367 | void VWB_Hlin (int x1, int x2, int y, int color); 368 | void VWB_Vlin (int y1, int y2, int x, int color); 369 | 370 | //=========================================================================== 371 | -------------------------------------------------------------------------------- /GFXE_C3D.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | ////////////////////////////////////// 20 | // 21 | // Graphics .H file for .C3D 22 | // IGRAB-ed on Tue Dec 21 15:06:10 1993 23 | // 24 | ////////////////////////////////////// 25 | 26 | typedef enum { 27 | // Lump Start 28 | CP_MAINMENUPIC=5, 29 | CP_NEWGAMEMENUPIC, // 6 30 | CP_LOADMENUPIC, // 7 31 | CP_SAVEMENUPIC, // 8 32 | CP_CONFIGMENUPIC, // 9 33 | CP_SOUNDMENUPIC, // 10 34 | CP_MUSICMENUPIC, // 11 35 | CP_KEYBOARDMENUPIC, // 12 36 | CP_KEYMOVEMENTPIC, // 13 37 | CP_KEYBUTTONPIC, // 14 38 | CP_JOYSTICKMENUPIC, // 15 39 | CP_OPTIONSMENUPIC, // 16 40 | CP_PADDLEWARPIC, // 17 41 | CP_QUITPIC, // 18 42 | CP_JOYSTICKPIC, // 19 43 | CP_MENUSCREENPIC, // 20 44 | TITLEPIC, // 21 45 | CREDITSPIC, // 22 46 | HIGHSCORESPIC, // 23 47 | FINALEPIC, // 24 48 | STATUSPIC, // 25 49 | SIDEBARSPIC, // 26 50 | SCROLLTOPPIC, // 27 51 | SCROLL1PIC, // 28 52 | SCROLL2PIC, // 29 53 | SCROLL3PIC, // 30 54 | SCROLL4PIC, // 31 55 | SCROLL5PIC, // 32 56 | SCROLL6PIC, // 33 57 | SCROLL7PIC, // 34 58 | SCROLL8PIC, // 35 59 | FIRSTLATCHPIC, // 36 60 | NOSHOTPOWERPIC, // 37 61 | SHOTPOWERPIC, // 38 62 | NOBODYPIC, // 39 63 | BODYPIC, // 40 64 | COMPAS1PIC, // 41 65 | COMPAS2PIC, // 42 66 | COMPAS3PIC, // 43 67 | COMPAS4PIC, // 44 68 | COMPAS5PIC, // 45 69 | COMPAS6PIC, // 46 70 | COMPAS7PIC, // 47 71 | COMPAS8PIC, // 48 72 | COMPAS9PIC, // 49 73 | COMPAS10PIC, // 50 74 | COMPAS11PIC, // 51 75 | COMPAS12PIC, // 52 76 | COMPAS13PIC, // 53 77 | COMPAS14PIC, // 54 78 | COMPAS15PIC, // 55 79 | COMPAS16PIC, // 56 80 | DEADPIC, // 57 81 | FIRSTSCALEPIC, // 58 82 | ORC1PIC, // 59 83 | ORC2PIC, // 60 84 | ORC3PIC, // 61 85 | ORC4PIC, // 62 86 | ORCATTACK1PIC, // 63 87 | ORCATTACK2PIC, // 64 88 | ORCOUCHPIC, // 65 89 | ORCDIE1PIC, // 66 90 | ORCDIE2PIC, // 67 91 | ORCDIE3PIC, // 68 92 | TROLL1PIC, // 69 93 | TROLL2PIC, // 70 94 | TROLL3PIC, // 71 95 | TROLL4PIC, // 72 96 | TROLLOUCHPIC, // 73 97 | TROLLATTACK1PIC, // 74 98 | TROLLATTACK2PIC, // 75 99 | TROLLATTACK3PIC, // 76 100 | TROLLDIE1PIC, // 77 101 | TROLLDIE2PIC, // 78 102 | TROLLDIE3PIC, // 79 103 | WARP1PIC, // 80 104 | WARP2PIC, // 81 105 | WARP3PIC, // 82 106 | WARP4PIC, // 83 107 | BOLTOBJPIC, // 84 108 | BOLTOBJ2PIC, // 85 109 | NUKEOBJPIC, // 86 110 | NUKEOBJ2PIC, // 87 111 | POTIONOBJPIC, // 88 112 | RKEYOBJPIC, // 89 113 | YKEYOBJPIC, // 90 114 | GKEYOBJPIC, // 91 115 | BKEYOBJPIC, // 92 116 | SCROLLOBJPIC, // 93 117 | CHESTOBJPIC, // 94 118 | PSHOT1PIC, // 95 119 | PSHOT2PIC, // 96 120 | BIGPSHOT1PIC, // 97 121 | BIGPSHOT2PIC, // 98 122 | DEMON1PIC, // 99 123 | DEMON2PIC, // 100 124 | DEMON3PIC, // 101 125 | DEMON4PIC, // 102 126 | DEMONATTACK1PIC, // 103 127 | DEMONATTACK2PIC, // 104 128 | DEMONATTACK3PIC, // 105 129 | DEMONOUCHPIC, // 106 130 | DEMONDIE1PIC, // 107 131 | DEMONDIE2PIC, // 108 132 | DEMONDIE3PIC, // 109 133 | MAGE1PIC, // 110 134 | MAGE2PIC, // 111 135 | MAGEOUCHPIC, // 112 136 | MAGEATTACKPIC, // 113 137 | MAGEDIE1PIC, // 114 138 | MAGEDIE2PIC, // 115 139 | BAT1PIC, // 116 140 | BAT2PIC, // 117 141 | BAT3PIC, // 118 142 | BAT4PIC, // 119 143 | BATDIE1PIC, // 120 144 | BATDIE2PIC, // 121 145 | GREL1PIC, // 122 146 | GREL2PIC, // 123 147 | GRELATTACKPIC, // 124 148 | GRELHITPIC, // 125 149 | GRELDIE1PIC, // 126 150 | GRELDIE2PIC, // 127 151 | GRELDIE3PIC, // 128 152 | GRELDIE4PIC, // 129 153 | GRELDIE5PIC, // 130 154 | GRELDIE6PIC, // 131 155 | NEMESISPIC, // 132 156 | FIRSTWALLPIC, // 133 157 | EXPWALL1PIC, // 134 158 | EXPWALL2PIC, // 135 159 | EXPWALL3PIC, // 136 160 | WALL1LPIC, // 137 161 | WALL1DPIC, // 138 162 | WALL2DPIC, // 139 163 | WALL2LPIC, // 140 164 | WALL3DPIC, // 141 165 | WALL3LPIC, // 142 166 | WALL4DPIC, // 143 167 | WALL4LPIC, // 144 168 | WALL5DPIC, // 145 169 | WALL5LPIC, // 146 170 | WALL6DPIC, // 147 171 | WALL6LPIC, // 148 172 | WALL7DPIC, // 149 173 | WALL7LPIC, // 150 174 | RDOOR1PIC, // 151 175 | RDOOR2PIC, // 152 176 | YDOOR1PIC, // 153 177 | YDOOR2PIC, // 154 178 | GDOOR1PIC, // 155 179 | GDOOR2PIC, // 156 180 | BDOOR1PIC, // 157 181 | BDOOR2PIC, // 158 182 | ENTERPLAQUEPIC, // 159 183 | 184 | CP_MENUMASKPICM=160, 185 | HAND1PICM, // 161 186 | HAND2PICM, // 162 187 | 188 | // Lump Start 189 | PADDLESPR=163, 190 | BALLSPR, // 164 191 | BALL1PIXELTOTHERIGHTSPR, // 165 192 | 193 | LEVEL1TEXT=456, 194 | LEVEL2TEXT, // 457 195 | LEVEL3TEXT, // 458 196 | LEVEL4TEXT, // 459 197 | LEVEL5TEXT, // 460 198 | LEVEL6TEXT, // 461 199 | LEVEL7TEXT, // 462 200 | LEVEL8TEXT, // 463 201 | LEVEL9TEXT, // 464 202 | LEVEL10TEXT, // 465 203 | LEVEL11TEXT, // 466 204 | LEVEL12TEXT, // 467 205 | LEVEL13TEXT, // 468 206 | LEVEL14TEXT, // 469 207 | LEVEL15TEXT, // 470 208 | LEVEL16TEXT, // 471 209 | LEVEL17TEXT, // 472 210 | LEVEL18TEXT, // 473 211 | LEVEL19TEXT, // 474 212 | LEVEL20TEXT, // 475 213 | OUTOFMEM, // 476 214 | PIRACY, // 477 215 | ENUMEND 216 | } graphicnums; 217 | 218 | // 219 | // Data LUMPs 220 | // 221 | #define CONTROLS_LUMP_START 5 222 | #define CONTROLS_LUMP_END 20 223 | 224 | #define PADDLE_LUMP_START 163 225 | #define PADDLE_LUMP_END 165 226 | 227 | #define ORC_LUMP_START 59 228 | #define ORC_LUMP_END 68 229 | 230 | #define TROLL_LUMP_START 69 231 | #define TROLL_LUMP_END 79 232 | 233 | #define WARP_LUMP_START 80 234 | #define WARP_LUMP_END 83 235 | 236 | #define BOLT_LUMP_START 84 237 | #define BOLT_LUMP_END 85 238 | 239 | #define NUKE_LUMP_START 86 240 | #define NUKE_LUMP_END 87 241 | 242 | #define POTION_LUMP_START 88 243 | #define POTION_LUMP_END 88 244 | 245 | #define RKEY_LUMP_START 89 246 | #define RKEY_LUMP_END 89 247 | 248 | #define YKEY_LUMP_START 90 249 | #define YKEY_LUMP_END 90 250 | 251 | #define GKEY_LUMP_START 91 252 | #define GKEY_LUMP_END 91 253 | 254 | #define BKEY_LUMP_START 92 255 | #define BKEY_LUMP_END 92 256 | 257 | #define SCROLL_LUMP_START 93 258 | #define SCROLL_LUMP_END 93 259 | 260 | #define CHEST_LUMP_START 94 261 | #define CHEST_LUMP_END 94 262 | 263 | #define PLAYER_LUMP_START 95 264 | #define PLAYER_LUMP_END 98 265 | 266 | #define DEMON_LUMP_START 99 267 | #define DEMON_LUMP_END 109 268 | 269 | #define MAGE_LUMP_START 110 270 | #define MAGE_LUMP_END 115 271 | 272 | #define BAT_LUMP_START 116 273 | #define BAT_LUMP_END 121 274 | 275 | #define GREL_LUMP_START 122 276 | #define GREL_LUMP_END 132 277 | 278 | #define EXPWALL_LUMP_START 134 279 | #define EXPWALL_LUMP_END 136 280 | 281 | #define WALL1_LUMP_START 137 282 | #define WALL1_LUMP_END 138 283 | 284 | #define WALL2_LUMP_START 139 285 | #define WALL2_LUMP_END 140 286 | 287 | #define WALL3_LUMP_START 141 288 | #define WALL3_LUMP_END 142 289 | 290 | #define WALL4_LUMP_START 143 291 | #define WALL4_LUMP_END 144 292 | 293 | #define WALL5_LUMP_START 145 294 | #define WALL5_LUMP_END 146 295 | 296 | #define WALL6_LUMP_START 147 297 | #define WALL6_LUMP_END 148 298 | 299 | #define WALL7_LUMP_START 149 300 | #define WALL7_LUMP_END 150 301 | 302 | #define RDOOR_LUMP_START 151 303 | #define RDOOR_LUMP_END 152 304 | 305 | #define YDOOR_LUMP_START 153 306 | #define YDOOR_LUMP_END 154 307 | 308 | #define GDOOR_LUMP_START 155 309 | #define GDOOR_LUMP_END 156 310 | 311 | #define BDOOR_LUMP_START 157 312 | #define BDOOR_LUMP_END 158 313 | 314 | 315 | // 316 | // Amount of each data item 317 | // 318 | #define NUMCHUNKS 478 319 | #define NUMFONT 2 320 | #define NUMFONTM 0 321 | #define NUMPICS 155 322 | #define NUMPICM 3 323 | #define NUMSPRITES 3 324 | #define NUMTILE8 108 325 | #define NUMTILE8M 36 326 | #define NUMTILE16 216 327 | #define NUMTILE16M 72 328 | #define NUMTILE32 0 329 | #define NUMTILE32M 0 330 | #define NUMEXTERNS 22 331 | // 332 | // File offsets for data items 333 | // 334 | #define STRUCTPIC 0 335 | #define STRUCTPICM 1 336 | #define STRUCTSPRITE 2 337 | 338 | #define STARTFONT 3 339 | #define STARTFONTM 5 340 | #define STARTPICS 5 341 | #define STARTPICM 160 342 | #define STARTSPRITES 163 343 | #define STARTTILE8 166 344 | #define STARTTILE8M 167 345 | #define STARTTILE16 168 346 | #define STARTTILE16M 384 347 | #define STARTTILE32 456 348 | #define STARTTILE32M 456 349 | #define STARTEXTERNS 456 350 | 351 | // 352 | // Thank you for using IGRAB! 353 | // 354 | -------------------------------------------------------------------------------- /C3_STATE.C: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // C3_STATE.C 20 | 21 | #include "C3_DEF.H" 22 | #pragma hdrstop 23 | 24 | /* 25 | ============================================================================= 26 | 27 | LOCAL CONSTANTS 28 | 29 | ============================================================================= 30 | */ 31 | 32 | 33 | /* 34 | ============================================================================= 35 | 36 | GLOBAL VARIABLES 37 | 38 | ============================================================================= 39 | */ 40 | 41 | 42 | 43 | /* 44 | ============================================================================= 45 | 46 | LOCAL VARIABLES 47 | 48 | ============================================================================= 49 | */ 50 | 51 | 52 | dirtype opposite[9] = 53 | {south,west,north,east,southwest,northwest,northeast,southeast,nodir}; 54 | 55 | 56 | 57 | //=========================================================================== 58 | 59 | 60 | /* 61 | =================== 62 | = 63 | = SpawnNewObj 64 | = 65 | =================== 66 | */ 67 | 68 | void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size) 69 | { 70 | GetNewObj (false); 71 | new->size = size; 72 | new->state = state; 73 | new->ticcount = random (state->tictime)+1; 74 | 75 | new->tilex = x; 76 | new->tiley = y; 77 | new->x = ((long)x<y = ((long)y<dir = nodir; 81 | 82 | actorat[new->tilex][new->tiley] = new; 83 | } 84 | 85 | void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size) 86 | { 87 | GetNewObj (false); 88 | new->size = size; 89 | new->state = state; 90 | new->ticcount = random (state->tictime)+1; 91 | new->active = true; 92 | 93 | new->x = x; 94 | new->y = y; 95 | new->tilex = x>>TILESHIFT; 96 | new->tiley = y>>TILESHIFT; 97 | CalcBounds(new); 98 | new->distance = 100; 99 | new->dir = nodir; 100 | } 101 | 102 | 103 | 104 | /* 105 | =================== 106 | = 107 | = CheckHandAttack 108 | = 109 | = If the object can move next to the player, it will return true 110 | = 111 | =================== 112 | */ 113 | 114 | boolean CheckHandAttack (objtype *ob) 115 | { 116 | long deltax,deltay,size; 117 | 118 | size = (long)ob->size + player->size + ob->speed*tics; 119 | deltax = ob->x - player->x; 120 | deltay = ob->y - player->y; 121 | 122 | if (deltax > size || deltax < -size || deltay > size || deltay < -size) 123 | return false; 124 | 125 | return true; 126 | } 127 | 128 | 129 | /* 130 | =================== 131 | = 132 | = T_DoDamage 133 | = 134 | = Attacks the player if still nearby, then immediately changes to next state 135 | = 136 | =================== 137 | */ 138 | 139 | void T_DoDamage (objtype *ob) 140 | { 141 | int points; 142 | 143 | 144 | if (!CheckHandAttack (ob)) 145 | { 146 | SD_PlaySound (MONSTERMISSSND); 147 | } 148 | else 149 | { 150 | points = 0; 151 | 152 | switch (ob->obclass) 153 | { 154 | case orcobj: 155 | points = 4; 156 | break; 157 | case trollobj: 158 | points = 8; 159 | break; 160 | case demonobj: 161 | points = 15; 162 | break; 163 | } 164 | TakeDamage (points); 165 | } 166 | 167 | ob->state = ob->state->next; 168 | } 169 | 170 | 171 | //========================================================================== 172 | 173 | /* 174 | ================================== 175 | = 176 | = Walk 177 | = 178 | ================================== 179 | */ 180 | 181 | boolean Walk (objtype *ob) 182 | { 183 | switch (ob->dir) 184 | { 185 | case north: 186 | if (actorat[ob->tilex][ob->tiley-1]) 187 | return false; 188 | ob->tiley--; 189 | ob->distance = TILEGLOBAL; 190 | return true; 191 | 192 | case northeast: 193 | if (actorat[ob->tilex+1][ob->tiley-1]) 194 | return false; 195 | ob->tilex++; 196 | ob->tiley--; 197 | ob->distance = TILEGLOBAL; 198 | return true; 199 | 200 | case east: 201 | if (actorat[ob->tilex+1][ob->tiley]) 202 | return false; 203 | ob->tilex++; 204 | ob->distance = TILEGLOBAL; 205 | return true; 206 | 207 | case southeast: 208 | if (actorat[ob->tilex+1][ob->tiley+1]) 209 | return false; 210 | ob->tilex++; 211 | ob->tiley++; 212 | ob->distance = TILEGLOBAL; 213 | return true; 214 | 215 | case south: 216 | if (actorat[ob->tilex][ob->tiley+1]) 217 | return false; 218 | ob->tiley++; 219 | ob->distance = TILEGLOBAL; 220 | return true; 221 | 222 | case southwest: 223 | if (actorat[ob->tilex-1][ob->tiley+1]) 224 | return false; 225 | ob->tilex--; 226 | ob->tiley++; 227 | ob->distance = TILEGLOBAL; 228 | return true; 229 | 230 | case west: 231 | if (actorat[ob->tilex-1][ob->tiley]) 232 | return false; 233 | ob->tilex--; 234 | ob->distance = TILEGLOBAL; 235 | return true; 236 | 237 | case northwest: 238 | if (actorat[ob->tilex-1][ob->tiley-1]) 239 | return false; 240 | ob->tilex--; 241 | ob->tiley--; 242 | ob->distance = TILEGLOBAL; 243 | return true; 244 | 245 | case nodir: 246 | return false; 247 | } 248 | 249 | Quit ("Walk: Bad dir"); 250 | return false; 251 | } 252 | 253 | 254 | 255 | /* 256 | ================================== 257 | = 258 | = ChaseThink 259 | = have the current monster go after the player, 260 | = either diagonally or straight on 261 | = 262 | ================================== 263 | */ 264 | 265 | void ChaseThink (objtype *obj, boolean diagonal) 266 | { 267 | int deltax,deltay,i; 268 | dirtype d[3]; 269 | dirtype tdir, olddir, turnaround; 270 | 271 | 272 | olddir=obj->dir; 273 | turnaround=opposite[olddir]; 274 | 275 | deltax=player->tilex - obj->tilex; 276 | deltay=player->tiley - obj->tiley; 277 | 278 | d[1]=nodir; 279 | d[2]=nodir; 280 | 281 | if (deltax>0) 282 | d[1]= east; 283 | if (deltax<0) 284 | d[1]= west; 285 | if (deltay>0) 286 | d[2]=south; 287 | if (deltay<0) 288 | d[2]=north; 289 | 290 | if (abs(deltay)>abs(deltax)) 291 | { 292 | tdir=d[1]; 293 | d[1]=d[2]; 294 | d[2]=tdir; 295 | } 296 | 297 | if (d[1]==turnaround) 298 | d[1]=nodir; 299 | if (d[2]==turnaround) 300 | d[2]=nodir; 301 | 302 | 303 | if (diagonal) 304 | { /*ramdiagonals try the best dir first*/ 305 | if (d[1]!=nodir) 306 | { 307 | obj->dir=d[1]; 308 | if (Walk(obj)) 309 | return; /*either moved forward or attacked*/ 310 | } 311 | 312 | if (d[2]!=nodir) 313 | { 314 | obj->dir=d[2]; 315 | if (Walk(obj)) 316 | return; 317 | } 318 | } 319 | else 320 | { /*ramstraights try the second best dir first*/ 321 | 322 | if (d[2]!=nodir) 323 | { 324 | obj->dir=d[2]; 325 | if (Walk(obj)) 326 | return; 327 | } 328 | 329 | if (d[1]!=nodir) 330 | { 331 | obj->dir=d[1]; 332 | if (Walk(obj)) 333 | return; 334 | } 335 | } 336 | 337 | /* there is no direct path to the player, so pick another direction */ 338 | 339 | obj->dir=olddir; 340 | if (Walk(obj)) 341 | return; 342 | 343 | if (US_RndT()>128) /*randomly determine direction of search*/ 344 | { 345 | for (tdir=north;tdir<=west;tdir++) 346 | { 347 | if (tdir!=turnaround) 348 | { 349 | obj->dir=tdir; 350 | if (Walk(obj)) 351 | return; 352 | } 353 | } 354 | } 355 | else 356 | { 357 | for (tdir=west;tdir>=north;tdir--) 358 | { 359 | if (tdir!=turnaround) 360 | { 361 | obj->dir=tdir; 362 | if (Walk(obj)) 363 | return; 364 | } 365 | } 366 | } 367 | 368 | obj->dir=turnaround; 369 | Walk(obj); /*last chance, don't worry about returned value*/ 370 | } 371 | 372 | 373 | /* 374 | ================= 375 | = 376 | = MoveObj 377 | = 378 | ================= 379 | */ 380 | 381 | void MoveObj (objtype *ob, long move) 382 | { 383 | ob->distance -=move; 384 | 385 | switch (ob->dir) 386 | { 387 | case north: 388 | ob->y -= move; 389 | return; 390 | case northeast: 391 | ob->x += move; 392 | ob->y -= move; 393 | return; 394 | case east: 395 | ob->x += move; 396 | return; 397 | case southeast: 398 | ob->x += move; 399 | ob->y += move; 400 | return; 401 | case south: 402 | ob->y += move; 403 | return; 404 | case southwest: 405 | ob->x -= move; 406 | ob->y += move; 407 | return; 408 | case west: 409 | ob->x -= move; 410 | return; 411 | case northwest: 412 | ob->x -= move; 413 | ob->y -= move; 414 | return; 415 | 416 | case nodir: 417 | return; 418 | } 419 | } 420 | 421 | 422 | /* 423 | ================= 424 | = 425 | = Chase 426 | = 427 | = returns true if hand attack range 428 | = 429 | ================= 430 | */ 431 | 432 | boolean Chase (objtype *ob, boolean diagonal) 433 | { 434 | long move; 435 | long deltax,deltay,size; 436 | 437 | move = ob->speed*tics; 438 | size = (long)ob->size + player->size + move; 439 | 440 | while (move) 441 | { 442 | deltax = ob->x - player->x; 443 | deltay = ob->y - player->y; 444 | 445 | if (deltax <= size && deltax >= -size 446 | && deltay <= size && deltay >= -size) 447 | { 448 | CalcBounds (ob); 449 | return true; 450 | } 451 | 452 | if (move < ob->distance) 453 | { 454 | MoveObj (ob,move); 455 | break; 456 | } 457 | actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal 458 | if (ob->dir == nodir) 459 | ob->dir = north; 460 | 461 | ob->x = ((long)ob->tilex<y = ((long)ob->tiley<distance; 464 | 465 | ChaseThink (ob,diagonal); 466 | if (!ob->distance) 467 | break; // no possible move 468 | actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker 469 | } 470 | CalcBounds (ob); 471 | return false; 472 | } 473 | 474 | //=========================================================================== 475 | 476 | 477 | /* 478 | =================== 479 | = 480 | = ShootActor 481 | = 482 | =================== 483 | */ 484 | 485 | void ShootActor (objtype *ob, unsigned damage) 486 | { 487 | ob->hitpoints -= damage; 488 | if (ob->hitpoints<=0) 489 | { 490 | switch (ob->obclass) 491 | { 492 | case orcobj: 493 | ob->state = &s_orcdie1; 494 | GivePoints (100); 495 | break; 496 | case trollobj: 497 | ob->state = &s_trolldie1; 498 | GivePoints (400); 499 | break; 500 | case demonobj: 501 | ob->state = &s_demondie1; 502 | GivePoints (1000); 503 | break; 504 | case mageobj: 505 | ob->state = &s_magedie1; 506 | GivePoints (600); 507 | break; 508 | case batobj: 509 | ob->state = &s_batdie1; 510 | GivePoints (100); 511 | break; 512 | case grelmobj: 513 | ob->state = &s_greldie1; 514 | GivePoints (10000); 515 | break; 516 | 517 | } 518 | ob->obclass = inertobj; 519 | ob->shootable = false; 520 | actorat[ob->tilex][ob->tiley] = NULL; 521 | } 522 | else 523 | { 524 | switch (ob->obclass) 525 | { 526 | case orcobj: 527 | ob->state = &s_orcouch; 528 | break; 529 | case trollobj: 530 | ob->state = &s_trollouch; 531 | break; 532 | case demonobj: 533 | ob->state = &s_demonouch; 534 | break; 535 | case mageobj: 536 | ob->state = &s_mageouch; 537 | break; 538 | case grelmobj: 539 | ob->state = &s_grelouch; 540 | break; 541 | 542 | } 543 | } 544 | ob->ticcount = ob->state->tictime; 545 | } 546 | 547 | -------------------------------------------------------------------------------- /C3_DEBUG.C: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // C3_DEBUG.C 20 | 21 | #include "C3_DEF.H" 22 | #pragma hdrstop 23 | 24 | /* 25 | ============================================================================= 26 | 27 | LOCAL CONSTANTS 28 | 29 | ============================================================================= 30 | */ 31 | 32 | #define VIEWTILEX 20 33 | #define VIEWTILEY (VIEWHEIGHT/16) 34 | 35 | /* 36 | ============================================================================= 37 | 38 | GLOBAL VARIABLES 39 | 40 | ============================================================================= 41 | */ 42 | 43 | 44 | /* 45 | ============================================================================= 46 | 47 | LOCAL VARIABLES 48 | 49 | ============================================================================= 50 | */ 51 | 52 | 53 | int maporgx; 54 | int maporgy; 55 | enum {mapview,tilemapview,actoratview,visview} viewtype; 56 | 57 | void ViewMap (void); 58 | 59 | //=========================================================================== 60 | 61 | 62 | 63 | /* 64 | ================== 65 | = 66 | = DebugMemory 67 | = 68 | ================== 69 | */ 70 | 71 | void DebugMemory (void) 72 | { 73 | int i; 74 | char scratch[80],str[10]; 75 | long mem; 76 | spritetype _seg *block; 77 | 78 | VW_FixRefreshBuffer (); 79 | US_CenterWindow (16,7); 80 | 81 | #if 0 82 | CA_OpenDebug (); 83 | for (i=0;i=0;y--) 145 | VW_ScreenToScreen (source+y*64,y*40,40,1); 146 | } 147 | 148 | IN_Shutdown (); 149 | 150 | VW_WaitVBL(70); 151 | bioskey(0); 152 | VW_WaitVBL(70); 153 | Quit (NULL); 154 | } 155 | 156 | 157 | //=========================================================================== 158 | 159 | /* 160 | ================ 161 | = 162 | = ShapeTest 163 | = 164 | ================ 165 | */ 166 | 167 | void ShapeTest (void) 168 | { 169 | 170 | } 171 | 172 | 173 | //=========================================================================== 174 | 175 | #define sc_1 0x02 176 | #define sc_2 0x03 177 | #define sc_3 0x04 178 | #define sc_4 0x05 179 | #define sc_5 0x06 180 | #define sc_6 0x07 181 | #define sc_7 0x08 182 | #define sc_8 0x09 183 | #define sc_9 0x0a 184 | #define sc_0 0x0b 185 | 186 | 187 | 188 | /* 189 | ================ 190 | = 191 | = DebugKeys 192 | = 193 | ================ 194 | */ 195 | 196 | int DebugKeys (void) 197 | { 198 | boolean esc; 199 | int level,i; 200 | 201 | if (Keyboard[sc_B]) // B = border color 202 | { 203 | CenterWindow(24,3); 204 | PrintY+=6; 205 | US_Print(" Border color (0-15):"); 206 | VW_UpdateScreen(); 207 | esc = !US_LineInput (px,py,str,NULL,true,2,0); 208 | if (!esc) 209 | { 210 | level = atoi (str); 211 | if (level>=0 && level<=15) 212 | VW_ColorBorder (level); 213 | } 214 | return 1; 215 | } 216 | 217 | #if 0 218 | 219 | if (Keyboard[sc_C]) // C = count objects 220 | { 221 | CountObjects(); 222 | return 1; 223 | } 224 | 225 | 226 | if (Keyboard[sc_D]) // D = start / end demo record 227 | { 228 | if (DemoMode == demo_Off) 229 | StartDemoRecord (); 230 | else if (DemoMode == demo_Record) 231 | { 232 | EndDemoRecord (); 233 | playstate = ex_completed; 234 | } 235 | return 1; 236 | } 237 | 238 | #endif 239 | 240 | if (Keyboard[sc_E]) // E = quit level 241 | { 242 | if (tedlevel) 243 | TEDDeath(); 244 | playstate = ex_warped; 245 | gamestate.mapon++; 246 | } 247 | 248 | if (Keyboard[sc_F]) // F = facing spot 249 | { 250 | CenterWindow (12,4); 251 | US_Print ("X:"); 252 | US_PrintUnsigned (player->x); 253 | US_Print ("Y:"); 254 | US_PrintUnsigned (player->y); 255 | US_Print ("A:"); 256 | US_PrintUnsigned (player->angle); 257 | VW_UpdateScreen(); 258 | IN_Ack(); 259 | return 1; 260 | } 261 | 262 | if (Keyboard[sc_G]) // G = god mode 263 | { 264 | CenterWindow (12,2); 265 | if (godmode) 266 | US_PrintCentered ("God mode OFF"); 267 | else 268 | US_PrintCentered ("God mode ON"); 269 | VW_UpdateScreen(); 270 | IN_Ack(); 271 | godmode ^= 1; 272 | return 1; 273 | } 274 | if (Keyboard[sc_H]) // H = hurt self 275 | { 276 | TakeDamage (5); 277 | } 278 | else if (Keyboard[sc_I]) // I = item cheat 279 | { 280 | CenterWindow (12,3); 281 | US_PrintCentered ("Free items!"); 282 | VW_UpdateScreen(); 283 | for (i=0;i<4;i++) 284 | { 285 | GiveBolt (); 286 | GiveNuke (); 287 | GivePotion (); 288 | if (!gamestate.keys[i]) 289 | GiveKey (i); 290 | } 291 | for (i=0;i<8;i++) 292 | GiveScroll (i,false); 293 | 294 | IN_Ack (); 295 | return 1; 296 | } 297 | else if (Keyboard[sc_M]) // M = memory info 298 | { 299 | DebugMemory(); 300 | return 1; 301 | } 302 | else if (Keyboard[sc_O]) // O = overhead 303 | { 304 | ViewMap(); 305 | return 1; 306 | } 307 | else if (Keyboard[sc_P]) // P = pause with no screen disruptioon 308 | { 309 | PicturePause (); 310 | return 1; 311 | } 312 | else if (Keyboard[sc_S]) // S = slow motion 313 | { 314 | singlestep^=1; 315 | CenterWindow (18,3); 316 | if (singlestep) 317 | US_PrintCentered ("Slow motion ON"); 318 | else 319 | US_PrintCentered ("Slow motion OFF"); 320 | VW_UpdateScreen(); 321 | IN_Ack (); 322 | return 1; 323 | } 324 | else if (Keyboard[sc_S]) // T = shape test 325 | { 326 | ShapeTest (); 327 | return 1; 328 | } 329 | else if (Keyboard[sc_V]) // V = extra VBLs 330 | { 331 | CenterWindow(30,3); 332 | PrintY+=6; 333 | US_Print(" Add how many extra VBLs(0-8):"); 334 | VW_UpdateScreen(); 335 | esc = !US_LineInput (px,py,str,NULL,true,2,0); 336 | if (!esc) 337 | { 338 | level = atoi (str); 339 | if (level>=0 && level<=8) 340 | extravbls = level; 341 | } 342 | return 1; 343 | } 344 | else if (Keyboard[sc_W]) // W = warp to level 345 | { 346 | CenterWindow(26,3); 347 | PrintY+=6; 348 | US_Print(" Warp to which level(1-21):"); 349 | VW_UpdateScreen(); 350 | esc = !US_LineInput (px,py,str,NULL,true,2,0); 351 | if (!esc) 352 | { 353 | level = atoi (str); 354 | if (level>0 && level<21) 355 | { 356 | gamestate.mapon = level-1; 357 | playstate = ex_warped; 358 | } 359 | } 360 | return 1; 361 | } 362 | else if (Keyboard[sc_X]) // X = item cheat 363 | { 364 | CenterWindow (12,3); 365 | US_PrintCentered ("Extra stuff!"); 366 | VW_UpdateScreen(); 367 | for (i=0;i<4;i++) 368 | { 369 | GiveBolt (); 370 | GiveNuke (); 371 | GivePotion (); 372 | } 373 | IN_Ack (); 374 | return 1; 375 | } 376 | else if (Keyboard[sc_Z]) // Z = game over 377 | { 378 | 379 | } 380 | else if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls 381 | { 382 | GiveScroll (LastScan-sc_1,false); 383 | IN_ClearKeysDown (); 384 | } 385 | 386 | return 0; 387 | } 388 | 389 | 390 | /* 391 | ===================== 392 | = 393 | = LatchDrawChar 394 | = 395 | ===================== 396 | */ 397 | 398 | void LatchDrawChar (unsigned x, unsigned y, unsigned picnum) 399 | { 400 | unsigned source, dest; 401 | 402 | dest = bufferofs + ylookup[y]+x; 403 | source = latchpics[0]+picnum*8; 404 | 405 | EGAWRITEMODE(1); 406 | EGAMAPMASK(15); 407 | 408 | asm mov bx,[linewidth] 409 | asm dec bx 410 | 411 | asm mov ax,[screenseg] 412 | asm mov es,ax 413 | asm mov ds,ax 414 | 415 | asm mov si,[source] 416 | asm mov di,[dest] 417 | 418 | asm movsb 419 | asm add di,bx 420 | asm movsb 421 | asm add di,bx 422 | asm movsb 423 | asm add di,bx 424 | asm movsb 425 | asm add di,bx 426 | asm movsb 427 | asm add di,bx 428 | asm movsb 429 | asm add di,bx 430 | asm movsb 431 | asm add di,bx 432 | asm movsb 433 | 434 | asm mov ax,ss 435 | asm mov ds,ax // restore turbo's data segment 436 | 437 | EGAWRITEMODE(0); 438 | } 439 | 440 | 441 | /* 442 | ===================== 443 | = 444 | = LatchDrawTile 445 | = 446 | ===================== 447 | */ 448 | 449 | void LatchDrawTile (unsigned x, unsigned y, unsigned picnum) 450 | { 451 | unsigned source, dest; 452 | 453 | dest = bufferofs + ylookup[y]+x; 454 | source = tileoffsets[picnum]; 455 | 456 | EGAWRITEMODE(1); 457 | EGAMAPMASK(15); 458 | 459 | asm mov bx,[linewidth] 460 | asm sub bx,2 461 | 462 | asm mov ax,[screenseg] 463 | asm mov es,ax 464 | asm mov ds,ax 465 | 466 | asm mov si,[source] 467 | asm mov di,[dest] 468 | asm mov dx,16 469 | 470 | lineloop: 471 | asm movsb 472 | asm movsb 473 | asm add di,bx 474 | 475 | asm dec dx 476 | asm jnz lineloop 477 | 478 | asm mov ax,ss 479 | asm mov ds,ax // restore turbo's data segment 480 | 481 | EGAWRITEMODE(0); 482 | } 483 | 484 | 485 | /* 486 | =================== 487 | = 488 | = OverheadRefresh 489 | = 490 | =================== 491 | */ 492 | 493 | void OverheadRefresh (void) 494 | { 495 | unsigned x,y,endx,endy,sx,sy; 496 | unsigned tile; 497 | 498 | 499 | if (++screenpage == 3) 500 | screenpage = 0; 501 | 502 | bufferofs = screenloc[screenpage]; 503 | 504 | endx = maporgx+VIEWTILEX; 505 | endy = maporgy+VIEWTILEY; 506 | 507 | for (y=maporgy;y>12)); 538 | LatchDrawChar(sx+1,sy,NUMBERCHARS+((tile&0x0f00)>>8)); 539 | LatchDrawChar(sx,sy+8,NUMBERCHARS+((tile&0x00f0)>>4)); 540 | LatchDrawChar(sx+1,sy+8,NUMBERCHARS+(tile&0x000f)); 541 | } 542 | } 543 | 544 | VW_SetScreen (bufferofs,0); 545 | displayofs = bufferofs; 546 | } 547 | 548 | 549 | /* 550 | =================== 551 | = 552 | = ViewMap 553 | = 554 | =================== 555 | */ 556 | 557 | void ViewMap (void) 558 | { 559 | boolean button0held; 560 | 561 | viewtype = actoratview; 562 | button0held = false; 563 | 564 | 565 | maporgx = player->tilex - VIEWTILEX/2; 566 | if (maporgx<0) 567 | maporgx = 0; 568 | maporgy = player->tiley - VIEWTILEY/2; 569 | if (maporgy<0) 570 | maporgy = 0; 571 | 572 | do 573 | { 574 | // 575 | // let user pan around 576 | // 577 | IN_ReadControl(0,&c); 578 | if (c.xaxis == -1 && maporgx>0) 579 | maporgx--; 580 | if (c.xaxis == 1 && maporgx0) 583 | maporgy--; 584 | if (c.yaxis == 1 && maporgyvisview) 592 | viewtype = mapview; 593 | } 594 | if (!c.button0) 595 | button0held = false; 596 | 597 | 598 | OverheadRefresh (); 599 | 600 | } while (!Keyboard[sc_Escape]); 601 | 602 | IN_ClearKeysDown (); 603 | DrawPlayScreen (); 604 | } 605 | 606 | 607 | -------------------------------------------------------------------------------- /C3_PLAY.C: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // C3_PLAY.C 20 | 21 | #include "C3_DEF.H" 22 | #pragma hdrstop 23 | 24 | /* 25 | ============================================================================= 26 | 27 | LOCAL CONSTANTS 28 | 29 | ============================================================================= 30 | */ 31 | 32 | #define POINTTICS 6 33 | 34 | 35 | /* 36 | ============================================================================= 37 | 38 | GLOBAL VARIABLES 39 | 40 | ============================================================================= 41 | */ 42 | 43 | ControlInfo c; 44 | boolean running,slowturn; 45 | 46 | int bordertime; 47 | objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist; 48 | 49 | unsigned farmapylookup[MAPSIZE]; 50 | byte *nearmapylookup[MAPSIZE]; 51 | 52 | boolean singlestep,godmode; 53 | int extravbls; 54 | 55 | // 56 | // replacing refresh manager 57 | // 58 | unsigned mapwidth,mapheight,tics; 59 | boolean compatability; 60 | byte *updateptr; 61 | unsigned mapwidthtable[64]; 62 | unsigned uwidthtable[UPDATEHIGH]; 63 | unsigned blockstarts[UPDATEWIDE*UPDATEHIGH]; 64 | #define UPDATESCREENSIZE (UPDATEWIDE*PORTTILESHIGH+2) 65 | #define UPDATESPARESIZE (UPDATEWIDE*2+4) 66 | #define UPDATESIZE (UPDATESCREENSIZE+2*UPDATESPARESIZE) 67 | byte update[UPDATESIZE]; 68 | 69 | int mousexmove,mouseymove; 70 | int pointcount,pointsleft; 71 | 72 | /* 73 | ============================================================================= 74 | 75 | LOCAL VARIABLES 76 | 77 | ============================================================================= 78 | */ 79 | 80 | void CalcBounds (objtype *ob); 81 | void DrawPlayScreen (void); 82 | 83 | 84 | // 85 | // near data map array (wall values only, get text number from far data) 86 | // 87 | byte tilemap[MAPSIZE][MAPSIZE]; 88 | byte spotvis[MAPSIZE][MAPSIZE]; 89 | objtype *actorat[MAPSIZE][MAPSIZE]; 90 | 91 | objtype dummyobj; 92 | 93 | int bordertime; 94 | int objectcount; 95 | 96 | void StopMusic(void); 97 | void StartMusic(void); 98 | 99 | 100 | //========================================================================== 101 | 102 | /////////////////////////////////////////////////////////////////////////// 103 | // 104 | // CenterWindow() - Generates a window of a given width & height in the 105 | // middle of the screen 106 | // 107 | /////////////////////////////////////////////////////////////////////////// 108 | 109 | #define MAXX 264 110 | #define MAXY 146 111 | 112 | void CenterWindow(word w,word h) 113 | { 114 | US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h); 115 | } 116 | 117 | //=========================================================================== 118 | 119 | 120 | /* 121 | ===================== 122 | = 123 | = CheckKeys 124 | = 125 | ===================== 126 | */ 127 | 128 | void CheckKeys (void) 129 | { 130 | if (screenfaded) // don't do anything with a faded screen 131 | return; 132 | 133 | // 134 | // pause key wierdness can't be checked as a scan code 135 | // 136 | if (Paused) 137 | { 138 | CenterWindow (8,3); 139 | US_PrintCentered ("PAUSED"); 140 | VW_UpdateScreen (); 141 | SD_MusicOff(); 142 | IN_Ack(); 143 | SD_MusicOn(); 144 | Paused = false; 145 | if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement 146 | } 147 | 148 | // 149 | // F1-F7/ESC to enter control panel 150 | // 151 | if ( (LastScan >= sc_F1 && LastScan <= sc_F7) || LastScan == sc_Escape) 152 | { 153 | StopMusic (); 154 | NormalScreen (); 155 | FreeUpMemory (); 156 | US_CenterWindow (20,8); 157 | US_CPrint ("Loading"); 158 | VW_UpdateScreen (); 159 | US_ControlPanel(); 160 | if (abortgame) 161 | { 162 | playstate = ex_abort; 163 | return; 164 | } 165 | StartMusic (); 166 | IN_ClearKeysDown(); 167 | if (restartgame) 168 | playstate = ex_resetgame; 169 | if (loadedgame) 170 | playstate = ex_loadedgame; 171 | DrawPlayScreen (); 172 | CacheScaleds (); 173 | lasttimecount = TimeCount; 174 | if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement 175 | } 176 | 177 | // 178 | // F10-? debug keys 179 | // 180 | if (Keyboard[sc_F10]) 181 | { 182 | DebugKeys(); 183 | if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement 184 | lasttimecount = TimeCount; 185 | } 186 | 187 | } 188 | 189 | 190 | //=========================================================================== 191 | 192 | /* 193 | ############################################################################# 194 | 195 | The objlist data structure 196 | 197 | ############################################################################# 198 | 199 | objlist containt structures for every actor currently playing. The structure 200 | is accessed as a linked list starting at *player, ending when ob->next == 201 | NULL. GetNewObj inserts a new object at the end of the list, meaning that 202 | if an actor spawn another actor, the new one WILL get to think and react the 203 | same frame. RemoveObj unlinks the given object and returns it to the free 204 | list, but does not damage the objects ->next pointer, so if the current object 205 | removes itself, a linked list following loop can still safely get to the 206 | next element. 207 | 208 | 209 | 210 | ############################################################################# 211 | */ 212 | 213 | 214 | /* 215 | ========================= 216 | = 217 | = InitObjList 218 | = 219 | = Call to clear out the entire object list, returning them all to the free 220 | = list. Allocates a special spot for the player. 221 | = 222 | ========================= 223 | */ 224 | 225 | void InitObjList (void) 226 | { 227 | int i; 228 | 229 | for (i=0;iprev; 279 | memset (new,0,sizeof(*new)); 280 | 281 | if (lastobj) 282 | lastobj->next = new; 283 | new->prev = lastobj; // new->next is allready NULL from memset 284 | 285 | new->active = false; 286 | lastobj = new; 287 | 288 | objectcount++; 289 | } 290 | 291 | //=========================================================================== 292 | 293 | /* 294 | ========================= 295 | = 296 | = RemoveObj 297 | = 298 | = Add the given object back into the free list, and unlink it from it's 299 | = neighbors 300 | = 301 | ========================= 302 | */ 303 | 304 | void RemoveObj (objtype *gone) 305 | { 306 | objtype **spotat; 307 | 308 | if (gone == player) 309 | Quit ("RemoveObj: Tried to remove the player!"); 310 | 311 | // 312 | // fix the next object's back link 313 | // 314 | if (gone == lastobj) 315 | lastobj = (objtype *)gone->prev; 316 | else 317 | gone->next->prev = gone->prev; 318 | 319 | // 320 | // fix the previous object's forward link 321 | // 322 | gone->prev->next = gone->next; 323 | 324 | // 325 | // add it back in to the free list 326 | // 327 | gone->prev = objfreelist; 328 | objfreelist = gone; 329 | } 330 | 331 | //========================================================================== 332 | 333 | /* 334 | =================== 335 | = 336 | = PollControls 337 | = 338 | =================== 339 | */ 340 | 341 | void PollControls (void) 342 | { 343 | unsigned buttons; 344 | 345 | IN_ReadControl(0,&c); 346 | 347 | if (MousePresent) 348 | { 349 | Mouse(MButtons); 350 | buttons = _BX; 351 | Mouse(MDelta); 352 | mousexmove = _CX; 353 | mouseymove = _DX; 354 | 355 | if (buttons&1) 356 | c.button0 = 1; 357 | if (buttons&2) 358 | c.button1 = 1; 359 | 360 | } 361 | 362 | if (Controls[0]==ctrl_Joystick) 363 | { 364 | if (c.x>120 || c.x <-120 || c.y>120 || c.y<-120) 365 | running = true; 366 | else 367 | running = false; 368 | if (c.x>-48 && c.x<48) 369 | slowturn = true; 370 | else 371 | slowturn = false; 372 | } 373 | else 374 | { 375 | if (Keyboard[sc_RShift]) 376 | running = true; 377 | else 378 | running = false; 379 | if (c.button0) 380 | slowturn = true; 381 | else 382 | slowturn = false; 383 | } 384 | } 385 | 386 | //========================================================================== 387 | 388 | /* 389 | ================= 390 | = 391 | = StopMusic 392 | = 393 | ================= 394 | */ 395 | 396 | void StopMusic(void) 397 | { 398 | int i; 399 | 400 | SD_MusicOff(); 401 | for (i = 0;i < LASTMUSIC;i++) 402 | if (audiosegs[STARTMUSIC + i]) 403 | { 404 | MM_SetPurge(&((memptr)audiosegs[STARTMUSIC + i]),3); 405 | MM_SetLock(&((memptr)audiosegs[STARTMUSIC + i]),false); 406 | } 407 | } 408 | 409 | //========================================================================== 410 | 411 | 412 | /* 413 | ================= 414 | = 415 | = StartMusic 416 | = 417 | ================= 418 | */ 419 | 420 | // JAB - Cache & start the appropriate music for this level 421 | void StartMusic(void) 422 | { 423 | musicnames chunk; 424 | 425 | SD_MusicOff(); 426 | chunk = TOOHOT_MUS; 427 | // if ((chunk == -1) || (MusicMode != smm_AdLib)) 428 | //DEBUG control panel return; 429 | 430 | MM_BombOnError (false); 431 | CA_CacheAudioChunk(STARTMUSIC + chunk); 432 | MM_BombOnError (true); 433 | if (mmerror) 434 | mmerror = false; 435 | else 436 | { 437 | MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true); 438 | SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]); 439 | } 440 | } 441 | 442 | //========================================================================== 443 | 444 | 445 | /* 446 | =================== 447 | = 448 | = PlayLoop 449 | = 450 | =================== 451 | */ 452 | 453 | void PlayLoop (void) 454 | { 455 | int give; 456 | 457 | void (*think)(); 458 | 459 | ingame = true; 460 | playstate = TimeCount = 0; 461 | gamestate.shotpower = handheight = 0; 462 | pointcount = pointsleft = 0; 463 | 464 | DrawLevelNumber (gamestate.mapon); 465 | DrawBars (); 466 | 467 | #ifndef PROFILE 468 | fizzlein = true; // fizzle fade in the first refresh 469 | #endif 470 | TimeCount = lasttimecount = lastnuke = 0; 471 | 472 | PollControls (); // center mouse 473 | StartMusic (); 474 | do 475 | { 476 | #ifndef PROFILE 477 | PollControls(); 478 | #else 479 | c.xaxis = 1; 480 | if (++TimeCount == 300) 481 | return; 482 | #endif 483 | 484 | for (obj = player;obj;obj = obj->next) 485 | if (obj->active) 486 | { 487 | if (obj->ticcount) 488 | { 489 | obj->ticcount-=tics; 490 | while ( obj->ticcount <= 0) 491 | { 492 | think = obj->state->think; 493 | if (think) 494 | { 495 | think (obj); 496 | if (!obj->state) 497 | { 498 | RemoveObj (obj); 499 | goto nextactor; 500 | } 501 | } 502 | 503 | obj->state = obj->state->next; 504 | if (!obj->state) 505 | { 506 | RemoveObj (obj); 507 | goto nextactor; 508 | } 509 | if (!obj->state->tictime) 510 | { 511 | obj->ticcount = 0; 512 | goto nextactor; 513 | } 514 | if (obj->state->tictime>0) 515 | obj->ticcount += obj->state->tictime; 516 | } 517 | } 518 | think = obj->state->think; 519 | if (think) 520 | { 521 | think (obj); 522 | if (!obj->state) 523 | RemoveObj (obj); 524 | } 525 | nextactor:; 526 | } 527 | 528 | 529 | if (bordertime) 530 | { 531 | bordertime -= tics; 532 | if (bordertime<=0) 533 | { 534 | bordertime = 0; 535 | VW_ColorBorder (3); 536 | } 537 | } 538 | 539 | if (pointcount) 540 | { 541 | pointcount -= tics; 542 | if (pointcount <= 0) 543 | { 544 | pointcount += POINTTICS; 545 | give = (pointsleft > 1000)? 1000 : 546 | ( 547 | (pointsleft > 100)? 100 : 548 | ((pointsleft < 20)? pointsleft : 20) 549 | ); 550 | SD_PlaySound (GETPOINTSSND); 551 | AddPoints (give); 552 | pointsleft -= give; 553 | if (!pointsleft) 554 | pointcount = 0; 555 | } 556 | } 557 | 558 | ThreeDRefresh (); 559 | 560 | CheckKeys(); 561 | if (singlestep) 562 | { 563 | VW_WaitVBL(14); 564 | lasttimecount = TimeCount; 565 | } 566 | if (extravbls) 567 | VW_WaitVBL(extravbls); 568 | 569 | }while (!playstate); 570 | StopMusic (); 571 | 572 | ingame = false; 573 | if (bordertime) 574 | { 575 | bordertime = 0; 576 | VW_ColorBorder (3); 577 | } 578 | 579 | if (!abortgame) 580 | AddPoints (pointsleft); 581 | else 582 | abortgame = false; 583 | } 584 | 585 | -------------------------------------------------------------------------------- /C3_DEF.H: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #include "ID_HEADS.H" 20 | #include 21 | #include 22 | 23 | //#define PROFILE 24 | 25 | /* 26 | ============================================================================= 27 | 28 | GLOBAL CONSTANTS 29 | 30 | ============================================================================= 31 | */ 32 | 33 | #define NAMESTART 180 34 | 35 | 36 | #define UNMARKGRCHUNK(chunk) (grneeded[chunk]&=~ca_levelbit) 37 | 38 | #define MOUSEINT 0x33 39 | 40 | #define EXPWALLSTART 8 41 | #define NUMEXPWALLS 7 42 | #define WALLEXP 15 43 | #define NUMFLOORS 36 44 | 45 | #define NUMFLOORS 36 46 | 47 | #define NUMLATCHPICS 100 48 | #define NUMSCALEPICS 100 49 | #define NUMSCALEWALLS 30 50 | 51 | 52 | #define FLASHCOLOR 5 53 | #define FLASHTICS 4 54 | 55 | 56 | #define NUMLEVELS 20 57 | 58 | #define VIEWX 0 // corner of view window 59 | #define VIEWY 0 60 | #define VIEWWIDTH (33*8) // size of view window 61 | #define VIEWHEIGHT (18*8) 62 | #define VIEWXH (VIEWX+VIEWWIDTH-1) 63 | #define VIEWYH (VIEWY+VIEWHEIGHT-1) 64 | 65 | #define CENTERX (VIEWX+VIEWWIDTH/2-1) // middle of view window 66 | #define CENTERY (VIEWY+VIEWHEIGHT/2-1) 67 | 68 | #define GLOBAL1 (1l<<16) 69 | #define TILEGLOBAL GLOBAL1 70 | #define TILESHIFT 16l 71 | 72 | #define MINDIST (2*GLOBAL1/5) 73 | #define FOCALLENGTH (TILEGLOBAL) // in global coordinates 74 | 75 | #define ANGLES 360 // must be divisable by 4 76 | 77 | #define MAPSIZE 64 // maps are 64*64 max 78 | #define MAXACTORS 150 // max number of tanks, etc / map 79 | 80 | #define NORTH 0 81 | #define EAST 1 82 | #define SOUTH 2 83 | #define WEST 3 84 | 85 | #define SIGN(x) ((x)>0?1:-1) 86 | #define ABS(x) ((int)(x)>0?(x):-(x)) 87 | #define LABS(x) ((long)(x)>0?(x):-(x)) 88 | 89 | #define MAXSCALE (VIEWWIDTH/2) 90 | 91 | 92 | #define MAXBODY 64 93 | #define MAXSHOTPOWER 56 94 | 95 | #define SCREEN1START 0 96 | #define SCREEN2START 8320 97 | 98 | #define PAGE1START 0x900 99 | #define PAGE2START 0x2000 100 | #define PAGE3START 0x3700 101 | #define FREESTART 0x4e00 102 | 103 | #define PIXRADIUS 512 104 | 105 | #define STATUSLINES (200-VIEWHEIGHT) 106 | 107 | enum bonusnumbers {B_BOLT,B_NUKE,B_POTION,B_RKEY,B_YKEY,B_GKEY,B_BKEY,B_SCROLL1, 108 | B_SCROLL2,B_SCROLL3,B_SCROLL4,B_SCROLL5,B_SCROLL6,B_SCROLL7,B_SCROLL8, 109 | B_GOAL,B_CHEST}; 110 | 111 | 112 | /* 113 | ============================================================================= 114 | 115 | GLOBAL TYPES 116 | 117 | ============================================================================= 118 | */ 119 | 120 | enum {BLANKCHAR=9,BOLTCHAR,NUKECHAR,POTIONCHAR,KEYCHARS,SCROLLCHARS=17, 121 | NUMBERCHARS=25}; 122 | 123 | typedef long fixed; 124 | 125 | typedef struct {int x,y;} tilept; 126 | typedef struct {fixed x,y;} globpt; 127 | 128 | typedef struct 129 | { 130 | int x1,x2,leftclip,rightclip;// first pixel of wall (may not be visable) 131 | unsigned height1,height2,color,walllength,side; 132 | long planecoord; 133 | } walltype; 134 | 135 | typedef enum 136 | {nothing,playerobj,bonusobj,orcobj,batobj,skeletonobj,trollobj,demonobj, 137 | mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj 138 | ,gateobj} classtype; 139 | 140 | typedef enum {north,east,south,west,northeast,southeast,southwest, 141 | northwest,nodir} dirtype; // a catacombs 2 carryover 142 | 143 | 144 | typedef struct statestruct 145 | { 146 | int shapenum; 147 | int tictime; 148 | void (*think) (); 149 | struct statestruct *next; 150 | } statetype; 151 | 152 | 153 | typedef struct objstruct 154 | { 155 | enum {no,yes} active; 156 | int ticcount; 157 | classtype obclass; 158 | statetype *state; 159 | 160 | boolean shootable; 161 | boolean tileobject; // true if entirely inside one tile 162 | 163 | long distance; 164 | dirtype dir; 165 | fixed x,y; 166 | unsigned tilex,tiley; 167 | int viewx; 168 | unsigned viewheight; 169 | 170 | int angle; 171 | int hitpoints; 172 | long speed; 173 | 174 | unsigned size; // global radius for hit rect calculation 175 | fixed xl,xh,yl,yh; // hit rectangle 176 | 177 | int temp1,temp2; 178 | struct objstruct *next,*prev; 179 | } objtype; 180 | 181 | 182 | typedef struct 183 | { 184 | int difficulty; 185 | int mapon; 186 | int bolts,nukes,potions,keys[4],scrolls[8]; 187 | long score; 188 | int body,shotpower; 189 | } gametype; 190 | 191 | typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame 192 | ,ex_loadedgame,ex_victorious,ex_abort} exittype; 193 | 194 | 195 | /* 196 | ============================================================================= 197 | 198 | C3_MAIN DEFINITIONS 199 | 200 | ============================================================================= 201 | */ 202 | 203 | extern char str[80],str2[20]; 204 | extern unsigned tedlevelnum; 205 | extern boolean tedlevel; 206 | extern gametype gamestate; 207 | extern exittype playstate; 208 | 209 | 210 | void NewGame (void); 211 | boolean SaveTheGame(int file); 212 | boolean LoadTheGame(int file); 213 | void ResetGame(void); 214 | void ShutdownId (void); 215 | void InitGame (void); 216 | void Quit (char *error); 217 | void TEDDeath(void); 218 | void DemoLoop (void); 219 | void SetupScalePic (unsigned picnum); 220 | void SetupScaleWall (unsigned picnum); 221 | void SetupScaling (void); 222 | void main (void); 223 | 224 | /* 225 | ============================================================================= 226 | 227 | C3_GAME DEFINITIONS 228 | 229 | ============================================================================= 230 | */ 231 | 232 | extern unsigned latchpics[NUMLATCHPICS]; 233 | extern unsigned tileoffsets[NUMTILE16]; 234 | extern unsigned textstarts[27]; 235 | 236 | 237 | #define L_CHARS 0 238 | #define L_NOSHOT 1 239 | #define L_SHOTBAR 2 240 | #define L_NOBODY 3 241 | #define L_BODYBAR 4 242 | 243 | 244 | void ScanInfoPlane (void); 245 | void ScanText (void); 246 | void SetupGameLevel (void); 247 | void Victory (void); 248 | void Died (void); 249 | void NormalScreen (void); 250 | void DrawPlayScreen (void); 251 | void LoadLatchMem (void); 252 | void FizzleFade (unsigned source, unsigned dest, 253 | unsigned width,unsigned height, boolean abortable); 254 | void FizzleOut (int showlevel); 255 | void FreeUpMemory (void); 256 | void GameLoop (void); 257 | 258 | 259 | /* 260 | ============================================================================= 261 | 262 | C3_PLAY DEFINITIONS 263 | 264 | ============================================================================= 265 | */ 266 | 267 | extern ControlInfo c; 268 | extern boolean running,slowturn; 269 | 270 | extern int bordertime; 271 | 272 | extern byte tilemap[MAPSIZE][MAPSIZE]; 273 | extern objtype *actorat[MAPSIZE][MAPSIZE]; 274 | extern byte spotvis[MAPSIZE][MAPSIZE]; 275 | 276 | extern objtype objlist[MAXACTORS],*new,*obj,*player; 277 | 278 | extern unsigned farmapylookup[MAPSIZE]; 279 | extern byte *nearmapylookup[MAPSIZE]; 280 | extern byte update[]; 281 | 282 | extern boolean godmode,singlestep; 283 | extern int extravbls; 284 | 285 | extern int mousexmove,mouseymove; 286 | extern int pointcount,pointsleft; 287 | 288 | 289 | void CenterWindow(word w,word h); 290 | void DebugMemory (void); 291 | void PicturePause (void); 292 | int DebugKeys (void); 293 | void CheckKeys (void); 294 | void InitObjList (void); 295 | void GetNewObj (boolean usedummy); 296 | void RemoveObj (objtype *gone); 297 | void PollControlls (void); 298 | void PlayLoop (void); 299 | 300 | 301 | /* 302 | ============================================================================= 303 | 304 | C3_STATE DEFINITIONS 305 | 306 | ============================================================================= 307 | */ 308 | 309 | void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size); 310 | void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size); 311 | boolean CheckHandAttack (objtype *ob); 312 | void T_DoDamage (objtype *ob); 313 | boolean Walk (objtype *ob); 314 | void ChaseThink (objtype *obj, boolean diagonal); 315 | void MoveObj (objtype *ob, long move); 316 | boolean Chase (objtype *ob, boolean diagonal); 317 | 318 | extern dirtype opposite[9]; 319 | 320 | /* 321 | ============================================================================= 322 | 323 | C3_TRACE DEFINITIONS 324 | 325 | ============================================================================= 326 | */ 327 | 328 | int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max); 329 | int BackTrace (int finish); 330 | void ForwardTrace (void); 331 | int FinishWall (void); 332 | void InsideCorner (void); 333 | void OutsideCorner (void); 334 | void FollowWalls (void); 335 | 336 | extern boolean aborttrace; 337 | 338 | /* 339 | ============================================================================= 340 | 341 | C3_DRAW DEFINITIONS 342 | 343 | ============================================================================= 344 | */ 345 | 346 | #define MAXWALLS 50 347 | #define DANGERHIGH 45 348 | 349 | #define MIDWALL (MAXWALLS/2) 350 | 351 | //========================================================================== 352 | 353 | extern tilept tile,lasttile,focal,left,mid,right; 354 | 355 | extern globpt edge,view; 356 | 357 | extern unsigned screenloc[3]; 358 | extern unsigned freelatch; 359 | 360 | extern int screenpage; 361 | 362 | extern boolean fizzlein; 363 | 364 | extern long lasttimecount; 365 | 366 | extern int firstangle,lastangle; 367 | 368 | extern fixed prestep; 369 | 370 | extern int traceclip,tracetop; 371 | 372 | extern fixed sintable[ANGLES+ANGLES/4],*costable; 373 | 374 | extern fixed viewx,viewy,viewsin,viewcos; // the focal point 375 | extern int viewangle; 376 | 377 | extern fixed scale,scaleglobal; 378 | extern unsigned slideofs; 379 | 380 | extern int zbuffer[VIEWXH+1]; 381 | 382 | extern walltype walls[MAXWALLS],*leftwall,*rightwall; 383 | 384 | 385 | extern fixed tileglobal; 386 | extern fixed focallength; 387 | extern fixed mindist; 388 | extern int viewheight; 389 | extern fixed scale; 390 | 391 | extern int walllight1[NUMFLOORS]; 392 | extern int walldark1[NUMFLOORS]; 393 | extern int walllight2[NUMFLOORS]; 394 | extern int walldark2[NUMFLOORS]; 395 | 396 | //========================================================================== 397 | 398 | void DrawLine (int xl, int xh, int y,int color); 399 | void DrawWall (walltype *wallptr); 400 | void TraceRay (unsigned angle); 401 | fixed FixedByFrac (fixed a, fixed b); 402 | void TransformPoint (fixed gx, fixed gy, int *screenx, unsigned *screenheight); 403 | fixed TransformX (fixed gx, fixed gy); 404 | int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max); 405 | void ForwardTrace (void); 406 | int FinishWall (void); 407 | int TurnClockwise (void); 408 | int TurnCounterClockwise (void); 409 | void FollowWall (void); 410 | 411 | void NewScene (void); 412 | void BuildTables (void); 413 | 414 | 415 | /* 416 | ============================================================================= 417 | 418 | C3_SCALE DEFINITIONS 419 | 420 | ============================================================================= 421 | */ 422 | 423 | 424 | #define COMPSCALECODESTART (65*6) // offset to start of code in comp scaler 425 | 426 | typedef struct 427 | { 428 | unsigned codeofs[65]; 429 | unsigned start[65]; 430 | unsigned width[65]; 431 | byte code[]; 432 | } t_compscale; 433 | 434 | typedef struct 435 | { 436 | unsigned width; 437 | unsigned codeofs[64]; 438 | } t_compshape; 439 | 440 | 441 | extern unsigned scaleblockwidth, 442 | scaleblockheight, 443 | scaleblockdest; 444 | 445 | extern byte plotpix[8]; 446 | extern byte bitmasks1[8][8]; 447 | extern byte bitmasks2[8][8]; 448 | 449 | 450 | extern t_compscale _seg *scaledirectory[MAXSCALE+1]; 451 | extern t_compshape _seg *shapedirectory[NUMSCALEPICS]; 452 | extern memptr walldirectory[NUMSCALEWALLS]; 453 | extern unsigned shapesize[MAXSCALE+1]; 454 | 455 | void DeplanePic (int picnum); 456 | void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale); 457 | unsigned BuildCompShape (t_compshape _seg **finalspot); 458 | 459 | 460 | /* 461 | ============================================================================= 462 | 463 | C3_ASM DEFINITIONS 464 | 465 | ============================================================================= 466 | */ 467 | 468 | extern unsigned wallheight [VIEWWIDTH]; 469 | extern unsigned wallwidth [VIEWWIDTH]; 470 | extern unsigned wallseg [VIEWWIDTH]; 471 | extern unsigned wallofs [VIEWWIDTH]; 472 | extern unsigned screenbyte [VIEWWIDTH]; 473 | extern unsigned screenbit [VIEWWIDTH]; 474 | extern unsigned bitmasks [64]; 475 | 476 | extern long wallscalecall; 477 | 478 | void ScaleWalls (void); 479 | 480 | /* 481 | ============================================================================= 482 | 483 | C3_WIZ DEFINITIONS 484 | 485 | ============================================================================= 486 | */ 487 | 488 | #define MAXHANDHEIGHT 72 489 | 490 | extern long lastnuke; 491 | extern int handheight; 492 | extern int boltsleft; 493 | 494 | /* 495 | ============================================================================= 496 | 497 | C3_ACT1 DEFINITIONS 498 | 499 | ============================================================================= 500 | */ 501 | 502 | extern statetype s_trollouch; 503 | extern statetype s_trolldie1; 504 | 505 | 506 | extern statetype s_orcpause; 507 | 508 | extern statetype s_orc1; 509 | extern statetype s_orc2; 510 | extern statetype s_orc3; 511 | extern statetype s_orc4; 512 | 513 | extern statetype s_orcattack1; 514 | extern statetype s_orcattack2; 515 | extern statetype s_orcattack3; 516 | 517 | extern statetype s_orcouch; 518 | 519 | extern statetype s_orcdie1; 520 | extern statetype s_orcdie2; 521 | extern statetype s_orcdie3; 522 | 523 | 524 | extern statetype s_demonouch; 525 | extern statetype s_demondie1; 526 | 527 | extern statetype s_mageouch; 528 | extern statetype s_magedie1; 529 | 530 | extern statetype s_grelouch; 531 | extern statetype s_greldie1; 532 | 533 | extern statetype s_batdie1; 534 | -------------------------------------------------------------------------------- /ID_RF_A.ASM: -------------------------------------------------------------------------------- 1 | ; Catacomb 3-D Source Code 2 | ; Copyright (C) 1993-2014 Flat Rock Software 3 | ; 4 | ; This program is free software; you can redistribute it and/or modify 5 | ; it under the terms of the GNU General Public License as published by 6 | ; the Free Software Foundation; either version 2 of the License, or 7 | ; (at your option) any later version. 8 | ; 9 | ; This program is distributed in the hope that it will be useful, 10 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ; GNU General Public License for more details. 13 | ; 14 | ; You should have received a copy of the GNU General Public License along 15 | ; with this program; if not, write to the Free Software Foundation, Inc., 16 | ; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | 18 | ; ID_RF_A.ASM 19 | 20 | IDEAL 21 | MODEL MEDIUM,C 22 | 23 | INCLUDE "ID_ASM.EQU" 24 | 25 | ;============================================================================ 26 | 27 | TILESWIDE = 21 28 | TILESHIGH = 14 29 | 30 | UPDATESIZE = (TILESWIDE+1)*TILESHIGH+1 31 | 32 | DATASEG 33 | 34 | EXTRN screenseg:WORD 35 | EXTRN updateptr:WORD 36 | EXTRN updatestart:WORD 37 | EXTRN masterofs:WORD ;start of master tile port 38 | EXTRN bufferofs:WORD ;start of current buffer port 39 | EXTRN screenstart:WORD ;starts of three screens (0/1/master) in EGA mem 40 | EXTRN grsegs:WORD 41 | EXTRN mapsegs:WORD 42 | EXTRN originmap:WORD 43 | EXTRN updatemapofs:WORD 44 | EXTRN tinf:WORD ;seg pointer to map header and tile info 45 | EXTRN blockstarts:WORD ;offsets from bufferofs for each update block 46 | 47 | planemask db ? 48 | planenum db ? 49 | 50 | CODESEG 51 | 52 | screenstartcs dw ? ;in code segment for accesability 53 | 54 | 55 | 56 | 57 | IFE GRMODE-CGAGR 58 | ;============================================================================ 59 | ; 60 | ; CGA refresh routines 61 | ; 62 | ;============================================================================ 63 | 64 | TILEWIDTH = 4 65 | 66 | ;================= 67 | ; 68 | ; RFL_NewTile 69 | ; 70 | ; Draws a composit two plane tile to the master screen and sets the update 71 | ; spot to 1 in both update pages, forcing the tile to be copied to the 72 | ; view pages the next two refreshes 73 | ; 74 | ; Called to draw newlly scrolled on strips and animating tiles 75 | ; 76 | ;================= 77 | 78 | PROC RFL_NewTile updateoffset:WORD 79 | PUBLIC RFL_NewTile 80 | USES SI,DI 81 | 82 | ; 83 | ; mark both update lists at this spot 84 | ; 85 | mov di,[updateoffset] 86 | 87 | mov bx,[updateptr] ;start of update matrix 88 | mov [BYTE bx+di],1 89 | 90 | mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line 91 | 92 | ; 93 | ; set di to the location in screenseg to draw the tile 94 | ; 95 | shl di,1 96 | mov si,[updatemapofs+di] ;offset in map from origin 97 | add si,[originmap] 98 | mov di,[blockstarts+di] ;screen location for tile 99 | add di,[masterofs] 100 | 101 | ; 102 | ; set BX to the foreground tile number and SI to the background number 103 | ; If either BX or SI = 0xFFFF, the tile does not need to be masked together 104 | ; as one of the planes totally eclipses the other 105 | ; 106 | mov es,[mapsegs+2] ;foreground plane 107 | mov bx,[es:si] 108 | mov es,[mapsegs] ;background plane 109 | mov si,[es:si] 110 | 111 | mov es,[screenseg] 112 | 113 | or bx,bx 114 | jz @@singletile 115 | jmp @@maskeddraw ;draw both together 116 | 117 | ;============= 118 | ; 119 | ; Draw single background tile from main memory 120 | ; 121 | ;============= 122 | 123 | @@singletile: 124 | shl si,1 125 | mov ds,[grsegs+STARTTILE16*2+si] 126 | 127 | xor si,si ;block is segment aligned 128 | 129 | REPT 15 130 | movsw 131 | movsw 132 | add di,dx 133 | ENDM 134 | movsw 135 | movsw 136 | 137 | mov ax,ss 138 | mov ds,ax ;restore turbo's data segment 139 | ret 140 | 141 | 142 | ;========= 143 | ; 144 | ; Draw a masked tile combo 145 | ; Interupts are disabled and the stack segment is reassigned 146 | ; 147 | ;========= 148 | @@maskeddraw: 149 | cli ; don't allow ints when SS is set 150 | shl bx,1 151 | mov ss,[grsegs+STARTTILE16M*2+bx] 152 | shl si,1 153 | mov ds,[grsegs+STARTTILE16*2+si] 154 | 155 | xor si,si ;first word of tile data 156 | 157 | REPT 16 158 | mov ax,[si] ;background tile 159 | and ax,[ss:si] ;mask 160 | or ax,[ss:si+64] ;masked data 161 | stosw 162 | mov ax,[si+2] ;background tile 163 | and ax,[ss:si+2] ;mask 164 | or ax,[ss:si+66] ;masked data 165 | stosw 166 | add si,4 167 | add di,dx 168 | ENDM 169 | 170 | mov ax,@DATA 171 | mov ss,ax 172 | sti 173 | mov ds,ax 174 | ret 175 | ENDP 176 | 177 | ENDIF 178 | 179 | 180 | 181 | IFE GRMODE-EGAGR 182 | ;=========================================================================== 183 | ; 184 | ; EGA refresh routines 185 | ; 186 | ;=========================================================================== 187 | 188 | TILEWIDTH = 2 189 | 190 | ;================= 191 | ; 192 | ; RFL_NewTile 193 | ; 194 | ; Draws a composit two plane tile to the master screen and sets the update 195 | ; spot to 1 in both update pages, forcing the tile to be copied to the 196 | ; view pages the next two refreshes 197 | ; 198 | ; Called to draw newlly scrolled on strips and animating tiles 199 | ; 200 | ; Assumes write mode 0 201 | ; 202 | ;================= 203 | 204 | PROC RFL_NewTile updateoffset:WORD 205 | PUBLIC RFL_NewTile 206 | USES SI,DI 207 | 208 | ; 209 | ; mark both update lists at this spot 210 | ; 211 | mov di,[updateoffset] 212 | 213 | mov bx,[updatestart] ;page 0 pointer 214 | mov [BYTE bx+di],1 215 | mov bx,[updatestart+2] ;page 1 pointer 216 | mov [BYTE bx+di],1 217 | 218 | ; 219 | ; set screenstartcs to the location in screenseg to draw the tile 220 | ; 221 | shl di,1 222 | mov si,[updatemapofs+di] ;offset in map from origin 223 | add si,[originmap] 224 | mov di,[blockstarts+di] ;screen location for tile 225 | add di,[masterofs] 226 | mov [cs:screenstartcs],di 227 | 228 | ; 229 | ; set BX to the foreground tile number and SI to the background number 230 | ; If either BX or SI = 0xFFFF, the tile does not need to be masked together 231 | ; as one of the planes totally eclipses the other 232 | ; 233 | mov es,[mapsegs+2] ;foreground plane 234 | mov bx,[es:si] 235 | mov es,[mapsegs] ;background plane 236 | mov si,[es:si] 237 | 238 | mov es,[screenseg] 239 | mov dx,SC_INDEX ;for stepping through map mask planes 240 | 241 | or bx,bx 242 | jz @@singletile 243 | jmp @@maskeddraw ;draw both together 244 | 245 | ;========= 246 | ; 247 | ; No foreground tile, so draw a single background tile. 248 | ; 249 | ;========= 250 | @@singletile: 251 | 252 | mov bx,SCREENWIDTH-2 ;add to get to start of next line 253 | shl si,1 254 | 255 | mov ax,[cs:screenstartcs] 256 | mov ds,[grsegs+STARTTILE16*2+si] 257 | 258 | xor si,si ;block is segment aligned 259 | 260 | mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0 261 | 262 | mov cx,4 ;draw four planes 263 | @@planeloop: 264 | mov dx,SC_INDEX 265 | WORDOUT 266 | 267 | mov di,[cs:screenstartcs] ;start at same place in all planes 268 | 269 | REPT 15 270 | movsw 271 | add di,bx 272 | ENDM 273 | movsw 274 | 275 | shl ah,1 ;shift plane mask over for next plane 276 | loop @@planeloop 277 | 278 | mov ax,ss 279 | mov ds,ax ;restore turbo's data segment 280 | ret 281 | 282 | 283 | ;========= 284 | ; 285 | ; Draw a masked tile combo 286 | ; Interupts are disabled and the stack segment is reassigned 287 | ; 288 | ;========= 289 | @@maskeddraw: 290 | cli ; don't allow ints when SS is set 291 | shl bx,1 292 | mov ss,[grsegs+STARTTILE16M*2+bx] 293 | shl si,1 294 | mov ds,[grsegs+STARTTILE16*2+si] 295 | 296 | xor si,si ;first word of tile data 297 | 298 | mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0 299 | 300 | mov di,[cs:screenstartcs] 301 | @@planeloopm: 302 | WORDOUT 303 | tileofs = 0 304 | lineoffset = 0 305 | REPT 16 306 | mov bx,[si+tileofs] ;background tile 307 | and bx,[ss:tileofs] ;mask 308 | or bx,[ss:si+tileofs+32] ;masked data 309 | mov [es:di+lineoffset],bx 310 | tileofs = tileofs + 2 311 | lineoffset = lineoffset + SCREENWIDTH 312 | ENDM 313 | add si,32 314 | shl ah,1 ;shift plane mask over for next plane 315 | cmp ah,10000b 316 | je @@done ;drawn all four planes 317 | jmp @@planeloopm 318 | 319 | @@done: 320 | mov ax,@DATA 321 | mov ss,ax 322 | sti 323 | mov ds,ax 324 | ret 325 | ENDP 326 | 327 | ENDIF 328 | 329 | IFE GRMODE-VGAGR 330 | ;============================================================================ 331 | ; 332 | ; VGA refresh routines 333 | ; 334 | ;============================================================================ 335 | 336 | 337 | ENDIF 338 | 339 | 340 | ;============================================================================ 341 | ; 342 | ; reasonably common refresh routines 343 | ; 344 | ;============================================================================ 345 | 346 | 347 | ;================= 348 | ; 349 | ; RFL_UpdateTiles 350 | ; 351 | ; Scans through the update matrix pointed to by updateptr, looking for 1s. 352 | ; A 1 represents a tile that needs to be copied from the master screen to the 353 | ; current screen (a new row or an animated tiled). If more than one adjacent 354 | ; tile in a horizontal row needs to be copied, they will be copied as a group. 355 | ; 356 | ; Assumes write mode 1 357 | ; 358 | ;================= 359 | 360 | 361 | ; AX 0/1 for scasb, temp for segment register transfers 362 | ; BX width for block copies 363 | ; CX REP counter 364 | ; DX line width deltas 365 | ; SI source for copies 366 | ; DI scas dest / movsb dest 367 | ; BP pointer to UPDATETERMINATE 368 | ; 369 | ; DS 370 | ; ES 371 | ; SS 372 | 373 | PROC RFL_UpdateTiles 374 | PUBLIC RFL_UpdateTiles 375 | USES SI,DI,BP 376 | 377 | jmp SHORT @@realstart 378 | @@done: 379 | ; 380 | ; all tiles have been scanned 381 | ; 382 | ret 383 | 384 | @@realstart: 385 | mov di,[updateptr] 386 | mov bp,(TILESWIDE+1)*TILESHIGH+1 387 | add bp,di ; when di = bx, all tiles have been scanned 388 | push di 389 | mov cx,-1 ; definately scan the entire thing 390 | 391 | ; 392 | ; scan for a 1 in the update list, meaning a tile needs to be copied 393 | ; from the master screen to the current screen 394 | ; 395 | @@findtile: 396 | pop di ; place to continue scaning from 397 | mov ax,ss 398 | mov es,ax ; search in the data segment 399 | mov ds,ax 400 | mov al,1 401 | repne scasb 402 | cmp di,bp 403 | je @@done 404 | 405 | cmp [BYTE di],al 406 | jne @@singletile 407 | jmp @@tileblock 408 | 409 | ;============ 410 | ; 411 | ; copy a single tile 412 | ; 413 | ;============ 414 | EVEN 415 | @@singletile: 416 | inc di ; we know the next tile is nothing 417 | push di ; save off the spot being scanned 418 | sub di,[updateptr] 419 | shl di,1 420 | mov di,[blockstarts-4+di] ; start of tile location on screen 421 | mov si,di 422 | add di,[bufferofs] ; dest in current screen 423 | add si,[masterofs] ; source in master screen 424 | 425 | mov dx,SCREENWIDTH-TILEWIDTH 426 | mov ax,[screenseg] 427 | mov ds,ax 428 | mov es,ax 429 | 430 | ;-------------------------- 431 | 432 | IFE GRMODE-CGAGR 433 | 434 | REPT 15 435 | movsw 436 | movsw 437 | add si,dx 438 | add di,dx 439 | ENDM 440 | movsw 441 | movsw 442 | 443 | ENDIF 444 | 445 | ;-------------------------- 446 | 447 | IFE GRMODE-EGAGR 448 | 449 | REPT 15 450 | movsb 451 | movsb 452 | add si,dx 453 | add di,dx 454 | ENDM 455 | movsb 456 | movsb 457 | 458 | ENDIF 459 | 460 | ;-------------------------- 461 | 462 | jmp @@findtile 463 | 464 | ;============ 465 | ; 466 | ; more than one tile in a row needs to be updated, so do it as a group 467 | ; 468 | ;============ 469 | EVEN 470 | @@tileblock: 471 | mov dx,di ; hold starting position + 1 in dx 472 | inc di ; we know the next tile also gets updated 473 | repe scasb ; see how many more in a row 474 | push di ; save off the spot being scanned 475 | 476 | mov bx,di 477 | sub bx,dx ; number of tiles in a row 478 | shl bx,1 ; number of bytes / row 479 | 480 | mov di,dx ; lookup position of start tile 481 | sub di,[updateptr] 482 | shl di,1 483 | mov di,[blockstarts-2+di] ; start of tile location 484 | mov si,di 485 | add di,[bufferofs] ; dest in current screen 486 | add si,[masterofs] ; source in master screen 487 | 488 | mov dx,SCREENWIDTH 489 | sub dx,bx ; offset to next line on screen 490 | IFE GRMODE-CGAGR 491 | sub dx,bx ; bx is words wide in CGA tiles 492 | ENDIF 493 | 494 | mov ax,[screenseg] 495 | mov ds,ax 496 | mov es,ax 497 | 498 | REPT 15 499 | mov cx,bx 500 | IFE GRMODE-CGAGR 501 | rep movsw 502 | ENDIF 503 | IFE GRMODE-EGAGR 504 | rep movsb 505 | ENDIF 506 | add si,dx 507 | add di,dx 508 | ENDM 509 | mov cx,bx 510 | IFE GRMODE-CGAGR 511 | rep movsw 512 | ENDIF 513 | IFE GRMODE-EGAGR 514 | rep movsb 515 | ENDIF 516 | 517 | dec cx ; was 0 from last rep movsb, now $ffff for scasb 518 | jmp @@findtile 519 | 520 | ENDP 521 | 522 | 523 | ;============================================================================ 524 | 525 | 526 | ;================= 527 | ; 528 | ; RFL_MaskForegroundTiles 529 | ; 530 | ; Scan through update looking for 3's. If the foreground tile there is a 531 | ; masked foreground tile, draw it to the screen 532 | ; 533 | ;================= 534 | 535 | PROC RFL_MaskForegroundTiles 536 | PUBLIC RFL_MaskForegroundTiles 537 | USES SI,DI,BP 538 | jmp SHORT @@realstart 539 | @@done: 540 | ; 541 | ; all tiles have been scanned 542 | ; 543 | ret 544 | 545 | @@realstart: 546 | mov di,[updateptr] 547 | mov bp,(TILESWIDE+1)*TILESHIGH+2 548 | add bp,di ; when di = bx, all tiles have been scanned 549 | push di 550 | mov cx,-1 ; definately scan the entire thing 551 | ; 552 | ; scan for a 3 in the update list 553 | ; 554 | @@findtile: 555 | mov ax,ss 556 | mov es,ax ; scan in the data segment 557 | mov al,3 558 | pop di ; place to continue scaning from 559 | repne scasb 560 | cmp di,bp 561 | je @@done 562 | 563 | ;============ 564 | ; 565 | ; found a tile, see if it needs to be masked on 566 | ; 567 | ;============ 568 | 569 | push di 570 | 571 | sub di,[updateptr] 572 | shl di,1 573 | mov si,[updatemapofs-2+di] ; offset from originmap 574 | add si,[originmap] 575 | 576 | mov es,[mapsegs+2] ; foreground map plane segment 577 | mov si,[es:si] ; foreground tile number 578 | 579 | or si,si 580 | jz @@findtile ; 0 = no foreground tile 581 | 582 | mov bx,si 583 | add bx,INTILE ;INTILE tile info table 584 | mov es,[tinf] 585 | test [BYTE PTR es:bx],80h ;high bit = masked tile 586 | jz @@findtile 587 | 588 | ;------------------- 589 | 590 | IFE GRMODE-CGAGR 591 | ;================= 592 | ; 593 | ; mask the tile CGA 594 | ; 595 | ;================= 596 | 597 | mov di,[blockstarts-2+di] 598 | add di,[bufferofs] 599 | mov es,[screenseg] 600 | shl si,1 601 | mov ds,[grsegs+STARTTILE16M*2+si] 602 | 603 | mov bx,64 ;data starts 64 bytes after mask 604 | 605 | xor si,si 606 | 607 | lineoffset = 0 608 | REPT 16 609 | mov ax,[es:di+lineoffset] ;background 610 | and ax,[si] ;mask 611 | or ax,[si+bx] ;masked data 612 | mov [es:di+lineoffset],ax ;background 613 | inc si 614 | inc si 615 | mov ax,[es:di+lineoffset+2] ;background 616 | and ax,[si] ;mask 617 | or ax,[si+bx] ;masked data 618 | mov [es:di+lineoffset+2],ax ;background 619 | inc si 620 | inc si 621 | lineoffset = lineoffset + SCREENWIDTH 622 | ENDM 623 | ENDIF 624 | 625 | ;------------------- 626 | 627 | IFE GRMODE-EGAGR 628 | ;================= 629 | ; 630 | ; mask the tile 631 | ; 632 | ;================= 633 | 634 | mov [BYTE planemask],1 635 | mov [BYTE planenum],0 636 | 637 | mov di,[blockstarts-2+di] 638 | add di,[bufferofs] 639 | mov [cs:screenstartcs],di 640 | mov es,[screenseg] 641 | shl si,1 642 | mov ds,[grsegs+STARTTILE16M*2+si] 643 | 644 | mov bx,32 ;data starts 32 bytes after mask 645 | 646 | @@planeloopm: 647 | mov dx,SC_INDEX 648 | mov al,SC_MAPMASK 649 | mov ah,[ss:planemask] 650 | WORDOUT 651 | mov dx,GC_INDEX 652 | mov al,GC_READMAP 653 | mov ah,[ss:planenum] 654 | WORDOUT 655 | 656 | xor si,si 657 | mov di,[cs:screenstartcs] 658 | lineoffset = 0 659 | REPT 16 660 | mov cx,[es:di+lineoffset] ;background 661 | and cx,[si] ;mask 662 | or cx,[si+bx] ;masked data 663 | inc si 664 | inc si 665 | mov [es:di+lineoffset],cx 666 | lineoffset = lineoffset + SCREENWIDTH 667 | ENDM 668 | add bx,32 ;the mask is now further away 669 | inc [ss:planenum] 670 | shl [ss:planemask],1 ;shift plane mask over for next plane 671 | cmp [ss:planemask],10000b ;done all four planes? 672 | je @@drawn ;drawn all four planes 673 | jmp @@planeloopm 674 | 675 | @@drawn: 676 | ENDIF 677 | 678 | ;------------------- 679 | 680 | mov ax,ss 681 | mov ds,ax 682 | mov cx,-1 ;definately scan the entire thing 683 | 684 | jmp @@findtile 685 | 686 | ENDP 687 | 688 | 689 | END 690 | 691 | -------------------------------------------------------------------------------- /C3_MAIN.C: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // C3_MAIN.C 20 | 21 | #include "C3_DEF.H" 22 | #pragma hdrstop 23 | 24 | /* 25 | ============================================================================= 26 | 27 | CATACOMB 3-D 28 | 29 | An Id Software production 30 | 31 | by John Carmack 32 | 33 | ============================================================================= 34 | */ 35 | 36 | /* 37 | ============================================================================= 38 | 39 | LOCAL CONSTANTS 40 | 41 | ============================================================================= 42 | */ 43 | 44 | 45 | /* 46 | ============================================================================= 47 | 48 | GLOBAL VARIABLES 49 | 50 | ============================================================================= 51 | */ 52 | 53 | memptr scalesegs[NUMPICS]; 54 | char str[80],str2[20]; 55 | unsigned tedlevelnum; 56 | boolean tedlevel; 57 | gametype gamestate; 58 | exittype playstate; 59 | 60 | /* 61 | ============================================================================= 62 | 63 | LOCAL VARIABLES 64 | 65 | ============================================================================= 66 | */ 67 | 68 | 69 | 70 | //=========================================================================== 71 | 72 | // JAB Hack begin 73 | #define MyInterrupt 0x60 74 | void interrupt (*intaddr)(); 75 | void interrupt (*oldintaddr)(); 76 | char *JHParmStrings[] = {"no386",nil}; 77 | 78 | void 79 | jabhack(void) 80 | { 81 | extern void far jabhack2(void); 82 | extern int far CheckIs386(void); 83 | 84 | int i; 85 | 86 | oldintaddr = getvect(MyInterrupt); 87 | 88 | for (i = 1;i < _argc;i++) 89 | if (US_CheckParm(_argv[i],JHParmStrings) == 0) 90 | return; 91 | 92 | if (CheckIs386()) 93 | { 94 | jabhack2(); 95 | setvect(MyInterrupt,intaddr); 96 | } 97 | } 98 | 99 | void 100 | jabunhack(void) 101 | { 102 | setvect(MyInterrupt,oldintaddr); 103 | } 104 | // JAB Hack end 105 | 106 | //=========================================================================== 107 | 108 | /* 109 | ===================== 110 | = 111 | = NewGame 112 | = 113 | = Set up new game to start from the beginning 114 | = 115 | ===================== 116 | */ 117 | 118 | void NewGame (void) 119 | { 120 | memset (&gamestate,0,sizeof(gamestate)); 121 | gamestate.mapon = 0; 122 | gamestate.body = MAXBODY; 123 | } 124 | 125 | //=========================================================================== 126 | 127 | #define RLETAG 0xABCD 128 | 129 | /* 130 | ================== 131 | = 132 | = SaveTheGame 133 | = 134 | ================== 135 | */ 136 | 137 | boolean SaveTheGame(int file) 138 | { 139 | word i,compressed,expanded; 140 | objtype *o; 141 | memptr bigbuffer; 142 | 143 | if (!CA_FarWrite(file,(void far *)&gamestate,sizeof(gamestate))) 144 | return(false); 145 | 146 | expanded = mapwidth * mapheight * 2; 147 | MM_GetPtr (&bigbuffer,expanded); 148 | 149 | for (i = 0;i < 3;i+=2) // Write planes 0 and 2 150 | { 151 | // 152 | // leave a word at start of compressed data for compressed length 153 | // 154 | compressed = (unsigned)CA_RLEWCompress ((unsigned huge *)mapsegs[i] 155 | ,expanded,((unsigned huge *)bigbuffer)+1,RLETAG); 156 | 157 | *(unsigned huge *)bigbuffer = compressed; 158 | 159 | if (!CA_FarWrite(file,(void far *)bigbuffer,compressed+2) ) 160 | { 161 | MM_FreePtr (&bigbuffer); 162 | return(false); 163 | } 164 | } 165 | 166 | for (o = player;o;o = o->next) 167 | if (!CA_FarWrite(file,(void far *)o,sizeof(objtype))) 168 | { 169 | MM_FreePtr (&bigbuffer); 170 | return(false); 171 | } 172 | 173 | MM_FreePtr (&bigbuffer); 174 | 175 | return(true); 176 | } 177 | 178 | //=========================================================================== 179 | 180 | /* 181 | ================== 182 | = 183 | = LoadTheGame 184 | = 185 | ================== 186 | */ 187 | 188 | boolean LoadTheGame(int file) 189 | { 190 | unsigned i,x,y; 191 | objtype *obj,*prev,*next,*followed; 192 | unsigned compressed,expanded; 193 | unsigned far *map,tile; 194 | memptr bigbuffer; 195 | 196 | if (!CA_FarRead(file,(void far *)&gamestate,sizeof(gamestate))) 197 | return(false); 198 | 199 | SetupGameLevel (); // load in and cache the base old level 200 | 201 | expanded = mapwidth * mapheight * 2; 202 | MM_GetPtr (&bigbuffer,expanded); 203 | 204 | for (i = 0;i < 3;i+=2) // Read planes 0 and 2 205 | { 206 | if (!CA_FarRead(file,(void far *)&compressed,sizeof(compressed)) ) 207 | { 208 | MM_FreePtr (&bigbuffer); 209 | return(false); 210 | } 211 | 212 | if (!CA_FarRead(file,(void far *)bigbuffer,compressed) ) 213 | { 214 | MM_FreePtr (&bigbuffer); 215 | return(false); 216 | } 217 | 218 | CA_RLEWexpand ((unsigned huge *)bigbuffer, 219 | (unsigned huge *)mapsegs[i],expanded,RLETAG); 220 | } 221 | 222 | MM_FreePtr (&bigbuffer); 223 | // 224 | // copy the wall data to a data segment array again, to handle doors and 225 | // bomb walls that are allready opened 226 | // 227 | memset (tilemap,0,sizeof(tilemap)); 228 | memset (actorat,0,sizeof(actorat)); 229 | map = mapsegs[0]; 230 | for (y=0;y0) 238 | (unsigned)actorat[x][y] = tile; 239 | } 240 | } 241 | 242 | 243 | // Read the object list back in - assumes at least one object in list 244 | 245 | InitObjList (); 246 | new = player; 247 | while (true) 248 | { 249 | prev = new->prev; 250 | next = new->next; 251 | if (!CA_FarRead(file,(void far *)new,sizeof(objtype))) 252 | return(false); 253 | followed = new->next; 254 | new->prev = prev; 255 | new->next = next; 256 | actorat[new->tilex][new->tiley] = new; // drop a new marker 257 | 258 | if (followed) 259 | GetNewObj (false); 260 | else 261 | break; 262 | } 263 | 264 | return(true); 265 | } 266 | 267 | //=========================================================================== 268 | 269 | /* 270 | ================== 271 | = 272 | = ResetGame 273 | = 274 | ================== 275 | */ 276 | 277 | void ResetGame(void) 278 | { 279 | NewGame (); 280 | 281 | ca_levelnum--; 282 | ca_levelbit>>=1; 283 | CA_ClearMarks(); 284 | ca_levelbit<<=1; 285 | ca_levelnum++; 286 | } 287 | 288 | //=========================================================================== 289 | 290 | 291 | /* 292 | ========================== 293 | = 294 | = ShutdownId 295 | = 296 | = Shuts down all ID_?? managers 297 | = 298 | ========================== 299 | */ 300 | 301 | void ShutdownId (void) 302 | { 303 | US_Shutdown (); 304 | #ifndef PROFILE 305 | SD_Shutdown (); 306 | IN_Shutdown (); 307 | #endif 308 | VW_Shutdown (); 309 | CA_Shutdown (); 310 | MM_Shutdown (); 311 | } 312 | 313 | 314 | //=========================================================================== 315 | 316 | /* 317 | ========================== 318 | = 319 | = InitGame 320 | = 321 | = Load a few things right away 322 | = 323 | ========================== 324 | */ 325 | 326 | void InitGame (void) 327 | { 328 | unsigned segstart,seglength; 329 | int i,x,y; 330 | unsigned *blockstart; 331 | 332 | // US_TextScreen(); 333 | 334 | MM_Startup (); 335 | VW_Startup (); 336 | #ifndef PROFILE 337 | IN_Startup (); 338 | SD_Startup (); 339 | #endif 340 | US_Startup (); 341 | 342 | // US_UpdateTextScreen(); 343 | 344 | CA_Startup (); 345 | US_Setup (); 346 | 347 | US_SetLoadSaveHooks(LoadTheGame,SaveTheGame,ResetGame); 348 | 349 | // 350 | // load in and lock down some basic chunks 351 | // 352 | 353 | CA_ClearMarks (); 354 | 355 | CA_MarkGrChunk(STARTFONT); 356 | CA_MarkGrChunk(STARTTILE8); 357 | CA_MarkGrChunk(STARTTILE8M); 358 | CA_MarkGrChunk(HAND1PICM); 359 | CA_MarkGrChunk(HAND2PICM); 360 | CA_MarkGrChunk(ENTERPLAQUEPIC); 361 | 362 | CA_CacheMarks (NULL); 363 | 364 | MM_SetLock (&grsegs[STARTFONT],true); 365 | MM_SetLock (&grsegs[STARTTILE8],true); 366 | MM_SetLock (&grsegs[STARTTILE8M],true); 367 | MM_SetLock (&grsegs[HAND1PICM],true); 368 | MM_SetLock (&grsegs[HAND2PICM],true); 369 | MM_SetLock (&grsegs[ENTERPLAQUEPIC],true); 370 | 371 | fontcolor = WHITE; 372 | 373 | 374 | // 375 | // build some tables 376 | // 377 | for (i=0;i= MINMEMORY) 683 | return; 684 | 685 | CA_CacheGrChunk (OUTOFMEM); 686 | finscreen = (unsigned)grsegs[OUTOFMEM]; 687 | ShutdownId (); 688 | movedata (finscreen,7,0xb800,0,4000); 689 | gotoxy (1,24); 690 | exit(1); 691 | } 692 | 693 | //=========================================================================== 694 | 695 | 696 | /* 697 | ========================== 698 | = 699 | = main 700 | = 701 | ========================== 702 | */ 703 | 704 | void main (void) 705 | { 706 | short i; 707 | 708 | if (stricmp(_argv[1], "/VER") == 0) 709 | { 710 | printf("Catacomb 3-D version 1.22 (Rev 1)\n"); 711 | printf("Copyright 1991-93 Softdisk Publishing\n"); 712 | printf("Developed for use with 100%% IBM compatibles\n"); 713 | printf("that have 640K memory and DOS version 3.3 or later\n"); 714 | printf("and EGA graphics or better.\n"); 715 | exit(0); 716 | } 717 | 718 | if (stricmp(_argv[1], "/?") == 0) 719 | { 720 | printf("Catacomb 3-D version 1.22\n"); 721 | printf("Copyright 1991-93 Softdisk Publishing\n\n"); 722 | printf("Syntax:\n"); 723 | printf("CAT3D [/]\n\n"); 724 | printf("Switch What it does\n"); 725 | printf("/? This Information\n"); 726 | printf("/VER Display Program Version Information\n"); 727 | printf("/COMP Fix problems with SVGA screens\n"); 728 | printf("/NOAL No AdLib or SoundBlaster detection\n"); 729 | printf("/NOJOYS Tell program to ignore joystick\n"); 730 | printf("/NOMOUSE Tell program to ignore mouse\n"); 731 | printf("/HIDDENCARD Overrides video detection\n\n"); 732 | printf("Each switch must include a '/' and multiple switches\n"); 733 | printf("must be seperated by at least one space.\n\n"); 734 | 735 | exit(0); 736 | } 737 | 738 | jabhack(); 739 | 740 | InitGame (); 741 | 742 | CheckMemory (); 743 | 744 | LoadLatchMem (); 745 | 746 | #ifdef PROFILE 747 | NewGame (); 748 | GameLoop (); 749 | #endif 750 | 751 | //NewGame (); 752 | //GameLoop (); 753 | 754 | DemoLoop(); 755 | Quit("Demo loop exited???"); 756 | } 757 | -------------------------------------------------------------------------------- /C3_SCALE.C: -------------------------------------------------------------------------------- 1 | /* Catacomb 3-D Source Code 2 | * Copyright (C) 1993-2014 Flat Rock Software 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | // C3_SCALE.C 20 | 21 | #include "C3_DEF.H" 22 | #pragma hdrstop 23 | 24 | //const unsigned viewheight = 144; 25 | const unsigned screenbwide = 40; 26 | const byte BACKGROUNDPIX = 5; 27 | 28 | unsigned shapesize[MAXSCALE+1]; 29 | t_compscale _seg *scaledirectory[MAXSCALE+1]; 30 | t_compshape _seg *shapedirectory[NUMSCALEPICS]; 31 | memptr walldirectory[NUMSCALEWALLS]; 32 | 33 | /* 34 | =========================== 35 | = 36 | = DeplanePic 37 | = 38 | = Takes a raw bit map of width bytes by height and creates a scaleable shape 39 | = 40 | = Returns the length of the shape in bytes 41 | = 42 | = Fills in spotvis (a convenient 64*64 array) with the color values 43 | = 44 | =========================== 45 | */ 46 | 47 | void DeplanePic (int picnum) 48 | { 49 | byte far *plane0,far *plane1,far *plane2,far *plane3; 50 | byte by0,by1,by2,by3; 51 | unsigned x,y,b,color,shift,width,height; 52 | byte *dest; 53 | 54 | // 55 | // convert ega pixels to byte color values in a temp buffer 56 | // 57 | width = pictable[picnum-STARTPICS].width; 58 | height = pictable[picnum-STARTPICS].height; 59 | 60 | if (width>64 || height!=64) 61 | Quit ("DePlanePic: Bad size shape"); 62 | 63 | memset (spotvis,BACKGROUNDPIX,sizeof(spotvis)); 64 | 65 | plane0 = (byte _seg *)grsegs[picnum]; 66 | plane1 = plane0 + width*height; 67 | plane2 = plane1 + width*height; 68 | plane3 = plane2 + width*height; 69 | 70 | for (y=0;ycode[0]; 149 | toppix = (viewheight-height)/2; 150 | fix = 0; 151 | 152 | for (src=0;src<=64;src++) 153 | { 154 | startpix = fix>>16; 155 | fix += step; 156 | endpix = fix>>16; 157 | 158 | work->start[src] = startpix; 159 | if (endpix>startpix) 160 | work->width[src] = endpix-startpix; 161 | else 162 | work->width[src] = 0; 163 | 164 | // 165 | // mark the start of the code 166 | // 167 | work->codeofs[src] = FP_OFF(code); 168 | 169 | // 170 | // compile some code if the source pixel generates any screen pixels 171 | // 172 | startpix+=toppix; 173 | endpix+=toppix; 174 | 175 | if (startpix == endpix || endpix < 0 || startpix >= VIEWHEIGHT || src == 64) 176 | continue; 177 | 178 | // 179 | // mov al,[si+src] 180 | // 181 | *code++ = 0x8a; 182 | *code++ = 0x44; 183 | *code++ = src; 184 | 185 | for (;startpix= VIEWHEIGHT) 188 | break; // off the bottom of the view area 189 | if (startpix < 0) 190 | continue; // not into the view area 191 | 192 | // 193 | // and [es:di+heightofs],al 194 | // 195 | *code++ = 0x26; 196 | *code++ = 0x20; 197 | *code++ = 0x85; 198 | *((unsigned far *)code)++ = startpix*screenbwide; 199 | } 200 | 201 | } 202 | 203 | // 204 | // retf 205 | // 206 | *code++ = 0xcb; 207 | 208 | totalsize = FP_OFF(code); 209 | MM_GetPtr (finalspot,totalsize); 210 | _fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize); 211 | MM_FreePtr (&(memptr)work); 212 | 213 | return totalsize; 214 | } 215 | 216 | 217 | 218 | 219 | /* 220 | ======================== 221 | = 222 | = BuildCompShape 223 | = 224 | = typedef struct 225 | = { 226 | = unsigned width; 227 | = unsigned codeofs[64]; 228 | = } t_compshape; 229 | = 230 | = Width is the number of compiled line draws in the shape. The shape 231 | = drawing code will assume that the midpoint of the shape is in the 232 | = middle of the width. 233 | = 234 | = The non background pixel data will start at codeofs[width], so codeofs 235 | = greater than width will be invalid. 236 | = 237 | = Each code offset will draw one vertical line of the shape, consisting 238 | = of 0 or more segments of scaled pixels. 239 | = 240 | = The scaled shapes use ss:0-4 as a scratch variable for the far call to 241 | = the compiled scaler, so zero it back out after the shape is scaled, or 242 | = a "null pointer assignment" will result upon termination. 243 | = 244 | = Setup for a call to a compiled shape 245 | = ----------------------------------- 246 | = ax toast 247 | = bx toast 248 | = cx toast 249 | = dx segment of compiled shape 250 | = si toast 251 | = di byte at top of view area to draw the line in 252 | = bp 0 253 | = ss:2 and ds the segment of the compiled scaler to use 254 | = es screenseg 255 | = 256 | = Upon return, ds IS NOT SET to the data segment. Do: 257 | = mov ax,ss 258 | = mov ds,ax 259 | = 260 | = 261 | = GC_BITMASK set to the pixels to be drawn in the row of bytes under DI 262 | = GC_MODE read mode 1, write mode 2 263 | = GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff 264 | = 265 | = 266 | = Code generated for each segment 267 | = ------------------------------- 268 | = mov bx,[(segend+1)*2] 269 | = mov cx,[bx] 270 | = mov [BYTE PTR bx],0xc8 // far return 271 | = mov ax,[segstart*2] 272 | = mov [ss:0],ax // entry point into the compiled scaler 273 | = mov ds,dx // (mov ds,cs) the data is after the compiled code 274 | = mov si,ofs data 275 | = call [bp] // scale some pixels 276 | = mov ds,[bp+2] 277 | = mov [bx],cx // un patch return 278 | = 279 | = Code generated after all segments on a line 280 | = ------------------------------------------- 281 | = retf 282 | = 283 | ======================== 284 | */ 285 | 286 | unsigned BuildCompShape (t_compshape _seg **finalspot) 287 | { 288 | t_compshape _seg *work; 289 | byte far *code; 290 | int firstline,lastline,x,y; 291 | unsigned firstpix,lastpix,width; 292 | unsigned totalsize,pixelofs; 293 | unsigned buff; 294 | 295 | 296 | // MM_GetPtr (&(memptr)work,20000); 297 | EGAWRITEMODE(0); 298 | EGAREADMAP(0); // use ega screen memory for temp buffer 299 | EGAMAPMASK(1); 300 | buff = screenloc[1]; 301 | work = (t_compshape _seg *)(0xa000+(buff+15)/16); 302 | 303 | // 304 | // find the width of the shape 305 | // 306 | firstline = -1; 307 | x=0; 308 | do 309 | { 310 | for (y=0;y<64;y++) 311 | if (spotvis[y][x] != BACKGROUNDPIX) 312 | { 313 | firstline = x; 314 | break; 315 | } 316 | if (++x == 64) 317 | Quit ("BuildCompShape: No shape data!"); 318 | } while (firstline == -1); 319 | 320 | lastline = -1; 321 | x=63; 322 | do 323 | { 324 | for (y=0;y<64;y++) 325 | if (spotvis[y][x] != BACKGROUNDPIX) 326 | { 327 | lastline = x; 328 | break; 329 | } 330 | x--; 331 | } while (lastline == -1); 332 | 333 | width = lastline-firstline+1; 334 | 335 | work->width = width; 336 | code = (byte far *)&work->codeofs[width]; 337 | 338 | // 339 | // copy all non background pixels to the work space 340 | // 341 | pixelofs = FP_OFF(code); 342 | 343 | for (x=firstline;x<=lastline;x++) 344 | for (y=0;y<64;y++) 345 | if (spotvis[y][x] != BACKGROUNDPIX) 346 | *code++ = spotvis[y][x]; 347 | 348 | // 349 | // start compiling the vertical lines 350 | // 351 | for (x=firstline;x<=lastline;x++) 352 | { 353 | work->codeofs[x-firstline] = FP_OFF(code); 354 | 355 | y=0; 356 | do 357 | { 358 | // 359 | // scan past black background pixels 360 | // 361 | while (spotvis[y][x] == BACKGROUNDPIX && y<64) 362 | y++; 363 | 364 | if (y>63) // no more segments 365 | break; 366 | 367 | firstpix = y+1; // +1 because width is before codeofs 368 | 369 | // 370 | // scan past scalable pixels 371 | // 372 | while (spotvis[y][x] != BACKGROUNDPIX && y<64) 373 | y++; 374 | 375 | if (y>63) 376 | lastpix = 65; 377 | else 378 | lastpix = y+1; // actually one pixel past the last displayed 379 | 380 | // 381 | // compile the scale call 382 | // 383 | *code++ = 0x8b; // mov bx,[lastpix*2] 384 | *code++ = 0x1e; 385 | *((unsigned far *)code)++ = lastpix*2; 386 | 387 | *code++ = 0x8b; // mov cx,[bx] 388 | *code++ = 0x0f; 389 | 390 | *code++ = 0xc6; // move [BYTE bx],0xcb 391 | *code++ = 0x07; 392 | *code++ = 0xcb; 393 | 394 | *code++ = 0xa1; // mov ax,[firstpix*2] /************* 395 | *((unsigned far *)code)++ = firstpix*2; 396 | 397 | *code++ = 0x36; // mov [ss:0],ax 398 | *code++ = 0xa3; 399 | *code++ = 0x00; 400 | *code++ = 0x00; 401 | 402 | *code++ = 0x8e; // mov ds,dx (mov ds,cs) 403 | *code++ = 0xda; 404 | 405 | *code++ = 0xbe; // mov si,OFFSET pixelofs-firstpixel 406 | *((unsigned far *)code)++ = pixelofs-firstpix; 407 | 408 | *code++ = 0xff; // call [DWORD bp] 409 | *code++ = 0x5e; 410 | *code++ = 0x00; 411 | 412 | *code++ = 0x8e; // mov ds,[bp+2] 413 | *code++ = 0x5e; 414 | *code++ = 0x02; 415 | 416 | *code++ = 0x89; // mov [bx],cx 417 | *code++ = 0x0f; 418 | 419 | pixelofs += (lastpix-firstpix); 420 | } while (y<63); 421 | 422 | // 423 | // retf 424 | // 425 | *code++ = 0xcb; 426 | } 427 | 428 | 429 | // 430 | // copy the final shape to a properly sized buffer 431 | // 432 | totalsize = FP_OFF(code); 433 | MM_GetPtr ((memptr *)finalspot,totalsize); 434 | _fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize); 435 | // MM_FreePtr (&(memptr)work); 436 | 437 | return totalsize; 438 | } 439 | 440 | 441 | 442 | /* 443 | ======================= 444 | = 445 | = ScaleShape 446 | = 447 | = Draws a compiled shape at [scale] pixels high 448 | = 449 | = Setup for call 450 | = -------------- 451 | = GC_MODE read mode 1, write mode 2 452 | = GC_COLORDONTCARE set to 0, so all reads from video memory return 0xff 453 | = GC_INDEX pointing at GC_BITMASK 454 | = 455 | ======================= 456 | */ 457 | 458 | static long longtemp; 459 | 460 | void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale) 461 | { 462 | t_compscale _seg *comptable; 463 | unsigned width,scalewidth; 464 | int x,pixel,lastpixel,pixwidth,min; 465 | unsigned far *codehandle, far *widthptr; 466 | unsigned badcodeptr; 467 | int rightclip; 468 | 469 | if (!compshape) 470 | Quit ("ScaleShape: NULL compshape ptr!"); 471 | 472 | scale = (scale+1)/2; 473 | if (!scale) 474 | return; // too far away 475 | if (scale>MAXSCALE) 476 | scale = MAXSCALE; 477 | comptable = scaledirectory[scale]; 478 | 479 | width = compshape->width; 480 | scalewidth = comptable->start[width]; 481 | 482 | pixel = xcenter - scalewidth/2; 483 | lastpixel = pixel+scalewidth-1; 484 | if (pixel >= VIEWWIDTH || lastpixel < 0) 485 | return; // totally off screen 486 | 487 | // 488 | // scan backwards from the right edge until pixels are visable 489 | // rightclip is the first NON VISABLE pixel 490 | // 491 | if (lastpixel>=VIEWWIDTH-1) 492 | rightclip = VIEWWIDTH-1; 493 | else 494 | rightclip = lastpixel; 495 | 496 | if (zbuffer[rightclip]>scale) 497 | { 498 | if (pixel>0) 499 | min = pixel; 500 | else 501 | min = 0; 502 | do 503 | { 504 | if (--rightclip < min) 505 | return; // totally covered or before 0 506 | if (zbuffer[rightclip]<=scale) 507 | break; 508 | } while (1); 509 | } 510 | rightclip++; 511 | 512 | // 513 | // scan from the left until it is on screen, leaving 514 | // [pixel],[pixwidth],[codehandle],and [widthptr] set correctly 515 | // 516 | *(((unsigned *)&longtemp)+1) = (unsigned)compshape; // seg of shape 517 | codehandle = &compshape->codeofs[0]; 518 | badcodeptr = compshape->codeofs[width]; 519 | widthptr = &comptable->width[0]; 520 | asm mov ax,[comptable] 521 | asm mov WORD PTR [2],ax // ds:0-4 is used as a far call pointer 522 | // by the compiled shapes 523 | pixwidth = *widthptr; // scaled width of this pixel 524 | while (!pixwidth) 525 | { 526 | pixwidth = *++widthptr; // find the first visable pixel 527 | codehandle++; 528 | } 529 | 530 | if (pixel<0) 531 | { 532 | do 533 | { 534 | if (pixel+pixwidth>0) 535 | { 536 | pixwidth += pixel; 537 | pixel = 0; 538 | break; 539 | } 540 | do 541 | { 542 | pixwidth = *++widthptr; 543 | codehandle++; 544 | } while (!pixwidth); 545 | pixel+=pixwidth; 546 | } while (1); 547 | } 548 | 549 | // 550 | // scan until it is visable, leaving 551 | // [pixel],[pixwidth],[codehandle],and [widthptr] set correctly 552 | // 553 | do 554 | { 555 | if (zbuffer[pixel] <= scale) 556 | break; // start drawing here 557 | pixel++; 558 | if (!--pixwidth) 559 | { 560 | do 561 | { 562 | pixwidth = *++widthptr; 563 | codehandle++; 564 | } while (!pixwidth); 565 | } 566 | } while (1); 567 | 568 | if (pixel+pixwidth>rightclip) 569 | pixwidth = rightclip-pixel; 570 | // 571 | // draw lines 572 | // 573 | do // while (1) 574 | { 575 | // 576 | // scale a vertical segment [pixwidth] pixels wide at [pixel] 577 | // 578 | (unsigned)longtemp = *codehandle; // offset of compiled code 579 | if ((unsigned)longtemp == badcodeptr) 580 | Quit ("ScaleShape: codehandle past end!"); 581 | 582 | asm mov bx,[pixel] 583 | asm mov di,bx 584 | asm shr di,1 585 | asm shr di,1 586 | asm shr di,1 // X in bytes 587 | asm add di,[bufferofs] 588 | asm and bx,7 589 | asm shl bx,1 590 | asm shl bx,1 591 | asm shl bx,1 592 | asm add bx,[pixwidth] // bx = pixel*8+pixwidth-1 593 | asm dec bx 594 | asm push bx 595 | asm mov al,BYTE PTR [bitmasks1+bx] 596 | asm mov dx,GC_INDEX+1 597 | asm out dx,al // set bit mask register 598 | 599 | asm mov es,[screenseg] 600 | asm push si 601 | asm push di 602 | asm push bp 603 | asm xor bp,bp 604 | asm mov dx,[WORD PTR longtemp+2] 605 | asm mov ds,[2] 606 | asm call ss:[DWORD PTR longtemp] // scale the line of pixels 607 | asm mov ax,ss 608 | asm mov ds,ax 609 | asm pop bp 610 | asm pop di 611 | asm pop si 612 | 613 | asm pop bx 614 | asm mov al,BYTE PTR [bitmasks2+bx] 615 | asm or al,al 616 | asm jz nosecond 617 | 618 | // 619 | // draw a second byte for vertical strips that cross two bytes 620 | // 621 | asm inc di 622 | asm mov dx,GC_INDEX+1 623 | asm out dx,al // set bit mask register 624 | asm push si 625 | asm push di 626 | asm push bp 627 | asm xor bp,bp 628 | asm mov dx,[WORD PTR longtemp+2] 629 | asm mov ds,[2] 630 | asm call ss:[DWORD PTR longtemp] // scale the line of pixels 631 | asm mov ax,ss 632 | asm mov ds,ax 633 | asm pop bp 634 | asm pop di 635 | asm pop si 636 | 637 | 638 | // 639 | // advance to the next drawn line 640 | // 641 | nosecond:; 642 | if ( (pixel+=pixwidth) == rightclip ) 643 | { 644 | asm mov WORD PTR [0],0 645 | asm mov WORD PTR [2],0 646 | return; // all done! 647 | } 648 | 649 | do 650 | { 651 | pixwidth = *++widthptr; 652 | codehandle++; 653 | } while (!pixwidth); 654 | 655 | if (pixel+pixwidth > rightclip) 656 | pixwidth = rightclip-pixel; 657 | 658 | } while (1); 659 | 660 | } 661 | 662 | // 663 | // bit mask tables for drawing scaled strips up to eight pixels wide 664 | // 665 | 666 | byte bitmasks1[8][8] = { 667 | {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}, 668 | {0x40,0x60,0x70,0x78,0x7c,0x7e,0x7f,0x7f}, 669 | {0x20,0x30,0x38,0x3c,0x3e,0x3f,0x3f,0x3f}, 670 | {0x10,0x18,0x1c,0x1e,0x1f,0x1f,0x1f,0x1f}, 671 | {0x8,0xc,0xe,0xf,0xf,0xf,0xf,0xf}, 672 | {0x4,0x6,0x7,0x7,0x7,0x7,0x7,0x7}, 673 | {0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3}, 674 | {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1} }; 675 | 676 | byte bitmasks2[8][8] = { 677 | {0,0,0,0,0,0,0,0}, 678 | {0,0,0,0,0,0,0,0x80}, 679 | {0,0,0,0,0,0,0x80,0xc0}, 680 | {0,0,0,0,0,0x80,0xc0,0xe0}, 681 | {0,0,0,0,0x80,0xc0,0xe0,0xf0}, 682 | {0,0,0,0x80,0xc0,0xe0,0xf0,0xf8}, 683 | {0,0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc}, 684 | {0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe} }; 685 | 686 | 687 | 688 | 689 | 690 | 691 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------