initial commit
sources taken from book CD: ack_lib -> /ACK/WIN/ACK_LIB fdemo -> /ACK/DOS/FDEMO/SOURCE (and /ACK/DOS/BORLAND as needed) mall -> /ACK/DOS/MALL/SOURCE (and /ACK/DOS/BORLAND as needed) some source files were missing for the demo projects and needed to be copied from /ACK/DOS/BORLAND (as indicated above)
This commit is contained in:
commit
865b466995
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
*.obj
|
||||||
|
*.exe
|
||||||
|
*.lib
|
||||||
|
*.lbc
|
||||||
|
*.lnk
|
436
ack_lib/ACK3D.H
Normal file
436
ack_lib/ACK3D.H
Normal file
|
@ -0,0 +1,436 @@
|
||||||
|
// ACK-3D.H header file for the engine interface.
|
||||||
|
// This file contains the main data structures and definitions
|
||||||
|
// required to support the ACK-3D engine. The data structures defined are
|
||||||
|
// the ones you use to set up the communication links between your application
|
||||||
|
// and the ACK-3D library. The four main data structures set up in this header file
|
||||||
|
// include: ACKENG, DOORS, NEWOBJECT, and OBJSEQ.
|
||||||
|
|
||||||
|
// USED TO RID OURSELVES OF THE MANY CASTING PROBLEMS
|
||||||
|
#define CAST(t,f) (t)(f)
|
||||||
|
|
||||||
|
// Internal definitions used to simplify field declarations.
|
||||||
|
typedef unsigned long ULONG;
|
||||||
|
typedef unsigned short USHORT;
|
||||||
|
typedef unsigned char UCHAR;
|
||||||
|
|
||||||
|
// Error codes returned from ACK-3D functions. You can use these error codes in your
|
||||||
|
// applications to debug the function calls.
|
||||||
|
#define ERR_BADFILE 100 // File not found, usually bad filename
|
||||||
|
#define ERR_BADCOMMAND 101 // Bad command found in the .INF file
|
||||||
|
#define ERR_BADOBJNUMBER 102 // Object number out of range
|
||||||
|
#define ERR_BADSYNTAX 103 // Invalid syntax in the .INF file
|
||||||
|
#define ERR_LOADINGBITMAP 104 // Error while reading a Bitmap file
|
||||||
|
#define ERR_BADDIRECTION 105 // Obsolete, was error in direction field of objects
|
||||||
|
#define ERR_BADSTARTX 106 // Error in initial X position of player
|
||||||
|
#define ERR_BADSTARTY 107 // Error in initial Y position of player
|
||||||
|
#define ERR_BADANGLE 108 // Error in initial player angle
|
||||||
|
#define ERR_BADMAPFILE 109 // Error in map file header
|
||||||
|
#define ERR_READINGMAP 110 // Error during read of map file
|
||||||
|
#define ERR_BADPICNAME 111 // Error in bitmap filename
|
||||||
|
#define ERR_INVALIDFORM 112 // Error in .BBM or .LBM format
|
||||||
|
#define ERR_NOPBM 113 // Error in .BBM format
|
||||||
|
#define ERR_BADPICFILE 114 // Error reading a bitmap file
|
||||||
|
#define ERR_NOMEMORY 115 // Out of memory error
|
||||||
|
#define ERR_BADPALFILE 116 // Error reading raw palette file
|
||||||
|
#define ERR_BADWINDOWSIZE 117 // Invalid window size for engine
|
||||||
|
#define ERR_TOMANYVIEWS 118 // Out of range object views
|
||||||
|
#define ERR_BADOBJECTNUM 119 // Invalid object index
|
||||||
|
#define ERR_BADOBJTYPE 120 // Invalid object type
|
||||||
|
|
||||||
|
// Defines for angle sizes used with the ACK-3D engine.
|
||||||
|
// These values are used as table look up indexes. The range is from 0 to 1800
|
||||||
|
// where each value represents and angle increment of 0.5 degrees;
|
||||||
|
// 0 = 0 degrees and 1800 = 360 degrees.
|
||||||
|
#define INT_ANGLE_1 5
|
||||||
|
#define INT_ANGLE_2 10
|
||||||
|
#define INT_ANGLE_4 20
|
||||||
|
#define INT_ANGLE_6 30
|
||||||
|
#define INT_ANGLE_32 160
|
||||||
|
#define INT_ANGLE_45 225
|
||||||
|
#define INT_ANGLE_90 450
|
||||||
|
#define INT_ANGLE_135 675
|
||||||
|
#define INT_ANGLE_180 900
|
||||||
|
#define INT_ANGLE_225 1125
|
||||||
|
#define INT_ANGLE_270 1350
|
||||||
|
#define INT_ANGLE_315 1575
|
||||||
|
#define INT_ANGLE_360 1800
|
||||||
|
|
||||||
|
// These values are returned by the AckMovePOV() and AckMoveObjectPOV() functions.
|
||||||
|
#define POV_NOTHING 0 // Nothing was hit
|
||||||
|
#define POV_XWALL 1 // An X wall was hit
|
||||||
|
#define POV_YWALL 2 // A Y wall was hit
|
||||||
|
#define POV_OBJECT 3 // An object was hit
|
||||||
|
#define POV_PLAYER 4 // The player was hit by object
|
||||||
|
#define POV_SLIDEX 5 // Sliding along an X wall
|
||||||
|
#define POV_SLIDEY 6 // Sliding along a Y wall
|
||||||
|
#define POV_NODOOR 0 // No door was opened
|
||||||
|
#define POV_XDOOR 1 // An X door was opened
|
||||||
|
#define POV_YDOOR 2 // A Y door was opened
|
||||||
|
#define POV_XSECRETDOOR 3 // An X secret door was opened
|
||||||
|
#define POV_YSECRETDOOR 4 // A Y secret door was opened
|
||||||
|
#define POV_DOORLOCKED 0x80 // Bit is on if door is locked
|
||||||
|
|
||||||
|
// Defines required to support bitmaps.
|
||||||
|
// Each bitmap used in ACK-3D is 64x64 pixels in size.
|
||||||
|
#define BITMAP_WIDTH 64
|
||||||
|
#define BITMAP_HEIGHT 64
|
||||||
|
#define BITMAP_SHIFT 6 // Bits to shift for bitmap width
|
||||||
|
#define BITMAP_SIZE (BITMAP_WIDTH * BITMAP_HEIGHT)
|
||||||
|
|
||||||
|
// Defines used to set up map grid. The grid is used with the ACKENG structure.
|
||||||
|
// Each grid component is 64x64 units in size.
|
||||||
|
#define GRID_MASK 0xFFC0 // Use FF80 for 128 and FFC0 for 64
|
||||||
|
#define GRID_SIZE 64 // The size of an individual grid unit
|
||||||
|
#define GRID_WIDTH 64
|
||||||
|
#define GRID_HEIGHT 64
|
||||||
|
#define GRID_MAX GRID_WIDTH * GRID_HEIGHT
|
||||||
|
#define GRID_XMAX BITMAP_WIDTH * GRID_WIDTH
|
||||||
|
#define GRID_YMAX BITMAP_WIDTH * GRID_HEIGHT
|
||||||
|
#define GRID_XMAXLONG (GRID_XMAX * FP_MULT)
|
||||||
|
#define GRID_YMAXLONG (GRID_YMAX * FP_MULT)
|
||||||
|
// The main grid array used with the ACKENG structure
|
||||||
|
#define GRID_ARRAY (GRID_WIDTH+2) * (GRID_HEIGHT+2)
|
||||||
|
|
||||||
|
// Defines to specify maximum sizes for the various components used with
|
||||||
|
// ACK-3D, including wall bitmaps, light zones, shading palette, views, multi-
|
||||||
|
// height walls, doors, object bitmaps, and objects.
|
||||||
|
#define MAX_WALLBMPS 256 // Total wall bitmaps allowed
|
||||||
|
#define MAX_ZONES 8 // Number of light zones
|
||||||
|
#define PAL_SIZE 4096 // Shading palette ranges
|
||||||
|
#define MAX_VIEWS 47 // Total sides to an object
|
||||||
|
#define MAX_MULTI 3 // Max height for multi-height walls
|
||||||
|
#define MAX_DOORS 10 // Max number of doors that can be opened or
|
||||||
|
// // closed at one time
|
||||||
|
#define MAX_OBJBMPS 256 // Total object bitmaps allowed
|
||||||
|
#define MAX_OBJECTS 254 // Total objects allowed in map
|
||||||
|
|
||||||
|
// Defines to set up different wall types.
|
||||||
|
#define WALL_TYPE_TRANS 0x0800 // Transparent wall
|
||||||
|
#define WALL_TYPE_MULTI 0x0400 // Wall is 1.5 times high
|
||||||
|
#define WALL_TYPE_UPPER 0x0200 // Wall is above floor level
|
||||||
|
#define WALL_TYPE_PASS 0x0100 // Wall can be walked through
|
||||||
|
|
||||||
|
#define TYPE_WALL 0
|
||||||
|
#define TYPE_OBJECT 1
|
||||||
|
|
||||||
|
#define RES_LOW 1 // Resolution is low for walls, floor, and ceiling
|
||||||
|
#define RES_MEDIUM 2 // Resolution is low only for floor and ceiling
|
||||||
|
|
||||||
|
//***************************************************************
|
||||||
|
// Definitions and data structures used to represent and process objects.
|
||||||
|
|
||||||
|
// These defines specify the two settings for the Active field in the NEWOBJECT structure.
|
||||||
|
#define OBJECT_ACTIVE 1 // Active and may be moveable
|
||||||
|
#define OBJECT_INACTIVE 0 // Won't be considered moveable
|
||||||
|
|
||||||
|
// These defines specify values for the Flags field in the NEWOBJECT structure.
|
||||||
|
// They are used to indicate the type of animation available for an object.
|
||||||
|
#define OF_PASSABLE 0x80 // Object can be walked thru
|
||||||
|
#define OF_ANIMATE 0x40 // Object bitmaps are animated
|
||||||
|
#define OF_MOVEABLE 0x20 // Object will move X,Y
|
||||||
|
#define OF_MULTIVIEW 0x10 // Object has multiple sides
|
||||||
|
#define OF_ANIMONCE 0x08 // Animate once then stop
|
||||||
|
#define OF_ANIMDONE 0x04 // One shot animation is completed
|
||||||
|
|
||||||
|
// These defines specify values for the CurrentType field in the NEWOBJECT structure.
|
||||||
|
// They are used to indicate the current status of the object.
|
||||||
|
// The names given are arbitrary and can be used for a variety of purposes.
|
||||||
|
#define NO_CREATE 1
|
||||||
|
#define NO_DESTROY 2
|
||||||
|
#define NO_WALK 3
|
||||||
|
#define NO_ATTACK 4
|
||||||
|
#define NO_INTERACT 5
|
||||||
|
|
||||||
|
// The Object Sequence structure. This structure is used by the NEWOBJECT structure.
|
||||||
|
#define MAX_OBJ_BITMAPS 32 // Max bitmaps per sequence type
|
||||||
|
typedef struct {
|
||||||
|
UCHAR flags; // Flags for this sequence
|
||||||
|
UCHAR bitmaps[MAX_OBJ_BITMAPS]; // Bitmap numbers in this sequence
|
||||||
|
short bmSides; // Number of views in sequence
|
||||||
|
short bmBitmapsPerView; // Number of bitmaps in each view
|
||||||
|
short AngleFactor; // Used internally to support the object sequence
|
||||||
|
UCHAR MaxBitmaps; // Max bitmaps in this sequence
|
||||||
|
} OBJSEQ;
|
||||||
|
|
||||||
|
// The defininition of the main object structure--NEWOBJECT.
|
||||||
|
typedef struct {
|
||||||
|
char Active; // Determines object status: 0=Inactive, 1=Active
|
||||||
|
UCHAR Flags; // Misc flags for this object
|
||||||
|
char Speed; // Speed of obj (used by application)
|
||||||
|
short Dir; // Direction of obj (used by application)
|
||||||
|
short x; // Current x,y location in grid
|
||||||
|
short y;
|
||||||
|
short mPos; // Current map location in grid
|
||||||
|
UCHAR id; // Object id
|
||||||
|
short CurrentType; // Create, Destroy, etc. is current
|
||||||
|
UCHAR *CurrentBitmaps; // Current bitmap list
|
||||||
|
short Sides; // Number of views
|
||||||
|
short aFactor; // Angle factor
|
||||||
|
short BitmapsPerView; // Number of bitmaps in each view
|
||||||
|
UCHAR CurrentBm; // Current bitmap number
|
||||||
|
UCHAR Maxbm; // Max bitmap number for this view
|
||||||
|
OBJSEQ Create; // Stores structures for the 5 object sequences
|
||||||
|
OBJSEQ Destroy;
|
||||||
|
OBJSEQ Walk;
|
||||||
|
OBJSEQ Attack;
|
||||||
|
OBJSEQ Interact;
|
||||||
|
} NEWOBJECT;
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// The definitions and data structure that are used to represent doors.
|
||||||
|
|
||||||
|
// The default value for the Speed field in the DOORS structure.
|
||||||
|
#define DEFAULT_DOOR_SPEED 2
|
||||||
|
// These defines are used to set the Type field.
|
||||||
|
// Obsolete door codes since any wall can be a door
|
||||||
|
#define DOOR_XCODE 60 // Map codes for the various doors
|
||||||
|
#define DOOR_SIDECODE 61
|
||||||
|
#define DOOR_YCODE 62
|
||||||
|
|
||||||
|
// These two defines are used to set the Flags field in the DOORS structure.
|
||||||
|
#define DOOR_OPENING 0x80 // Set if door is currently opening
|
||||||
|
#define DOOR_CLOSING 0x40 // Set if door is currently closing
|
||||||
|
// Other attributes that can be assigned to the Flags field.
|
||||||
|
#define DOOR_TYPE_SECRET 0x8000 // Secret door
|
||||||
|
#define DOOR_LOCKED 0x4000 // Locked door
|
||||||
|
#define DOOR_TYPE_SLIDE 0x2000 // Sliding door
|
||||||
|
#define DOOR_TYPE_SPLIT 0x1000 // Split door
|
||||||
|
|
||||||
|
// The main DOORS structure.
|
||||||
|
typedef struct {
|
||||||
|
short mPos; // Stores position info for a door
|
||||||
|
short mPos1;
|
||||||
|
short mCode; // Bitmap ID of the door
|
||||||
|
short mCode1;
|
||||||
|
UCHAR ColOffset; // Column offset for the door
|
||||||
|
char Speed; // Speed setting for opening and closing the door
|
||||||
|
char Type; // Code for the door type
|
||||||
|
UCHAR Flags; // Door attribute settings
|
||||||
|
} DOORS;
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
// The defines and data structure for the main interface structure--ACKENG.
|
||||||
|
|
||||||
|
// These defines are used for the LightFlag field in the ACKENG structure.
|
||||||
|
#define SHADING_ON 1 // Set if distance shading is on
|
||||||
|
#define SHADING_OFF 0
|
||||||
|
|
||||||
|
// These defines are used for the SysFlags field in the ACKENG structure.
|
||||||
|
#define SYS_SOLID_BACK 0x8000 // On if solid color bkgd vs picture
|
||||||
|
#define SYS_SOLID_FLOOR 0x4000 // On if solid vs texture floor
|
||||||
|
#define SYS_SOLID_CEIL 0x2000 // On if solid vs texture ceiling
|
||||||
|
#define SYS_NO_WALLS 0x1000 // On if walls are NOT to display
|
||||||
|
#define SYS_SINGLE_BMP 0x0800 // On if 1 bitmap for floor & ceiling
|
||||||
|
|
||||||
|
// These defines indicate how bitmaps will be loaded. they are used with the bmLoadType field.
|
||||||
|
#define BMLOAD_BBM 0 // Bitmaps will be loaded using BBM format
|
||||||
|
#define BMLOAD_GIF 1 // Bitmaps will be loaded using GIF format
|
||||||
|
#define BMLOAD_PCX 2 // Bitmaps will be loaded using PCX format
|
||||||
|
|
||||||
|
// The main interface structure used between the application and the ACK-3D engine.
|
||||||
|
// This structure MUST be allocated or defined before any ACK-3D calls are made.
|
||||||
|
typedef struct {
|
||||||
|
USHORT xGrid[GRID_ARRAY]; // Map for X walls
|
||||||
|
USHORT yGrid[GRID_ARRAY]; // Map for Y walls
|
||||||
|
UCHAR *mxGrid[GRID_ARRAY]; // Wall data for multi-height X walls
|
||||||
|
UCHAR *myGrid[GRID_ARRAY]; // Wall data for multi-height Y walls
|
||||||
|
UCHAR *bMaps[MAX_WALLBMPS]; // Pointers to wall bitmaps
|
||||||
|
UCHAR *oMaps[MAX_OBJBMPS]; // Pointers to object bitmaps
|
||||||
|
|
||||||
|
UCHAR *ScreenBuffer; // 64k buffer for screen
|
||||||
|
UCHAR *OverlayBuffer; // Buffer for compiled overlay
|
||||||
|
UCHAR *BkgdBuffer; // Buffer for ceiling, floor
|
||||||
|
|
||||||
|
short xPlayer; // X value from 0 to 4095--stores current position
|
||||||
|
short yPlayer; // Y value from 0 to 4095--stores current position
|
||||||
|
short PlayerAngle; // Angle value from 0 to 1799
|
||||||
|
|
||||||
|
short DoorSpeed; // Door open/close speed
|
||||||
|
short NonSecretCode; // Wall code for secret door
|
||||||
|
|
||||||
|
UCHAR TopColor; // Base color of ceiling
|
||||||
|
UCHAR BottomColor; // Base color of floor
|
||||||
|
UCHAR FloorBitmap; // Bitmap number for single floor
|
||||||
|
UCHAR CeilBitmap; // Bitmap number for single ceiling
|
||||||
|
|
||||||
|
UCHAR LightFlag; // 0 = no light shading, 1 = ON
|
||||||
|
UCHAR PalTable[PAL_SIZE]; // 16 zones of 256 colors each
|
||||||
|
|
||||||
|
short WinStartX; // Value of left side of viewport
|
||||||
|
short WinStartY; // Value of top side of viewport
|
||||||
|
short WinEndX; // Value of right side
|
||||||
|
short WinEndY; // Value of bottom side
|
||||||
|
short CenterRow; // Value of (WinEndY-WinStartY)/2
|
||||||
|
short CenterOffset; // Center row times bytes per row
|
||||||
|
short WinWidth; // Value of WinEndX - WinStartX
|
||||||
|
short WinHeight; // Value of WinEndY - WinStartY
|
||||||
|
USHORT WinLength; // Number of dwords in window
|
||||||
|
USHORT WinStartOffset; // Value of WinStartY * 320
|
||||||
|
USHORT SysFlags; // General system flags--determines display attributes
|
||||||
|
UCHAR bmLoadType; // Bitmap load flags (BBM, GIF, PCX, etc)
|
||||||
|
short MaxObjects; // Total number of objects in map
|
||||||
|
NEWOBJECT *ObjList[MAX_OBJECTS+1]; // Current objects in map
|
||||||
|
DOORS Door[MAX_DOORS]; // Doors moving at one time
|
||||||
|
} ACKENG;
|
||||||
|
|
||||||
|
// Structure used to build the palette ranges for light shading
|
||||||
|
// There are 16 color ranges (or zones) each containing 256 colors.
|
||||||
|
typedef struct {
|
||||||
|
unsigned char start; // Starting color for this range
|
||||||
|
unsigned char length; // Length of range
|
||||||
|
} ColorRange;
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// Function prototypes for the user callable ACK-3D functions.
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKINIT.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Reads trig files, builds wall and object maps, and performs the general
|
||||||
|
// initialization tasks. This function also sets up the distance table used by ACK-3D.
|
||||||
|
short AckInitialize(ACKENG *ae);
|
||||||
|
|
||||||
|
// Opens a resource file and prepares for reading.
|
||||||
|
short AckOpenResource(char *ResFileName);
|
||||||
|
|
||||||
|
// Closes the currently open resource file.
|
||||||
|
void AckCloseResource(void);
|
||||||
|
|
||||||
|
// Reads the map file and sets up the map grids.
|
||||||
|
short AckReadMapFile(ACKENG *ae,char *MapFileName);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKLDBMP.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Loads a bitmap and places it in either a wall bitmap array or an object bitmap array.
|
||||||
|
short AckLoadBitmap(ACKENG *ae,short BitmapNumber,short BitmapType,char *bmFileName);
|
||||||
|
|
||||||
|
// Loads a wall bitmap and places it into the wall array.
|
||||||
|
short AckLoadWall(ACKENG *ae,short WallNumber,char *bmFileName);
|
||||||
|
|
||||||
|
// Loads an object bitmap and places it into the object array.
|
||||||
|
short AckLoadObject(ACKENG *ae,short BmpNumber,char *bmFileName);
|
||||||
|
|
||||||
|
// Fills in an ObjList structure with the information passed in.
|
||||||
|
short AckCreateObject(ACKENG *ae,short ObjNumber);
|
||||||
|
|
||||||
|
// Sets up an object into one of the pre-defined sequences (CREATE, DESTRY, and so on).
|
||||||
|
short AckSetObjectType(ACKENG *ae,short oNum,short oType);
|
||||||
|
|
||||||
|
// Fills in an object structure with a communication structure passed by the application.
|
||||||
|
short AckSetupObject(ACKENG *ae,short oNum,short oType,OBJSEQ *os);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKIFF.C, ACKGIF.C, and ACKPCX.C
|
||||||
|
//*************************************************************************
|
||||||
|
// Reads in a .LBM or .BBM file and returns a buffer.
|
||||||
|
UCHAR *AckReadiff(char *FileName);
|
||||||
|
|
||||||
|
// Reads a 256 color GIF file and returns a buffer.
|
||||||
|
UCHAR *AckReadgif(char *FileName);
|
||||||
|
|
||||||
|
// Reads in a 256 color PCX file and returns a buffer.
|
||||||
|
UCHAR *AckReadPCX(char *filename);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKVIEW.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Assigns the current engine structure to various global variables.
|
||||||
|
// This function MUST be called before AckBuildView() is called.
|
||||||
|
void AckRegisterStructure(ACKENG *ae);
|
||||||
|
|
||||||
|
// Draws the current view into ScreenBuffer.
|
||||||
|
void AckBuildView(void);
|
||||||
|
|
||||||
|
// Returns the angle (0-1919) between two objects.
|
||||||
|
short AckGetObjectAngle(long DeltaX,long DeltaY);
|
||||||
|
|
||||||
|
// Checks if a collision occurs. Used by AckCheckDoorOpen routine.
|
||||||
|
short AckCheckHit(short xPlayer,short yPlayer,short ViewAngle);
|
||||||
|
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKPOV.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Used by AckMovePOV() and AckMoveObjectPOV() to check collision with objects.
|
||||||
|
short AckCheckObjPosn(short xPlayer,short yPlayer,short oIndex);
|
||||||
|
|
||||||
|
// Runs the list of objects to check movement.
|
||||||
|
void AckCheckObjectMovement(void);
|
||||||
|
|
||||||
|
// Moves the POV by the specified amount at the specified angle.
|
||||||
|
short AckMovePOV(short Angle,short Amount);
|
||||||
|
|
||||||
|
// Moves the object POV by the specified amount at the specified angle.
|
||||||
|
short AckMoveObjectPOV(short ObjIndex,short Angle,short Amount);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable function defined in ACKOVER.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Reads overlay file and compiles it into the OverlayBuffer.
|
||||||
|
short AckCreateOverlay(ACKENG *ae, UCHAR *OverlayScreen);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable function defined in ACKBKGD.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Builds background buffer from TopColor, BottomColor, and LightFlag.
|
||||||
|
short AckBuildBackground(ACKENG *ae);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable function defined in ACKDOOR.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Check if a door in front to open
|
||||||
|
short AckCheckDoorOpen(short xPlayer,short yPlayer,short PlayerAngle);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable function defined in ACKWRAP.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Frees memory buffers.
|
||||||
|
short AckWrapUp(ACKENG *ae);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKUTIL.C.
|
||||||
|
//*************************************************************************
|
||||||
|
// Internal memory allocation for development purposes
|
||||||
|
void *AckMalloc(size_t mSize);
|
||||||
|
|
||||||
|
// All memory allocated with AckMalloc() must use AckFree() to free memory.
|
||||||
|
void AckFree(void *m);
|
||||||
|
|
||||||
|
// Reads in a palette file and sets the screen palette.
|
||||||
|
short AckLoadAndSetPalette(char *FileName);
|
||||||
|
|
||||||
|
// Fills in the shading palette table.
|
||||||
|
void AckSetupPalRanges(ACKENG *ae,ColorRange *ranges);
|
||||||
|
|
||||||
|
// Returns the object index number of the last object hit.
|
||||||
|
short AckGetObjectHit(void);
|
||||||
|
|
||||||
|
// Returns the map location of the last wall hit.
|
||||||
|
short AckGetWallHit(void);
|
||||||
|
|
||||||
|
// Removes the specified object from the map.
|
||||||
|
short AckDeleteObject(ACKENG *ae,short ObjectIndex);
|
||||||
|
|
||||||
|
// Sets a new bitmap or changes image in the bitmap array.
|
||||||
|
short AckSetNewBitmapPtr(short BitmapNumber,UCHAR **Maps,UCHAR *NewBitmap);
|
||||||
|
|
||||||
|
// Frees up the memory used by the bitmap.
|
||||||
|
short AckFreeBitmap(UCHAR *bmType);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// The user callable functions defined in ACKRTN.ASM.
|
||||||
|
//*************************************************************************
|
||||||
|
// Sets a previously loaded palette.
|
||||||
|
void AckSetPalette(UCHAR *PalBuffer);
|
||||||
|
|
||||||
|
// Places video in standard 320x200 mode 13h.
|
||||||
|
void AckSetVGAmode(void);
|
||||||
|
|
||||||
|
// Places video in 80x25 color text mode 3.
|
||||||
|
void AckSetTextmode(void);
|
||||||
|
|
||||||
|
// Displays the contents of ScreenBuffer and OverlayBuffer if desired.
|
||||||
|
short AckDisplayScreen(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
42
ack_lib/ACKBKGD.C
Normal file
42
ack_lib/ACKBKGD.C
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
//typedef unsigned short USHORT;
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
|
||||||
|
|
||||||
|
void AckBuildCeilingFloor (UCHAR *, short, short, short, short, short, short);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Generates a solid floor and ceiling
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckBuildBackground (ACKENG * ae)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Let the assembly routine do all the hard work */
|
||||||
|
|
||||||
|
#if FLOOR_ACTIVE
|
||||||
|
#else
|
||||||
|
AckBuildCeilingFloor (ae->BkgdBuffer,
|
||||||
|
ae->LightFlag,
|
||||||
|
ae->TopColor,
|
||||||
|
ae->BottomColor,
|
||||||
|
ae->WinStartY,
|
||||||
|
ae->WinEndY,
|
||||||
|
ae->CenterRow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
150
ack_lib/ACKDATA.C
Normal file
150
ack_lib/ACKDATA.C
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
|
||||||
|
long scPtr;
|
||||||
|
UCHAR *bmWall;
|
||||||
|
|
||||||
|
long bmDistance;
|
||||||
|
long BackDropRows;
|
||||||
|
USHORT ScreenOffset;
|
||||||
|
|
||||||
|
long xPglobal;
|
||||||
|
long yPglobal;
|
||||||
|
long xBegGlobal;
|
||||||
|
long yBegGlobal;
|
||||||
|
|
||||||
|
ACKENG *aeGlobal;
|
||||||
|
USHORT *xGridGlobal;
|
||||||
|
USHORT *yGridGlobal;
|
||||||
|
long xPglobalHI;
|
||||||
|
long yPglobalHI;
|
||||||
|
ULONG *rbaTable;
|
||||||
|
short rsHandle;
|
||||||
|
|
||||||
|
long LastX1;
|
||||||
|
long LastY1;
|
||||||
|
long iLastX;
|
||||||
|
long iLastY;
|
||||||
|
|
||||||
|
long x_xPos;
|
||||||
|
long x_yPos;
|
||||||
|
long x_xNext;
|
||||||
|
long x_yNext;
|
||||||
|
long y_xPos;
|
||||||
|
long y_yPos;
|
||||||
|
long y_xNext;
|
||||||
|
long y_yNext;
|
||||||
|
|
||||||
|
short MaxDistance;
|
||||||
|
short LightFlag;
|
||||||
|
short ErrorCode;
|
||||||
|
|
||||||
|
long xMapPosn;
|
||||||
|
long yMapPosn;
|
||||||
|
|
||||||
|
USHORT *Grid;
|
||||||
|
USHORT *ObjGrid;
|
||||||
|
SLICE Slice[VIEW_WIDTH];
|
||||||
|
SLICE *sPtr;
|
||||||
|
|
||||||
|
short TotalSpecial;
|
||||||
|
|
||||||
|
short DistanceTable[MAX_DISTANCE + 1];
|
||||||
|
long *AdjustTable;
|
||||||
|
|
||||||
|
short xSecretmPos;
|
||||||
|
short xSecretmPos1;
|
||||||
|
short xSecretColumn;
|
||||||
|
|
||||||
|
short ySecretmPos;
|
||||||
|
short ySecretmPos1;
|
||||||
|
short ySecretColumn;
|
||||||
|
|
||||||
|
short TotalSecret;
|
||||||
|
short ViewColumn;
|
||||||
|
|
||||||
|
long *SinTable;
|
||||||
|
long *CosTable;
|
||||||
|
|
||||||
|
long *LongTanTable;
|
||||||
|
long *LongInvTanTable;
|
||||||
|
long InvCosTable[INT_ANGLE_360];
|
||||||
|
long InvSinTable[INT_ANGLE_360];
|
||||||
|
long *LongCosTable;
|
||||||
|
long *ViewCosTable;
|
||||||
|
|
||||||
|
long *xNextTable;
|
||||||
|
long *yNextTable;
|
||||||
|
|
||||||
|
short LastFloorAngle = -1;
|
||||||
|
short LastFloorX;
|
||||||
|
short LastFloorY;
|
||||||
|
short LastMapPosn;
|
||||||
|
short LastObjectHit;
|
||||||
|
short TotalObjects;
|
||||||
|
short FoundObjectCount;
|
||||||
|
UCHAR ObjectsSeen[MAX_OBJECTS + 1];
|
||||||
|
short MoveObjectCount;
|
||||||
|
UCHAR MoveObjectList[MAX_OBJECTS + 1];
|
||||||
|
UCHAR ObjNumber[MAX_OBJECTS + 1];
|
||||||
|
USHORT ObjRelDist[MAX_OBJECTS + 1];
|
||||||
|
short ObjColumn[MAX_OBJECTS + 1];
|
||||||
|
short ObjAngle[MAX_OBJECTS + 1];
|
||||||
|
short DirAngle[] =
|
||||||
|
{INT_ANGLE_270, INT_ANGLE_315, 0,
|
||||||
|
INT_ANGLE_45, INT_ANGLE_90,
|
||||||
|
INT_ANGLE_135, INT_ANGLE_180,
|
||||||
|
INT_ANGLE_225};
|
||||||
|
|
||||||
|
UCHAR WorkPalette[768];
|
||||||
|
UCHAR *BackArray[INT_ANGLE_360];
|
||||||
|
short Resolution;
|
||||||
|
|
||||||
|
long Flooru;
|
||||||
|
long Floorv;
|
||||||
|
long Floordu;
|
||||||
|
long Floordv;
|
||||||
|
long Floorkx;
|
||||||
|
long Floorky;
|
||||||
|
long Floorku;
|
||||||
|
long Floorkv;
|
||||||
|
long Floorkdu;
|
||||||
|
long Floorkdv;
|
||||||
|
UCHAR *Floorbm;
|
||||||
|
UCHAR *Floorscr;
|
||||||
|
UCHAR *FloorscrTop;
|
||||||
|
UCHAR *Floorptr2;
|
||||||
|
UCHAR *Floors1;
|
||||||
|
UCHAR *Floors2;
|
||||||
|
long Floorht;
|
||||||
|
long Floorwt;
|
||||||
|
short Floorvht;
|
||||||
|
short Flooreht;
|
||||||
|
long FloorLastbNum;
|
||||||
|
long FloorLastbm;
|
||||||
|
|
||||||
|
short ViewHeight = 31;
|
||||||
|
short CeilingHeight = 31;
|
||||||
|
short LastWallHeight;
|
||||||
|
short PlayerAngle;
|
||||||
|
short ViewAngle;
|
||||||
|
USHORT SysFlags;
|
||||||
|
UCHAR **WallbMaps;
|
||||||
|
UCHAR *VidTop;
|
||||||
|
UCHAR *VidBottom;
|
||||||
|
short BotRowTable[320];
|
||||||
|
USHORT FloorMap[4096];
|
||||||
|
USHORT CeilMap[4096];
|
||||||
|
UCHAR HitMap[4096];
|
||||||
|
|
||||||
|
UCHAR *VidSeg;
|
||||||
|
char *scantables[96];
|
||||||
|
UCHAR AckKeys[128]; // Buffer for keystrokes
|
||||||
|
long AckTimerCounter;
|
||||||
|
|
||||||
|
// **** End of Data ****
|
||||||
|
|
||||||
|
|
34
ack_lib/ACKDISP.C
Normal file
34
ack_lib/ACKDISP.C
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
//typedef unsigned short USHORT;
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
|
||||||
|
void AckDrawPage (void);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// This function has been replaced by AckDisplayScreen in assembler
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short xxxAckDisplayScreen (void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Let the assembly routine do the hard work */
|
||||||
|
AckDrawPage ();
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
391
ack_lib/ACKDOOR.C
Normal file
391
ack_lib/ACKDOOR.C
Normal file
|
@ -0,0 +1,391 @@
|
||||||
|
// This source file contains the functions needed to process doors.
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
extern DOORS *gDoor;
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Check all the active doors to see what current state they are in. If a
|
||||||
|
// door's column offset is non-zero, it is either opening or closing,
|
||||||
|
// so the speed of the door is added in and the door is checked to
|
||||||
|
// see if it is fully opened or fully closed.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void CheckDoors (void)
|
||||||
|
{
|
||||||
|
short i, MapPosn, mPos, mPos1;
|
||||||
|
short mx, my, DeltaGrid;
|
||||||
|
short xPlayer, yPlayer;
|
||||||
|
DOORS *dPtr;
|
||||||
|
|
||||||
|
xPlayer = xPglobal;
|
||||||
|
yPlayer = yPglobal;
|
||||||
|
dPtr = &gDoor[0];
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_DOORS; i++)
|
||||||
|
{
|
||||||
|
if (dPtr->ColOffset) // Door is not closed
|
||||||
|
{ // Add speed to door column offset
|
||||||
|
dPtr->ColOffset += dPtr->Speed;
|
||||||
|
mPos = dPtr->mPos; // Get grid position of door
|
||||||
|
mPos1 = dPtr->mPos1;
|
||||||
|
|
||||||
|
// Door is closing and is visible. Put old codes back to make non-passable
|
||||||
|
if (dPtr->Speed < 1 && dPtr->ColOffset < 65)
|
||||||
|
{ // Get corner of grid
|
||||||
|
MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> BITMAP_SHIFT);
|
||||||
|
// Is player in same grid square that the door is in?
|
||||||
|
if (MapPosn == mPos || MapPosn == mPos1)
|
||||||
|
{
|
||||||
|
dPtr->ColOffset -= dPtr->Speed; // Reduce column offset
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Is the door along an x wall
|
||||||
|
if (dPtr->Type == DOOR_XCODE)
|
||||||
|
{ // Store bitmap ids for doors
|
||||||
|
xGridGlobal[mPos] = dPtr->mCode;
|
||||||
|
xGridGlobal[mPos1] = dPtr->mCode1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Door is along a y wall
|
||||||
|
yGridGlobal[mPos] = dPtr->mCode;
|
||||||
|
yGridGlobal[mPos1] = dPtr->mCode1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Door is close enough to fully closed to get rid
|
||||||
|
// of the door from the array
|
||||||
|
if (dPtr->ColOffset < 3)
|
||||||
|
{
|
||||||
|
dPtr->ColOffset = 0; // Close door
|
||||||
|
dPtr->mPos = -1;
|
||||||
|
dPtr->mPos1 = -1;
|
||||||
|
dPtr->Flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Door is fully opened--time to start closing it
|
||||||
|
if (dPtr->ColOffset > 0xA0)
|
||||||
|
{
|
||||||
|
dPtr->Speed = -dPtr->Speed; // Start to reduce speed
|
||||||
|
dPtr->Flags &= ~DOOR_OPENING; // Set flag to indicate door closing
|
||||||
|
dPtr->Flags |= DOOR_CLOSING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dPtr++; // Advance to check next door
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Now check for any action occuring in a secret door. This is currently
|
||||||
|
// setup to handle only one door at a time in the X and Y directions, but
|
||||||
|
// it should be fairly straightforward to use a list of doors, similiar
|
||||||
|
// to normal doors, to handle more than one.
|
||||||
|
//=============================================================================
|
||||||
|
if (xSecretColumn)
|
||||||
|
{
|
||||||
|
if (xSecretColumn > 0) // See if the door is to the right of us
|
||||||
|
{
|
||||||
|
mPos = xSecretmPos1;
|
||||||
|
DeltaGrid = -1;
|
||||||
|
xSecretColumn += aeGlobal->DoorSpeed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPos = xSecretmPos;
|
||||||
|
DeltaGrid = 0;
|
||||||
|
xSecretColumn -= aeGlobal->DoorSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
my = mPos & 0xFFC0;
|
||||||
|
mx = (mPos - my) << 6;
|
||||||
|
|
||||||
|
if (abs (xSecretColumn) > BITMAP_WIDTH) // Beyond one grid square
|
||||||
|
{
|
||||||
|
mx += xSecretColumn;
|
||||||
|
my = my + (mx >> BITMAP_SHIFT);
|
||||||
|
if (xGridGlobal[my]) // No further, an obstruction
|
||||||
|
{
|
||||||
|
xGridGlobal[xSecretmPos] = 0;
|
||||||
|
xGridGlobal[xSecretmPos1] = 0;
|
||||||
|
my += DeltaGrid;
|
||||||
|
xGridGlobal[my] = aeGlobal->NonSecretCode;
|
||||||
|
xGridGlobal[my + 1] = aeGlobal->NonSecretCode;
|
||||||
|
yGridGlobal[my] = aeGlobal->NonSecretCode;
|
||||||
|
yGridGlobal[my + GRID_WIDTH] = aeGlobal->NonSecretCode;
|
||||||
|
xSecretColumn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (my != mPos)
|
||||||
|
{
|
||||||
|
xGridGlobal[xSecretmPos] = 0;
|
||||||
|
xGridGlobal[xSecretmPos1] = 0;
|
||||||
|
if (xSecretColumn > 0)
|
||||||
|
{
|
||||||
|
xSecretColumn -= (BITMAP_WIDTH - 1);
|
||||||
|
xGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
xSecretmPos1 = my;
|
||||||
|
my--;
|
||||||
|
xGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
xSecretmPos = my;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xSecretColumn += (BITMAP_WIDTH - 1);
|
||||||
|
xGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
xGridGlobal[my + 1] = DOOR_TYPE_SECRET + 1;
|
||||||
|
xSecretmPos = my;
|
||||||
|
xSecretmPos = my + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // End if (xGrid[my]) ... else ...
|
||||||
|
} // End if (abs(xSecretColumn) > GRID_SIZE)
|
||||||
|
} // End if (xSecretColumn)
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Perform same process on a secret door that may be moving in the Y
|
||||||
|
// direction. The same door can move either way, depending on which
|
||||||
|
// angle the player struck it at.
|
||||||
|
//=============================================================================
|
||||||
|
if (ySecretColumn)
|
||||||
|
{
|
||||||
|
if (ySecretColumn > 0)
|
||||||
|
{
|
||||||
|
mPos = ySecretmPos1;
|
||||||
|
DeltaGrid = -GRID_WIDTH;
|
||||||
|
ySecretColumn += aeGlobal->DoorSpeed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPos = ySecretmPos;
|
||||||
|
DeltaGrid = 0;
|
||||||
|
ySecretColumn -= aeGlobal->DoorSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
my = mPos & 0xFFC0;
|
||||||
|
mx = (mPos - my) << 6;
|
||||||
|
|
||||||
|
if (abs (ySecretColumn) > BITMAP_WIDTH)
|
||||||
|
{
|
||||||
|
my += ySecretColumn;
|
||||||
|
my = (my & 0xFFC0) + (mx >> 6);
|
||||||
|
if (yGridGlobal[my])
|
||||||
|
{
|
||||||
|
yGridGlobal[ySecretmPos] = 0;
|
||||||
|
yGridGlobal[ySecretmPos1] = 0;
|
||||||
|
my += DeltaGrid;
|
||||||
|
xGridGlobal[my] = aeGlobal->NonSecretCode;
|
||||||
|
xGridGlobal[my + 1] = aeGlobal->NonSecretCode;
|
||||||
|
yGridGlobal[my] = aeGlobal->NonSecretCode;
|
||||||
|
yGridGlobal[my + GRID_WIDTH] = aeGlobal->NonSecretCode;
|
||||||
|
ySecretColumn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (my != mPos)
|
||||||
|
{
|
||||||
|
yGridGlobal[ySecretmPos] = 0;
|
||||||
|
yGridGlobal[ySecretmPos1] = 0;
|
||||||
|
if (ySecretColumn > 0)
|
||||||
|
{
|
||||||
|
ySecretColumn -= (BITMAP_WIDTH - 1);
|
||||||
|
yGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
ySecretmPos1 = my;
|
||||||
|
my -= GRID_WIDTH;
|
||||||
|
yGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
ySecretmPos = my;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ySecretColumn += (BITMAP_WIDTH - 1);
|
||||||
|
yGridGlobal[my] = DOOR_TYPE_SECRET + 1;
|
||||||
|
yGridGlobal[my + GRID_WIDTH] = DOOR_TYPE_SECRET + 1;
|
||||||
|
ySecretmPos = my;
|
||||||
|
ySecretmPos = my + GRID_WIDTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal function called by FindDoorSlot(). This function
|
||||||
|
// locates a door from its map coordinate and return the index.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short FindDoor (short MapPosn)
|
||||||
|
{
|
||||||
|
short index;
|
||||||
|
|
||||||
|
for (index = 0; index < MAX_DOORS; index++)
|
||||||
|
{
|
||||||
|
if (MapPosn == gDoor[index].mPos ||
|
||||||
|
MapPosn == gDoor[index].mPos1)
|
||||||
|
{
|
||||||
|
return (index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal routine called by AckCheckDoorOpen() This function
|
||||||
|
// finds an empty slot for a door. If the door already occupies a slot
|
||||||
|
// and it is in a non-closed state, an error is returned.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short FindDoorSlot (short MapPosn)
|
||||||
|
{
|
||||||
|
short index;
|
||||||
|
|
||||||
|
index = FindDoor (MapPosn);
|
||||||
|
if (index >= 0 && gDoor[index].ColOffset)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
for (index = 0; index < MAX_DOORS; index++)
|
||||||
|
{
|
||||||
|
if (gDoor[index].mPos == -1)
|
||||||
|
return (index);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Checks directly in front of the POV to see if a door is there. If so,
|
||||||
|
// and the door is not locked, the door is set to begin opening.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckCheckDoorOpen (short xPlayer, short yPlayer, short PlayerAngle)
|
||||||
|
{
|
||||||
|
short i,j,DoorCode;
|
||||||
|
|
||||||
|
DoorCode = POV_NODOOR;
|
||||||
|
// Check to see if player is close to a wall
|
||||||
|
i = AckCheckHit (xPlayer, yPlayer, PlayerAngle);
|
||||||
|
// A secret door is found along an x wall
|
||||||
|
if (i == 1 && xGridGlobal[xMapPosn] & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (xSecretColumn == 0) // Player is on the right side of door
|
||||||
|
{
|
||||||
|
DoorCode = POV_XSECRETDOOR;
|
||||||
|
// Secret door is locked; can't open
|
||||||
|
if (xGridGlobal[xMapPosn] & DOOR_LOCKED)
|
||||||
|
return (DoorCode | POV_DOORLOCKED);
|
||||||
|
// Get grid map position that corresponds with the x wall
|
||||||
|
// position of where the door starts
|
||||||
|
xSecretmPos = xMapPosn;
|
||||||
|
if (iLastX > xPlayer) // Door is to the right of player
|
||||||
|
{
|
||||||
|
xSecretmPos1 = xMapPosn + 1;
|
||||||
|
LastMapPosn = xMapPosn;
|
||||||
|
xSecretColumn = 1; // Set to indicate player is on right side
|
||||||
|
yGridGlobal[xMapPosn] = yGridGlobal[xMapPosn - GRID_WIDTH];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Door is to the left of the player
|
||||||
|
LastMapPosn = xSecretmPos1 = xMapPosn - 1;
|
||||||
|
xSecretColumn = -1;
|
||||||
|
yGridGlobal[xSecretmPos1] = yGridGlobal[xSecretmPos1 - GRID_WIDTH];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A secret door is found along a y wall
|
||||||
|
if (i == 2 && yGridGlobal[yMapPosn] & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (ySecretColumn == 0)
|
||||||
|
{
|
||||||
|
DoorCode = POV_YSECRETDOOR;
|
||||||
|
|
||||||
|
if (yGridGlobal[yMapPosn] & DOOR_LOCKED)
|
||||||
|
return (DoorCode | POV_DOORLOCKED);
|
||||||
|
|
||||||
|
ySecretmPos = yMapPosn;
|
||||||
|
if (iLastY > yPlayer)
|
||||||
|
{
|
||||||
|
LastMapPosn = yMapPosn;
|
||||||
|
ySecretmPos1 = yMapPosn + GRID_WIDTH;
|
||||||
|
xGridGlobal[yMapPosn] = xGridGlobal[yMapPosn - 1];
|
||||||
|
ySecretColumn = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LastMapPosn = ySecretmPos1 = yMapPosn - GRID_WIDTH;
|
||||||
|
xGridGlobal[ySecretmPos1] = xGridGlobal[ySecretmPos1 - 1];
|
||||||
|
ySecretColumn = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A sliding or split door is found along an x wall
|
||||||
|
if (i == 1 && (xGridGlobal[xMapPosn] & (DOOR_TYPE_SLIDE + DOOR_TYPE_SPLIT)))
|
||||||
|
{
|
||||||
|
j = FindDoorSlot (xMapPosn);
|
||||||
|
if (j >= 0)
|
||||||
|
{
|
||||||
|
DoorCode = POV_XDOOR;
|
||||||
|
|
||||||
|
LastMapPosn = gDoor[j].mPos = xMapPosn;
|
||||||
|
if ((short) iLastX > xPlayer)
|
||||||
|
i = xMapPosn + 1;
|
||||||
|
else
|
||||||
|
LastMapPosn = i = xMapPosn - 1;
|
||||||
|
if (xGridGlobal[xMapPosn] & DOOR_LOCKED)
|
||||||
|
{
|
||||||
|
gDoor[j].mPos = -1;
|
||||||
|
return (DoorCode | POV_DOORLOCKED);
|
||||||
|
}
|
||||||
|
// Update door data structure
|
||||||
|
gDoor[j].mCode = xGridGlobal[xMapPosn];
|
||||||
|
gDoor[j].mCode1 = xGridGlobal[i];
|
||||||
|
gDoor[j].mPos1 = i;
|
||||||
|
gDoor[j].ColOffset = 1;
|
||||||
|
gDoor[j].Speed = aeGlobal->DoorSpeed;
|
||||||
|
gDoor[j].Type = DOOR_XCODE;
|
||||||
|
gDoor[j].Flags = DOOR_OPENING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A sliding or split door is found along a y wall
|
||||||
|
if (i == 2 && (yGridGlobal[yMapPosn] & (DOOR_TYPE_SLIDE + DOOR_TYPE_SPLIT)))
|
||||||
|
{
|
||||||
|
j = FindDoorSlot (yMapPosn);
|
||||||
|
if (j >= 0)
|
||||||
|
{
|
||||||
|
DoorCode = POV_YDOOR;
|
||||||
|
LastMapPosn = gDoor[j].mPos = yMapPosn;
|
||||||
|
if ((short) iLastY > yPlayer)
|
||||||
|
i = yMapPosn + GRID_WIDTH;
|
||||||
|
else
|
||||||
|
LastMapPosn = i = yMapPosn - GRID_WIDTH;
|
||||||
|
|
||||||
|
if (yGridGlobal[yMapPosn] & DOOR_LOCKED)
|
||||||
|
{
|
||||||
|
gDoor[j].mPos = -1;
|
||||||
|
return (DoorCode | POV_DOORLOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
gDoor[j].mCode = yGridGlobal[yMapPosn];
|
||||||
|
gDoor[j].mCode1 = yGridGlobal[i];
|
||||||
|
gDoor[j].mPos1 = i;
|
||||||
|
gDoor[j].ColOffset = 1;
|
||||||
|
gDoor[j].Speed = aeGlobal->DoorSpeed;
|
||||||
|
gDoor[j].Type = DOOR_YCODE;
|
||||||
|
gDoor[j].Flags = DOOR_OPENING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (DoorCode);
|
||||||
|
}
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
66
ack_lib/ACKENG.H
Normal file
66
ack_lib/ACKENG.H
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// ACKENG.H header file for supporting raycasting routines.
|
||||||
|
// This file contains the main data structure named SLICE and definitions
|
||||||
|
// required to support the raycasting routines. The data structures defined
|
||||||
|
// in this file are not to be used directly by the programmer who is using
|
||||||
|
// the functions in the ACK-3D library. To locate data structures for the
|
||||||
|
// ACK-3D interface, see the file ACK3D.H.
|
||||||
|
|
||||||
|
#define TRANS_WALLS 0
|
||||||
|
#define FLOOR_ACTIVE 1
|
||||||
|
#define USE_XMS 0 // Set to 0 if XMS not desired
|
||||||
|
|
||||||
|
#define MAX_RBA 500 // Number of rba's in resource header
|
||||||
|
|
||||||
|
// Fixed point constants used to perform fixed point calculations.
|
||||||
|
#define FP_SHIFT 16
|
||||||
|
#define FP_MULT 65536
|
||||||
|
#define FP_HALF 32768
|
||||||
|
|
||||||
|
#define VIEW_WIDTH 320 // The number of columns in a view (screen)
|
||||||
|
#define MAX_DISTANCE 2048 // The max distance from the POV to a wall slice
|
||||||
|
|
||||||
|
#define TYPE_WALL 0
|
||||||
|
#define TYPE_OBJECT 1
|
||||||
|
#define TYPE_PALETTE 2
|
||||||
|
|
||||||
|
#define MAX_HEIGHT 960 // Maximum height of a wall
|
||||||
|
#define MIN_HEIGHT 8 // Minimum height of a wall
|
||||||
|
|
||||||
|
#define MAX_UPDOWN 30 // Max up or down spots for each level
|
||||||
|
|
||||||
|
#define MAP_STARTCODE 0xFC // Force player to this square
|
||||||
|
#define MAP_UPCODE 0xFD // Go up to previous level
|
||||||
|
#define MAP_DOWNCODE 0xFE // Go down to next level
|
||||||
|
#define MAP_GOALCODE 0xFF // Finish line!
|
||||||
|
|
||||||
|
#define ST_WALL 1
|
||||||
|
#define ST_OBJECT 2
|
||||||
|
|
||||||
|
#define COLS_PER_BYTE 1 // Use 1 for normal mode 13h, 4 for modeX
|
||||||
|
#define BYTES_PER_ROW 320 // Use 320 for normal mode 13h, 80 for modeX
|
||||||
|
#define DWORDS_PER_ROW (BYTES_PER_ROW / 4)
|
||||||
|
#define SCREEN_SIZE 64000
|
||||||
|
|
||||||
|
// Holds information for the current wall section found during the raycasting process.
|
||||||
|
// During the raycasting process, ACK-3D casts out rays, looks for a wall at a
|
||||||
|
// given screen column position, and if a wall (slice) is found, information about
|
||||||
|
// the slice is stored in this structure.
|
||||||
|
|
||||||
|
typedef struct _slicer {
|
||||||
|
UCHAR **bMap; // Pointer to wall bitmap found while ray casting
|
||||||
|
UCHAR *mPtr; // Grid pointer to reference multi-height wall data
|
||||||
|
short bNumber; // Bitmap number of the wall found
|
||||||
|
unsigned short bColumn; // Screen column location of the found slice
|
||||||
|
short Distance; // Distance from the POV to the slice
|
||||||
|
short mPos; // Position of the slice in the associated map
|
||||||
|
unsigned char Type; // Indicates if the slice is a wall or object
|
||||||
|
void (*Fnc)(void); // Pointer to a function to draw wall or object
|
||||||
|
unsigned char Active; // Indicates last slice in listif a wall or object is displayable or not
|
||||||
|
// The next two pointers are used if the current slice
|
||||||
|
// is part of a transparent wall
|
||||||
|
struct _slicer *Prev; // References the wall slice in front of current slice
|
||||||
|
struct _slicer *Next; // References the wall slice behind the current slice
|
||||||
|
} SLICE;
|
||||||
|
|
||||||
|
|
||||||
|
|
119
ack_lib/ACKEXT.H
Normal file
119
ack_lib/ACKEXT.H
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/* ACK-3D ( Animation Construction Kit 3D ) */
|
||||||
|
|
||||||
|
extern UCHAR *BackArray[];
|
||||||
|
extern long xPglobal;
|
||||||
|
extern long yPglobal;
|
||||||
|
extern long xBegGlobal;
|
||||||
|
extern long yBegGlobal;
|
||||||
|
extern long BackDropRows;
|
||||||
|
extern ACKENG *aeGlobal;
|
||||||
|
extern USHORT *xGridGlobal;
|
||||||
|
extern USHORT *yGridGlobal;
|
||||||
|
extern long xPglobalHI;
|
||||||
|
extern long yPglobalHI;
|
||||||
|
extern ULONG *rbaTable;
|
||||||
|
|
||||||
|
extern long bmDistance;
|
||||||
|
|
||||||
|
|
||||||
|
extern short rsHandle;
|
||||||
|
extern long LastX1;
|
||||||
|
extern long LastY1;
|
||||||
|
extern long iLastX;
|
||||||
|
extern long iLastY;
|
||||||
|
extern short MaxDistance;
|
||||||
|
extern short ErrorCode;
|
||||||
|
extern short LightFlag;
|
||||||
|
|
||||||
|
extern long xMapPosn;
|
||||||
|
extern long yMapPosn;
|
||||||
|
|
||||||
|
extern short DefZone[];
|
||||||
|
extern short AckLightZones[];
|
||||||
|
extern UCHAR *HtTable[];
|
||||||
|
extern USHORT *Grid;
|
||||||
|
extern USHORT *ObjGrid;
|
||||||
|
extern UCHAR HitMap[];
|
||||||
|
extern UCHAR *BitmapXferPtr;
|
||||||
|
extern short TotalSpecial;
|
||||||
|
extern short DistanceTable[];
|
||||||
|
extern long *AdjustTable;
|
||||||
|
extern short xSecretmPos;
|
||||||
|
extern short xSecretmPos1;
|
||||||
|
extern short xSecretColumn;
|
||||||
|
extern short ySecretmPos;
|
||||||
|
extern short ySecretmPos1;
|
||||||
|
extern short ySecretColumn;
|
||||||
|
extern short TotalSecret;
|
||||||
|
extern short ViewColumn;
|
||||||
|
extern long *SinTable;
|
||||||
|
extern long *CosTable;
|
||||||
|
extern long *LongTanTable;
|
||||||
|
extern long *LongInvTanTable;
|
||||||
|
extern long InvCosTable[];
|
||||||
|
extern long InvSinTable[];
|
||||||
|
extern long *LongCosTable;
|
||||||
|
extern long *ViewCosTable;
|
||||||
|
extern long *xNextTable;
|
||||||
|
extern long *yNextTable;
|
||||||
|
extern UCHAR ObjectsSeen[];
|
||||||
|
extern UCHAR MoveObjectList[];
|
||||||
|
extern short TotalObjects;
|
||||||
|
extern short FoundObjectCount;
|
||||||
|
extern short MoveObjectCount;
|
||||||
|
extern short LastObjectHit;
|
||||||
|
extern short LastMapPosn;
|
||||||
|
extern UCHAR ObjNumber[];
|
||||||
|
extern USHORT ObjRelDist[];
|
||||||
|
extern short ObjColumn[];
|
||||||
|
extern short ObjAngle[];
|
||||||
|
extern short DirAngle[];
|
||||||
|
extern UCHAR LightMap[];
|
||||||
|
|
||||||
|
extern USHORT FloorMap[];
|
||||||
|
extern USHORT CeilMap[];
|
||||||
|
extern SLICE Slice[];
|
||||||
|
extern USHORT ScreenOffset;
|
||||||
|
extern short LastFloorAngle;
|
||||||
|
extern short LastFloorX;
|
||||||
|
extern short LastFloorY;
|
||||||
|
extern long Flooru;
|
||||||
|
extern long Floorv;
|
||||||
|
extern long Floordu;
|
||||||
|
extern long Floordv;
|
||||||
|
extern long Floorkx;
|
||||||
|
extern long Floorky;
|
||||||
|
extern long Floorku;
|
||||||
|
extern long Floorkv;
|
||||||
|
extern long Floorkdu;
|
||||||
|
extern long Floorkdv;
|
||||||
|
extern UCHAR *Floorbm;
|
||||||
|
extern UCHAR *Floorscr;
|
||||||
|
extern UCHAR *FloorscrTop;
|
||||||
|
extern UCHAR *Floorptr2;
|
||||||
|
extern UCHAR *Floors1;
|
||||||
|
extern UCHAR *Floors2;
|
||||||
|
extern long Floorht;
|
||||||
|
extern long Floorwt;
|
||||||
|
extern short Floorvht;
|
||||||
|
extern short Flooreht;
|
||||||
|
extern short ViewAngle;
|
||||||
|
extern short ViewHeight;
|
||||||
|
extern short CeilingHeight;
|
||||||
|
extern short Resolution;
|
||||||
|
extern short LastWallHeight;
|
||||||
|
extern short PlayerAngle;
|
||||||
|
extern short ViewAngle;
|
||||||
|
extern USHORT SysFlags;
|
||||||
|
extern SLICE Slice[];
|
||||||
|
extern SLICE *sPtr;
|
||||||
|
extern UCHAR **WallbMaps;
|
||||||
|
extern UCHAR *VidTop;
|
||||||
|
extern UCHAR *VidBottom;
|
||||||
|
extern short BotRowTable[];
|
||||||
|
extern USHORT FloorMap[];
|
||||||
|
extern USHORT CeilMap[];
|
||||||
|
extern char *scantables[];
|
||||||
|
|
||||||
|
|
||||||
|
|
1239
ack_lib/ACKFLOOR.C
Normal file
1239
ack_lib/ACKFLOOR.C
Normal file
File diff suppressed because it is too large
Load diff
30
ack_lib/ACKGIF.C
Normal file
30
ack_lib/ACKGIF.C
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// This source file contains the functions needed to read in GIF files.
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <bios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Read a GIF format file and return a buffer containing the uncompressed
|
||||||
|
// image.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
#pragma argsused
|
||||||
|
unsigned char *AckReadgif (char *picname)
|
||||||
|
{
|
||||||
|
// This is a stub routine used only as a place holder for the actual
|
||||||
|
// GIF read routine. It was omitted based on current patent issues.
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
231
ack_lib/ACKIFF.C
Normal file
231
ack_lib/ACKIFF.C
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
// This source file contains the functions needed to read in BBM files.
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
//=============================================================================
|
||||||
|
// This function will return a pointer to a buffer that holds the raw image.
|
||||||
|
// just free the pointer to delete this buffer. After returning, the array
|
||||||
|
// colordat will hold the adjusted palette of this pic.
|
||||||
|
//
|
||||||
|
// Also, this has been modified to only read in form PBM brushes. form ILBM's
|
||||||
|
// (the "old" type) are not supported. use the "new" deluxe paint .lbm type
|
||||||
|
// and do not choose "old".
|
||||||
|
//=============================================================================
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <bios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <mem.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
#include "iff.h"
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
|
||||||
|
extern char rsName[];
|
||||||
|
|
||||||
|
unsigned char colordat[768]; // maximum it can be...256 colors
|
||||||
|
|
||||||
|
unsigned char cplanes[8][80]; // setting max at 640 pixels width
|
||||||
|
// thats 8 pixels per byte per plane
|
||||||
|
unsigned char *pplanes= &cplanes[0][0]; // for a form pbm
|
||||||
|
|
||||||
|
#define MAX_BUF_POS 4096
|
||||||
|
|
||||||
|
int rdbufpos;
|
||||||
|
int rdSize;
|
||||||
|
UCHAR rdBuffer[MAX_BUF_POS+2];
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
void CloseFile(FILE *fp)
|
||||||
|
{
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
if (rsHandle)
|
||||||
|
{
|
||||||
|
rsHandle = _lopen(rsName,OF_READ);
|
||||||
|
if (rsHandle < 1)
|
||||||
|
rsHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *AckReadiff(char *picname)
|
||||||
|
{
|
||||||
|
FILE *pic;
|
||||||
|
short handle;
|
||||||
|
form_chunk fchunk;
|
||||||
|
ChunkHeader chunk;
|
||||||
|
BitMapHeader bmhd;
|
||||||
|
long length,fpos;
|
||||||
|
char value; // must remain signed, no matter what. ignore any warnings.
|
||||||
|
short sofar;
|
||||||
|
short width,height,planes;
|
||||||
|
short pixw;
|
||||||
|
unsigned char *destx, *savedestx;
|
||||||
|
|
||||||
|
rdbufpos = MAX_BUF_POS + 1;
|
||||||
|
rdSize = MAX_BUF_POS;
|
||||||
|
|
||||||
|
if (!rsHandle)
|
||||||
|
handle = _lopen(picname,OF_READ);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = rsHandle;
|
||||||
|
_llseek(rsHandle,rbaTable[(ULONG)picname],SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
_lread(handle,&fchunk,sizeof(form_chunk));
|
||||||
|
|
||||||
|
if (fchunk.type != FORM)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
|
||||||
|
ErrorCode = ERR_INVALIDFORM;
|
||||||
|
return(0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fchunk.subtype != ID_PBM)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
ErrorCode = ERR_NOPBM;
|
||||||
|
return(0L);
|
||||||
|
}
|
||||||
|
// now lets loop...Because the Chunks can be in any order!
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
_lread(handle,&chunk,sizeof(ChunkHeader));
|
||||||
|
chunk.ckSize = ByteFlipLong(chunk.ckSize);
|
||||||
|
if (chunk.ckSize & 1) chunk.ckSize ++; // must be word aligned
|
||||||
|
if(chunk.ckID == ID_BMHD)
|
||||||
|
{
|
||||||
|
_lread(handle,&bmhd,sizeof(BitMapHeader));
|
||||||
|
bmhd.w=iffswab(bmhd.w); // the only things we need.
|
||||||
|
bmhd.h=iffswab(bmhd.h);
|
||||||
|
destx = (unsigned char *)AckMalloc((bmhd.w * bmhd.h)+4);
|
||||||
|
if ( !destx )
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
ErrorCode = ERR_NOMEMORY;
|
||||||
|
return(0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
savedestx = destx;
|
||||||
|
|
||||||
|
destx[0] = bmhd.w%256;
|
||||||
|
destx[1] = bmhd.w/256;
|
||||||
|
destx[2] = bmhd.h%256;
|
||||||
|
destx[3] = bmhd.h/256;
|
||||||
|
destx += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(chunk.ckID == ID_CMAP)
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
unsigned char r,g;
|
||||||
|
|
||||||
|
_lread(handle,colordat,chunk.ckSize);
|
||||||
|
for (i=0;i<768;i++)
|
||||||
|
{
|
||||||
|
r = colordat[i]; // r,g do not stand for red and green
|
||||||
|
g = r >> 2;
|
||||||
|
colordat[i] = g;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(chunk.ckID == ID_BODY)
|
||||||
|
{
|
||||||
|
for(height = 0; height<bmhd.h; height ++)
|
||||||
|
{
|
||||||
|
unsigned char *dest;
|
||||||
|
dest = (unsigned char *)&(pplanes[0]); // point at first char
|
||||||
|
sofar = bmhd.w; // number of bytes = 8
|
||||||
|
if (sofar&1) sofar++;
|
||||||
|
while (sofar)
|
||||||
|
{
|
||||||
|
if (bmhd.compression)
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
_lread(handle,&value,1);
|
||||||
|
if (value > 0)
|
||||||
|
{
|
||||||
|
short len;
|
||||||
|
len = value +1;
|
||||||
|
sofar -= len;
|
||||||
|
if (!(_lread(handle,dest,len)))
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
ErrorCode = ERR_BADPICFILE;
|
||||||
|
AckFree(savedestx);
|
||||||
|
return(0L);
|
||||||
|
}
|
||||||
|
dest +=len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
short count;
|
||||||
|
count = -value; // get amount to dup
|
||||||
|
count ++;
|
||||||
|
sofar -= count;
|
||||||
|
value = 0;
|
||||||
|
_lread(handle,&value,1);
|
||||||
|
while (--count >= 0) *dest++ = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_lread(handle,dest,sofar);
|
||||||
|
sofar = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sofar < 0)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
}
|
||||||
|
_fmemcpy(destx,pplanes,bmhd.w);
|
||||||
|
destx += bmhd.w;
|
||||||
|
}
|
||||||
|
break; // leave if we've unpacked the BODY
|
||||||
|
}
|
||||||
|
|
||||||
|
_llseek(handle,chunk.ckSize,SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return((char *)savedestx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long ByteFlipLong(long NUMBER)
|
||||||
|
{
|
||||||
|
long Y, T;
|
||||||
|
short I;
|
||||||
|
|
||||||
|
T = NUMBER;
|
||||||
|
Y=0;for (I=0;I<4;I++){Y = Y | (T & 0xFF);if (I<3) {Y = Y << 8;T = T >> 8;}}
|
||||||
|
return(Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
short iffswab(unsigned short number)
|
||||||
|
{
|
||||||
|
unsigned short xx1,xx2;
|
||||||
|
unsigned short result;
|
||||||
|
|
||||||
|
xx1 = number <<8; xx2 = number >>8; result = xx1|xx2;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
542
ack_lib/ACKINIT.C
Normal file
542
ack_lib/ACKINIT.C
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
// This file contains the key initialization functions for the ACK-3D engine.
|
||||||
|
// The main function AckInitialize() must be called first before any of the
|
||||||
|
// other ACK-3D functions are called. The internal functions defined in this file
|
||||||
|
// perform all of the set up work of loading tables and resource files.
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
extern char AckKeyboardSetup;
|
||||||
|
extern char AckTimerSetup;
|
||||||
|
|
||||||
|
short *LowerTable[2048];
|
||||||
|
short tmpLowerValue[400];
|
||||||
|
short LowerLen[2048];
|
||||||
|
short OurDataSeg;
|
||||||
|
|
||||||
|
char rsName[128];
|
||||||
|
|
||||||
|
long FloorCosTable[VIEW_WIDTH+1];
|
||||||
|
|
||||||
|
short AckBuildTables(ACKENG *ae);
|
||||||
|
void AckBuildHeightTables(ACKENG *ae);
|
||||||
|
void AckBuildGrid(ACKENG *ae);
|
||||||
|
void SetupFloors(ACKENG *ae);
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Internal function called by AckInitialize(). This function sets up the
|
||||||
|
// internal variables that are required to support the off-screen buffer
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
void AckSetupWindow(ACKENG *ae)
|
||||||
|
{
|
||||||
|
// Access the center row of the viewport
|
||||||
|
ae->CenterRow = ae->WinStartY + ((ae->WinEndY - ae->WinStartY) / 2);
|
||||||
|
// Access a memory location for the center row
|
||||||
|
ae->CenterOffset = ae->CenterRow * BYTES_PER_ROW;
|
||||||
|
// Access the starting memory location of the viewport
|
||||||
|
ae->WinStartOffset = ae->WinStartY * BYTES_PER_ROW;
|
||||||
|
// Calculate the window length in double words
|
||||||
|
ae->WinLength = ((ae->WinEndY - ae->WinStartY)+1) * DWORDS_PER_ROW;
|
||||||
|
// Calculates the viewport window width and height
|
||||||
|
ae->WinWidth = (ae->WinEndX - ae->WinStartX) + 1;
|
||||||
|
ae->WinHeight = (ae->WinEndY - ae->WinStartY) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Initializes the ACK interface structure and reads in the TRIG tables
|
||||||
|
// from either the stand alone file TRIG.DAT or from a resource file that
|
||||||
|
// was opened previous to this call.
|
||||||
|
// This function MUST be called before AckBuildView() and AckDisplayScreen()
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
short AckInitialize(ACKENG *ae)
|
||||||
|
{
|
||||||
|
short i,result = 0;
|
||||||
|
short j;
|
||||||
|
UCHAR topcolor;
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__ // Conditional for Borland C++
|
||||||
|
OurDataSeg = _DS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AckKeyboardSetup = 0; // Indicates keyboard interrupt has not been set up
|
||||||
|
AckTimerSetup = 0; // Indicates timer has not been set up
|
||||||
|
|
||||||
|
// Check to see if viewport coordinates are set up properly
|
||||||
|
if (!ae->WinEndY || !ae->WinEndX ||
|
||||||
|
(ae->WinEndY - ae->WinStartY) < 10 || // Height is less than 10 pixels
|
||||||
|
(ae->WinEndX - ae->WinStartX) < 10) // Width is less than 10 pixels
|
||||||
|
{
|
||||||
|
return(ERR_BADWINDOWSIZE); // Return error code for invalid viewport
|
||||||
|
}
|
||||||
|
|
||||||
|
result = AckBuildTables(ae); // Read in TRIG.DAT and allocate tables
|
||||||
|
if (result)
|
||||||
|
return(result);
|
||||||
|
|
||||||
|
AckSetupWindow(ae); // Set up the internal coordinates for the viewport
|
||||||
|
SetupFloors(ae); // Set up the floors
|
||||||
|
AckBuildHeightTables(ae); // Build height and adjustment tables
|
||||||
|
topcolor = ae->TopColor;
|
||||||
|
BackDropRows = 100;
|
||||||
|
|
||||||
|
for (i = 0; i < 640; i++)
|
||||||
|
{
|
||||||
|
BackArray[i] = AckMalloc(BackDropRows+1);
|
||||||
|
if (BackArray[i] == NULL)
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
memset(BackArray[i],topcolor,BackDropRows);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Opens a resource file for use by any ACK routine that requires a
|
||||||
|
// filename. Only one resource file can be opened at a time.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
short AckOpenResource(char *fName)
|
||||||
|
{
|
||||||
|
ULONG hLen;
|
||||||
|
|
||||||
|
if (rsHandle) // Is a resource file currently opened?
|
||||||
|
_lclose(rsHandle); // Close it before opening a new one
|
||||||
|
|
||||||
|
rsHandle = _lopen(fName,OF_READ); // Open new resource file
|
||||||
|
if (rsHandle < 1) // Check to see if file is opened properly
|
||||||
|
{
|
||||||
|
rsHandle = 0; // Reset file handle
|
||||||
|
return(ERR_BADFILE); // Return error code for faliure
|
||||||
|
}
|
||||||
|
|
||||||
|
hLen = MAX_RBA * sizeof(long); // Get size of file
|
||||||
|
if (rbaTable == NULL)
|
||||||
|
rbaTable = (ULONG *)AckMalloc(hLen); // Allocate buffer for file
|
||||||
|
if (rbaTable == NULL) // Was memory available?
|
||||||
|
{
|
||||||
|
_lclose(rsHandle); // Close file
|
||||||
|
rsHandle = 0; // Reset file handle
|
||||||
|
return(ERR_NOMEMORY); // Return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read in the file and check for byte count error
|
||||||
|
if (_lread(rsHandle,(ULONG *)rbaTable,hLen) != hLen)
|
||||||
|
{
|
||||||
|
_lclose(rsHandle); // Close file
|
||||||
|
rsHandle = 0; // Reset file handle
|
||||||
|
AckFree(rbaTable); // Free up buffer
|
||||||
|
return(ERR_BADFILE); // Return file error code
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(rsName,fName); // Store resource filename
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Closes a resource file if one is opened.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
void AckCloseResource(void)
|
||||||
|
{
|
||||||
|
if (rsHandle) // Check to make sure resource file is opened
|
||||||
|
_lclose(rsHandle); // Close the resource
|
||||||
|
|
||||||
|
if (rbaTable != NULL) // Do we need to free the memory for the file buffer?
|
||||||
|
{
|
||||||
|
AckFree(rbaTable); // Free up the file buffer
|
||||||
|
rbaTable = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsHandle = 0; // Reset the file handle
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Internal function used to pre-define height tables for the wall
|
||||||
|
// drawing code.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
void BuildWallDstTables(void)
|
||||||
|
{
|
||||||
|
short i,j,dst,row,HiValue;
|
||||||
|
long ldst,value,LowValue,len;
|
||||||
|
short *lp;
|
||||||
|
|
||||||
|
for (ldst = 10;ldst < 2048; ldst++)
|
||||||
|
{
|
||||||
|
HiValue = value = 0;
|
||||||
|
row = 0;
|
||||||
|
|
||||||
|
while (HiValue < 64 && row < 100)
|
||||||
|
{
|
||||||
|
HiValue = (value >> 8) & 0xFF;
|
||||||
|
tmpLowerValue[row] = HiValue;
|
||||||
|
row++;
|
||||||
|
value += ldst;
|
||||||
|
}
|
||||||
|
|
||||||
|
LowerLen[ldst] = row;
|
||||||
|
len = row * 2;
|
||||||
|
j = 1;
|
||||||
|
if (row == LowerLen[ldst-1])
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
lp = LowerTable[ldst-1];
|
||||||
|
for (i = 0; i < row; i++)
|
||||||
|
{
|
||||||
|
if (tmpLowerValue[i] != lp[i])
|
||||||
|
{
|
||||||
|
j = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j)
|
||||||
|
{
|
||||||
|
lp = AckMalloc(len);
|
||||||
|
if (lp == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LowerTable[ldst] = lp;
|
||||||
|
for (i = 0; i < row; i++)
|
||||||
|
lp[i] = tmpLowerValue[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LowerTable[ldst] = LowerTable[ldst-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Internal function called from AckInitialize() to read in the trig tables
|
||||||
|
// and allocate memory for the various buffers.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
short AckBuildTables(ACKENG *ae)
|
||||||
|
{
|
||||||
|
short handle,len,ca,na;
|
||||||
|
int c,s,ang;
|
||||||
|
long fAng,tu,tv;
|
||||||
|
SLICE *sa,*saNext;
|
||||||
|
|
||||||
|
BuildWallDstTables(); // Create the distance tables
|
||||||
|
|
||||||
|
if (!rsHandle) // Check to make sure resource file is not opened
|
||||||
|
{
|
||||||
|
handle = _lopen("trig.dat",OF_READ); // Open trig data file
|
||||||
|
if (handle < 1)
|
||||||
|
return(ERR_BADFILE); // File can't be opened; return error code
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = rsHandle; // Get handle for resource file
|
||||||
|
_llseek(handle,rbaTable[0],SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate memory for trig and coordinate tables
|
||||||
|
LongTanTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
LongInvTanTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
CosTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
SinTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
LongCosTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
xNextTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
yNextTable = (long *)AckMalloc(sizeof(long) * INT_ANGLE_360);
|
||||||
|
ViewCosTable = (long *)AckMalloc(sizeof(long) * VIEW_WIDTH);
|
||||||
|
|
||||||
|
// Allocate memory for map grid and object grid
|
||||||
|
Grid = (unsigned short *)AckMalloc((GRID_MAX * 2)+1);
|
||||||
|
ObjGrid = (unsigned short *)AckMalloc((GRID_MAX * 2)+1);
|
||||||
|
|
||||||
|
// Allocate memory for height adjustment table
|
||||||
|
AdjustTable = (long *)AckMalloc((MAX_DISTANCE+1) * sizeof(long));
|
||||||
|
// Allocate memory for screen buffers
|
||||||
|
ae->ScreenBuffer = (UCHAR *)AckMalloc(SCREEN_SIZE+640);
|
||||||
|
ae->BkgdBuffer = (UCHAR *)AckMalloc(SCREEN_SIZE+640);
|
||||||
|
|
||||||
|
if (LongTanTable == NULL || // Make sure memory is allocated for tables
|
||||||
|
LongInvTanTable == NULL ||
|
||||||
|
CosTable == NULL ||
|
||||||
|
SinTable == NULL ||
|
||||||
|
LongCosTable == NULL ||
|
||||||
|
xNextTable == NULL ||
|
||||||
|
yNextTable == NULL ||
|
||||||
|
Grid == NULL ||
|
||||||
|
ObjGrid == NULL ||
|
||||||
|
AdjustTable == NULL ||
|
||||||
|
ae->ScreenBuffer == NULL ||
|
||||||
|
ae->BkgdBuffer == NULL ||
|
||||||
|
ViewCosTable == NULL)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_NOMEMORY); // Return memory allocation error code
|
||||||
|
}
|
||||||
|
|
||||||
|
len = sizeof(long) * INT_ANGLE_360; // Calculate size for each trig table
|
||||||
|
_lread(handle,SinTable,len); // Read in trig data and place in appropriate tables
|
||||||
|
_lread(handle,CosTable,len);
|
||||||
|
_lread(handle,LongTanTable,len);
|
||||||
|
_lread(handle,LongInvTanTable,len);
|
||||||
|
_lread(handle,InvCosTable,len);
|
||||||
|
_lread(handle,InvSinTable,len);
|
||||||
|
_lread(handle,LongCosTable,len);
|
||||||
|
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle); // Done reading, close trig.dat
|
||||||
|
|
||||||
|
ca = INT_ANGLE_32;
|
||||||
|
na = -1;
|
||||||
|
|
||||||
|
// Set up viewing tables for 32 to -32 angle sweep
|
||||||
|
for (len = 0; len < VIEW_WIDTH; len++)
|
||||||
|
{
|
||||||
|
ViewCosTable[len] = LongCosTable[ca];
|
||||||
|
FloorCosTable[len] = InvCosTable[ca] >> 6;
|
||||||
|
ca += na;
|
||||||
|
if (ca <= 0) // Index is less than 0 so switch
|
||||||
|
{
|
||||||
|
ca = -ca;
|
||||||
|
na = -na;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust tables for 90, 180, and 270 degree angles
|
||||||
|
LongTanTable[INT_ANGLE_90] = LongTanTable[INT_ANGLE_90+1];
|
||||||
|
LongInvTanTable[INT_ANGLE_90] = LongInvTanTable[INT_ANGLE_90+1];
|
||||||
|
LongTanTable[INT_ANGLE_180] = LongTanTable[INT_ANGLE_180+1];
|
||||||
|
LongInvTanTable[INT_ANGLE_180] = LongInvTanTable[INT_ANGLE_180+1];
|
||||||
|
LongTanTable[INT_ANGLE_270] = LongTanTable[INT_ANGLE_270+1];
|
||||||
|
LongInvTanTable[INT_ANGLE_270] = LongInvTanTable[INT_ANGLE_270+1];
|
||||||
|
|
||||||
|
for (len = 0; len < INT_ANGLE_360; len++)
|
||||||
|
{
|
||||||
|
yNextTable[len] = (long)BITMAP_WIDTH * LongTanTable[len]; // Calculate y intercept increments
|
||||||
|
xNextTable[len] = (long)BITMAP_WIDTH * LongInvTanTable[len]; // Calculate x intercept increments
|
||||||
|
InvCosTable[len] = InvCosTable[len] >> 4; // Scale inverse tables
|
||||||
|
InvSinTable[len] = InvSinTable[len] >> 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the array od slice structures to represent the full width of the view
|
||||||
|
// Each slice structure is initialized by setting its data fields to 0s
|
||||||
|
// Each slice in the array is also linked to a second slice to reference a slice that
|
||||||
|
// could be visually behind the current slice
|
||||||
|
for (len = 0; len < VIEW_WIDTH; len++)
|
||||||
|
{
|
||||||
|
sa = &Slice[len]; // Initialize array of slice structures
|
||||||
|
memset(sa,0,sizeof(SLICE)); // Set all data to 0
|
||||||
|
for (ca = 0; ca < 8; ca++)
|
||||||
|
{
|
||||||
|
saNext = AckMalloc(sizeof(SLICE)); // Create a slice structure to link in
|
||||||
|
if (saNext == NULL)
|
||||||
|
return(ERR_NOMEMORY); // Check for memory allocation
|
||||||
|
memset(saNext,0,sizeof(SLICE)); // Initialize all data to 0
|
||||||
|
sa->Next = saNext; // Link in slice
|
||||||
|
saNext->Prev = sa;
|
||||||
|
sa = saNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Reads a map file and processes any multi-height walls.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
short AckReadMapFile(ACKENG *ae,char *fName)
|
||||||
|
{
|
||||||
|
short len,handle,rdlen,count,i,pos;
|
||||||
|
int mLen,aLen;
|
||||||
|
UCHAR buf[MAX_MULTI+2];
|
||||||
|
UCHAR *mPtr;
|
||||||
|
|
||||||
|
if (!rsHandle) // Check to see if resource file is open already
|
||||||
|
{ // No resource file so open new one
|
||||||
|
handle = _lopen(fName,OF_READ); // Open the specified resource
|
||||||
|
if (handle < 1)
|
||||||
|
return(ERR_BADMAPFILE); // File was not opened; return error code
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = rsHandle; // Get handle to open resource
|
||||||
|
_llseek(handle,rbaTable[(ULONG)fName],SEEK_SET); // Access opened resource file
|
||||||
|
}
|
||||||
|
|
||||||
|
aLen = GRID_ARRAY * 2;
|
||||||
|
mLen = GRID_MAX * 2;
|
||||||
|
|
||||||
|
if (_lread(handle,Grid,mLen) != mLen) // Read in grid map data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP); // Return file read error code
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lread(handle,ObjGrid,mLen) != mLen) // Read in object map data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lread(handle,ae->xGrid,aLen) != aLen) // Read in x grid data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lread(handle,ae->yGrid,aLen) != aLen) // Read in y grid data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lread(handle,FloorMap,mLen) != mLen) // Read in floor map data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_lread(handle,CeilMap,mLen) != mLen) // Read in ceiling map data
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_READINGMAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
_lread(handle,&count,2); // Check counter for multi-height walls
|
||||||
|
if (count)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count;i++) // Read in multi-height wall data
|
||||||
|
{
|
||||||
|
_lread(handle,&pos,2); // Get grid position for this multi-height wall
|
||||||
|
mPtr = (UCHAR *)AckMalloc(MAX_MULTI+1); // Allocate memory for multi-height wall data
|
||||||
|
if (mPtr == NULL)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
ae->mxGrid[pos] = mPtr; // Store pointer to multi-height wall
|
||||||
|
ae->myGrid[pos] = mPtr;
|
||||||
|
ae->mxGrid[pos+1] = mPtr;
|
||||||
|
ae->myGrid[pos+GRID_WIDTH] = mPtr;
|
||||||
|
_lread(handle,buf,MAX_MULTI);
|
||||||
|
buf[MAX_MULTI] = '\0';
|
||||||
|
len = strlen(buf);
|
||||||
|
if (len > MAX_MULTI) len = MAX_MULTI;
|
||||||
|
*mPtr = len;
|
||||||
|
if (len)
|
||||||
|
memmove(&mPtr[1],buf,len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rsHandle) // Close handle
|
||||||
|
_lclose(handle);
|
||||||
|
|
||||||
|
AckBuildGrid(ae); // Build object lists
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Internal function to create height and distance tables for objects. In
|
||||||
|
// the DistanceTable[] each entry represents the distance from the player
|
||||||
|
// to a wall. The value stored in the array is the hight of the wall at
|
||||||
|
// the corresponding distance. For example, DistanceTable[100] indicates
|
||||||
|
// that the distance to the wall is 100 units. The value stored at this
|
||||||
|
// location is 81--the pixel height f the wall.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
void AckBuildHeightTables(ACKENG *ae)
|
||||||
|
{
|
||||||
|
short i,x;
|
||||||
|
short result;
|
||||||
|
long height;
|
||||||
|
|
||||||
|
height = BITMAP_WIDTH * 128L; // Calculate distance to height conversion factor
|
||||||
|
|
||||||
|
DistanceTable[0] = MAX_HEIGHT; // First entry = max. height (960)
|
||||||
|
|
||||||
|
//************ 64 * 65536 ********
|
||||||
|
AdjustTable[0] = 4194304L / height;
|
||||||
|
|
||||||
|
for (i = 1; i < MAX_DISTANCE; i++) // Loop to calculate each entry for the arrays
|
||||||
|
{
|
||||||
|
DistanceTable[i] = height / i;
|
||||||
|
if (height - (DistanceTable[i] * i) > (i / 2))
|
||||||
|
DistanceTable[i]++; // Add 1 to height value
|
||||||
|
if (DistanceTable[i] < MIN_HEIGHT) // Adjust for min. height (8)
|
||||||
|
DistanceTable[i] = MIN_HEIGHT;
|
||||||
|
if (DistanceTable[i] > MAX_HEIGHT) // Adjust for maax. height (960)
|
||||||
|
DistanceTable[i] = MAX_HEIGHT;
|
||||||
|
AdjustTable[i] = 2097152L / DistanceTable[i]; // Calculate entry for
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
// Internal function called by AckReadMapFile() to process the objects
|
||||||
|
// in the map. Moveable vs stationary objects are processed here.
|
||||||
|
//ññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññññ
|
||||||
|
void AckBuildGrid(ACKENG *ae)
|
||||||
|
{
|
||||||
|
short i,j,CurIndex,pos,x1,y1;
|
||||||
|
USHORT MapCode,MapHiCode;
|
||||||
|
|
||||||
|
// Initialize doors
|
||||||
|
for (i = 0; i < MAX_DOORS; i++)
|
||||||
|
{
|
||||||
|
ae->Door[i].ColOffset = 0;
|
||||||
|
ae->Door[i].mPos = ae->Door[i].mPos1 = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ae->SysFlags |= SYS_NO_WALLS; // Assume no floating walls
|
||||||
|
|
||||||
|
CurIndex = 1;
|
||||||
|
TotalSpecial = 0;
|
||||||
|
TotalSecret = 0;
|
||||||
|
for (i = 0; i < GRID_HEIGHT; i++) // Loop until entire grid has been checked
|
||||||
|
{
|
||||||
|
for (j = 0; j < GRID_WIDTH; j++)
|
||||||
|
{
|
||||||
|
pos = (i * GRID_WIDTH) + j;
|
||||||
|
MapCode = ObjGrid[pos]; // Check object at current grid position
|
||||||
|
if (MapCode) // Is there an object here?
|
||||||
|
{
|
||||||
|
CurIndex = MapCode & 0xFF;
|
||||||
|
if (CurIndex < MAX_OBJECTS) // Get the index of the object into
|
||||||
|
{
|
||||||
|
if (ae->ObjList[CurIndex] == NULL) // No object allocated yet
|
||||||
|
{
|
||||||
|
// Allocate memory for object
|
||||||
|
ae->ObjList[CurIndex] = (NEWOBJECT *)AckMalloc(sizeof(NEWOBJECT));
|
||||||
|
if (ae->ObjList[CurIndex] != NULL)
|
||||||
|
memset(ae->ObjList[CurIndex],0,sizeof(NEWOBJECT));
|
||||||
|
}
|
||||||
|
// If memory has been allocated calculate coordinates for object
|
||||||
|
if (ae->ObjList[CurIndex] != NULL)
|
||||||
|
{
|
||||||
|
x1 = (j * BITMAP_WIDTH) + (BITMAP_WIDTH/2);
|
||||||
|
y1 = (i * BITMAP_WIDTH) + (BITMAP_WIDTH/2);
|
||||||
|
ae->ObjList[CurIndex]->x = x1; // Store x,y position
|
||||||
|
ae->ObjList[CurIndex]->y = y1;
|
||||||
|
ae->ObjList[CurIndex]->mPos = pos; // Store map position
|
||||||
|
ae->ObjList[CurIndex]->Active = 1; // Indicates object is active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
327
ack_lib/ACKLDBMP.C
Normal file
327
ack_lib/ACKLDBMP.C
Normal file
|
@ -0,0 +1,327 @@
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
char *GetExtent(char *s);
|
||||||
|
UCHAR *AckReadiff(char *s);
|
||||||
|
UCHAR *AckReadPCX(char *s);
|
||||||
|
short BlankSlice(short,UCHAR *);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Determines if the column of the bitmap contains all transparent colors
|
||||||
|
// or not. If so then it is marked to be skipped during the draw phase.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short BlankSlice(short col,UCHAR *bmp)
|
||||||
|
{
|
||||||
|
short i,pos;
|
||||||
|
|
||||||
|
pos = col * 64;
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
if (bmp[pos++])
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Loads a bitmap of different formats based on the setting of bmLoadType
|
||||||
|
// in the ACKENG interface structure. The bitmap loaded is placed into
|
||||||
|
// either the wall bitmap array or the object array based on the value
|
||||||
|
// of BitmapType passed to this function.
|
||||||
|
// BitmapName can be either a filename or an index into the currently
|
||||||
|
// open resource file.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckLoadBitmap(ACKENG *ae,short BitmapNumber,short BitmapType,char *BitmapName)
|
||||||
|
{
|
||||||
|
short handle,bFlag;
|
||||||
|
short x,y,bLen;
|
||||||
|
short sPos,dPos;
|
||||||
|
UCHAR ch;
|
||||||
|
UCHAR *buf;
|
||||||
|
UCHAR *bmp;
|
||||||
|
UCHAR *bmpFlags;
|
||||||
|
|
||||||
|
bFlag = 0;
|
||||||
|
|
||||||
|
bLen = BITMAP_SIZE + BITMAP_WIDTH;
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
if (ae->bmLoadType == BMLOAD_BBM)
|
||||||
|
buf = AckReadiff(BitmapName);
|
||||||
|
|
||||||
|
if (ae->bmLoadType == BMLOAD_GIF)
|
||||||
|
buf = AckReadgif(BitmapName);
|
||||||
|
|
||||||
|
if (ae->bmLoadType == BMLOAD_PCX)
|
||||||
|
buf = AckReadPCX(BitmapName);
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
return(ERR_LOADINGBITMAP);
|
||||||
|
|
||||||
|
x = (*(short *)buf);
|
||||||
|
y = (*(short *)&buf[2]);
|
||||||
|
if ((x*y) != BITMAP_SIZE)
|
||||||
|
{
|
||||||
|
AckFree(buf);
|
||||||
|
return(ERR_INVALIDFORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove(buf,&buf[4],BITMAP_SIZE);
|
||||||
|
bFlag = 1;
|
||||||
|
|
||||||
|
bmp = AckMalloc(bLen);
|
||||||
|
if (bmp == NULL)
|
||||||
|
{
|
||||||
|
AckFree(buf);
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BitmapType == TYPE_WALL)
|
||||||
|
{
|
||||||
|
ae->bMaps[BitmapNumber] = bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BitmapType == TYPE_OBJECT)
|
||||||
|
{
|
||||||
|
ae->oMaps[BitmapNumber] = bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bFlag)
|
||||||
|
{
|
||||||
|
handle = _lopen(BitmapName,OF_READ);
|
||||||
|
if (handle < 1)
|
||||||
|
{
|
||||||
|
AckFree(buf);
|
||||||
|
AckFree(bmp);
|
||||||
|
return(ERR_BADFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
read(handle,buf,4); // Skip width and height for now
|
||||||
|
read(handle,buf,BITMAP_SIZE);
|
||||||
|
_lclose(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = 0; y < BITMAP_HEIGHT; y++)
|
||||||
|
{
|
||||||
|
sPos = y;
|
||||||
|
dPos = y * BITMAP_WIDTH;
|
||||||
|
for (x = 0; x < BITMAP_WIDTH; x++)
|
||||||
|
{
|
||||||
|
ch = buf[sPos];
|
||||||
|
bmp[dPos++] = ch;
|
||||||
|
sPos += BITMAP_WIDTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bmpFlags = &bmp[BITMAP_SIZE];
|
||||||
|
memset(bmpFlags,0,BITMAP_WIDTH);
|
||||||
|
|
||||||
|
for (x = 0; x < BITMAP_WIDTH; x++)
|
||||||
|
{
|
||||||
|
if (!BlankSlice(x,bmp))
|
||||||
|
bmpFlags[x] = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AckFree(buf);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Returns a pointer to the file extent
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
char *GetExtent(char *s)
|
||||||
|
{
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
e = strchr(s,'.');
|
||||||
|
if (e == NULL)
|
||||||
|
return(s);
|
||||||
|
e++;
|
||||||
|
|
||||||
|
return(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Calls AckLoadBitmap with the TYPE_WALL flag set so the bitmap is placed
|
||||||
|
// in the wall array.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckLoadWall(ACKENG *ae,short WallNumber,char *bmFileName)
|
||||||
|
{
|
||||||
|
return( AckLoadBitmap(ae,WallNumber,TYPE_WALL,bmFileName) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Calls AckLoadBitmap with the TYPE_OBJECT flag set so the bitmap is
|
||||||
|
// placed in the object array.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckLoadObject(ACKENG *ae,short BmpNumber,char *bmFileName)
|
||||||
|
{
|
||||||
|
return( AckLoadBitmap(ae,BmpNumber,TYPE_OBJECT,bmFileName) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Creates an object structure. This function MUST be called before the
|
||||||
|
// object data can be initialized in the NEWOBJECT structure.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckCreateObject(ACKENG *ae,short ObjNumber)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ae->ObjList[ObjNumber] == NULL)
|
||||||
|
{
|
||||||
|
ae->ObjList[ObjNumber] = (NEWOBJECT *)AckMalloc(sizeof(NEWOBJECT));
|
||||||
|
|
||||||
|
if (ae->ObjList[ObjNumber] == NULL)
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
|
||||||
|
memset(ae->ObjList[ObjNumber],0,sizeof(NEWOBJECT));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjNumber >= ae->MaxObjects)
|
||||||
|
ae->MaxObjects = ObjNumber + 1;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Sets an object up into one of the predefined phase types (CREATE,DESTROY,
|
||||||
|
// etc.). Moveable objects are placed into a special list that is used
|
||||||
|
// later in the drawing phase.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckSetObjectType(ACKENG *ae,short oNum,short oType)
|
||||||
|
{
|
||||||
|
short i,j,result = 0;
|
||||||
|
OBJSEQ *os;
|
||||||
|
|
||||||
|
|
||||||
|
switch (oType)
|
||||||
|
{
|
||||||
|
case NO_CREATE:
|
||||||
|
os = &ae->ObjList[oNum]->Create;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_DESTROY:
|
||||||
|
os = &ae->ObjList[oNum]->Destroy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_WALK:
|
||||||
|
os = &ae->ObjList[oNum]->Walk;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_ATTACK:
|
||||||
|
os = &ae->ObjList[oNum]->Attack;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_INTERACT:
|
||||||
|
os = &ae->ObjList[oNum]->Interact;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = ERR_BADOBJTYPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
ae->ObjList[oNum]->CurrentBitmaps = (UCHAR *)&os->bitmaps;
|
||||||
|
ae->ObjList[oNum]->Flags = os->flags;
|
||||||
|
ae->ObjList[oNum]->Sides = os->bmSides;
|
||||||
|
ae->ObjList[oNum]->BitmapsPerView = os->bmBitmapsPerView;
|
||||||
|
ae->ObjList[oNum]->CurrentBm = 0;
|
||||||
|
ae->ObjList[oNum]->Maxbm = os->MaxBitmaps;
|
||||||
|
ae->ObjList[oNum]->CurrentType = oType;
|
||||||
|
ae->ObjList[oNum]->aFactor = os->AngleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ae->ObjList[oNum]->Flags & OF_MOVEABLE)
|
||||||
|
{
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < MoveObjectCount; i++)
|
||||||
|
{
|
||||||
|
if (MoveObjectList[i] == oNum)
|
||||||
|
{
|
||||||
|
j = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!j)
|
||||||
|
MoveObjectList[MoveObjectCount++] = oNum;
|
||||||
|
|
||||||
|
i = (ae->ObjList[oNum]->y & 0xFFC0) + (ae->ObjList[oNum]->x >> 6);
|
||||||
|
ObjGrid[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Fills in the object structure with a communication structure passed
|
||||||
|
// by the application. This allows the application to setup the fields
|
||||||
|
// such as number of sides to an object, what bitmaps are displayed for
|
||||||
|
// each side, etc. The object structures are defined in ACK3D.H
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckSetupObject(ACKENG *ae,short oNum,short oType,OBJSEQ *os)
|
||||||
|
{
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
if (ae->ObjList[oNum] == NULL)
|
||||||
|
return(ERR_BADOBJECTNUM);
|
||||||
|
|
||||||
|
if (os->flags & OF_MULTIVIEW)
|
||||||
|
{
|
||||||
|
os->AngleFactor = INT_ANGLE_360 / os->bmSides;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (oType)
|
||||||
|
{
|
||||||
|
case NO_CREATE:
|
||||||
|
memmove(&ae->ObjList[oNum]->Create,os,sizeof(OBJSEQ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_DESTROY:
|
||||||
|
memmove(&ae->ObjList[oNum]->Destroy,os,sizeof(OBJSEQ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_WALK:
|
||||||
|
memmove(&ae->ObjList[oNum]->Walk,os,sizeof(OBJSEQ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_ATTACK:
|
||||||
|
memmove(&ae->ObjList[oNum]->Attack,os,sizeof(OBJSEQ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_INTERACT:
|
||||||
|
memmove(&ae->ObjList[oNum]->Interact,os,sizeof(OBJSEQ));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = ERR_BADOBJTYPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result && ae->ObjList[oNum]->CurrentBitmaps == NULL)
|
||||||
|
result = AckSetObjectType(ae,oNum,oType);
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
470
ack_lib/ACKOBJ.C
Normal file
470
ack_lib/ACKOBJ.C
Normal file
|
@ -0,0 +1,470 @@
|
||||||
|
// This source file contains the internal functions needed to add objects
|
||||||
|
// to the slice structures as a view is being built.
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "ack3d.h" // Main ACK-3D internal and interface data structures
|
||||||
|
#include "ackeng.h" // Internal data structures and constants
|
||||||
|
#include "ackext.h" // Defines external (global) variables
|
||||||
|
|
||||||
|
extern short gWinStartX; // Global variables to define the left and
|
||||||
|
extern short gWinEndX; // right edge of the viewport
|
||||||
|
// A function pointer to refernce the actual routine used to build a wall slice
|
||||||
|
extern void (*WallMaskRtn)(void);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal function called by FindObject(). Your programs may call this
|
||||||
|
// function if they need to calculate the angle between two points. dx and
|
||||||
|
// dy represent the deltas between the two points. (i.e. dx = x1 - x and
|
||||||
|
// dy = y1 - y)
|
||||||
|
//
|
||||||
|
// Quadrants
|
||||||
|
// 2 | 3 If the object is in quadrants 0 or 2, we need
|
||||||
|
// ---+--- to add the resulting angle to the quad value less
|
||||||
|
// 1 | 0 than the resulting angle. If the object is in
|
||||||
|
// quadrants 1 or 3, we need to subtract the
|
||||||
|
// resulting angle from the next higher quadrant
|
||||||
|
// value. This is because quads 1 and 3 are negative
|
||||||
|
// values returned from arctan, while 0 and 2 are
|
||||||
|
// positive.
|
||||||
|
//
|
||||||
|
// The angle between the two points is determined by using the formula:
|
||||||
|
// tan (angle) = dy/dx. The look-up table LongTanTable[] is used to
|
||||||
|
// access tangent values of angles.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckGetObjectAngle(long dx,long dy)
|
||||||
|
{
|
||||||
|
short i,quadrant,objAngle;
|
||||||
|
short Beg;
|
||||||
|
long avalue;
|
||||||
|
|
||||||
|
if (dx == 0 || dy == 0) // Test to see if angle is 0, 90, 180, or 270
|
||||||
|
{
|
||||||
|
if (dx == 0) // Distance is directly up or down
|
||||||
|
{
|
||||||
|
if (dy < 0) // Distance is straight up
|
||||||
|
return(INT_ANGLE_270);
|
||||||
|
return(INT_ANGLE_90);
|
||||||
|
}
|
||||||
|
if (dx < 0) // dy = 0; distance is directly left or right
|
||||||
|
return(INT_ANGLE_180);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to determine which quadrant is involved
|
||||||
|
quadrant = 0; // Set to quad 0 as default
|
||||||
|
if (dx < 0 && dy > 0) // We're in quad 1
|
||||||
|
quadrant = INT_ANGLE_180;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dx < 0 && dy < 0) // We're in quad 2
|
||||||
|
quadrant = INT_ANGLE_270;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dx > 0 && dy < 0) // We're in quad 3
|
||||||
|
quadrant = INT_ANGLE_360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the absolute values to use for our ratio
|
||||||
|
if (dy < 0)
|
||||||
|
dy = -dy;
|
||||||
|
if (dx < 0)
|
||||||
|
dx = -dx;
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// Next we need to convert dy into the same fixed point representation
|
||||||
|
// as used in our tangent table. Then, we divide dy by dx (rise/run)
|
||||||
|
// to get the ratio so we can determine the tangent of the angle between
|
||||||
|
// the two pints. We use the ratio to search the tangent table
|
||||||
|
// and the index that is returned tells us what the actual angle is.
|
||||||
|
// We only need to check angles from 0 to 90 degrees. Later, the angle
|
||||||
|
// will be adjusted to take into account which quadrant we are in.
|
||||||
|
//=======================================================================
|
||||||
|
dy = dy << FP_SHIFT; // Make the dividend the same fixed point as the table
|
||||||
|
avalue = dy / dx; // Get our ratio to search for
|
||||||
|
// This ratio tells us the tangent of the angle
|
||||||
|
if (LongTanTable[INT_ANGLE_90-1] <= avalue) // Angle is 89 degrees
|
||||||
|
return(INT_ANGLE_90-1);
|
||||||
|
objAngle = 0; // Initialize angle to 0
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Now we use a binary lookup trick to speed up the search. This invloves
|
||||||
|
// a test to see if the angle is between o and 45 degrees or between 45 and
|
||||||
|
// 90 degrees. Then, we search the list sequentially to find the first value
|
||||||
|
// higher than our ratio.
|
||||||
|
//=============================================================================
|
||||||
|
Beg = 0; // Assume midpoint between 0 and 45 degrees
|
||||||
|
if (LongTanTable[INT_ANGLE_45] < avalue)
|
||||||
|
{
|
||||||
|
if (LongTanTable[360] < avalue)
|
||||||
|
Beg = 360; // Use angle of 360
|
||||||
|
else
|
||||||
|
Beg = INT_ANGLE_45; // Midpoint between 45 and 90 degrees
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop to check the tan table and find the correct angle
|
||||||
|
for (i = Beg; i < INT_ANGLE_90; i++)
|
||||||
|
{
|
||||||
|
if (LongTanTable[i] > avalue) // We've passed by the angle
|
||||||
|
{
|
||||||
|
objAngle = i - 1; // Get the correct angle
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objAngle < 0) // Adjust for angle=0
|
||||||
|
objAngle = 0;
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
// Now we adjust the resulting angle based on the quadrant. If we are in
|
||||||
|
// quad 0 we do nothing. If we're in quads 1 and 3 we subtract the angle from
|
||||||
|
// the next higher quad angle. If we're in quad 2 we add the angle to the next
|
||||||
|
// lower quad angle to get the actual angle (0-1800) between the points.
|
||||||
|
//============================================================================
|
||||||
|
if (quadrant)
|
||||||
|
{
|
||||||
|
if (quadrant != INT_ANGLE_270)
|
||||||
|
objAngle = quadrant - objAngle;
|
||||||
|
else
|
||||||
|
objAngle += INT_ANGLE_180;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the angle between the two points. This value is mainly used for
|
||||||
|
// determining the angle between the POV and an object, but it could
|
||||||
|
// be used for generic purposes as well.
|
||||||
|
return(objAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal function that returns the square root of a long value.
|
||||||
|
// This function is called by Find)bject().
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short long_sqrt(long v)
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
unsigned short result,tmp;
|
||||||
|
unsigned long low,high;
|
||||||
|
|
||||||
|
if (v <= 1L) return((unsigned)v); // Value is less than 1; return value
|
||||||
|
low = v; // Initialize starting variables
|
||||||
|
high = 0L;
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
result += result;
|
||||||
|
high = (high << 2) | ((low >>30) & 0x3);
|
||||||
|
low <<= 2; // Shift left by 2
|
||||||
|
tmp = result + result + 1;
|
||||||
|
if (high >= tmp)
|
||||||
|
{
|
||||||
|
result++;
|
||||||
|
high -= tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal function called by AckBuildView() which checks the list of
|
||||||
|
// objects found during the ray cast process and places the object slices
|
||||||
|
// into the wall slices.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void FindObject(void)
|
||||||
|
{
|
||||||
|
short i,j,StartX,EndX;
|
||||||
|
short oCount;
|
||||||
|
short minAngle,maxAngle,objAngle;
|
||||||
|
short objColumn;
|
||||||
|
USHORT distance;
|
||||||
|
long dx,dy;
|
||||||
|
short count,SaveCenter;
|
||||||
|
short ObjNum,oQuad,pQuad,numsides,afact;
|
||||||
|
short NewX,NewY,LightFlag;
|
||||||
|
short MaxOpp,Column,ColBeg,ColEnd;
|
||||||
|
short wt,ObjIndex;
|
||||||
|
short vidwt,vidht,hoff;
|
||||||
|
short MaxObjs;
|
||||||
|
short SliceLen;
|
||||||
|
USHORT BmpColumn;
|
||||||
|
long xp,yp;
|
||||||
|
short wht;
|
||||||
|
UCHAR *wall,*ScreenBuffer;
|
||||||
|
UCHAR *pTable;
|
||||||
|
UCHAR **omaps;
|
||||||
|
SLICE *sa,*sa2,*saNext;
|
||||||
|
UCHAR *bmpFlags;
|
||||||
|
NEWOBJECT **oList;
|
||||||
|
NEWOBJECT *oPtr;
|
||||||
|
|
||||||
|
if (FoundObjectCount) // Make sure objects were found during ray casting
|
||||||
|
{
|
||||||
|
oList = &aeGlobal->ObjList[0]; // Get pointer to the array of objects
|
||||||
|
StartX = gWinStartX; // Starting column of view
|
||||||
|
EndX = gWinEndX; // Ending column of view
|
||||||
|
|
||||||
|
minAngle = PlayerAngle - (INT_ANGLE_32 + 10); // Starting angle of view
|
||||||
|
if (minAngle < 0) // Check for wrap-around at angle 0
|
||||||
|
minAngle += INT_ANGLE_360;
|
||||||
|
maxAngle = PlayerAngle + (INT_ANGLE_32 + 10); // Ending angle of view
|
||||||
|
if (maxAngle >= INT_ANGLE_360) // Check for wrap-around at angle 360
|
||||||
|
maxAngle -= INT_ANGLE_360;
|
||||||
|
|
||||||
|
TotalObjects = 0; // Stores nmber of objects in view
|
||||||
|
SliceLen = sizeof(SLICE) - 9; // Amount of slice we'll move later
|
||||||
|
|
||||||
|
// Loop and process each object in the view. This invloves setting up
|
||||||
|
// a few arrays to store the object number, the distance from the player
|
||||||
|
// to the object, the viewing angle, and the view column where the object
|
||||||
|
// will be displayed.
|
||||||
|
|
||||||
|
for (oCount = 0; oCount < FoundObjectCount; oCount++)
|
||||||
|
{
|
||||||
|
i = ObjectsSeen[oCount]; // Get index to possible object
|
||||||
|
oPtr = oList[i]; // Pointer to object structure
|
||||||
|
if (oPtr == NULL) // Make sure it's a valid object
|
||||||
|
continue;
|
||||||
|
if (!oPtr->Active) // Make sure it's visible
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dx = oPtr->x - xPglobal; // Get the delta x,y between the
|
||||||
|
dy = oPtr->y - yPglobal; // object and the player
|
||||||
|
|
||||||
|
// Calculate the angle the object is relative to the player
|
||||||
|
if ((objAngle = AckGetObjectAngle(dx,dy)) < 0)
|
||||||
|
continue; // Negative angle means it can't be seen
|
||||||
|
|
||||||
|
// Here we determine if the POV is looking toward the right or
|
||||||
|
// the left and the actual column of the view (from 0 to view width)
|
||||||
|
// where the object would be seen.
|
||||||
|
if (minAngle > maxAngle) // If looking towards the right
|
||||||
|
{
|
||||||
|
if (objAngle >= minAngle) // Cal. view column of object
|
||||||
|
objColumn = objAngle - minAngle;
|
||||||
|
else
|
||||||
|
objColumn = (objAngle+INT_ANGLE_360) - minAngle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
objColumn = objAngle - minAngle; // Calc. view column of object
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the distance to the object
|
||||||
|
distance = long_sqrt((dx * dx) + (dy * dy));
|
||||||
|
// No need to check further if it's too far away
|
||||||
|
if (distance >= MaxDistance)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Place the objects in the correct order so further ones are behind
|
||||||
|
j = TotalObjects; // Current number of objects we've found
|
||||||
|
if (j)
|
||||||
|
{
|
||||||
|
// Sort the objects found by distance so that further ones
|
||||||
|
// are drawn BEFORE closer ones.
|
||||||
|
for (count = 0; count < TotalObjects; count++)
|
||||||
|
{
|
||||||
|
if (distance <= ObjRelDist[count])
|
||||||
|
{
|
||||||
|
for (j = TotalObjects; j > count; j--)
|
||||||
|
{
|
||||||
|
ObjRelDist[j] = ObjRelDist[j-1];
|
||||||
|
ObjNumber[j] = ObjNumber[j-1];
|
||||||
|
ObjColumn[j] = ObjColumn[j-1];
|
||||||
|
ObjAngle[j] = ObjAngle[j-1];
|
||||||
|
}
|
||||||
|
j = count;
|
||||||
|
count = TotalObjects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hold onto relavant data for the object found
|
||||||
|
ObjNumber[j] = i; // Store the object number
|
||||||
|
ObjRelDist[j] = distance; // Store the distance to the object
|
||||||
|
ObjColumn[j] = objColumn; // Store view column where object resides
|
||||||
|
ObjAngle[j] = objAngle; // Store the viewing angle
|
||||||
|
TotalObjects++; // Bump the count of objects in view
|
||||||
|
ObjRelDist[TotalObjects] = 0L; // Set to relative dist. in next object to 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't find any objects on the above pass, so we're done
|
||||||
|
if (!TotalObjects)
|
||||||
|
return;
|
||||||
|
|
||||||
|
omaps = &aeGlobal->oMaps[0]; // Bitmaps used for objects
|
||||||
|
pQuad = PlayerAngle / INT_ANGLE_45; // Quadrant POV is facing
|
||||||
|
|
||||||
|
// Check each object in the list to be displayed and get the object's
|
||||||
|
// bitmap. Also, calulate the width and height of the object.
|
||||||
|
// This loop also checks to see if an object has multiple sides
|
||||||
|
// and it determines which bitmap should be used to display the object.
|
||||||
|
for (i = 0; i < TotalObjects; i++)
|
||||||
|
{
|
||||||
|
ObjIndex = ObjNumber[i]; // Actual object found
|
||||||
|
oPtr = oList[ObjIndex]; // Pointer to object structure
|
||||||
|
if (oPtr == NULL) // Again check for a null object
|
||||||
|
continue;
|
||||||
|
// Current bitmap for the object (this number can change if the
|
||||||
|
// object is animated)
|
||||||
|
ObjNum = oPtr->CurrentBitmaps[oPtr->CurrentBm];
|
||||||
|
distance = ObjRelDist[i]; // Get relative distance to object
|
||||||
|
// Make sure distance is within a reasonable entry in our
|
||||||
|
// pre-calculated table
|
||||||
|
if (distance >= (MAX_DISTANCE - 10))
|
||||||
|
distance = MAX_DISTANCE-11;
|
||||||
|
|
||||||
|
// Get the width of the object
|
||||||
|
wt = DistanceTable[distance]; // Adjust the width using the distance
|
||||||
|
// Keep the width of the object reasonable
|
||||||
|
if (wt > 300) // The object is too wide
|
||||||
|
continue; // Skip over
|
||||||
|
if (wt < 6) wt = 6; // Adjust if too small
|
||||||
|
|
||||||
|
// Get the scale factor which was pre-calculated based on
|
||||||
|
// distance in AckInitialize() function
|
||||||
|
yp = AdjustTable[distance];
|
||||||
|
xp = 0; // First col of the object to display
|
||||||
|
|
||||||
|
NewX = ObjColumn[i]; // View column where object resides
|
||||||
|
|
||||||
|
// Check if object has multiple sides. If so we need to determine
|
||||||
|
// the correct bitmap to display based on the angle between the
|
||||||
|
// POV and the object. We'll perform a trick here by breaking down
|
||||||
|
// the problem into quadrants and then use the quadrant to determine
|
||||||
|
// which side we're facing. The object itself is facing a certain
|
||||||
|
// angle (stored in the Dir field of the object structure) so this
|
||||||
|
// needs to be taken into account as well.
|
||||||
|
if (oPtr->Flags & OF_MULTIVIEW)
|
||||||
|
{
|
||||||
|
afact = oPtr->aFactor; // Get the angles per side of object
|
||||||
|
numsides = oPtr->Sides; // Get total sides for this object
|
||||||
|
pQuad = ObjAngle[i] / afact; // Get the quadrant from POV to object
|
||||||
|
oQuad = oPtr->Dir / afact; // Get the quadrant it wants to face
|
||||||
|
|
||||||
|
// The difference between the POV-Object angle and the angle the
|
||||||
|
// object is facing determines the actual side of the object that
|
||||||
|
// can currently be seen
|
||||||
|
j = (pQuad - oQuad) + (numsides >> 1);
|
||||||
|
|
||||||
|
// Check for wrap-around and keep within range
|
||||||
|
if (j >= numsides)
|
||||||
|
j -= numsides;
|
||||||
|
// Check wrap-around in both directions
|
||||||
|
if (j < 0)
|
||||||
|
j += numsides;
|
||||||
|
|
||||||
|
// Calculate which bitmap set we should use (each side could
|
||||||
|
// have multiple bitmaps for animation)
|
||||||
|
j *= oPtr->BitmapsPerView;
|
||||||
|
j += oPtr->CurrentBm;
|
||||||
|
// Get the actual bitmap for this side and animation
|
||||||
|
ObjNum = oPtr->CurrentBitmaps[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done processing multiple sides. Next, find the
|
||||||
|
// ending column based on the starting column plus the scaled
|
||||||
|
// width of the object.
|
||||||
|
ColEnd = NewX + wt;
|
||||||
|
// Finally get the pointer to the actual bitmap
|
||||||
|
wall = omaps[ObjNum];
|
||||||
|
// Pick up the transparent flags at end of bitmap
|
||||||
|
bmpFlags = &wall[BITMAP_SIZE];
|
||||||
|
j = distance;
|
||||||
|
|
||||||
|
// Loop from starting column to ending column and fold in the
|
||||||
|
// object into the appropriate slice structure.
|
||||||
|
for (Column = NewX - wt; Column < ColEnd; Column++)
|
||||||
|
{
|
||||||
|
// Make sure column is within view width
|
||||||
|
if (Column >= StartX && Column <= EndX)
|
||||||
|
{
|
||||||
|
// Scale bitmap column down from fixed point
|
||||||
|
BmpColumn = xp >> FP_SHIFT;
|
||||||
|
if (bmpFlags[BmpColumn]) // If transparent column
|
||||||
|
goto keepgoing; // Ouch! But it works
|
||||||
|
|
||||||
|
j = distance;
|
||||||
|
// Account for fisheye effect
|
||||||
|
dy = ViewCosTable[Column] >> 2;
|
||||||
|
dx = distance * dy;
|
||||||
|
// Now we strip off somemore decimal points and check round-up
|
||||||
|
dy = dx >> 12;
|
||||||
|
if (dx - (dy << 12) >= 4096)
|
||||||
|
dy++;
|
||||||
|
if (dy > 32L)
|
||||||
|
j = dy;
|
||||||
|
|
||||||
|
// Now we pick up the slice for this column and insert sort
|
||||||
|
// the object slice based on the distance. This allows objects
|
||||||
|
// to appear between walls at various distances, behind
|
||||||
|
// transparent walls, and so on.
|
||||||
|
sa = &Slice[Column]; // Access the corresponding slice
|
||||||
|
if (sa->Active) // Multiple slices for this column?
|
||||||
|
{
|
||||||
|
while (sa != NULL)
|
||||||
|
{
|
||||||
|
if (j <= sa->Distance)
|
||||||
|
{
|
||||||
|
sa2 = sa;
|
||||||
|
while (sa2->Next != NULL) // Go to end of slices
|
||||||
|
sa2 = sa2->Next;
|
||||||
|
saNext = sa2->Prev;
|
||||||
|
while (sa2 != sa) // Move slice down to create
|
||||||
|
{ // a space for new slice
|
||||||
|
memcpy(sa2,saNext,sizeof(SLICE)-9);
|
||||||
|
sa2->Active = saNext->Active;
|
||||||
|
sa2 = sa2->Prev;
|
||||||
|
saNext = saNext->Prev;
|
||||||
|
}
|
||||||
|
// Fill in the slice structure with the
|
||||||
|
// info about the object
|
||||||
|
sa->Distance = distance;
|
||||||
|
sa->bNumber = ObjNum;
|
||||||
|
sa->bColumn = BmpColumn;
|
||||||
|
sa->bMap = omaps;
|
||||||
|
sa->Active = 1;
|
||||||
|
sa->Type = ST_OBJECT;
|
||||||
|
sa->Fnc = WallMaskRtn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!sa->Active)
|
||||||
|
break;
|
||||||
|
sa = sa->Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Only one slice is used for this column (typical)
|
||||||
|
{
|
||||||
|
if (j <= sa->Distance) // Only put it in if object is
|
||||||
|
{ // closer than current slice
|
||||||
|
sa->Active = 1;
|
||||||
|
saNext = sa->Next;
|
||||||
|
memcpy(saNext,sa,sizeof(SLICE)-9);
|
||||||
|
sa->Distance = distance;
|
||||||
|
sa->bColumn = BmpColumn;
|
||||||
|
sa->bNumber = ObjNum;
|
||||||
|
sa->bMap = omaps;
|
||||||
|
sa->Type = ST_OBJECT;
|
||||||
|
sa->Fnc = WallMaskRtn;
|
||||||
|
saNext->Active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keepgoing:
|
||||||
|
xp += yp; // Advance the next column to display (scaling)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// **** End of Source ****
|
73
ack_lib/ACKOVER.C
Normal file
73
ack_lib/ACKOVER.C
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Creates an overlay buffer that contains non-transparent information
|
||||||
|
// about the image. Position and length of the non-transparent areas is
|
||||||
|
// stored for later processing after the drawing phase. Theoretically the
|
||||||
|
// amount of information stored in the overlay buffer could exceed the
|
||||||
|
// actual size of the image.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckCreateOverlay(ACKENG *ae,UCHAR *sBuf)
|
||||||
|
{
|
||||||
|
USHORT bPos,vPos,vLen;
|
||||||
|
USHORT len,sPos,sPos1;
|
||||||
|
|
||||||
|
vLen = (ae->WinEndY - ae->WinStartY) * BYTES_PER_ROW;
|
||||||
|
vPos = ae->WinStartY * BYTES_PER_ROW;
|
||||||
|
bPos = 0;
|
||||||
|
sPos = vPos;
|
||||||
|
|
||||||
|
while (vLen > 0)
|
||||||
|
{
|
||||||
|
if (sBuf[sPos])
|
||||||
|
{
|
||||||
|
sPos1 = sPos;
|
||||||
|
while (vLen > 0 && sBuf[sPos1++])
|
||||||
|
vLen--;
|
||||||
|
|
||||||
|
len = (sPos1 - sPos) - 1;
|
||||||
|
(*(short *)&ae->ScreenBuffer[bPos]) = len;
|
||||||
|
bPos += 2;
|
||||||
|
(*(short *)&ae->ScreenBuffer[bPos]) = sPos;
|
||||||
|
bPos += 2;
|
||||||
|
memmove(&ae->ScreenBuffer[bPos],&sBuf[sPos],len);
|
||||||
|
bPos += len;
|
||||||
|
sPos = sPos1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sPos++;
|
||||||
|
vLen--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*(short *)&ae->ScreenBuffer[bPos]) = 0;
|
||||||
|
bPos += 2;
|
||||||
|
|
||||||
|
ae->OverlayBuffer = AckMalloc(bPos);
|
||||||
|
|
||||||
|
if (ae->OverlayBuffer != NULL)
|
||||||
|
{
|
||||||
|
memmove(ae->OverlayBuffer,ae->ScreenBuffer,bPos);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
162
ack_lib/ACKPCX.C
Normal file
162
ack_lib/ACKPCX.C
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
// This source file contains the functions needed to read in PCX files.
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
//typedef unsigned short USHORT;
|
||||||
|
|
||||||
|
#include "ack3d.h" // Main ACK-3D internal and interface data structures
|
||||||
|
#include "ackeng.h" // Internal data structures and constants
|
||||||
|
#include "ackext.h" // Defines external (global) variables
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char manufacturer; // Always set to 0
|
||||||
|
char version; // Always 5 for 256-color files
|
||||||
|
char encoding; // Always set to 1
|
||||||
|
char bits_per_pixel; // Should be 8 for 256-color files
|
||||||
|
short xmin,ymin; // Coordinates for top left corner
|
||||||
|
short xmax,ymax; // Width and height of image
|
||||||
|
short hres; // Horizontal resolution of image
|
||||||
|
short vres; // Vertical resolution of image
|
||||||
|
char palette16[48]; // EGA palette; not used for 256-color files
|
||||||
|
char reserved; // Reserved for future use
|
||||||
|
char color_planes; // Color planes
|
||||||
|
short bytes_per_line; // Number of bytes in 1 line of pixels
|
||||||
|
short palette_type; // Should be 2 for color palette
|
||||||
|
char filler[58]; // Reserved
|
||||||
|
} PcxHeader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PcxHeader hdr; // Header information
|
||||||
|
UCHAR *bitmap; // The bitmap data
|
||||||
|
UCHAR pal[768]; // Color palette for the bitmap data
|
||||||
|
unsigned short imagebytes,width,height; // Size of the bitmap
|
||||||
|
} PcxFile;
|
||||||
|
|
||||||
|
#define PCX_MAX_SIZE 64000L
|
||||||
|
enum {PCX_OK,PCX_NOMEM,PCX_TOOBIG,PCX_NOFILE};
|
||||||
|
|
||||||
|
enum {NORMAL,RLE};
|
||||||
|
//enum {FALSE,TRUE};
|
||||||
|
|
||||||
|
PcxFile pcxGlobal; // data structure for reading PCX files
|
||||||
|
|
||||||
|
extern unsigned char colordat[];
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// This routine loads a 256 color PCX file. The file can be a standalone
|
||||||
|
// PCX file or it can be combined with a resource. If the data is part
|
||||||
|
// of a resource, the rshandle flag will be set. The bitmap data is read
|
||||||
|
// into a buffer that is the size of the bitmap + 4 bytes. The first 4
|
||||||
|
// bytes in the buffer contain the width and height of the bitmap.
|
||||||
|
//=============================================================================
|
||||||
|
unsigned char *AckReadPCX(char *filename)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
int mode=NORMAL,nbytes;
|
||||||
|
char abyte,*p;
|
||||||
|
short handle;
|
||||||
|
PcxFile *pcx;
|
||||||
|
|
||||||
|
pcx = &pcxGlobal;
|
||||||
|
// Open the file since no resource is open.
|
||||||
|
if (!rsHandle)
|
||||||
|
{
|
||||||
|
handle = _lopen(filename,OF_READ); // Open the file for reading
|
||||||
|
if (handle == HFILE_ERROR) // Make sure file is opened
|
||||||
|
{
|
||||||
|
ErrorCode = ERR_BADFILE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Use the resource instead
|
||||||
|
{
|
||||||
|
handle = rsHandle; // Use the handle to the resource file
|
||||||
|
// Move to the location in the resource where the data is stored
|
||||||
|
_llseek(handle,rbaTable[(ULONG)filename],SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_lread(handle,&pcx->hdr,sizeof(PcxHeader)); // Read in the header data
|
||||||
|
pcx->width=1+pcx->hdr.xmax-pcx->hdr.xmin; // Store width and height
|
||||||
|
pcx->height=1+pcx->hdr.ymax-pcx->hdr.ymin;
|
||||||
|
// Store number of bytes used for image
|
||||||
|
pcx->imagebytes=(unsigned int)(pcx->width*pcx->height);
|
||||||
|
|
||||||
|
// Make sure bitmap is correct size
|
||||||
|
if (pcx->imagebytes > PCX_MAX_SIZE)
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
ErrorCode = ERR_INVALIDFORM;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate size for bitmap. 4 extra bytes are included to give
|
||||||
|
// room to store bitmap width and height info.
|
||||||
|
pcx->bitmap=(char*)AckMalloc(pcx->imagebytes+4);
|
||||||
|
|
||||||
|
if (pcx->bitmap == NULL) // Make sure memory is allocated
|
||||||
|
{
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
ErrorCode = ERR_NOMEMORY;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
p=&pcx->bitmap[4]; // Get address of data area
|
||||||
|
|
||||||
|
// Loop and read in pixel data for bitmap
|
||||||
|
// Uses RLE decompression
|
||||||
|
for (i=0;i<pcx->imagebytes;i++)
|
||||||
|
{
|
||||||
|
if (mode == NORMAL) // Normal color read mode
|
||||||
|
{
|
||||||
|
_lread(handle,&abyte,1); // Read in pixel value from file
|
||||||
|
if ((unsigned char)abyte > 0xbf) // Value read > 191
|
||||||
|
{
|
||||||
|
nbytes=abyte & 0x3f; // Get the RLE counter
|
||||||
|
_lread(handle,&abyte,1);
|
||||||
|
if (--nbytes > 0) // Is counter greater than 1?
|
||||||
|
mode=RLE; // Yes, we're in RLE mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (--nbytes == 0) // When counter down to 0
|
||||||
|
mode=NORMAL; // return to color read mode
|
||||||
|
*p++=abyte; // Store pixel value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get palette from PCX file, 256 color palette store 768 bytes from
|
||||||
|
// end of file. For a resource file we need to find the position where
|
||||||
|
// the next file starts and then backup 768 bytes
|
||||||
|
if (rsHandle)
|
||||||
|
_llseek(handle,rbaTable[(ULONG)(filename + 1)]-768L,SEEK_CUR);
|
||||||
|
else
|
||||||
|
_llseek(handle,-768L,SEEK_END);
|
||||||
|
|
||||||
|
// Store the palette data in our global colordat array
|
||||||
|
_lread(handle,colordat,768);
|
||||||
|
p=colordat;
|
||||||
|
for (i=0;i<768;i++) // bit shift palette
|
||||||
|
*p++ = *p >> 2;
|
||||||
|
|
||||||
|
if (!rsHandle) // Close pcx file if not using a resource
|
||||||
|
_lclose(handle);
|
||||||
|
|
||||||
|
// Add in bitmap width and height to first 4 bytes of buffer
|
||||||
|
p = pcx->bitmap;
|
||||||
|
(*(short *)p) = pcx->width;
|
||||||
|
p += sizeof(short);
|
||||||
|
(*(short *)p) = pcx->height;
|
||||||
|
|
||||||
|
return(pcx->bitmap); // return bitmap buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
671
ack_lib/ACKPOV.C
Normal file
671
ack_lib/ACKPOV.C
Normal file
|
@ -0,0 +1,671 @@
|
||||||
|
// Source file ACKPOV.C - Player and Object Movement routines
|
||||||
|
// (c) 1995 ACK Software (Lary Myers)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Internal function called by AckMovePOV(). Checks the passed X and Y
|
||||||
|
// coordinates of the player against the object coordinates to see if the player will
|
||||||
|
// encouner an object.
|
||||||
|
//************************************************************************
|
||||||
|
short AckCheckObjPosn(short xPlayer,short yPlayer, short oIndex)
|
||||||
|
{
|
||||||
|
short i,result,maxObj;
|
||||||
|
short MapPosn;
|
||||||
|
NEWOBJECT **oList;
|
||||||
|
NEWOBJECT *oPtr;
|
||||||
|
|
||||||
|
result = POV_NOTHING; // Initialize to nothing found
|
||||||
|
MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> 6); // Calculate grid square the player will be in
|
||||||
|
maxObj = aeGlobal->MaxObjects; // Total number of objects used
|
||||||
|
oList = &aeGlobal->ObjList[0]; // Reference the list of objects
|
||||||
|
|
||||||
|
for (i = 0; i < maxObj; i++) // Loop and check each object in the list
|
||||||
|
{
|
||||||
|
oPtr = oList[i]; // Point to current object
|
||||||
|
if (oPtr == NULL) // No object here; skip to next object in list
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!oPtr->Active || oPtr->Flags & OF_PASSABLE) // Object is not active or is passable
|
||||||
|
continue; // Skip to next object in list
|
||||||
|
|
||||||
|
if (MapPosn == oPtr->mPos && i != oIndex) // Object is found in the player's grid position
|
||||||
|
{
|
||||||
|
LastObjectHit = i; // Store the number of the object found
|
||||||
|
return(POV_OBJECT); // Return flag to indicate an object is found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Internal function called by AckMovePOV() to see if a wall or object is located in
|
||||||
|
// the player's current grid square. This function checks for walls or objects in the
|
||||||
|
// x-plane using the xGrid array. The bitmap code for the wall or object is returned.
|
||||||
|
// A value returned of 0 indicates that no wall or object is present or that the wall
|
||||||
|
// is passable.
|
||||||
|
//************************************************************************
|
||||||
|
USHORT GetWallX(short mPos)
|
||||||
|
{
|
||||||
|
USHORT mCode;
|
||||||
|
|
||||||
|
mCode = xGridGlobal[mPos]; // Get bitmap code at specified map position
|
||||||
|
if (mCode & WALL_TYPE_PASS) // Passable walls can be walked through
|
||||||
|
mCode = 0;
|
||||||
|
return(mCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Internal function called by AckMovePOV() to see if a wall or object is located in
|
||||||
|
// the player's current grid square. This function checks for walls or objects in the
|
||||||
|
// y-plane using the yGrid array. The bitmap code for the wall or object is returned.
|
||||||
|
// A value returned of 0 indicates that no wall or object is present or that the wall
|
||||||
|
// is passable.
|
||||||
|
//************************************************************************
|
||||||
|
USHORT GetWallY(short mPos)
|
||||||
|
{
|
||||||
|
USHORT mCode;
|
||||||
|
|
||||||
|
mCode = yGridGlobal[mPos]; // Get bitmap code at specified map position
|
||||||
|
if (mCode & WALL_TYPE_PASS) // Passable walls can be walked through
|
||||||
|
mCode = 0;
|
||||||
|
return(mCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Moves the POV based on Angle for Amount. After moving but prior to
|
||||||
|
// returning the position of the POV is check for collisions.
|
||||||
|
//************************************************************************
|
||||||
|
short AckMovePOV(short Angle,short Amount)
|
||||||
|
{
|
||||||
|
short x1,y1,HitResult; // New coordinate position
|
||||||
|
short xp,yp; // Starting player coordinates
|
||||||
|
short xLeft,xRight,yTop,yBottom; // Coordinates for grid square
|
||||||
|
short mPos; // Map position for xGrid[], yGrid[]
|
||||||
|
USHORT mCodeX,mCodeY; // Return codes for x,y wall arrays
|
||||||
|
|
||||||
|
HitResult = POV_NOTHING; // We haven't hit anything yet
|
||||||
|
xp = aeGlobal->xPlayer; // Get the current x,y player coordinates
|
||||||
|
yp = aeGlobal->yPlayer;
|
||||||
|
|
||||||
|
xLeft = xp & 0xFFC0; // Determine coordinates of the boundaries
|
||||||
|
yTop = yp & 0xFFC0; // of the grid square we're in.
|
||||||
|
xRight = xLeft + GRID_SIZE;
|
||||||
|
yBottom = yTop + GRID_SIZE;
|
||||||
|
|
||||||
|
// Calculate the x,y distance of movement using the angle and distance
|
||||||
|
// x1,y1 = the new coordinate position of the player.
|
||||||
|
x1 = xp + (long)((CosTable[Angle] * Amount) >> FP_SHIFT);
|
||||||
|
y1 = yp + (long)((SinTable[Angle] * Amount) >> FP_SHIFT);
|
||||||
|
// Calculate current map position for the xGrid[] and yGrid[] arrays
|
||||||
|
mPos = yTop + (xp >> 6); // Current Map Posn
|
||||||
|
|
||||||
|
// It's time to see what happens when we move
|
||||||
|
if (x1 < xp) // Are we moving left?
|
||||||
|
{
|
||||||
|
if (GetWallX(mPos)) // Wall found in current square (left edge)
|
||||||
|
{
|
||||||
|
if (x1 < xLeft || abs(x1-xLeft) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
x1 = xp; // Use the previous x position
|
||||||
|
HitResult = POV_SLIDEX; // We're possibly sliding along the left x wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 > xp) // Are we moving right?
|
||||||
|
{
|
||||||
|
if (GetWallX(mPos+1)) // Wall found in current square (right edge)
|
||||||
|
{
|
||||||
|
if (x1 > xRight || abs(xRight-x1) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
x1 = xp; // Use the previous x position
|
||||||
|
HitResult = POV_SLIDEX; // We're possibly sliding along the right x wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < yp) // Are we moving up?
|
||||||
|
{
|
||||||
|
if (GetWallY(mPos)) // Wall found in current square (top edge)
|
||||||
|
{
|
||||||
|
if (y1 < yTop || abs(y1-yTop) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
y1 = yp; // Use the previous y position
|
||||||
|
HitResult = POV_SLIDEY; // We're possibly sliding along the top wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 > yp) // Are we moving down?
|
||||||
|
{
|
||||||
|
if (GetWallY(mPos+GRID_WIDTH)) // Wall found in current square (bottom edge)
|
||||||
|
{
|
||||||
|
if (y1 > yBottom || abs(yBottom-y1) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
y1 = yp; // Use the previous y position
|
||||||
|
HitResult = POV_SLIDEY; // We're sliding along the bottom wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A wall or object hasn't been hit yet--we must look further.
|
||||||
|
// The current grid sqaure will be divided into four regions:
|
||||||
|
// A = top left; B = top right; C = bottom left; D = bottom right
|
||||||
|
// Each of these regions will be checked to see if the player's new position (x1,y1)
|
||||||
|
// is close to a wall or object that borders one of these regions.
|
||||||
|
// Each grid square is 64x64 units, so each region to check is 32x32 units.
|
||||||
|
if (!HitResult)
|
||||||
|
{ // Check region A--top left area of grid
|
||||||
|
if (y1 < (yTop+32)) // New y position falls in top half
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+32)) // New x position falls in left half
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos-GRID_WIDTH); // Check adjacent x wall (to left)
|
||||||
|
mCodeY = GetWallY(mPos-1); // Check adjacent y wall (above)
|
||||||
|
|
||||||
|
if (mCodeX && y1 < (yTop+28)) // Adjacent x wall found and new y coord
|
||||||
|
{ // is within 28 units
|
||||||
|
if (x1 < (xLeft+28)) // New x coord. is within 28 units of edge
|
||||||
|
{
|
||||||
|
if (xp > (xLeft+27)) // Previous x position was outside range
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 < (xLeft+28)) // Adjacent y wall found and new x coord.
|
||||||
|
{ // is within 28 units
|
||||||
|
if (y1 < (yTop+28)) // New y coord. is within 28 units of edge
|
||||||
|
{
|
||||||
|
if (yp > (yTop+27)) // Previous y position was outside range
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check region B--top right area
|
||||||
|
if (x1 > (xRight-32) && !HitResult)// New x is at top right
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+1-GRID_WIDTH); // Check adjacent x wall (to right)
|
||||||
|
mCodeY = GetWallY(mPos+1); // Check adjacent y wall (above)
|
||||||
|
|
||||||
|
if (mCodeX && y1 < (yTop+28)) // Adjacent x wall found
|
||||||
|
{
|
||||||
|
if (x1 > (xRight-28))
|
||||||
|
{
|
||||||
|
if (xp < (xRight-27))
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 > (xRight-28)) // Adjacent y wall found
|
||||||
|
{
|
||||||
|
if (y1 < (yTop+28))
|
||||||
|
{
|
||||||
|
if (yp > (yTop+27))
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check region C--bottom left area
|
||||||
|
if (y1 > (yTop+32) && !HitResult) // We are below upper half of square
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+32)) // and on the left half of square
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+GRID_WIDTH); // Check adjacent x wall (to left)
|
||||||
|
mCodeY = GetWallY(mPos-1+GRID_WIDTH); // Check adjacent y wall (below)
|
||||||
|
|
||||||
|
if (mCodeX && y1 > (yBottom-28)) // Adjacent x wall found
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+28))
|
||||||
|
{
|
||||||
|
if (xp > (xLeft+27))
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 < (xLeft+28)) // Adjacent y wall found
|
||||||
|
{
|
||||||
|
if (y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (yp < (yBottom-27))
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check region D--bottom right area
|
||||||
|
if (x1 > (xRight-32) && !HitResult) // Check right side of square
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+1+GRID_WIDTH); // Check adjacent x wall (to right)
|
||||||
|
mCodeY = GetWallY(mPos+1+GRID_WIDTH); // Check adjacent y wall (below)
|
||||||
|
|
||||||
|
if (mCodeX && y1 > (yBottom-28)) // Adjacent x wall found
|
||||||
|
{
|
||||||
|
if (x1 > (xRight-28))
|
||||||
|
{
|
||||||
|
if (xp < (xRight-27))
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 > (xRight-28)) // Adjacent y wall found
|
||||||
|
{
|
||||||
|
if (y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (yp < (yBottom-27))
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AckCheckObjPosn(x1,y1,0)) // We've hit an object--not a wall
|
||||||
|
return(POV_OBJECT);
|
||||||
|
|
||||||
|
if (HitResult == POV_SLIDEX && y1 == yp) // We've hit an x wall and we're not sliding
|
||||||
|
HitResult = POV_XWALL;
|
||||||
|
|
||||||
|
if (HitResult == POV_SLIDEY && x1 == xp) // We've hit a y wall and we're not sliding
|
||||||
|
HitResult = POV_YWALL;
|
||||||
|
|
||||||
|
aeGlobal->xPlayer = x1; // Update player's new x,y position
|
||||||
|
aeGlobal->yPlayer = y1;
|
||||||
|
|
||||||
|
return(HitResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Moves an object based on Angle and Amount then checks for collision
|
||||||
|
// with other objects AND the POV.
|
||||||
|
//************************************************************************
|
||||||
|
short AckMoveObjectPOV(short ObjIndex,short Angle,short Amount)
|
||||||
|
{
|
||||||
|
short xp,yp,x1,y1,HitResult,oNum;
|
||||||
|
USHORT mCodeX,mCodeY;
|
||||||
|
short xLeft,xRight,yTop,yBottom,mPos;
|
||||||
|
short MapPosn,PlayerPosn;
|
||||||
|
NEWOBJECT **oList;
|
||||||
|
NEWOBJECT *oPtr;
|
||||||
|
|
||||||
|
oList = &aeGlobal->ObjList[0]; // Reference the start of the object list
|
||||||
|
oPtr = oList[ObjIndex]; // Set a pointer to the object being moved
|
||||||
|
|
||||||
|
if (oPtr == NULL) // no object is available to move; we're done
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
xp = oPtr->x; // Get the current x,y coordinate of the object
|
||||||
|
yp = oPtr->y;
|
||||||
|
// Calculate the new x,y, cordinates of the object (after moving)
|
||||||
|
x1 = xp + (short)((CosTable[Angle] * Amount) >> FP_SHIFT);
|
||||||
|
y1 = yp + (short)((SinTable[Angle] * Amount) >> FP_SHIFT);
|
||||||
|
|
||||||
|
xLeft = xp & 0xFFC0; // Determine the coordinates of the grid square the
|
||||||
|
xRight = xLeft + GRID_SIZE - 1; // object is currently in
|
||||||
|
yTop = yp & 0xFFC0;
|
||||||
|
yBottom = yTop + GRID_SIZE - 1;
|
||||||
|
mPos = yTop + (xp >> 6); // Calculate the map position of the grid square the object is in
|
||||||
|
MapPosn = (y1 & 0xFFC0) + (x1 >> 6); // Calculate the map position of the grid square the
|
||||||
|
// object is moving to
|
||||||
|
|
||||||
|
// Check to see if the object will encouner another object while moving
|
||||||
|
oNum = AckCheckObjPosn(x1,y1,ObjIndex);
|
||||||
|
if (oNum > 0) // Yes, return falg to indicate object found
|
||||||
|
return(POV_OBJECT);
|
||||||
|
|
||||||
|
HitResult = POV_NOTHING; // Nothing found yet, initialize flag
|
||||||
|
if (x1 < xp) // Are we moving left?
|
||||||
|
{
|
||||||
|
if (GetWallX(mPos)) // Wall found in current square (left edge)
|
||||||
|
{
|
||||||
|
if (x1 < xLeft || abs(x1-xLeft) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
x1 = xp; // Use the previous x position
|
||||||
|
HitResult = POV_SLIDEX; // We're possibly sliding along the left x wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 > xp) // Are we moving right?
|
||||||
|
{
|
||||||
|
if (GetWallX(mPos+1)) // Wall found in current square (right edge)
|
||||||
|
{
|
||||||
|
if (x1 > xRight || abs(xRight-x1) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
x1 = xp; // Use the previous x position
|
||||||
|
HitResult = POV_SLIDEX; // We're possibly sliding along the right x wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < yp) // Are we moving up?
|
||||||
|
{
|
||||||
|
if (GetWallY(mPos)) // Wall found in current square (top edge)
|
||||||
|
{
|
||||||
|
if (y1 < yTop || abs(y1-yTop) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
y1 = yp; // Use the previous y position
|
||||||
|
HitResult = POV_SLIDEY; // We're possibly sliding along the top wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 > yp) // Are we moving down?
|
||||||
|
{
|
||||||
|
if (GetWallY(mPos+GRID_WIDTH)) // Wall found in current square (bottom edge)
|
||||||
|
{
|
||||||
|
if (y1 > yBottom || abs(yBottom-y1) < 28) // We crossed the wall or we're too close
|
||||||
|
{
|
||||||
|
y1 = yp; // Use the previous y position
|
||||||
|
HitResult = POV_SLIDEY; // We're sliding along the bottom wall
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HitResult) // Nothing hit yet, look further
|
||||||
|
{
|
||||||
|
if (y1 < (yTop+32)) // We are above upper half of square
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+32)) // and on the left half of square
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos-GRID_WIDTH); // Check adjacent x wall (to left)
|
||||||
|
mCodeY = GetWallY(mPos-1); // Check adjacent y wall (above)
|
||||||
|
|
||||||
|
if (mCodeX && y1 < (yTop+28)) // Adjacent x wall found and new y coord
|
||||||
|
{ // is within 28 units
|
||||||
|
if (x1 < (xLeft+28)) // New x coord. is within 28 units of edge
|
||||||
|
{
|
||||||
|
if (xp > (xLeft+27)) // Previous x position was outside range
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 < (xLeft+28)) // Adjacent y wall found and new x coord.
|
||||||
|
{ // is within 28 units
|
||||||
|
if (y1 < (yTop+28)) // New y coord. is within 28 units of edge
|
||||||
|
{
|
||||||
|
if (yp > (yTop+27)) // Previous y position was outside range
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 > (xRight-32) && !HitResult) // New x is at top right
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+1-GRID_WIDTH); // Check adjacent x wall (to right)
|
||||||
|
mCodeY = GetWallY(mPos+1); // Check adjacent y wall (above)
|
||||||
|
|
||||||
|
if (mCodeX && y1 < (yTop+28)) // Adjacent x wall found
|
||||||
|
{
|
||||||
|
if (x1 > (xRight-28))
|
||||||
|
{
|
||||||
|
if (xp < (xRight-27))
|
||||||
|
{
|
||||||
|
x1 = xp; // Use previous x position
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 > (xRight-28)) // Adjacent y wall found
|
||||||
|
{
|
||||||
|
if (y1 < (yTop+28))
|
||||||
|
{
|
||||||
|
if (yp > (yTop+27))
|
||||||
|
{
|
||||||
|
y1 = yp; // Use previous y position
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp;
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 > (yTop+32) && !HitResult) // We are below upper half of square
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+32)) // and on the left half of square
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+GRID_WIDTH);
|
||||||
|
mCodeY = GetWallY(mPos-1+GRID_WIDTH);
|
||||||
|
|
||||||
|
if (mCodeX && y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (x1 < (xLeft+28))
|
||||||
|
{
|
||||||
|
if (xp > (xLeft+27))
|
||||||
|
{
|
||||||
|
x1 = xp;
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp;
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 < (xLeft+28))
|
||||||
|
{
|
||||||
|
if (y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (yp < (yBottom-27))
|
||||||
|
{
|
||||||
|
y1 = yp;
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp;
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 > (xRight-32) && !HitResult) // on right side of square
|
||||||
|
{
|
||||||
|
mCodeX = GetWallX(mPos+1+GRID_WIDTH);
|
||||||
|
mCodeY = GetWallY(mPos+1+GRID_WIDTH);
|
||||||
|
|
||||||
|
if (mCodeX && y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (x1 > (xRight-28))
|
||||||
|
{
|
||||||
|
if (xp < (xRight-27))
|
||||||
|
{
|
||||||
|
x1 = xp;
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y1 = yp;
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCodeY && x1 > (xRight-28))
|
||||||
|
{
|
||||||
|
if (y1 > (yBottom-28))
|
||||||
|
{
|
||||||
|
if (yp < (yBottom-27))
|
||||||
|
{
|
||||||
|
y1 = yp;
|
||||||
|
HitResult = POV_SLIDEY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x1 = xp;
|
||||||
|
HitResult = POV_SLIDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oPtr->x = x1; // Update the new x,y coordinates for the object
|
||||||
|
oPtr->y = y1;
|
||||||
|
oPtr->mPos = MapPosn; // Update the grid map position for the object
|
||||||
|
|
||||||
|
PlayerPosn = (aeGlobal->yPlayer & 0xFFC0) + (aeGlobal->xPlayer >> 6);
|
||||||
|
if (MapPosn == PlayerPosn)
|
||||||
|
return(POV_PLAYER);
|
||||||
|
|
||||||
|
return(HitResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Checks the list of objects used in an application and sets up the current bitmap for
|
||||||
|
// each object that can be animated. Object animation is performed by displaying
|
||||||
|
// different bitmaps for an object in sequence.
|
||||||
|
//************************************************************************
|
||||||
|
void AckCheckObjectMovement(void)
|
||||||
|
{
|
||||||
|
short i,maxObj;
|
||||||
|
short dx;
|
||||||
|
NEWOBJECT **oList;
|
||||||
|
NEWOBJECT *oPtr;
|
||||||
|
|
||||||
|
maxObj = aeGlobal->MaxObjects; // Get the number of objects used
|
||||||
|
oList = &aeGlobal->ObjList[0]; // Reference the list of objects
|
||||||
|
|
||||||
|
for (i = 1; i < maxObj; i++) // Loop to check each object in the list
|
||||||
|
{
|
||||||
|
oPtr = oList[i]; // Access current object in list
|
||||||
|
if (oPtr == NULL) // No object here; skip
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!oPtr->Active) // Object is not active; skip
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!oPtr->Speed) // Object has no speed setting; skip
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!(oPtr->Flags & OF_ANIMATE)) // Object is not set up for animation
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dx = oPtr->CurrentBm + 1; // Use the next bitmap
|
||||||
|
if (dx >= oPtr->Maxbm) // We're at the end of the list of bitmaps
|
||||||
|
{
|
||||||
|
if (oPtr->Flags & OF_ANIMONCE) // Object should only be animated once
|
||||||
|
{
|
||||||
|
oPtr->Flags &= ~OF_ANIMATE; // Reset flags to indicate that we're done
|
||||||
|
oPtr->Flags |= OF_ANIMDONE; // animating the object
|
||||||
|
dx = oPtr->CurrentBm; // Keep current bitmap number
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dx = 0; // Start at the beginning of the set of bitmaps
|
||||||
|
}
|
||||||
|
oPtr->CurrentBm = dx; // Store the next bitmap as the current one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
630
ack_lib/ACKRAY.C
Normal file
630
ack_lib/ACKRAY.C
Normal file
|
@ -0,0 +1,630 @@
|
||||||
|
//****************** ( Animation Construction Kit 3D ) **********************
|
||||||
|
// Ray Casting Routines
|
||||||
|
// CopyRight (c) 1993 Author: Lary Myers
|
||||||
|
//***************************************************************************
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
extern short ViewAngle;
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
//
|
||||||
|
//**************************************************************************
|
||||||
|
short ObjectExist(UCHAR onum)
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
if (!FoundObjectCount)
|
||||||
|
return(result);
|
||||||
|
|
||||||
|
for (i = 0; i < FoundObjectCount; i++)
|
||||||
|
{
|
||||||
|
if (ObjectsSeen[i] == onum)
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
long x_xPos,x_yPos,x_xNext,x_yNext;
|
||||||
|
long y_xPos,y_yPos,y_xNext,y_yNext;
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
void xRaySetup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
x_yNext = yNextTable[ViewAngle]; // PreCalc'd value of BITMAP_WIDTH * Tan(angle)
|
||||||
|
|
||||||
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
||||||
|
{
|
||||||
|
x_xPos = xBegGlobal + BITMAP_WIDTH; // Looking to the right
|
||||||
|
x_xNext = BITMAP_WIDTH; // Positive direction
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x_xPos = xBegGlobal; // Looking to the left
|
||||||
|
x_xNext = -BITMAP_WIDTH; // Negative direction
|
||||||
|
x_yNext = -x_yNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the Y coordinate for the current square
|
||||||
|
x_yPos = (((long)x_xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
//
|
||||||
|
//**************************************************************************
|
||||||
|
UINT xRayCast(void)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short TablePosn;
|
||||||
|
short MapPosn,CurPosn;
|
||||||
|
short xBeg;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,xAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX,oBegY;
|
||||||
|
long xd,yd,sy;
|
||||||
|
long ObjDist;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (x_xPos < 0 || x_xPos > GRID_XMAX ||
|
||||||
|
x_yPos < 0 || x_yPos > GRID_YMAXLONG)
|
||||||
|
break;
|
||||||
|
|
||||||
|
//************* Fixed point Y/64 * 64 X / 64 **********
|
||||||
|
MapPosn = ((x_yPos >> FP_SHIFT) & 0xFFC0) + (x_xPos >> 6);
|
||||||
|
|
||||||
|
|
||||||
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
Color &= 0x7F;
|
||||||
|
if (!ObjectExist(Color))
|
||||||
|
ObjectsSeen[FoundObjectCount++] = Color;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Check to see if a wall is being struck by the ray
|
||||||
|
if ((Color = xGridGlobal[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
xMapPosn = MapPosn; // Hold onto the map location
|
||||||
|
iLastX = x_xPos;
|
||||||
|
LastY1 = x_yPos;
|
||||||
|
if ((Color & 0xFF) == DOOR_XCODE) // Is this a door?
|
||||||
|
{
|
||||||
|
yd = ((x_yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
||||||
|
xd = yd + BITMAP_WIDTH; // And the right side
|
||||||
|
ObjDist = (x_yPos + (x_yNext >> 1)) >> FP_SHIFT; // Calc door distance
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
x_xPos += x_xNext; // Nope, continue casting
|
||||||
|
x_yPos += x_yNext; // the ray as before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastY1 = x_yPos + (x_yNext >> 1); // Adjust the X,Y values so
|
||||||
|
iLastX += (x_xNext >> 1); // the door is halfway in sq.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Color & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (xSecretColumn != 0)
|
||||||
|
{
|
||||||
|
sy = xSecretColumn * LongTanTable[ViewAngle];
|
||||||
|
ObjDist = (x_yPos + sy) >> FP_SHIFT;
|
||||||
|
yd = ((x_yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
||||||
|
xd = yd + BITMAP_WIDTH; // And the right side
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
x_xPos += x_xNext; // Nope, continue casting
|
||||||
|
x_yPos += x_yNext; // the ray as before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LastY1 = x_yPos + sy;
|
||||||
|
iLastX += xSecretColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
x_xPos += x_xNext; // Next X coordinate (fixed at 64 or -64)
|
||||||
|
x_yPos += x_yNext; // Next calculated Y coord for a delta of X
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); // Return that no wall was found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
UINT OldxRay(void)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short TablePosn;
|
||||||
|
short MapPosn,CurPosn;
|
||||||
|
short xBeg;
|
||||||
|
long xPos,xNext;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,xAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX,oBegY;
|
||||||
|
long yPos;
|
||||||
|
long yNext;
|
||||||
|
long xd,yd,sy;
|
||||||
|
long ObjDist;
|
||||||
|
|
||||||
|
yNext = yNextTable[ViewAngle]; // PreCalc'd value of BITMAP_WIDTH * Tan(angle)
|
||||||
|
|
||||||
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
||||||
|
{
|
||||||
|
xPos = xBegGlobal + BITMAP_WIDTH; // Looking to the right
|
||||||
|
xNext = BITMAP_WIDTH; // Positive direction
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xPos = xBegGlobal; // Looking to the left
|
||||||
|
xNext = -BITMAP_WIDTH; // Negative direction
|
||||||
|
yNext = -yNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the Y coordinate for the current square
|
||||||
|
yPos = (((long)xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (xPos < 0 || xPos > GRID_XMAX ||
|
||||||
|
yPos < 0 || yPos > GRID_YMAXLONG)
|
||||||
|
break;
|
||||||
|
|
||||||
|
//************* Fixed point Y/64 * 64 X / 64 ***********
|
||||||
|
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
|
||||||
|
|
||||||
|
|
||||||
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
Color &= 0x7F;
|
||||||
|
if (!ObjectExist(Color))
|
||||||
|
ObjectsSeen[FoundObjectCount++] = Color;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Check to see if a wall is being struck by the ray
|
||||||
|
if ((Color = xGridGlobal[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
xMapPosn = MapPosn; // Hold onto the map location
|
||||||
|
iLastX = xPos;
|
||||||
|
LastY1 = yPos;
|
||||||
|
if ((Color & 0xFF) == DOOR_XCODE) // Is this a door?
|
||||||
|
{
|
||||||
|
yd = ((yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
||||||
|
xd = yd + BITMAP_WIDTH; // And the right side
|
||||||
|
ObjDist = (yPos + (yNext >> 1)) >> FP_SHIFT; // Calc door distance
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
xPos += xNext; // Nope, continue casting
|
||||||
|
yPos += yNext; // the ray as before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastY1 = yPos + (yNext >> 1); // Adjust the X,Y values so
|
||||||
|
iLastX += (xNext >> 1); // the door is halfway in sq.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Color & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (xSecretColumn != 0)
|
||||||
|
{
|
||||||
|
sy = xSecretColumn * LongTanTable[ViewAngle];
|
||||||
|
ObjDist = (yPos + sy) >> FP_SHIFT;
|
||||||
|
yd = ((yPos >> FP_SHIFT) & GRID_MASK); // Get the left side
|
||||||
|
xd = yd + BITMAP_WIDTH; // And the right side
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
xPos += xNext; // Nope, continue casting
|
||||||
|
yPos += yNext; // the ray as before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LastY1 = yPos + sy;
|
||||||
|
iLastX += xSecretColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
xPos += xNext; // Next X coordinate (fixed at 64 or -64)
|
||||||
|
yPos += yNext; // Next calculated Y coord for a delta of X
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); // Return that no wall was found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
void yRaySetup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
y_xNext = xNextTable[ViewAngle]; // Pre-calc'd value of BITMAP_WIDTH / tan(angle)
|
||||||
|
|
||||||
|
if (ViewAngle < INT_ANGLE_180)
|
||||||
|
{
|
||||||
|
y_yPos = yBegGlobal + BITMAP_WIDTH; // Looking down
|
||||||
|
y_yNext = BITMAP_WIDTH; // Positive direction
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
y_yPos = yBegGlobal; // Looking up
|
||||||
|
y_yNext = -BITMAP_WIDTH; // Negative direction
|
||||||
|
y_xNext = -y_xNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the X coordinate for the current square
|
||||||
|
y_xPos = (((long)y_yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
UINT yRayCast(void)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short MapPosn;
|
||||||
|
short yBeg;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,yAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX;
|
||||||
|
long xd,yd,ObjDist,sx;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (y_xPos < 0 || y_xPos > GRID_XMAXLONG ||
|
||||||
|
y_yPos < 0 || y_yPos > GRID_YMAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
//********** Y/64 * 64 Fixed point and /64 *****
|
||||||
|
MapPosn = (y_yPos & 0xFFC0) + (y_xPos >> (FP_SHIFT+6));
|
||||||
|
|
||||||
|
|
||||||
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
Color &= 0x7F;
|
||||||
|
if (!ObjectExist(Color))
|
||||||
|
ObjectsSeen[FoundObjectCount++] = Color;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check for a wall being struck
|
||||||
|
if ((Color = yGridGlobal[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
yMapPosn = MapPosn; // Hold onto map position
|
||||||
|
LastX1 = y_xPos;
|
||||||
|
iLastY = y_yPos;
|
||||||
|
|
||||||
|
if ((Color & 0xFF) == DOOR_YCODE) // Is this a door?
|
||||||
|
{
|
||||||
|
yd = ((y_xPos >> FP_SHIFT) & GRID_MASK); // Calc top side of square
|
||||||
|
xd = yd + BITMAP_WIDTH; // And bottom side of square
|
||||||
|
ObjDist = (y_xPos + (y_xNext >> 1)) >> FP_SHIFT;
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
y_xPos += y_xNext; // No, continue on with ray cast
|
||||||
|
y_yPos += y_yNext;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastX1 = y_xPos + (y_xNext >> 1); // Adjust coordinates so door is
|
||||||
|
iLastY += (y_yNext >> 1); // Halfway into wall
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Color & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (ySecretColumn != 0)
|
||||||
|
{
|
||||||
|
sx = ySecretColumn * LongInvTanTable[ViewAngle];
|
||||||
|
ObjDist = (y_xPos + sx) >> FP_SHIFT;
|
||||||
|
yd = ((y_xPos >> FP_SHIFT) & GRID_MASK); // Get the top side
|
||||||
|
xd = yd + BITMAP_WIDTH; // And the bottom side
|
||||||
|
if (ObjDist < yd || ObjDist > xd) // Is door visible?
|
||||||
|
{
|
||||||
|
y_xPos += y_xNext; // Nope, continue casting
|
||||||
|
y_yPos += y_yNext; // the ray as before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LastX1 = y_xPos + sx;
|
||||||
|
iLastY += ySecretColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
y_xPos += y_xNext; // Next calculated X value for delta Y
|
||||||
|
y_yPos += y_yNext; // Next fixed value of 64 or -64
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); // Return here if no Y wall is found
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
UINT OldyRay(void)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short MapPosn;
|
||||||
|
short yBeg;
|
||||||
|
long yPos,yNext;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,yAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX;
|
||||||
|
long xPos;
|
||||||
|
long xNext;
|
||||||
|
long xd,yd,ObjDist,sx;
|
||||||
|
|
||||||
|
xNext = xNextTable[ViewAngle]; // Pre-calc'd value of BITMAP_WIDTH / tan(angle)
|
||||||
|
|
||||||
|
if (ViewAngle < INT_ANGLE_180)
|
||||||
|
{
|
||||||
|
yPos = yBegGlobal + BITMAP_WIDTH; /* Looking down */
|
||||||
|
yNext = BITMAP_WIDTH; /* Positive direction */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yPos = yBegGlobal; /* Looking up */
|
||||||
|
yNext = -BITMAP_WIDTH; /* Negative direction */
|
||||||
|
xNext = -xNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the X coordinate for the current square */
|
||||||
|
xPos = (((long)yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (xPos < 0 || xPos > GRID_XMAXLONG ||
|
||||||
|
yPos < 0 || yPos > GRID_YMAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*********** Y/64 * 64 Fixed point and /64 ******/
|
||||||
|
// MapPosn = ((yPos / BITMAP_WIDTH) * GRID_WIDTH) + (xPos >> (FP_SHIFT+BITMAP_SHIFT));
|
||||||
|
// MapPosn = ((yPos & GRID_MASK) >> 1) + (xPos >> (FP_SHIFT+BITMAP_SHIFT));
|
||||||
|
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
|
||||||
|
|
||||||
|
|
||||||
|
if ((Color = ObjGrid[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
Color &= 0x7F;
|
||||||
|
if (!ObjectExist(Color))
|
||||||
|
ObjectsSeen[FoundObjectCount++] = Color;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Check for a wall being struck **/
|
||||||
|
if ((Color = yGridGlobal[MapPosn]) != 0)
|
||||||
|
{
|
||||||
|
yMapPosn = MapPosn; /* Hold onto map position */
|
||||||
|
LastX1 = xPos;
|
||||||
|
iLastY = yPos;
|
||||||
|
|
||||||
|
if ((Color & 0xFF) == DOOR_YCODE) /* Is this a door? */
|
||||||
|
{
|
||||||
|
yd = ((xPos >> FP_SHIFT) & GRID_MASK); /* Calc top side of square */
|
||||||
|
xd = yd + BITMAP_WIDTH; /* And bottom side of square */
|
||||||
|
ObjDist = (xPos + (xNext >> 1)) >> FP_SHIFT;
|
||||||
|
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
|
||||||
|
{
|
||||||
|
xPos += xNext; /* No, continue on with ray cast */
|
||||||
|
yPos += yNext;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastX1 = xPos + (xNext >> 1); /* Adjust coordinates so door is */
|
||||||
|
iLastY += (yNext >> 1); /* Halfway into wall */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Color & DOOR_TYPE_SECRET)
|
||||||
|
{
|
||||||
|
if (ySecretColumn != 0)
|
||||||
|
{
|
||||||
|
sx = ySecretColumn * LongInvTanTable[ViewAngle];
|
||||||
|
ObjDist = (xPos + sx) >> FP_SHIFT;
|
||||||
|
yd = ((xPos >> FP_SHIFT) & GRID_MASK); /* Get the top side */
|
||||||
|
xd = yd + BITMAP_WIDTH; /* And the bottom side */
|
||||||
|
if (ObjDist < yd || ObjDist > xd) /* Is door visible? */
|
||||||
|
{
|
||||||
|
xPos += xNext; /* Nope, continue casting */
|
||||||
|
yPos += yNext; /* the ray as before */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LastX1 = xPos + sx;
|
||||||
|
iLastY += ySecretColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
xPos += xNext; /* Next calculated X value for delta Y */
|
||||||
|
yPos += yNext; /* Next fixed value of 64 or -64 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); /* Return here if no Y wall is found */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
UINT xRayMulti(UINT MinDist,short MinHeight)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short TablePosn;
|
||||||
|
short MapPosn,CurPosn;
|
||||||
|
short xBeg;
|
||||||
|
long xPos,xNext;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,xAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX,oBegY;
|
||||||
|
long yPos;
|
||||||
|
long yNext;
|
||||||
|
long xd,yd,sy;
|
||||||
|
long ObjDist;
|
||||||
|
|
||||||
|
yNext = yNextTable[ViewAngle]; /* PreCalc'd value of BITMAP_WIDTH * Tan(angle) */
|
||||||
|
|
||||||
|
if (ViewAngle > INT_ANGLE_270 || ViewAngle < INT_ANGLE_90)
|
||||||
|
{
|
||||||
|
xPos = xBegGlobal + BITMAP_WIDTH; /* Looking to the right */
|
||||||
|
xNext = BITMAP_WIDTH; /* Positive direction */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xPos = xBegGlobal; /* Looking to the left */
|
||||||
|
xNext = -BITMAP_WIDTH; /* Negative direction */
|
||||||
|
yNext = -yNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the Y coordinate for the current square */
|
||||||
|
yPos = (((long)xPos - (long)xPglobal) * LongTanTable[ViewAngle]) + yPglobalHI;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (xPos < 0 || xPos > GRID_XMAX ||
|
||||||
|
yPos < 0 || yPos > GRID_YMAXLONG)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/************** Fixed point Y/64 * 64 X / 64 ***********/
|
||||||
|
MapPosn = ((yPos >> FP_SHIFT) & 0xFFC0) + (xPos >> 6);
|
||||||
|
|
||||||
|
/* Check to see if a wall is being struck by the ray */
|
||||||
|
if ((Color = xGridGlobal[MapPosn]) & WALL_TYPE_MULTI)
|
||||||
|
{
|
||||||
|
if ((Color & 0xFF) > MinHeight)
|
||||||
|
{
|
||||||
|
xd = xPos - xPglobal;
|
||||||
|
yd = InvCosTable[ViewAngle] >> 4;
|
||||||
|
if (MinDist < ((xd * yd) >> 10))
|
||||||
|
{
|
||||||
|
xMapPosn = MapPosn; /* Hold onto the map location */
|
||||||
|
iLastX = xPos;
|
||||||
|
LastY1 = yPos;
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xPos += xNext; /* Next X coordinate (fixed at 64 or -64) */
|
||||||
|
yPos += yNext; /* Next calculated Y coord for a delta of X */
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); /* Return that no wall was found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
UINT yRayMulti(UINT MinDist,short MinHeight)
|
||||||
|
{
|
||||||
|
UINT Color;
|
||||||
|
short i,j,mx,my;
|
||||||
|
short MapPosn;
|
||||||
|
short yBeg;
|
||||||
|
long yPos,yNext;
|
||||||
|
short BitmapColumn;
|
||||||
|
short xCenter,yCenter,yAdj;
|
||||||
|
short ObjPosn;
|
||||||
|
short oBegX;
|
||||||
|
long xPos;
|
||||||
|
long xNext;
|
||||||
|
long xd,yd,ObjDist,sx;
|
||||||
|
|
||||||
|
xNext = xNextTable[ViewAngle]; /* Pre-calc'd value of BITMAP_WIDTH / tan(angle) */
|
||||||
|
|
||||||
|
if (ViewAngle < INT_ANGLE_180)
|
||||||
|
{
|
||||||
|
yPos = yBegGlobal + BITMAP_WIDTH; /* Looking down */
|
||||||
|
yNext = BITMAP_WIDTH; /* Positive direction */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yPos = yBegGlobal; /* Looking up */
|
||||||
|
yNext = -BITMAP_WIDTH; /* Negative direction */
|
||||||
|
xNext = -xNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the X coordinate for the current square */
|
||||||
|
xPos = (((long)yPos - (long)yPglobal) * LongInvTanTable[ViewAngle]) + xPglobalHI;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (xPos < 0 || xPos > GRID_XMAXLONG ||
|
||||||
|
yPos < 0 || yPos > GRID_YMAX)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*********** Y/64 * 64 Fixed point and /64 ******/
|
||||||
|
MapPosn = (yPos & 0xFFC0) + (xPos >> (FP_SHIFT+6));
|
||||||
|
|
||||||
|
/** Check for a wall being struck **/
|
||||||
|
if ((Color = yGridGlobal[MapPosn]) & WALL_TYPE_MULTI)
|
||||||
|
{
|
||||||
|
if ((Color & 0xFF) > MinHeight)
|
||||||
|
{
|
||||||
|
xd = yPos - yPglobal;
|
||||||
|
yd = InvCosTable[ViewAngle] >> 4;
|
||||||
|
if (MinDist < ((xd * yd) >> 10))
|
||||||
|
{
|
||||||
|
yMapPosn = MapPosn; /* Hold onto the map location */
|
||||||
|
LastX1 = xPos;
|
||||||
|
iLastY = yPos;
|
||||||
|
return(Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xPos += xNext; /* Next calculated X value for delta Y */
|
||||||
|
yPos += yNext; /* Next fixed value of 64 or -64 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0); /* Return here if no Y wall is found */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
989
ack_lib/ACKRTN.ASM
Normal file
989
ack_lib/ACKRTN.ASM
Normal file
|
@ -0,0 +1,989 @@
|
||||||
|
|
||||||
|
locals
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387 ; Allow 386 processor
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT,STDCALL ;32-bit OS/2 model
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
COLOR dw ?
|
||||||
|
RETVAL dw ?
|
||||||
|
MAPPOSN dw ?
|
||||||
|
XBEG dd ?
|
||||||
|
XD dd ?
|
||||||
|
YD dd ?
|
||||||
|
YTEMP dd ?
|
||||||
|
SY dd ?
|
||||||
|
SX dd ?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
include "ackrtn.inc"
|
||||||
|
|
||||||
|
SC_INDEX EQU 03C4h ; Sequencer Controller access
|
||||||
|
HIGH_ADDR equ 80h ; High byte of screen offset
|
||||||
|
GC_INDEX equ 3ceh ;Graphics Controller Index register
|
||||||
|
CRTC_INDEX equ 3d4h ;CRT Controller Index register
|
||||||
|
MAP_MASK equ 2 ;Map Mask register index in SC
|
||||||
|
MEMORY_MODE equ 4 ;Memory Mode register index in SC
|
||||||
|
MAX_SCAN_LINE equ 9 ;Maximum Scan Line reg index in CRTC
|
||||||
|
START_ADDRESS_HIGH equ 0ch ;Start Address High reg index in CRTC
|
||||||
|
UNDERLINE equ 14h ;Underline Location reg index in CRTC
|
||||||
|
MODE_CONTROL equ 17h ;Mode Control register index in CRTC
|
||||||
|
READ_MAP equ 4 ;Read Map register index in GC
|
||||||
|
GRAPHICS_MODE equ 5 ;Graphics Mode register index in GC
|
||||||
|
MISCELLANEOUS equ 6 ;Miscellaneous register index in GC
|
||||||
|
SCREEN_WIDTH equ 320 ;# of pixels across screen
|
||||||
|
SCREEN_HEIGHT equ 400 ;# of scan lines on screen
|
||||||
|
|
||||||
|
|
||||||
|
extrn _ViewAngle:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _xPglobal:dword
|
||||||
|
extrn _yPglobal:dword
|
||||||
|
extrn _xBegGlobal:dword
|
||||||
|
extrn _yBegGlobal:dword
|
||||||
|
extrn _aeGlobal:dword
|
||||||
|
extrn _xGridGlobal:dword
|
||||||
|
extrn _yGridGlobal:dword
|
||||||
|
extrn _xPglobalHI:dword
|
||||||
|
extrn _yPglobalHI:dword
|
||||||
|
extrn _rbaTable:dword
|
||||||
|
extrn _rsHandle:word
|
||||||
|
extrn _LastX1:dword
|
||||||
|
extrn _LastY1:dword
|
||||||
|
extrn _iLastX:dword
|
||||||
|
extrn _iLastY;dword
|
||||||
|
extrn _MaxDistance:word
|
||||||
|
extrn _ErrorCode:word
|
||||||
|
extrn _xMapPosn:dword
|
||||||
|
extrn _yMapPosn:dword
|
||||||
|
extrn _Grid:dword
|
||||||
|
extrn _ObjGrid:dword
|
||||||
|
|
||||||
|
extrn _xSecretmPos:word
|
||||||
|
extrn _xSecretmPos1:word
|
||||||
|
extrn _xSecretColumn:word
|
||||||
|
|
||||||
|
extrn _ySecretmPos:word
|
||||||
|
extrn _ySecretmPos1:word
|
||||||
|
extrn _ySecretColumn:word
|
||||||
|
|
||||||
|
extrn _TotalSecret:word
|
||||||
|
extrn _ViewColumn:word
|
||||||
|
extrn _SinTable:dword
|
||||||
|
extrn _CosTable:dword
|
||||||
|
extrn _LongTanTable:dword
|
||||||
|
extrn _LongInvTanTable:dword
|
||||||
|
extrn _InvCosTable:byte
|
||||||
|
extrn _InvSinTable:byte
|
||||||
|
extrn _LongCosTable:dword
|
||||||
|
extrn _ViewCosTable:dword
|
||||||
|
extrn _xNextTable:dword
|
||||||
|
extrn _yNextTable:dword
|
||||||
|
|
||||||
|
extrn _LastMapPosn:word
|
||||||
|
extrn _LastObjectHit:word
|
||||||
|
extrn _TotalObjects:word
|
||||||
|
extrn _FoundObjectCount:word
|
||||||
|
extrn _ObjectsSeen:byte
|
||||||
|
extrn _MoveObjectCount:word
|
||||||
|
extrn _MoveObjectList:byte
|
||||||
|
extrn _ObjNumber:byte
|
||||||
|
extrn _ObjRelDist:byte
|
||||||
|
extrn _ObjColumn:byte
|
||||||
|
|
||||||
|
extrn _x_xPos:dword
|
||||||
|
extrn _x_yPos:dword
|
||||||
|
extrn _x_xNext:dword
|
||||||
|
extrn _x_yNext:dword
|
||||||
|
extrn _y_xPos:dword
|
||||||
|
extrn _y_yPos:dword
|
||||||
|
extrn _y_xNext:dword
|
||||||
|
extrn _y_yNext:dword
|
||||||
|
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
extrn _FloorscrTop:dword
|
||||||
|
extrn _Floorptr2:dword
|
||||||
|
extrn _Floorht:word
|
||||||
|
extrn _Floorwt:word
|
||||||
|
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gWinStartY:word
|
||||||
|
extrn _gWinStartX:word
|
||||||
|
extrn _gWinWidth:word
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
|
||||||
|
extrn _gWinFullWidth:word
|
||||||
|
extrn _gWinDWORDS:dword
|
||||||
|
extrn _gWinStartOffset:dword
|
||||||
|
|
||||||
|
extrn _VidSeg:dword
|
||||||
|
extrn _AckKeys:byte
|
||||||
|
|
||||||
|
extrn _OurDataSeg:word
|
||||||
|
|
||||||
|
extrn _HitMap:byte
|
||||||
|
|
||||||
|
ACKPUBS AckInkey
|
||||||
|
ACKPUBS AckKbdInt
|
||||||
|
ACKPUBS AckPutVideo
|
||||||
|
ACKPUBS AckGetVideo
|
||||||
|
ACKPUBS AckCopyToVideo
|
||||||
|
ACKPUBS AckSetPalette
|
||||||
|
ACKPUBS AckDisplayScreen
|
||||||
|
ACKPUBS AckInitVideoSelector
|
||||||
|
ACKPUBS AckGetIntVector
|
||||||
|
ACKPUBS AckSetIntVector
|
||||||
|
ACKPUBS AckSetVGAmode
|
||||||
|
ACKPUBS AckSetTextMode
|
||||||
|
ACKPUBS AckDrawPage
|
||||||
|
ACKPUBS xRaySetup
|
||||||
|
ACKPUBS yRaySetup
|
||||||
|
ACKPUBS xRayCast
|
||||||
|
ACKPUBS yRayCast
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Checks for a keystroke and returns 0 if none, else scan/char in AX
|
||||||
|
; This routine should NOT be used if the keyboard vector has been changed
|
||||||
|
; to the AckKbdInt routine below.
|
||||||
|
; unsigned short AckInkey(void);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckInkey
|
||||||
|
push ebx
|
||||||
|
mov ax,0100h
|
||||||
|
int 16h
|
||||||
|
mov bx,0
|
||||||
|
jz ackinkey_10
|
||||||
|
xor ax,ax
|
||||||
|
int 16h
|
||||||
|
mov bx,ax
|
||||||
|
|
||||||
|
ackinkey_10:
|
||||||
|
mov ax,bx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Interrupt 9 keyboard handler. Places keys into the keyboard array so they
|
||||||
|
; can be checked by the application.
|
||||||
|
; Do NOT call this routine directly!!!
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckKbdInt
|
||||||
|
push eax
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
push ds
|
||||||
|
xor ebx,ebx
|
||||||
|
in al,60h
|
||||||
|
mov bl,al
|
||||||
|
in al,61h
|
||||||
|
mov ah,al
|
||||||
|
or al,80h
|
||||||
|
out 61h,al
|
||||||
|
mov al,ah
|
||||||
|
out 61h,al
|
||||||
|
mov al,20h
|
||||||
|
out 20h,al
|
||||||
|
mov ax,cs:[word ptr _OurDataSeg]
|
||||||
|
mov ds,ax
|
||||||
|
mov esi,offset _AckKeys
|
||||||
|
mov eax,ebx
|
||||||
|
and eax,127
|
||||||
|
mov [byte ptr esi+eax],1
|
||||||
|
test ebx,128
|
||||||
|
jz aki_10
|
||||||
|
mov [byte ptr esi+eax],0
|
||||||
|
|
||||||
|
aki_10:
|
||||||
|
pop ds
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
pop eax
|
||||||
|
iretd
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Older version which now simply calls AckDrawPage.
|
||||||
|
; void AckDisplayScreen(void);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckDisplayScreen
|
||||||
|
push ebp
|
||||||
|
ACKCALL AckDrawPage
|
||||||
|
pop ebp
|
||||||
|
xor eax,eax
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Puts a single byte onto the video
|
||||||
|
; void AckPutVideo(unsigned int offset,unsigned char color);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckPutVideo
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push es
|
||||||
|
push ebx
|
||||||
|
push edi
|
||||||
|
mov bx,[word ptr _VidSeg+2]
|
||||||
|
mov es,bx
|
||||||
|
movzx edi,[word ptr _VidSeg]
|
||||||
|
add edi,[dword ptr ebp+8]
|
||||||
|
mov edx,[ebp+12]
|
||||||
|
mov [edi],dl
|
||||||
|
pop edi
|
||||||
|
pop ebx
|
||||||
|
pop es
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Retrieves a single byte from the video
|
||||||
|
; unsigned char AckGetVideo(unsigned int offset);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckGetVideo
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push ds
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
movzx esi,[word ptr _VidSeg]
|
||||||
|
add esi,[dword ptr ebp+8]
|
||||||
|
mov ax,[word ptr _VidSeg+2]
|
||||||
|
mov ds,ax
|
||||||
|
mov al,[esi]
|
||||||
|
mov ah,0
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
pop ds
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Copies a block from the data segment buffer to the video screen
|
||||||
|
; void AckCopyToVideo(unsigned int SrcOff,unsigned int len);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckCopyToVideo
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push es
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov esi,[ebp+8]
|
||||||
|
mov ecx,[ebp+12]
|
||||||
|
movzx edi,[word ptr _VidSeg]
|
||||||
|
mov ax,[word ptr _VidSeg+2]
|
||||||
|
mov es,ax
|
||||||
|
rep movsb
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop es
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Retrieves a selector to Video memory and stores it in the VidSeg global
|
||||||
|
; void AckInitVideoSelector(void);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckInitVideoSelector
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov ax,2 ; Allocate selector for real mode address
|
||||||
|
mov bx,0A000h ; Get Video address
|
||||||
|
int 31h
|
||||||
|
mov [word ptr _VidSeg+2],ax
|
||||||
|
mov [word ptr _VidSeg],0
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Retrieves a protected mode interrupt vector.
|
||||||
|
; void AckGetIntVector(int VectorNumber,int *sel,int *off);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckGetIntVector
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push es
|
||||||
|
mov ebx,[ebp+8]
|
||||||
|
mov eax,204h
|
||||||
|
int 31h
|
||||||
|
mov ebx,[ebp+12]
|
||||||
|
mov [ebx],cx
|
||||||
|
mov ebx,[ebp+16]
|
||||||
|
mov [ebx],dx
|
||||||
|
pop es
|
||||||
|
; mov eax,ecx
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Sets a protected mode interrupt handler.
|
||||||
|
; void AckSetIntVector(int VecNum,unsigned int VecSel,unsigned int VecOff);
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSetIntVector
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov ebx,[ebp+8]
|
||||||
|
mov ecx,[ebp+12]
|
||||||
|
mov edx,[ebp+16]
|
||||||
|
;; mov cx,cs
|
||||||
|
mov eax,205h
|
||||||
|
cli
|
||||||
|
int 31h
|
||||||
|
sti
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSetPalette
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push ds
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov esi,[ebp+8]
|
||||||
|
mov ebx,0
|
||||||
|
mov ecx,256
|
||||||
|
mov dx,3c8h
|
||||||
|
|
||||||
|
asp_loop:
|
||||||
|
mov al,bl
|
||||||
|
out dx,al
|
||||||
|
inc bx
|
||||||
|
inc dx
|
||||||
|
lodsb
|
||||||
|
out dx,al
|
||||||
|
lodsb
|
||||||
|
out dx,al
|
||||||
|
lodsb
|
||||||
|
out dx,al
|
||||||
|
dec dx
|
||||||
|
loop asp_loop
|
||||||
|
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop ds
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSetVGAmode
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov ax,0013h ;AH = 0 means mode set, AL = 13h selects
|
||||||
|
int 10h ;BIOS video interrupt
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
; Uncomment the following code to setup a 320x200 modeX environment
|
||||||
|
;------------------------------------------------------------------------------
|
||||||
|
;; Change CPU addressing of video memory to linear (not odd/even,
|
||||||
|
;; chain, or chain 4), to allow us to access all 256K of display
|
||||||
|
;; memory. When this is done, VGA memory will look just like memory
|
||||||
|
;; in modes 10h and 12h, except that each byte of display memory will
|
||||||
|
;; control one 256-color pixel, with 4 adjacent pixels at any given
|
||||||
|
;; address, one pixel per plane.
|
||||||
|
;;------------------------------------------------------------------------------
|
||||||
|
; mov dx,SC_INDEX
|
||||||
|
; mov al,MEMORY_MODE
|
||||||
|
; out dx,al
|
||||||
|
; inc dx
|
||||||
|
; in al,dx
|
||||||
|
; and al,not 08h ;turn off chain 4
|
||||||
|
; or al,04h ;turn off odd/even
|
||||||
|
; out dx,al
|
||||||
|
; mov dx,GC_INDEX
|
||||||
|
; mov al,GRAPHICS_MODE
|
||||||
|
; out dx,al
|
||||||
|
; inc dx
|
||||||
|
; in al,dx
|
||||||
|
; and al,not 10h ;turn off odd/even
|
||||||
|
; out dx,al
|
||||||
|
; dec dx
|
||||||
|
; mov al,MISCELLANEOUS
|
||||||
|
; out dx,al
|
||||||
|
; inc dx
|
||||||
|
; in al,dx
|
||||||
|
; and al,not 02h ;turn off chain
|
||||||
|
; out dx,al
|
||||||
|
; mov dx,SC_INDEX
|
||||||
|
; mov ax,(0fh shl 8) + MAP_MASK
|
||||||
|
; out dx,ax
|
||||||
|
;
|
||||||
|
; mov dx,CRTC_INDEX
|
||||||
|
;;------------------------------------------------------------------------------
|
||||||
|
;; Change CRTC scanning from doubleword mode to byte mode, allowing
|
||||||
|
;; the CRTC to scan more than 64K of video data.
|
||||||
|
;;------------------------------------------------------------------------------
|
||||||
|
; mov al,UNDERLINE
|
||||||
|
; out dx,al
|
||||||
|
; inc dx
|
||||||
|
; in al,dx
|
||||||
|
; and al,not 40h ;turn off doubleword
|
||||||
|
; out dx,al
|
||||||
|
; dec dx
|
||||||
|
; mov al,MODE_CONTROL
|
||||||
|
; out dx,al
|
||||||
|
; inc dx
|
||||||
|
; in al,dx
|
||||||
|
; or al,40h ;turn on the byte mode bit, so memory is
|
||||||
|
; ; scanned for video data in a purely
|
||||||
|
; ; linear way, just as in modes 10h and 12h
|
||||||
|
; out dx,al
|
||||||
|
; ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSetTextMode
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov ax,3
|
||||||
|
int 10h
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckDrawPage
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push es
|
||||||
|
push ds
|
||||||
|
|
||||||
|
;; mov edi,[_VidSeg]
|
||||||
|
mov edi,0
|
||||||
|
mov di,[word ptr _VidSeg]
|
||||||
|
mov esi,[_gScrnBuffer]
|
||||||
|
cmp [word ptr _gWinFullWidth],0
|
||||||
|
jz short dp_smallscreen
|
||||||
|
|
||||||
|
mov eax,[_gWinStartOffset]
|
||||||
|
add edi,eax
|
||||||
|
add esi,eax
|
||||||
|
mov ecx,[_gWinDWORDS]
|
||||||
|
|
||||||
|
mov ax,[word ptr _VidSeg+2]
|
||||||
|
mov es,ax
|
||||||
|
;; mov ds,ax
|
||||||
|
|
||||||
|
mov dx,3dah
|
||||||
|
|
||||||
|
fp020:
|
||||||
|
in al,dx ;Wait until vertical retrace is on
|
||||||
|
test al,8
|
||||||
|
jz fp020
|
||||||
|
|
||||||
|
fp030:
|
||||||
|
in al,dx ;Wait until vertical retrace is off
|
||||||
|
test al,8
|
||||||
|
jnz fp030
|
||||||
|
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
dp_smallscreen:
|
||||||
|
mov eax,[_gWinStartOffset]
|
||||||
|
add edi,eax
|
||||||
|
add esi,eax
|
||||||
|
movzx eax,[_gWinStartX]
|
||||||
|
add edi,eax
|
||||||
|
add esi,eax
|
||||||
|
mov dx,[_gWinHeight]
|
||||||
|
inc dx
|
||||||
|
movzx ebx,[_gWinWidth]
|
||||||
|
mov ebp,320
|
||||||
|
sub ebp,ebx ;width to advance pointers
|
||||||
|
|
||||||
|
mov ax,[word ptr _VidSeg+2]
|
||||||
|
mov es,ax
|
||||||
|
;; mov ds,ax
|
||||||
|
|
||||||
|
dp010:
|
||||||
|
mov ecx,ebx
|
||||||
|
shr ecx,1
|
||||||
|
rep movsw
|
||||||
|
rcl ecx,1
|
||||||
|
rep movsb
|
||||||
|
add edi,ebp
|
||||||
|
add esi,ebp
|
||||||
|
dec dx
|
||||||
|
jnz dp010
|
||||||
|
|
||||||
|
dp090:
|
||||||
|
pop ds
|
||||||
|
pop es
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xRaySetup
|
||||||
|
push esi ; Save registers used
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov dx,[_ViewAngle] ; Get the current angle for casting
|
||||||
|
movzx esi,dx ; Use this angle for table look up
|
||||||
|
shl esi,2 ; Hold onto viewangle * 4 for table access
|
||||||
|
mov ebx,[_yNextTable] ; Base address of list of y increment coordinates
|
||||||
|
mov eax,[esi+ebx] ; Use angle as index into table
|
||||||
|
mov [dword ptr _x_yNext],eax; Store y increment value
|
||||||
|
cmp dx,INT_ANGLE_270 ; Is angle > 270 degrees?
|
||||||
|
jg short inbetween
|
||||||
|
cmp dx,INT_ANGLE_90 ; Is angle >= 90 degrees?
|
||||||
|
jge short not_inbetween
|
||||||
|
; Set up the ray for casting to the right (270 to 90 degrees)
|
||||||
|
inbetween:
|
||||||
|
mov ecx,[_xBegGlobal] ; Get left corner of grid square
|
||||||
|
add ecx,64 ; Calculate right corner
|
||||||
|
mov [dword ptr _x_xPos],ecx ; Store starting x position
|
||||||
|
mov [dword ptr _x_xNext],large 64 ; Store next x grid increment
|
||||||
|
jmp short xr_cont ; to the right (+64)
|
||||||
|
; Set up the ray for casting to the keft (90 to 270 degrees)
|
||||||
|
not_inbetween:
|
||||||
|
movzx ecx,[word ptr _xBegGlobal] ; Get left corner of grid square
|
||||||
|
mov [_x_xPos],ecx ; Store starting x position
|
||||||
|
mov [dword ptr _x_xNext],large -64 ; Store next x grid increment
|
||||||
|
; to the left (-64)
|
||||||
|
neg [dword ptr _x_yNext] ; Negate the second y intersection
|
||||||
|
; coordinate
|
||||||
|
xr_cont:
|
||||||
|
movzx eax,[word ptr _xPglobal] ; Get player’s x coordinate
|
||||||
|
sub ecx,eax ; x Distance from player’s position
|
||||||
|
; to edge of grid
|
||||||
|
mov ebx,[dword ptr _LongTanTable] ; Get address of tangent table
|
||||||
|
imul ecx,[dword ptr esi+ebx] ; Tangent(angle) * Distance
|
||||||
|
add ecx,[dword ptr _yPglobalHI] ;
|
||||||
|
mov [dword ptr _x_yPos],ecx ; Store first y coordinate where
|
||||||
|
; we hit an x boundary
|
||||||
|
pop edx ; Restore registers
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xRayCast
|
||||||
|
push esi ; Save registers used
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov esi,[_x_xPos] ; Get x,y starting position
|
||||||
|
mov edi,[_x_yPos] ; (1st grid border intersection point)
|
||||||
|
xor ecx,ecx ; Init our bitmap variable
|
||||||
|
|
||||||
|
looptop: ; Start the ray casting loop
|
||||||
|
mov edx,esi ; Get x starting position
|
||||||
|
cmp edx,large 0 ; If it’s < 0 we’re done!
|
||||||
|
jl short getout
|
||||||
|
cmp edx,large 4096 ; If it’s > 4,096 we’re done
|
||||||
|
jge short getout
|
||||||
|
mov eax,edi ; Get y starting position
|
||||||
|
cmp eax,large 0 ; If it’s < 0 we’re done
|
||||||
|
jl short getout
|
||||||
|
cmp eax,large 010000000h ; If it’s out of range we’re done
|
||||||
|
jl short inbounds
|
||||||
|
getout:
|
||||||
|
jmp loopdone
|
||||||
|
|
||||||
|
inbounds: ; We’re in-range; continue casting
|
||||||
|
sar eax,16 ; Scale y starting position
|
||||||
|
and eax,-64
|
||||||
|
sar edx,6 ; Scale x starting position
|
||||||
|
add eax,edx ; Calculate grid map position
|
||||||
|
cmp eax,4095 ; Test map position to see if it’s in range
|
||||||
|
ja getout
|
||||||
|
mov [byte ptr _HitMap+eax],1 ; Record the square we cast through
|
||||||
|
mov ebx,[_xGridGlobal] ; Get pointer to x wall map
|
||||||
|
mov cx,[ebx+eax*2] ; Get the bitmap number there
|
||||||
|
jcxz next_square ; Nothing found in square--move ahead
|
||||||
|
|
||||||
|
wall_here: ; We found something!
|
||||||
|
mov [word ptr COLOR],cx ; Save the bitmap number
|
||||||
|
mov [_xMapPosn],eax ; Save the map position
|
||||||
|
mov [dword ptr _iLastX],esi ; Save the x,y position of the grid
|
||||||
|
mov [dword ptr _LastY1],edi ; border where the hit was found
|
||||||
|
test cx,DOOR_WALL ; Did we find a door?
|
||||||
|
jz short not_door ; No match--go process a wall slice
|
||||||
|
|
||||||
|
; At this point we’ve found a door, so we need to process it.
|
||||||
|
mov edx,edi ; Get y position
|
||||||
|
sar edx,16 ; Scale position
|
||||||
|
and edx,large 00000FFC0h
|
||||||
|
mov [dword ptr YD],edx ; YD = (yPos >> FP_SHIFT) & 0xFFC0;
|
||||||
|
; YD is the left side of door (grid corner)
|
||||||
|
add edx,large 64
|
||||||
|
mov [dword ptr XD],edx ; XD = YD + GRID_SIZE;
|
||||||
|
; XD is the right side of door (grid corner)
|
||||||
|
mov eax,[dword ptr _x_yNext] ; Get y increment
|
||||||
|
sar eax,1 ; Use half of inrement
|
||||||
|
add eax,edi ; Add 1/2 y increment to y position
|
||||||
|
; We need to calculate distance to door
|
||||||
|
mov [YTEMP],eax ; Store new y location
|
||||||
|
sar eax,16 ; We now have actual distance to door
|
||||||
|
cmp eax,[dword ptr YD] ; Is distance < YD?
|
||||||
|
jl short door_not_visible ; Process invisible door
|
||||||
|
cmp eax,[dword ptr XD] ; Is distance > XD?
|
||||||
|
jle short door_visible ; Process visible door
|
||||||
|
|
||||||
|
door_not_visible: ; Door is invisible so skip to next square
|
||||||
|
add esi,[dword ptr _x_xNext] ; Add x,y increment to current grid border
|
||||||
|
add edi,[dword ptr _x_yNext] ; position
|
||||||
|
jmp looptop ; Cast again to check next position
|
||||||
|
|
||||||
|
door_visible: ; Process a visible door
|
||||||
|
mov eax,[dword ptr YTEMP] ; Get y position of door
|
||||||
|
mov [dword ptr _LastY1],eax ; LastY1 = yTemp;
|
||||||
|
mov eax,[dword ptr _x_xNext] ; Adjust x,y position so that door
|
||||||
|
sar eax,1 ; is halfway in square
|
||||||
|
add [dword ptr _iLastX],eax ; iLastX += xNext >> 1;
|
||||||
|
|
||||||
|
not_door: ; We don’t think we have a door
|
||||||
|
test cx,DOOR_TYPE_SECRET ; Check bitmap type
|
||||||
|
jz short br_no_secret ; Not a secret door
|
||||||
|
cmp [word ptr _xSecretColumn],0
|
||||||
|
jne short secret_door ; We’ve found a secret door
|
||||||
|
|
||||||
|
br_no_secret:
|
||||||
|
jmp short give_color ; Move on and get the wall’s color
|
||||||
|
|
||||||
|
secret_door: ; Process a secret door
|
||||||
|
movzx eax,[word ptr _xSecretColumn] ; Get secret column location
|
||||||
|
movzx ebx,[word ptr _ViewAngle] ; Get ViewAngle to door
|
||||||
|
shl ebx,2
|
||||||
|
add ebx,[dword ptr _LongTanTable] ; Add in address of tan table
|
||||||
|
imul eax,[dword ptr ebx] ; Look up tangent of angle
|
||||||
|
mov [dword ptr SY],eax ; SY = xSecretColumn * tan(ViewAngle)
|
||||||
|
mov ebx,edi ; Get x_yPos
|
||||||
|
add eax,ebx ; SY + x_yPos
|
||||||
|
mov [dword ptr YTEMP],eax ; Store distance to door
|
||||||
|
sar eax,16 ; eax = (x_yPos + SY) >> FP_SHIFT
|
||||||
|
; This gives us actual distance to door
|
||||||
|
sar ebx,16 ; Now calculate the left side
|
||||||
|
and ebx,large 00000FFC0h
|
||||||
|
mov [dword ptr YD],ebx ; YD = x_yPos >> FP_SHIFT & GRID_MASK
|
||||||
|
mov ecx,ebx ; Calculate the right side (XD)
|
||||||
|
add ecx,large 64 ; XD = YD = BITMAP_WIDTH
|
||||||
|
cmp eax,ebx ; Is distance < YD?
|
||||||
|
jl short next_square
|
||||||
|
cmp eax,ecx ; Is distance <= XD?
|
||||||
|
jle short secret_is_visible
|
||||||
|
|
||||||
|
secret_not_visible: ; Process invisible secret door
|
||||||
|
jmp short next_square
|
||||||
|
|
||||||
|
secret_is_visible: ; Process visible secret door
|
||||||
|
mov eax,[dword ptr YTEMP]
|
||||||
|
mov [dword ptr _LastY1],eax
|
||||||
|
mov eax,[dword ptr _xSecretColumn]
|
||||||
|
add [dword ptr _iLastX],eax
|
||||||
|
jmp short give_color
|
||||||
|
|
||||||
|
next_square: ; Didin’t find anything--go to next square
|
||||||
|
add esi,[dword ptr _x_xNext] ; Add x,y increment to current grid border
|
||||||
|
add edi,[dword ptr _x_yNext] ; position
|
||||||
|
jmp looptop ; Start over again
|
||||||
|
|
||||||
|
loopdone:
|
||||||
|
mov [word ptr COLOR],0 ; Use bitmap value of 0 to indicate
|
||||||
|
; nothing has been found
|
||||||
|
give_color:
|
||||||
|
movzx eax,[word ptr COLOR] ; Get color of wall
|
||||||
|
|
||||||
|
xRayDone:
|
||||||
|
pop edx ; Restore registers
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC yRaySetup
|
||||||
|
push esi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov dx,[word _ViewAngle]
|
||||||
|
movzx esi,dx
|
||||||
|
shl esi,2 ; // Hold onto viewangle * 4
|
||||||
|
mov ebx,[dword ptr _xNextTable]
|
||||||
|
mov eax,[esi+ebx]
|
||||||
|
mov [dword ptr _y_xNext],eax
|
||||||
|
cmp dx,INT_ANGLE_180
|
||||||
|
jge short y_not_inbetween
|
||||||
|
|
||||||
|
y_inbetween:
|
||||||
|
mov ecx,[_yBegGlobal]
|
||||||
|
add ecx,64
|
||||||
|
mov [dword ptr _y_yPos],ecx
|
||||||
|
mov [dword ptr _y_yNext],large 64
|
||||||
|
jmp short y_yr_cont
|
||||||
|
|
||||||
|
y_not_inbetween:
|
||||||
|
mov ecx,[_yBegGlobal]
|
||||||
|
mov [_y_yPos],ecx
|
||||||
|
mov [dword ptr _y_yNext],large -64
|
||||||
|
neg [dword ptr _y_xNext]
|
||||||
|
|
||||||
|
y_yr_cont:
|
||||||
|
mov eax,[_yPglobal]
|
||||||
|
sub ecx,eax
|
||||||
|
mov ebx,[dword ptr _LongInvTanTable]
|
||||||
|
imul ecx,[dword ptr esi+ebx]
|
||||||
|
add ecx,[dword ptr _xPglobalHI]
|
||||||
|
mov [dword ptr _y_xPos],ecx
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC yRayCast
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
mov esi,[dword ptr _y_xPos]
|
||||||
|
mov edi,[dword ptr _y_yPos]
|
||||||
|
xor ecx,ecx
|
||||||
|
|
||||||
|
y_looptop:
|
||||||
|
;-; mov edx,[dword ptr _y_xPos]
|
||||||
|
mov edx,esi
|
||||||
|
cmp edx,large 0
|
||||||
|
jl short y_getout
|
||||||
|
cmp edx,large 010000000h
|
||||||
|
jge short y_getout
|
||||||
|
;-; mov eax,[_y_yPos]
|
||||||
|
mov eax,edi
|
||||||
|
cmp eax,large 0
|
||||||
|
jl short y_getout
|
||||||
|
cmp eax,large 4096
|
||||||
|
jl short y_inbounds
|
||||||
|
|
||||||
|
y_getout:
|
||||||
|
jmp loopdone
|
||||||
|
|
||||||
|
y_inbounds:
|
||||||
|
sar edx,22
|
||||||
|
and eax,-64
|
||||||
|
add eax,edx
|
||||||
|
cmp eax,4095
|
||||||
|
ja y_getout
|
||||||
|
|
||||||
|
mov [byte ptr _HitMap+eax],1
|
||||||
|
|
||||||
|
mov ebx,[dword ptr _yGridGlobal]
|
||||||
|
mov cx,[ebx+eax*2]
|
||||||
|
;-; test cx,cx
|
||||||
|
;-; jnz short y_wall_here
|
||||||
|
;-; jmp y_next_square
|
||||||
|
jcxz y_next_square
|
||||||
|
|
||||||
|
y_wall_here:
|
||||||
|
mov [word ptr COLOR],cx
|
||||||
|
mov [_yMapPosn],eax
|
||||||
|
|
||||||
|
;-; mov ebx,[dword ptr _y_xPos]
|
||||||
|
mov ebx,esi
|
||||||
|
mov [dword ptr _LastX1],ebx
|
||||||
|
;-; mov edx,[dword ptr _y_yPos]
|
||||||
|
mov edx,edi
|
||||||
|
mov [dword ptr _iLastY],edx
|
||||||
|
mov edx,ebx
|
||||||
|
|
||||||
|
test cx,DOOR_WALL
|
||||||
|
jz short y_not_door
|
||||||
|
|
||||||
|
sar ebx,16
|
||||||
|
and ebx,large 00000FFC0h
|
||||||
|
mov [dword ptr YD],ebx
|
||||||
|
|
||||||
|
add ebx,large 64
|
||||||
|
mov [dword ptr XD],ebx
|
||||||
|
|
||||||
|
mov eax,[dword ptr _y_xNext]
|
||||||
|
sar eax,1
|
||||||
|
add edx,eax
|
||||||
|
mov [dword ptr YTEMP],edx
|
||||||
|
sar edx,16
|
||||||
|
|
||||||
|
cmp edx,[dword ptr YD]
|
||||||
|
jl short y_door_not_visible
|
||||||
|
cmp edx,[dword ptr XD]
|
||||||
|
jle short y_door_visible
|
||||||
|
|
||||||
|
y_door_not_visible:
|
||||||
|
;-; mov eax,[dword ptr _y_xNext]
|
||||||
|
;-; add [dword ptr _y_xPos],eax
|
||||||
|
;-; mov eax,[dword ptr _y_yNext]
|
||||||
|
;-; add [dword ptr _y_yPos],eax
|
||||||
|
add esi,[dword ptr _y_xNext]
|
||||||
|
add edi,[dword ptr _y_yNext]
|
||||||
|
jmp y_looptop
|
||||||
|
|
||||||
|
y_door_visible:
|
||||||
|
mov eax,[dword ptr YTEMP]
|
||||||
|
mov [dword ptr _LastX1],eax
|
||||||
|
mov eax,[dword ptr _y_yNext]
|
||||||
|
sar eax,1
|
||||||
|
add [dword ptr _iLastY],eax
|
||||||
|
|
||||||
|
y_not_door:
|
||||||
|
test cx,DOOR_TYPE_SECRET
|
||||||
|
jz short y_br_no_secret
|
||||||
|
cmp [word ptr _ySecretColumn],0
|
||||||
|
jne short y_secret_door
|
||||||
|
|
||||||
|
y_br_no_secret:
|
||||||
|
jmp y_give_color
|
||||||
|
|
||||||
|
y_secret_door:
|
||||||
|
movzx eax,[word ptr _ySecretColumn]
|
||||||
|
movzx edx,[word ptr _ViewAngle]
|
||||||
|
mov ebx,[dword ptr _LongInvTanTable]
|
||||||
|
imul eax,[dword ptr ebx+edx*4]
|
||||||
|
mov [dword ptr SX],eax
|
||||||
|
;-; mov ebx,[dword ptr _y_xPos]
|
||||||
|
mov ebx,esi
|
||||||
|
add eax,ebx
|
||||||
|
mov [dword ptr YTEMP],eax
|
||||||
|
sar eax,16
|
||||||
|
sar ebx,16
|
||||||
|
and ebx,large 00000FFC0h
|
||||||
|
mov ecx,ebx
|
||||||
|
add ecx,large 64
|
||||||
|
|
||||||
|
cmp eax,ebx
|
||||||
|
jl short y_secret_not_visible
|
||||||
|
cmp eax,ecx
|
||||||
|
jle short y_secret_is_visible
|
||||||
|
|
||||||
|
y_secret_not_visible:
|
||||||
|
jmp y_door_not_visible
|
||||||
|
|
||||||
|
y_secret_is_visible:
|
||||||
|
mov eax,[dword ptr YTEMP]
|
||||||
|
mov [dword ptr _LastX1],eax
|
||||||
|
mov eax,[dword ptr _ySecretColumn]
|
||||||
|
add [dword ptr _iLastY],eax
|
||||||
|
jmp short y_give_color
|
||||||
|
|
||||||
|
y_next_square:
|
||||||
|
;-; mov eax,[dword ptr _y_xNext]
|
||||||
|
;-; add [dword ptr _y_xPos],eax
|
||||||
|
;-; mov eax,[dword ptr _y_yNext]
|
||||||
|
;-; add [dword ptr _y_yPos],eax
|
||||||
|
add esi,[dword ptr _y_xNext]
|
||||||
|
add edi,[dword ptr _y_yNext]
|
||||||
|
jmp y_looptop
|
||||||
|
|
||||||
|
y_loopdone:
|
||||||
|
mov [word ptr COLOR],0
|
||||||
|
|
||||||
|
y_give_color:
|
||||||
|
movzx eax,[word ptr COLOR]
|
||||||
|
|
||||||
|
yRayDone:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
130
ack_lib/ACKRTN.INC
Normal file
130
ack_lib/ACKRTN.INC
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
_BORLANDC_ = 1
|
||||||
|
|
||||||
|
MACRO ACKPROC L
|
||||||
|
IFDEF _BORLANDC_
|
||||||
|
PROC _&L NEAR
|
||||||
|
ENDIF
|
||||||
|
IFDEF _WATCOMC_
|
||||||
|
PROC &L_ NEAR
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
MACRO ACKEXT L
|
||||||
|
IFDEF _BORLANDC_
|
||||||
|
extrn _&L:NEAR
|
||||||
|
ENDIF
|
||||||
|
IFDEF _WATCOMC_
|
||||||
|
extrn &L_:NEAR
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
|
||||||
|
MACRO ACKPUBS LAB
|
||||||
|
IFDEF _BORLANDC_
|
||||||
|
public _&LAB
|
||||||
|
ENDIF
|
||||||
|
IFDEF _WATCOMC_
|
||||||
|
public &LAB_
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
MACRO ACKCALL LAB
|
||||||
|
IFDEF _BORLANDC_
|
||||||
|
call _&LAB
|
||||||
|
ENDIF
|
||||||
|
IFDEF _WATCOMC_
|
||||||
|
call &LAB_
|
||||||
|
ENDIF
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
IFDEF _BORLANDC_
|
||||||
|
VIDSEG equ 0a0000000h
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IFDEF _WATCOMC_
|
||||||
|
VIDSEG equ 0a0000h
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
;; Equates for SLICE struct
|
||||||
|
sabMap equ 0
|
||||||
|
samPtr equ 4
|
||||||
|
sabNumber equ 8
|
||||||
|
sabColumn equ 10
|
||||||
|
saDist equ 12
|
||||||
|
samPos equ 14
|
||||||
|
saType equ 16
|
||||||
|
saFnc equ 17
|
||||||
|
saActive equ 21
|
||||||
|
saPrev equ 22
|
||||||
|
saNext equ 26
|
||||||
|
saSize equ 30 ;size of SLICE structure
|
||||||
|
|
||||||
|
; Equates for upper byte of walls
|
||||||
|
WALL_TYPE_UPPER equ 0200h
|
||||||
|
WALL_TYPE_MULTI equ 0400h
|
||||||
|
WALL_UPPER_MULTI equ 0600h
|
||||||
|
WALL_TYPE_TRANS equ 0800h
|
||||||
|
DOOR_TYPE_SECRET equ 8000h
|
||||||
|
DOOR_LOCKED equ 4000h
|
||||||
|
DOOR_TYPE_SLIDE equ 2000h
|
||||||
|
DOOR_TYPE_SPLIT equ 1000h
|
||||||
|
DOOR_WALL equ 3000h
|
||||||
|
|
||||||
|
; Equates for LightFlag
|
||||||
|
SHADING_OFF equ 0
|
||||||
|
SHADING_ON equ 1
|
||||||
|
|
||||||
|
|
||||||
|
ST_WALL equ 1
|
||||||
|
ST_OBJECT equ 2
|
||||||
|
|
||||||
|
DOOR_XCODE equ 60
|
||||||
|
DOOR_YCODE equ 62
|
||||||
|
|
||||||
|
RES_LOW equ 1
|
||||||
|
|
||||||
|
;; Equates for SCOL struct
|
||||||
|
Vid equ 0
|
||||||
|
Wall equ 4
|
||||||
|
Pal equ 8
|
||||||
|
dst equ 12
|
||||||
|
wht equ 14
|
||||||
|
multi equ 16
|
||||||
|
topht equ 18
|
||||||
|
botht equ 20
|
||||||
|
savwht equ 22
|
||||||
|
mulcnt equ 24
|
||||||
|
savVid equ 26
|
||||||
|
bNum equ 30
|
||||||
|
scLen equ 32 ; length of structure
|
||||||
|
|
||||||
|
; Equates for SysFlag
|
||||||
|
SYS_SOLID_BACK equ 8000h ; On if solid color bkgd vs picture
|
||||||
|
SYS_SOLID_FLOOR equ 4000h ; On if solid vs texture floor
|
||||||
|
SYS_SOLID_CEIL equ 2000h ; On if solid vs texture ceiling
|
||||||
|
SYS_NO_WALLS equ 1000h ; On if walls are NOT to display
|
||||||
|
|
||||||
|
Color equ ebp-4
|
||||||
|
retval equ ebp-6
|
||||||
|
MapPosn equ ebp-8
|
||||||
|
xBeg equ ebp-10
|
||||||
|
;xPos equ ebp-14
|
||||||
|
;xNext equ ebp-18
|
||||||
|
;yPos equ ebp-22
|
||||||
|
;yNext equ ebp-26
|
||||||
|
xd equ ebp-30
|
||||||
|
yd equ ebp-34
|
||||||
|
yTemp equ ebp-38
|
||||||
|
sy equ ebp-42
|
||||||
|
sx equ ebp-46
|
||||||
|
|
||||||
|
INT_ANGLE_32 equ 160
|
||||||
|
INT_ANGLE_90 equ 450
|
||||||
|
INT_ANGLE_135 equ 675
|
||||||
|
INT_ANGLE_180 equ 900
|
||||||
|
INT_ANGLE_225 equ 1125
|
||||||
|
INT_ANGLE_270 equ 1350
|
||||||
|
INT_ANGLE_360 equ 1800
|
||||||
|
|
||||||
|
|
571
ack_lib/ACKRTN1.ASM
Normal file
571
ack_lib/ACKRTN1.ASM
Normal file
|
@ -0,0 +1,571 @@
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT
|
||||||
|
|
||||||
|
.DATA
|
||||||
|
|
||||||
|
SVTABLE dd ?
|
||||||
|
ENDPOS dd ?
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
|
||||||
|
include "ackrtn.inc"
|
||||||
|
|
||||||
|
extrn _VidSeg:dword
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _bmDistance:dword
|
||||||
|
extrn _bmWall:dword
|
||||||
|
extrn _scPtr:dword
|
||||||
|
extrn _VidTop:dword
|
||||||
|
extrn _VidBottom:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
|
||||||
|
extrn _gPalTable:dword
|
||||||
|
extrn _gWinStartX:word
|
||||||
|
extrn _gWinStartY:word
|
||||||
|
extrn _gWinEndX:word
|
||||||
|
extrn _gWinEndY:word
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _ViewHeight:word
|
||||||
|
extrn _SysFlags:word
|
||||||
|
extrn _Slice:byte
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
extrn _Floorht:word
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _gWinStartOffset:dword
|
||||||
|
|
||||||
|
extrn _scVid:dword
|
||||||
|
extrn _scWall:dword
|
||||||
|
extrn _scPal:dword
|
||||||
|
extrn _scdst:word
|
||||||
|
extrn _scwht:word
|
||||||
|
extrn _scmulti:word
|
||||||
|
extrn _sctopht:word
|
||||||
|
extrn _scbotht:word
|
||||||
|
extrn _scsavwht:word
|
||||||
|
extrn _scmulcnt:word
|
||||||
|
extrn _scsavVid:dword
|
||||||
|
extrn _scbNum:word
|
||||||
|
extrn _scMulData:dword
|
||||||
|
extrn _scColumn:dword
|
||||||
|
extrn _WallbMaps:dword
|
||||||
|
extrn _LowerTable:dword
|
||||||
|
extrn _gBottomOff:dword
|
||||||
|
|
||||||
|
ACKEXT ShowColLow
|
||||||
|
ACKEXT ShowColMaskLow
|
||||||
|
|
||||||
|
ACKPUBS ShowCol
|
||||||
|
ACKPUBS ShowColMask
|
||||||
|
ACKPUBS DrawWalls
|
||||||
|
|
||||||
|
|
||||||
|
align 2
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowCol
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
|
||||||
|
mov edi,[_scVid] ;Video buffer position
|
||||||
|
mov ebp,[_scPal] ;Pointer to palette for shading
|
||||||
|
|
||||||
|
mov ax,[_scwht] ;Height to use
|
||||||
|
mov [_scsavwht],ax ;save for later
|
||||||
|
|
||||||
|
movzx ecx,[_sctopht]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,ecx
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ch,al
|
||||||
|
inc ch
|
||||||
|
|
||||||
|
mov esi,[_bmDistance]
|
||||||
|
mov esi,[_LowerTable+esi*4]
|
||||||
|
mov [SVTABLE],esi
|
||||||
|
|
||||||
|
mov eax,0
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
test [word ptr _scbNum],WALL_TYPE_UPPER
|
||||||
|
jz short toprun
|
||||||
|
mov edx,[_bmDistance]
|
||||||
|
|
||||||
|
zztoploop:
|
||||||
|
dec ch
|
||||||
|
jz short zzdomulti
|
||||||
|
sub di,320
|
||||||
|
add bx,dx
|
||||||
|
cmp bh,cl
|
||||||
|
jge short zzdomulti
|
||||||
|
jmp zztoploop
|
||||||
|
|
||||||
|
zzdomulti:
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
jmp chkmulti
|
||||||
|
|
||||||
|
toprun:
|
||||||
|
mov ebx,[_bmWall]
|
||||||
|
|
||||||
|
toploop:
|
||||||
|
movzx edx,[word ptr esi]
|
||||||
|
cmp dl,cl
|
||||||
|
jg short botrun
|
||||||
|
lea esi,[esi+2]
|
||||||
|
neg edx
|
||||||
|
mov al,[ebx+edx]
|
||||||
|
mov al,[ebp+eax]
|
||||||
|
mov [edi],al
|
||||||
|
add edi,-320
|
||||||
|
dec ch
|
||||||
|
jnz toploop
|
||||||
|
|
||||||
|
botrun:
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_scbotht]
|
||||||
|
mov dx,[_scsavwht]
|
||||||
|
mov ch,dl
|
||||||
|
mov esi,[SVTABLE]
|
||||||
|
inc ebx
|
||||||
|
dec cl
|
||||||
|
|
||||||
|
botloop:
|
||||||
|
lea edi,[edi+320]
|
||||||
|
movzx edx,[word ptr esi]
|
||||||
|
cmp dl,cl
|
||||||
|
jge short chkmulti
|
||||||
|
lea esi,[esi+2]
|
||||||
|
mov al,[ebx+edx]
|
||||||
|
mov al,[ebp+eax]
|
||||||
|
mov [edi],al
|
||||||
|
dec ch
|
||||||
|
jnz botloop
|
||||||
|
|
||||||
|
chkmulti:
|
||||||
|
mov edi,[_scsavVid]
|
||||||
|
cmp [word ptr _scmulti],0
|
||||||
|
jz alldone
|
||||||
|
mov cx,[_scmulcnt]
|
||||||
|
|
||||||
|
mov ebx,[_scMulData] ;ptr to count and wall data
|
||||||
|
mov cl,[ebx] ;get number of walls to draw
|
||||||
|
inc ebx
|
||||||
|
mov al,[ebx] ;first wall to show
|
||||||
|
inc ebx
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
movzx ebx,al ;get wall number
|
||||||
|
mov esi,[_scColumn] ;Current bitmap column to display x 64
|
||||||
|
lea esi,[esi+63]
|
||||||
|
mov [_scColumn],esi ;save for later use
|
||||||
|
mov eax,[_WallbMaps] ;Get array of bitmaps
|
||||||
|
mov ebx,[eax+ebx*4] ;Get the bitmap we are using
|
||||||
|
add ebx,esi ;point to bottom of column
|
||||||
|
|
||||||
|
mov ax,[_scwht] ;Get height of window
|
||||||
|
mov ch,ah
|
||||||
|
cmp ch,0 ;Is there more room to draw?
|
||||||
|
jz short alldone ;br if at top of window
|
||||||
|
|
||||||
|
mov esi,[SVTABLE]
|
||||||
|
mov eax,0
|
||||||
|
|
||||||
|
mulloop:
|
||||||
|
movzx eax,[word ptr esi] ;Get height displacement for this row
|
||||||
|
cmp al,64 ;Did we do the entire column?
|
||||||
|
jge short nextlevel ;Yes, see if more walls
|
||||||
|
lea esi,[esi+2]
|
||||||
|
neg eax ;Invert so we can add it below
|
||||||
|
movzx eax,[byte ptr ebx+eax] ;Get the pixel from the bitmap
|
||||||
|
mov al,[ebp+eax] ;Map it to the palette for shading
|
||||||
|
mov [edi],al ;Place it into the video buffer
|
||||||
|
dec ch ;Bump the window height
|
||||||
|
jz short alldone ;br if at the top of the window
|
||||||
|
sub edi,320 ;next video row
|
||||||
|
jmp mulloop
|
||||||
|
|
||||||
|
nextlevel:
|
||||||
|
dec cl ;Bump wall count
|
||||||
|
jz short alldone ;br if no more walls
|
||||||
|
mov ebx,[_scMulData] ;Get pointer to the multi-ht data
|
||||||
|
movzx eax,[byte ptr ebx] ;next wall number
|
||||||
|
inc ebx ;Advance for next wall
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
mov ebx,[_WallbMaps] ;Get wall array
|
||||||
|
mov ebx,[ebx+eax*4] ;Get wall bitmap to use
|
||||||
|
add ebx,[dword ptr _scColumn] ;add in current column
|
||||||
|
mov eax,0
|
||||||
|
mov esi,[SVTABLE]
|
||||||
|
jmp mulloop
|
||||||
|
|
||||||
|
alldone:
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
align 2
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowColMask
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov ebp,eax
|
||||||
|
mov [_scPtr],eax
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov edx,[_scPal]
|
||||||
|
mov ax,[_scwht]
|
||||||
|
mov [_scsavwht],ax
|
||||||
|
movzx ecx,[_sctopht]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,ecx
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ch,al
|
||||||
|
inc ch
|
||||||
|
mov eax,0
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
test [word ptr _scbNum],WALL_TYPE_UPPER
|
||||||
|
jz short m_toprun
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
m_zztoploop:
|
||||||
|
dec ch
|
||||||
|
jz short m_zzdomulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jge short m_zzdomulti
|
||||||
|
sub edi,320
|
||||||
|
jmp m_zztoploop
|
||||||
|
|
||||||
|
m_zzdomulti:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
jmp m_chkmulti
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
m_toprun:
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
|
||||||
|
m_toploop:
|
||||||
|
movzx eax,bh
|
||||||
|
neg eax
|
||||||
|
movzx eax,[byte ptr esi+eax]
|
||||||
|
or al,al
|
||||||
|
jz short m_blank1
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov [edi],al
|
||||||
|
|
||||||
|
m_blank1:
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jg short m_botrun
|
||||||
|
dec ch
|
||||||
|
jz short m_botrun
|
||||||
|
sub edi,320
|
||||||
|
jmp m_toploop
|
||||||
|
|
||||||
|
m_botrun:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_scbotht]
|
||||||
|
mov bx,[_scsavwht]
|
||||||
|
mov ch,bl
|
||||||
|
mov ebx,0
|
||||||
|
inc esi
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov eax,0
|
||||||
|
dec cl
|
||||||
|
|
||||||
|
m_botloop:
|
||||||
|
add edi,320
|
||||||
|
mov al,bh
|
||||||
|
mov al,[esi+eax]
|
||||||
|
or al,al
|
||||||
|
jz short m_blank2
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov [edi],al
|
||||||
|
|
||||||
|
m_blank2:
|
||||||
|
dec ch
|
||||||
|
jz short m_chkmulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jl m_botloop
|
||||||
|
|
||||||
|
m_chkmulti:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
cmp [word ptr _scmulti],0
|
||||||
|
jz short m_alldone
|
||||||
|
mov cx,[_scmulcnt]
|
||||||
|
mov bx,[_scwht]
|
||||||
|
mov ch,bh
|
||||||
|
cmp ch,0
|
||||||
|
jz short m_alldone
|
||||||
|
|
||||||
|
mov edi,[_scsavVid]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,63
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ebx,0
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
|
||||||
|
m_mulloop:
|
||||||
|
sub edi,320
|
||||||
|
movzx eax,bh
|
||||||
|
neg eax
|
||||||
|
movzx eax,[byte ptr esi+eax]
|
||||||
|
or al,al
|
||||||
|
jz m_blank3
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov [edi],al
|
||||||
|
|
||||||
|
m_blank3:
|
||||||
|
dec ch
|
||||||
|
jz short m_alldone
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,64
|
||||||
|
jge short m_nextlevel
|
||||||
|
jmp m_mulloop
|
||||||
|
|
||||||
|
m_nextlevel:
|
||||||
|
mov ebx,0
|
||||||
|
dec cl
|
||||||
|
jnz m_mulloop
|
||||||
|
|
||||||
|
m_alldone:
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; This routine runs through the list of slices and draws the walls.
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawWalls
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
|
||||||
|
mov ax,[_gWinHeight]
|
||||||
|
shr ax,1
|
||||||
|
mov [_Floorht],ax
|
||||||
|
mov ax,[_ViewHeight]
|
||||||
|
mov [_sctopht],ax
|
||||||
|
mov dx,64
|
||||||
|
sub dx,ax
|
||||||
|
mov [_scbotht],dx
|
||||||
|
movsx ebx,[word ptr _gWinStartX]
|
||||||
|
movsx ecx,[_gCenterOff]
|
||||||
|
add ecx,ebx
|
||||||
|
add ecx,[_gScrnBuffer]
|
||||||
|
mov [_scVid],ecx
|
||||||
|
cmp [word ptr _Resolution],1 ;is this low resolution?
|
||||||
|
je stw_lowres ;yes, perform faster draw
|
||||||
|
|
||||||
|
movzx eax,[_gWinEndX]
|
||||||
|
imul eax,saSize
|
||||||
|
mov [ENDPOS],eax
|
||||||
|
imul ebx,saSize
|
||||||
|
|
||||||
|
stw010:
|
||||||
|
mov ebp,offset _Slice ; offset to slices array
|
||||||
|
add ebp,ebx
|
||||||
|
|
||||||
|
stw020:
|
||||||
|
cmp [byte ptr ebp+saActive],0 ;is this an active slice?
|
||||||
|
jz short stw030 ;nope, so it's the last one
|
||||||
|
cmp [dword ptr ebp+saNext],0 ;is this the last slice?
|
||||||
|
jz short stw030 ;yes, so can't go further
|
||||||
|
mov ebp,[dword ptr ebp+saNext] ;point to next slice
|
||||||
|
jmp short stw020
|
||||||
|
|
||||||
|
stw030:
|
||||||
|
mov ax,[word ptr ebp+sabNumber] ;bitmap number
|
||||||
|
mov cx,ax
|
||||||
|
and cx,0ffh ;isolate number from flags
|
||||||
|
mov [_scmulcnt],cx ;save as current multi count
|
||||||
|
mov [_scbNum],ax ;and bitmap number and flags
|
||||||
|
|
||||||
|
mov cx,0 ;set multi-flag to none
|
||||||
|
test ax,WALL_TYPE_MULTI
|
||||||
|
jz short stw040
|
||||||
|
mov esi,[dword ptr ebp+samPtr]
|
||||||
|
mov [_scMulData],esi
|
||||||
|
or esi,esi ;is there multi-ht data?
|
||||||
|
jz short stw040 ;br if not
|
||||||
|
mov cx,1 ;set multi-flag to yes
|
||||||
|
|
||||||
|
stw040:
|
||||||
|
mov [_scmulti],cx
|
||||||
|
mov ecx,[dword ptr ebp+sabMap] ;get pointer to bitmaps
|
||||||
|
movzx esi,al ;get low byte of bitmap number
|
||||||
|
shl esi,2
|
||||||
|
|
||||||
|
mov esi,[dword ptr ecx+esi] ;get actual bitmap pointer
|
||||||
|
movsx ecx,[word ptr ebp+saDist] ;distance to slice
|
||||||
|
mov [_bmDistance],ecx ;save for draw routine
|
||||||
|
shr ecx,6 ;bring it down into palette range
|
||||||
|
cmp ecx,15 ;check against max palette number
|
||||||
|
jbe short stw050
|
||||||
|
mov ecx,15 ;force to max if above
|
||||||
|
|
||||||
|
stw050:
|
||||||
|
shl ecx,8 ;x256 for palette entry
|
||||||
|
mov edi,[_gPalTable] ;pointer to palette table
|
||||||
|
add edi,ecx
|
||||||
|
movsx ecx,[word ptr ebp+sabColumn] ;column of bitmap slice
|
||||||
|
shl ecx,6 ;x64 to get correct row (column)
|
||||||
|
add esi,ecx ;adjust wall point to correct column
|
||||||
|
mov [_scColumn],ecx ;save for multi-ht walls
|
||||||
|
|
||||||
|
mov [_scWall],esi
|
||||||
|
mov [_scPal],edi
|
||||||
|
mov eax,0
|
||||||
|
mov [_scsavVid],eax ;null out saved video
|
||||||
|
|
||||||
|
mov ax,[_Floorht] ;window height / 2 saved earlier
|
||||||
|
mov [_scwht],ax
|
||||||
|
|
||||||
|
mov esi,ebx
|
||||||
|
call [dword ptr ebp+saFnc]
|
||||||
|
mov ebx,esi
|
||||||
|
|
||||||
|
stw075:
|
||||||
|
cmp [dword ptr ebp+saPrev],0 ;is this the first slice?
|
||||||
|
jz short stw080 ;yes, go to next column
|
||||||
|
mov ebp,[dword ptr ebp+saPrev] ;pick up previous slice
|
||||||
|
jmp stw030 ;and start again with same column
|
||||||
|
|
||||||
|
|
||||||
|
stw080:
|
||||||
|
inc [dword ptr _scVid] ;next video position
|
||||||
|
add ebx,saSize
|
||||||
|
cmp ebx,[ENDPOS]
|
||||||
|
ja stw_getout ;yes, get out
|
||||||
|
jmp stw010
|
||||||
|
|
||||||
|
stw_lowres:
|
||||||
|
mov eax,ebx ; current column of display
|
||||||
|
imul eax,saSize ; size of slice structure
|
||||||
|
mov ebp,offset _Slice ; offset to slices
|
||||||
|
add ebp,eax
|
||||||
|
|
||||||
|
stwlr020:
|
||||||
|
cmp [byte ptr ebp+saActive],0 ;is this an active slice?
|
||||||
|
jz short stwlr030 ;nope, so it's the last one
|
||||||
|
cmp [dword ptr ebp+saNext],0 ;is this the last slice?
|
||||||
|
jz short stwlr030 ;yes, so can't go further
|
||||||
|
mov ebp,[dword ptr ebp+saNext] ;point to next slice
|
||||||
|
jmp short stwlr020
|
||||||
|
|
||||||
|
stwlr030:
|
||||||
|
mov ax,[word ptr ebp+sabNumber] ;bitmap number
|
||||||
|
mov cx,ax
|
||||||
|
and cx,0ffh ;isolate number from flags
|
||||||
|
mov [_scmulcnt],cx ;save as current multi count
|
||||||
|
mov [_scbNum],ax ;and bitmap number and flags
|
||||||
|
|
||||||
|
mov cx,0 ;set multi-flag to none
|
||||||
|
test ax,WALL_TYPE_MULTI
|
||||||
|
jz short stwlr040
|
||||||
|
|
||||||
|
mov esi,[dword ptr ebp+samPtr]
|
||||||
|
mov [_scMulData],esi
|
||||||
|
or esi,esi ;is there multi-height data?
|
||||||
|
jz short stwlr040 ;br if not
|
||||||
|
mov cx,1 ;set multi-flag to yes
|
||||||
|
|
||||||
|
stwlr040:
|
||||||
|
mov [_scmulti],cx
|
||||||
|
mov ecx,[dword ptr ebp+sabMap] ;get pointer to bitmaps
|
||||||
|
movzx esi,al ;get low byte of bitmap number
|
||||||
|
shl esi,2
|
||||||
|
mov esi,[dword ptr ecx+esi] ;get actual bitmap pointer
|
||||||
|
movsx ecx,[word ptr ebp+saDist] ;distance to slice
|
||||||
|
mov [_bmDistance],ecx ;save for draw routine
|
||||||
|
shr ecx,6 ;bring it down into palette range
|
||||||
|
cmp ecx,15 ;check against max palette number
|
||||||
|
jbe short stwlr050
|
||||||
|
mov ecx,15 ;force to max if above
|
||||||
|
|
||||||
|
stwlr050:
|
||||||
|
shl ecx,8 ;x256 for palette entry
|
||||||
|
mov edi,[_gPalTable] ;pointer to palette table
|
||||||
|
add edi,ecx
|
||||||
|
movsx ecx,[byte ptr ebp+sabColumn] ;column of bitmap slice
|
||||||
|
shl ecx,6 ;x64 to get correct row (column)
|
||||||
|
add esi,ecx ;adjust wall point to correct column
|
||||||
|
mov [_scColumn],ecx ;save for multi-ht walls
|
||||||
|
|
||||||
|
mov [_scWall],esi
|
||||||
|
mov [_scPal],edi
|
||||||
|
mov eax,0
|
||||||
|
mov [_scsavVid],eax ;null out saved video
|
||||||
|
|
||||||
|
mov ax,[_Floorht] ;window height / 2 saved earlier
|
||||||
|
mov [_scwht],ax
|
||||||
|
|
||||||
|
mov esi,ebx
|
||||||
|
cmp [byte ptr ebp+saType],ST_WALL ;transparent wall?
|
||||||
|
je short stwlr060 ;nope, use solid slice routine
|
||||||
|
ACKCALL ShowColMaskLow
|
||||||
|
jmp short stwlr070
|
||||||
|
|
||||||
|
stwlr060:
|
||||||
|
ACKCALL ShowColLow
|
||||||
|
|
||||||
|
stwlr070:
|
||||||
|
mov ebx,esi
|
||||||
|
cmp [dword ptr ebp+saPrev],0 ;is this the first slice?
|
||||||
|
jz short stwlr080 ;yes, go to next column
|
||||||
|
mov ebp,[dword ptr ebp+saPrev] ;pick up previous slice
|
||||||
|
jmp stwlr030 ;and start again with same column
|
||||||
|
|
||||||
|
|
||||||
|
stwlr080:
|
||||||
|
add [dword ptr _scVid],2 ;next video position
|
||||||
|
inc ebx ;next column
|
||||||
|
inc ebx ;next column
|
||||||
|
cmp bx,[word ptr _gWinEndX] ;are we at the end of the window?
|
||||||
|
ja short stw_getout ;yes, get out
|
||||||
|
jmp stw_lowres
|
||||||
|
|
||||||
|
stw_getout:
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
805
ack_lib/ACKRTN2.ASM
Normal file
805
ack_lib/ACKRTN2.ASM
Normal file
|
@ -0,0 +1,805 @@
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387 ; Allow 386 processor
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT ;32-bit OS/2 model
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
include "ackrtn.inc"
|
||||||
|
MASM
|
||||||
|
|
||||||
|
extrn _WallDistTable:dword
|
||||||
|
extrn _FloorMap:word
|
||||||
|
extrn _CeilMap:word
|
||||||
|
extrn _LastWallHeight:word
|
||||||
|
extrn _ViewAngle:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _xPglobal:dword
|
||||||
|
extrn _yPglobal:dword
|
||||||
|
extrn _xBegGlobal:dword
|
||||||
|
extrn _yBegGlobal:dword
|
||||||
|
extrn _aeGlobal:dword
|
||||||
|
extrn _xGridGlobal:dword
|
||||||
|
extrn _yGridGlobal:dword
|
||||||
|
extrn _xPglobalHI:dword
|
||||||
|
extrn _yPglobalHI:dword
|
||||||
|
extrn _rbaTable:dword
|
||||||
|
extrn _rsHandle:word
|
||||||
|
extrn _LastX1:dword
|
||||||
|
extrn _LastY1:dword
|
||||||
|
extrn _iLastX:dword
|
||||||
|
extrn _iLastY;dword
|
||||||
|
extrn _MaxDistance:word
|
||||||
|
extrn _BackArray:dword
|
||||||
|
extrn _zdTable:dword
|
||||||
|
extrn _ErrorCode:word
|
||||||
|
extrn _xMapPosn:dword
|
||||||
|
extrn _yMapPosn:dword
|
||||||
|
extrn _Grid:dword
|
||||||
|
extrn _ObjGrid:dword
|
||||||
|
extrn _WallbMaps:dword
|
||||||
|
extrn _ViewHeight:word
|
||||||
|
extrn _CeilingHeight:word
|
||||||
|
extrn _gTopColor:byte
|
||||||
|
extrn _gBottomColor:byte
|
||||||
|
extrn _PlayerAngle:word
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gBkgdBuffer:dword
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
extrn _gWinStartOffset:dword
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _gWinEndY:dword
|
||||||
|
extrn _SysFlags:word
|
||||||
|
extrn _sPtr:dword
|
||||||
|
extrn _mxGridGlobal:dword
|
||||||
|
extrn _myGridGlobal:dword
|
||||||
|
|
||||||
|
extrn _xSecretmPos:word
|
||||||
|
extrn _xSecretmPos1:word
|
||||||
|
extrn _xSecretColumn:word
|
||||||
|
|
||||||
|
extrn _ySecretmPos:word
|
||||||
|
extrn _ySecretmPos1:word
|
||||||
|
extrn _ySecretColumn:word
|
||||||
|
|
||||||
|
extrn _TotalSecret:word
|
||||||
|
extrn _ViewColumn:word
|
||||||
|
extrn _SinTable:dword
|
||||||
|
extrn _CosTable:dword
|
||||||
|
extrn _LongTanTable:dword
|
||||||
|
extrn _LongInvTanTable:dword
|
||||||
|
extrn _InvCosTable:byte
|
||||||
|
extrn _InvSinTable:byte
|
||||||
|
extrn _LongCosTable:dword
|
||||||
|
extrn _ViewCosTable:dword
|
||||||
|
extrn _xNextTable:dword
|
||||||
|
extrn _yNextTable:dword
|
||||||
|
|
||||||
|
extrn _LastMapPosn:word
|
||||||
|
extrn _LastObjectHit:word
|
||||||
|
extrn _TotalObjects:word
|
||||||
|
extrn _FoundObjectCount:word
|
||||||
|
extrn _ObjectsSeen:byte
|
||||||
|
extrn _MoveObjectCount:word
|
||||||
|
extrn _MoveObjectList:byte
|
||||||
|
extrn _ObjNumber:byte
|
||||||
|
extrn _ObjRelDist:byte
|
||||||
|
extrn _ObjColumn:byte
|
||||||
|
|
||||||
|
extrn _x_xPos:dword
|
||||||
|
extrn _x_yPos:dword
|
||||||
|
extrn _x_xNext:dword
|
||||||
|
extrn _x_yNext:dword
|
||||||
|
extrn _y_xPos:dword
|
||||||
|
extrn _y_yPos:dword
|
||||||
|
extrn _y_xNext:dword
|
||||||
|
extrn _y_yNext:dword
|
||||||
|
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _Flooru:dword
|
||||||
|
extrn _Floorv:dword
|
||||||
|
extrn _Floordu:dword
|
||||||
|
extrn _Floordv:dword
|
||||||
|
extrn _Floorkx:dword
|
||||||
|
extrn _Floorky:dword
|
||||||
|
extrn _Floorku:dword
|
||||||
|
extrn _Floorkv:dword
|
||||||
|
extrn _Floorkdu:dword
|
||||||
|
extrn _Floorkdv:dword
|
||||||
|
extrn _Floorbm:dword
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
extrn _FloorscrTop:dword
|
||||||
|
extrn _Floorptr2:dword
|
||||||
|
extrn _Floorht:dword
|
||||||
|
extrn _Floorwt:dword
|
||||||
|
extrn _Floorvht:word
|
||||||
|
extrn _Flooreht:word
|
||||||
|
extrn _FloorLastbNum:dword
|
||||||
|
extrn _FloorLastbm:dword
|
||||||
|
|
||||||
|
extrn _bmDistance:dword
|
||||||
|
extrn _scwht:word
|
||||||
|
extrn _scWall:dword
|
||||||
|
extrn _scPal:dword
|
||||||
|
extrn _scVid:dword
|
||||||
|
extrn _scantables:dword
|
||||||
|
|
||||||
|
ACKEXT DrawBackDrop
|
||||||
|
ACKEXT ShowCol
|
||||||
|
ACKEXT ShowColMask
|
||||||
|
ACKEXT FindDoor
|
||||||
|
ACKEXT xRayCast
|
||||||
|
ACKEXT yRayCast
|
||||||
|
|
||||||
|
ACKPUBS xxxAckDrawFloor
|
||||||
|
ACKPUBS xxxAckDrawFloorOnly
|
||||||
|
ACKPUBS xxxAckDrawCeilingOnly
|
||||||
|
|
||||||
|
.DATA
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Globals used by the AckDrawFloor routine
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
BCOL dd ?
|
||||||
|
HEIGHT dd ?
|
||||||
|
VA dd ?
|
||||||
|
SY dd ?
|
||||||
|
EY dd ?
|
||||||
|
BFSCRN dd ?
|
||||||
|
BCSCRN dd ?
|
||||||
|
FSCRN dd ?
|
||||||
|
CSCRN dd ?
|
||||||
|
CV dd ?
|
||||||
|
SV dd ?
|
||||||
|
BA dd ?
|
||||||
|
BA1 dd ?
|
||||||
|
ZDPTR dd ?
|
||||||
|
POS dd ?
|
||||||
|
BMPOS dd ?
|
||||||
|
MPOS dd ?
|
||||||
|
MPOSHI dd ?
|
||||||
|
SCANTBL dd ?
|
||||||
|
LINENUM dd ?
|
||||||
|
LASTDIST dd ?
|
||||||
|
;LASTX dd ?
|
||||||
|
;LASTY dd ?
|
||||||
|
LASTEBP dd ?
|
||||||
|
LASTEAX dd ?
|
||||||
|
LASTEDX dd ?
|
||||||
|
WALLDIST dd ?
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xxxAckDrawFloor
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
movzx eax,[word ptr _PlayerAngle]
|
||||||
|
mov ecx,eax
|
||||||
|
sub eax,INT_ANGLE_32
|
||||||
|
jnc short adf_20
|
||||||
|
add eax,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_20:
|
||||||
|
mov ebx,640
|
||||||
|
cdq
|
||||||
|
idiv ebx
|
||||||
|
mov [BCOL],edx
|
||||||
|
|
||||||
|
mov eax,89
|
||||||
|
sub ax,[word ptr _ViewHeight]
|
||||||
|
mov [HEIGHT],eax
|
||||||
|
|
||||||
|
sub ecx,INT_ANGLE_32
|
||||||
|
jnc short adf_30
|
||||||
|
add ecx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_30:
|
||||||
|
mov [VA],ecx
|
||||||
|
movzx eax,[word ptr _gWinHeight]
|
||||||
|
sar eax,1
|
||||||
|
movzx ebx,[word ptr _gWinEndY]
|
||||||
|
sub ebx,eax
|
||||||
|
inc ebx
|
||||||
|
sub ebx,5 ; 6
|
||||||
|
mov [EY],ebx
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx eax,[word ptr _gCenterOff]
|
||||||
|
mov ebx,eax
|
||||||
|
add eax,1920
|
||||||
|
add eax,edi
|
||||||
|
mov [BFSCRN],eax
|
||||||
|
sub ebx,1600 ;1920
|
||||||
|
add ebx,edi
|
||||||
|
mov [BCSCRN],ebx
|
||||||
|
mov ebp,0
|
||||||
|
mov [LINENUM],ebp
|
||||||
|
mov [LASTDIST],ebp
|
||||||
|
mov ebx,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],ebx
|
||||||
|
mov ebx,[VA]
|
||||||
|
|
||||||
|
adf_loop:
|
||||||
|
mov eax,[_CosTable]
|
||||||
|
shl ebx,2
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [CV],eax
|
||||||
|
mov eax,[_SinTable]
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [SV],eax
|
||||||
|
|
||||||
|
mov eax,[dword ptr _WallDistTable+ebp*4]
|
||||||
|
mov [WALLDIST],eax
|
||||||
|
|
||||||
|
mov eax,[BCSCRN]
|
||||||
|
mov [CSCRN],eax
|
||||||
|
|
||||||
|
mov ecx,[EY]
|
||||||
|
mov ebx,[BCOL]
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adf_l10
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adf_l10:
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA1],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adf_l20
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adf_l20:
|
||||||
|
mov [BCOL],ebx
|
||||||
|
lea esi,[offset _zdTable]
|
||||||
|
mov ecx,[EY] ;Number of rows to draw
|
||||||
|
imul eax,ebp,800
|
||||||
|
|
||||||
|
add esi,eax
|
||||||
|
add esi,24 ;ebx
|
||||||
|
mov edi,[BFSCRN]
|
||||||
|
push ebp
|
||||||
|
|
||||||
|
adf_yloop:
|
||||||
|
mov edx,[esi]
|
||||||
|
lea esi,[esi+4]
|
||||||
|
cmp edx,[WALLDIST]
|
||||||
|
jb short adf_distokay
|
||||||
|
lea edi,[edi+320]
|
||||||
|
jmp adf_ycont
|
||||||
|
|
||||||
|
adf_distokay:
|
||||||
|
cmp edx,[LASTDIST]
|
||||||
|
jne short adf_newdist
|
||||||
|
; mov eax,[LASTX]
|
||||||
|
; mov ebx,[LASTY]
|
||||||
|
mov ebp,[LASTEBP]
|
||||||
|
mov eax,[LASTEAX]
|
||||||
|
mov edx,[LASTEDX]
|
||||||
|
jmp short adf_samedist
|
||||||
|
|
||||||
|
adf_newdist:
|
||||||
|
mov [LASTDIST],edx
|
||||||
|
mov eax,[CV]
|
||||||
|
mov ebx,[SV]
|
||||||
|
imul eax,edx
|
||||||
|
imul ebx,edx
|
||||||
|
sar eax,16
|
||||||
|
sar ebx,16
|
||||||
|
mov edx,[_xPglobal]
|
||||||
|
add eax,edx
|
||||||
|
mov edx,[_yPglobal]
|
||||||
|
add ebx,edx
|
||||||
|
; mov [LASTX],eax
|
||||||
|
; mov [LASTY],ebx
|
||||||
|
|
||||||
|
;adf_samedist:
|
||||||
|
mov edx,ebx
|
||||||
|
and edx,0FC0h
|
||||||
|
mov ebp,eax
|
||||||
|
sar ebp,6
|
||||||
|
add ebp,edx ;Pos within floor and ceiling maps
|
||||||
|
|
||||||
|
and ebx,63
|
||||||
|
shl ebx,6
|
||||||
|
and eax,63
|
||||||
|
add eax,ebx ;bitmap position
|
||||||
|
|
||||||
|
;; mov ebx,0
|
||||||
|
|
||||||
|
shl ebp,1
|
||||||
|
mov [LASTEBP],ebp
|
||||||
|
mov [LASTEAX],eax
|
||||||
|
|
||||||
|
movzx ebx,[word ptr _FloorMap+ebp]
|
||||||
|
mov edx,[_WallbMaps]
|
||||||
|
mov edx,[edx+ebx*4]
|
||||||
|
movzx edx,[byte ptr edx+eax]
|
||||||
|
mov ebx,[SCANTBL]
|
||||||
|
mov dl,[ebx+edx]
|
||||||
|
mov dh,dl
|
||||||
|
mov [LASTEDX],edx
|
||||||
|
|
||||||
|
adf_samedist:
|
||||||
|
mov [edi],dx
|
||||||
|
lea edi,[edi+320]
|
||||||
|
|
||||||
|
movzx ebx,[word ptr _CeilMap+ebp]
|
||||||
|
mov ebp,[CSCRN]
|
||||||
|
test bx,bx
|
||||||
|
jz short adf_yback
|
||||||
|
|
||||||
|
mov edx,[_WallbMaps]
|
||||||
|
mov edx,[edx+ebx*4]
|
||||||
|
movzx eax,[byte ptr edx+eax]
|
||||||
|
mov edx,[SCANTBL]
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [ebp],ax
|
||||||
|
|
||||||
|
mov eax,[LINENUM]
|
||||||
|
add eax,4
|
||||||
|
mov [LINENUM],eax
|
||||||
|
mov eax,[_scantables+eax]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
lea ebp,[ebp-320]
|
||||||
|
mov [CSCRN],ebp
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec ecx
|
||||||
|
jnz adf_yloop
|
||||||
|
|
||||||
|
jmp short adf_ynext
|
||||||
|
|
||||||
|
adf_yback:
|
||||||
|
mov eax,[BA]
|
||||||
|
mov dl,[eax]
|
||||||
|
mov eax,[BA1]
|
||||||
|
mov dh,[eax]
|
||||||
|
mov [ebp],dx
|
||||||
|
|
||||||
|
adf_ycont:
|
||||||
|
mov eax,[LINENUM]
|
||||||
|
add eax,4
|
||||||
|
mov [LINENUM],eax
|
||||||
|
mov eax,[_scantables+eax]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
sub [dword ptr CSCRN],320
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec ecx
|
||||||
|
jnz adf_yloop
|
||||||
|
|
||||||
|
adf_ynext:
|
||||||
|
mov [dword ptr LINENUM],0
|
||||||
|
mov eax,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
mov ebx,[VA]
|
||||||
|
lea ebx,[ebx+2]
|
||||||
|
cmp ebx,INT_ANGLE_360
|
||||||
|
jb short adf_l90
|
||||||
|
sub ebx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_l90:
|
||||||
|
mov [VA],ebx ;Note: EBX is used for VA at top of loop!
|
||||||
|
add [dword ptr BFSCRN],2
|
||||||
|
add [dword ptr BCSCRN],2
|
||||||
|
pop ebp
|
||||||
|
lea ebp,[ebp+2]
|
||||||
|
cmp ebp,320
|
||||||
|
jb adf_loop
|
||||||
|
|
||||||
|
|
||||||
|
adf_exit:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xxxAckDrawFloorOnly
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
movzx eax,[word ptr _PlayerAngle]
|
||||||
|
mov ecx,eax
|
||||||
|
sub eax,INT_ANGLE_32
|
||||||
|
jnc short adfo_20
|
||||||
|
add eax,INT_ANGLE_360
|
||||||
|
|
||||||
|
adfo_20:
|
||||||
|
mov ebx,640
|
||||||
|
cdq
|
||||||
|
idiv ebx
|
||||||
|
mov [BCOL],edx
|
||||||
|
|
||||||
|
mov eax,89
|
||||||
|
sub ax,[word ptr _ViewHeight]
|
||||||
|
mov [HEIGHT],eax
|
||||||
|
|
||||||
|
sub ecx,INT_ANGLE_32
|
||||||
|
jnc short adfo_30
|
||||||
|
add ecx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adfo_30:
|
||||||
|
mov [VA],ecx
|
||||||
|
movzx eax,[word ptr _gWinHeight]
|
||||||
|
sar eax,1
|
||||||
|
movzx ebx,[word ptr _gWinEndY]
|
||||||
|
sub ebx,eax
|
||||||
|
inc ebx
|
||||||
|
sub ebx,5 ; 6
|
||||||
|
mov [EY],ebx
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx eax,[word ptr _gCenterOff]
|
||||||
|
mov ebx,eax
|
||||||
|
add eax,1920
|
||||||
|
add eax,edi
|
||||||
|
mov [BFSCRN],eax
|
||||||
|
sub ebx,1600 ;1920
|
||||||
|
add ebx,edi
|
||||||
|
mov [BCSCRN],ebx
|
||||||
|
mov ebp,0
|
||||||
|
mov [LINENUM],ebp
|
||||||
|
mov ebx,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],ebx
|
||||||
|
mov ebx,[VA]
|
||||||
|
|
||||||
|
adfo_loop:
|
||||||
|
mov eax,[_CosTable]
|
||||||
|
shl ebx,2
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [CV],eax
|
||||||
|
mov eax,[_SinTable]
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [SV],eax
|
||||||
|
|
||||||
|
mov eax,[BCSCRN]
|
||||||
|
mov [CSCRN],eax
|
||||||
|
|
||||||
|
mov ecx,[EY]
|
||||||
|
mov ebx,[BCOL]
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adfo_l10
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adfo_l10:
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA1],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adfo_l20
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adfo_l20:
|
||||||
|
mov [BCOL],ebx
|
||||||
|
lea esi,[offset _zdTable]
|
||||||
|
mov ecx,[EY] ;Number of rows to draw
|
||||||
|
imul eax,ebp,800
|
||||||
|
|
||||||
|
add esi,eax
|
||||||
|
add esi,24 ;ebx
|
||||||
|
mov edi,[BFSCRN]
|
||||||
|
push ebp
|
||||||
|
|
||||||
|
adfo_yloop:
|
||||||
|
mov edx,[esi]
|
||||||
|
lea esi,[esi+4]
|
||||||
|
mov eax,[CV]
|
||||||
|
mov ebx,[SV]
|
||||||
|
imul eax,edx
|
||||||
|
imul ebx,edx
|
||||||
|
sar eax,16
|
||||||
|
sar ebx,16
|
||||||
|
mov edx,[_xPglobal]
|
||||||
|
add eax,edx
|
||||||
|
mov edx,[_yPglobal]
|
||||||
|
add ebx,edx
|
||||||
|
|
||||||
|
mov edx,ebx
|
||||||
|
and edx,0FC0h
|
||||||
|
mov ebp,eax
|
||||||
|
sar ebp,6
|
||||||
|
add ebp,edx ;Pos within floor and ceiling maps
|
||||||
|
|
||||||
|
and ebx,63
|
||||||
|
shl ebx,6
|
||||||
|
and eax,63
|
||||||
|
add eax,ebx ;bitmap position
|
||||||
|
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
shl ebp,1
|
||||||
|
mov bx,[word ptr _FloorMap+ebp]
|
||||||
|
mov edx,[_WallbMaps]
|
||||||
|
mov edx,[edx+ebx*4]
|
||||||
|
movzx edx,[byte ptr edx+eax]
|
||||||
|
mov ebx,[SCANTBL]
|
||||||
|
mov dl,[ebx+edx]
|
||||||
|
mov dh,dl
|
||||||
|
mov [edi],dx
|
||||||
|
lea edi,[edi+320]
|
||||||
|
|
||||||
|
mov eax,[BA]
|
||||||
|
mov dl,[eax]
|
||||||
|
mov eax,[BA1]
|
||||||
|
mov dh,[eax]
|
||||||
|
mov ebp,[CSCRN]
|
||||||
|
mov [ebp],dx
|
||||||
|
|
||||||
|
adfo_ycont:
|
||||||
|
lea ebp,[ebp-320]
|
||||||
|
mov [CSCRN],ebp
|
||||||
|
mov eax,[LINENUM]
|
||||||
|
add eax,4
|
||||||
|
mov [LINENUM],eax
|
||||||
|
mov eax,[_scantables+eax]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec ecx
|
||||||
|
jnz adfo_yloop
|
||||||
|
|
||||||
|
adfo_ynext:
|
||||||
|
mov [dword ptr LINENUM],0
|
||||||
|
mov eax,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
mov ebx,[VA]
|
||||||
|
lea ebx,[ebx+2]
|
||||||
|
cmp ebx,INT_ANGLE_360
|
||||||
|
jb short adfo_l90
|
||||||
|
sub ebx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adfo_l90:
|
||||||
|
mov [VA],ebx ;Note: EBX is used for VA at top of loop!
|
||||||
|
add [dword ptr BFSCRN],2
|
||||||
|
add [dword ptr BCSCRN],2
|
||||||
|
pop ebp
|
||||||
|
lea ebp,[ebp+2]
|
||||||
|
cmp ebp,320
|
||||||
|
jb adfo_loop
|
||||||
|
|
||||||
|
adfo_exit:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xxxAckDrawCeilingOnly
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
movzx eax,[word ptr _PlayerAngle]
|
||||||
|
mov ecx,eax
|
||||||
|
sub eax,INT_ANGLE_32
|
||||||
|
jnc short adco_20
|
||||||
|
add eax,INT_ANGLE_360
|
||||||
|
|
||||||
|
adco_20:
|
||||||
|
mov ebx,640
|
||||||
|
cdq
|
||||||
|
idiv ebx
|
||||||
|
mov [BCOL],edx
|
||||||
|
|
||||||
|
mov eax,89
|
||||||
|
sub ax,[word ptr _ViewHeight]
|
||||||
|
mov [HEIGHT],eax
|
||||||
|
|
||||||
|
sub ecx,INT_ANGLE_32
|
||||||
|
jnc short adco_30
|
||||||
|
add ecx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adco_30:
|
||||||
|
mov [VA],ecx
|
||||||
|
movzx eax,[word ptr _gWinHeight]
|
||||||
|
sar eax,1
|
||||||
|
movzx ebx,[word ptr _gWinEndY]
|
||||||
|
sub ebx,eax
|
||||||
|
inc ebx
|
||||||
|
sub ebx,5 ; 6
|
||||||
|
mov [EY],ebx
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx eax,[word ptr _gCenterOff]
|
||||||
|
mov ebx,eax
|
||||||
|
sub ebx,1600 ;1920
|
||||||
|
add ebx,edi
|
||||||
|
mov [BCSCRN],ebx
|
||||||
|
mov ebp,0
|
||||||
|
mov [LINENUM],ebp
|
||||||
|
mov ebx,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],ebx
|
||||||
|
mov ebx,[VA]
|
||||||
|
|
||||||
|
adco_loop:
|
||||||
|
mov eax,[_CosTable]
|
||||||
|
shl ebx,2
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [CV],eax
|
||||||
|
mov eax,[_SinTable]
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [SV],eax
|
||||||
|
|
||||||
|
mov eax,[BCSCRN]
|
||||||
|
mov [CSCRN],eax
|
||||||
|
|
||||||
|
mov ecx,[EY]
|
||||||
|
mov ebx,[BCOL]
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adco_l10
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adco_l10:
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA1],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adco_l20
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adco_l20:
|
||||||
|
mov [BCOL],ebx
|
||||||
|
lea esi,[offset _zdTable]
|
||||||
|
mov ecx,[EY] ;Number of rows to draw
|
||||||
|
imul eax,ebp,800
|
||||||
|
|
||||||
|
add esi,eax
|
||||||
|
add esi,24 ;ebx
|
||||||
|
push ebp
|
||||||
|
|
||||||
|
adco_yloop:
|
||||||
|
mov edx,[esi]
|
||||||
|
lea esi,[esi+4]
|
||||||
|
mov eax,[CV]
|
||||||
|
mov ebx,[SV]
|
||||||
|
imul eax,edx
|
||||||
|
imul ebx,edx
|
||||||
|
sar eax,16
|
||||||
|
sar ebx,16
|
||||||
|
mov edx,[_xPglobal]
|
||||||
|
add eax,edx
|
||||||
|
mov edx,[_yPglobal]
|
||||||
|
add ebx,edx
|
||||||
|
|
||||||
|
mov edx,ebx
|
||||||
|
and edx,0FC0h
|
||||||
|
mov ebp,eax
|
||||||
|
sar ebp,6
|
||||||
|
add ebp,edx ;Pos within floor and ceiling maps
|
||||||
|
|
||||||
|
and ebx,63
|
||||||
|
shl ebx,6
|
||||||
|
and eax,63
|
||||||
|
add eax,ebx ;bitmap position
|
||||||
|
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
shl ebp,1
|
||||||
|
movzx ebx,[word ptr _CeilMap+ebp]
|
||||||
|
mov ebp,[CSCRN]
|
||||||
|
test bx,bx
|
||||||
|
jz short adco_yback
|
||||||
|
|
||||||
|
mov edx,[_WallbMaps]
|
||||||
|
mov edx,[edx+ebx*4]
|
||||||
|
movzx eax,[byte ptr edx+eax]
|
||||||
|
mov edx,[SCANTBL]
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [ebp],ax
|
||||||
|
|
||||||
|
mov eax,[LINENUM]
|
||||||
|
add eax,4
|
||||||
|
mov [LINENUM],eax
|
||||||
|
mov eax,[_scantables+eax]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
lea ebp,[ebp-320]
|
||||||
|
mov [CSCRN],ebp
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec ecx
|
||||||
|
jnz adco_yloop
|
||||||
|
|
||||||
|
jmp short adco_ynext
|
||||||
|
|
||||||
|
adco_yback:
|
||||||
|
mov eax,[BA]
|
||||||
|
mov dl,[eax]
|
||||||
|
mov eax,[BA1]
|
||||||
|
mov dh,[eax]
|
||||||
|
mov [ebp],dx
|
||||||
|
|
||||||
|
adco_ycont:
|
||||||
|
mov eax,[LINENUM]
|
||||||
|
add eax,4
|
||||||
|
mov [LINENUM],eax
|
||||||
|
mov eax,[_scantables+eax]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
sub [dword ptr CSCRN],320
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec ecx
|
||||||
|
jnz adco_yloop
|
||||||
|
|
||||||
|
adco_ynext:
|
||||||
|
mov [dword ptr LINENUM],0
|
||||||
|
mov eax,[dword ptr _scantables]
|
||||||
|
mov [SCANTBL],eax
|
||||||
|
mov ebx,[VA]
|
||||||
|
lea ebx,[ebx+2]
|
||||||
|
cmp ebx,INT_ANGLE_360
|
||||||
|
jb short adco_l90
|
||||||
|
sub ebx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adco_l90:
|
||||||
|
mov [VA],ebx ;Note: EBX is used for VA at top of loop!
|
||||||
|
add [dword ptr BCSCRN],2
|
||||||
|
pop ebp
|
||||||
|
lea ebp,[ebp+2]
|
||||||
|
cmp ebp,320
|
||||||
|
jb adco_loop
|
||||||
|
|
||||||
|
|
||||||
|
adco_exit:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
830
ack_lib/ACKRTN3.ASM
Normal file
830
ack_lib/ACKRTN3.ASM
Normal file
|
@ -0,0 +1,830 @@
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387 ; Allow 386 processor
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT ;32-bit OS/2 model
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
include "ackrtn.inc"
|
||||||
|
|
||||||
|
extrn _gMultiWalls:word
|
||||||
|
extrn _WallDistTable:dword
|
||||||
|
extrn _BackDropRows:dword
|
||||||
|
extrn _FloorCeilRtn:dword
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _bmDistance:dword
|
||||||
|
extrn _bmWall:dword
|
||||||
|
extrn _scPtr:dword
|
||||||
|
extrn _VidTop:dword
|
||||||
|
extrn _VidBottom:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
extrn _PlayerAngle:word
|
||||||
|
extrn _BackArray:dword
|
||||||
|
extrn _gWinStartX:word
|
||||||
|
extrn _gWinStartY:word
|
||||||
|
extrn _gWinEndX:word
|
||||||
|
extrn _gWinEndY:word
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _gWinWidth:word
|
||||||
|
extrn _gCenterRow:word
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
|
||||||
|
extrn _scVid:dword
|
||||||
|
extrn _scWall:dword
|
||||||
|
extrn _scPal:dword
|
||||||
|
extrn _scdst:word
|
||||||
|
extrn _scwht:word
|
||||||
|
extrn _scmulti:word
|
||||||
|
extrn _sctopht:word
|
||||||
|
extrn _scbotht:word
|
||||||
|
extrn _scsavwht:word
|
||||||
|
extrn _scmulcnt:word
|
||||||
|
extrn _scsavVid:dword
|
||||||
|
extrn _scbNum:word
|
||||||
|
extrn _scMulData:dword
|
||||||
|
extrn _scColumn:dword
|
||||||
|
extrn _WallbMaps:dword
|
||||||
|
|
||||||
|
extrn _FloorMap:word
|
||||||
|
extrn _CeilMap:word
|
||||||
|
extrn _LastWallHeight:word
|
||||||
|
extrn _ViewAngle:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _xPglobal:dword
|
||||||
|
extrn _yPglobal:dword
|
||||||
|
extrn _xBegGlobal:dword
|
||||||
|
extrn _yBegGlobal:dword
|
||||||
|
extrn _aeGlobal:dword
|
||||||
|
extrn _xGridGlobal:dword
|
||||||
|
extrn _yGridGlobal:dword
|
||||||
|
extrn _xPglobalHI:dword
|
||||||
|
extrn _yPglobalHI:dword
|
||||||
|
extrn _rbaTable:dword
|
||||||
|
extrn _rsHandle:word
|
||||||
|
extrn _LastX1:dword
|
||||||
|
extrn _LastY1:dword
|
||||||
|
extrn _iLastX:dword
|
||||||
|
extrn _iLastY;dword
|
||||||
|
extrn _MaxDistance:word
|
||||||
|
extrn _ErrorCode:word
|
||||||
|
extrn _xMapPosn:dword
|
||||||
|
extrn _yMapPosn:dword
|
||||||
|
extrn _Grid:dword
|
||||||
|
extrn _ObjGrid:dword
|
||||||
|
extrn _ViewHeight:word
|
||||||
|
extrn _CeilingHeight:word
|
||||||
|
extrn _gTopColor:byte
|
||||||
|
extrn _gBottomColor:byte
|
||||||
|
extrn _PlayerAngle:word
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gBkgdBuffer:dword
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _SysFlags:word
|
||||||
|
|
||||||
|
|
||||||
|
extrn _xSecretmPos:word
|
||||||
|
extrn _xSecretmPos1:word
|
||||||
|
extrn _xSecretColumn:word
|
||||||
|
|
||||||
|
extrn _ySecretmPos:word
|
||||||
|
extrn _ySecretmPos1:word
|
||||||
|
extrn _ySecretColumn:word
|
||||||
|
|
||||||
|
extrn _TotalSecret:word
|
||||||
|
extrn _ViewColumn:word
|
||||||
|
extrn _SinTable:dword
|
||||||
|
extrn _CosTable:dword
|
||||||
|
extrn _LongTanTable:dword
|
||||||
|
extrn _LongInvTanTable:dword
|
||||||
|
extrn _InvCosTable:byte
|
||||||
|
extrn _InvSinTable:byte
|
||||||
|
extrn _LongCosTable:dword
|
||||||
|
extrn _ViewCosTable:dword
|
||||||
|
extrn _xNextTable:dword
|
||||||
|
extrn _yNextTable:dword
|
||||||
|
|
||||||
|
extrn _LastMapPosn:word
|
||||||
|
extrn _LastObjectHit:word
|
||||||
|
extrn _TotalObjects:word
|
||||||
|
extrn _FoundObjectCount:word
|
||||||
|
extrn _ObjectsSeen:byte
|
||||||
|
extrn _MoveObjectCount:word
|
||||||
|
extrn _MoveObjectList:byte
|
||||||
|
extrn _ObjNumber:byte
|
||||||
|
extrn _ObjRelDist:byte
|
||||||
|
extrn _ObjColumn:byte
|
||||||
|
|
||||||
|
extrn _x_xPos:dword
|
||||||
|
extrn _x_yPos:dword
|
||||||
|
extrn _x_xNext:dword
|
||||||
|
extrn _x_yNext:dword
|
||||||
|
extrn _y_xPos:dword
|
||||||
|
extrn _y_yPos:dword
|
||||||
|
extrn _y_xNext:dword
|
||||||
|
extrn _y_yNext:dword
|
||||||
|
|
||||||
|
extrn _Slice:dword
|
||||||
|
extrn _sPtr:dword
|
||||||
|
extrn _HitMap:byte
|
||||||
|
|
||||||
|
ACKEXT xRaySetup
|
||||||
|
ACKEXT yRaySetup
|
||||||
|
ACKEXT BuildSlice
|
||||||
|
ACKEXT xRayCast
|
||||||
|
ACKEXT yRayCast
|
||||||
|
ACKEXT AckDrawFloor
|
||||||
|
ACKEXT AckDrawFloorOnly
|
||||||
|
ACKEXT AckDrawCeilingOnly
|
||||||
|
ACKEXT DrawWalls
|
||||||
|
ACKEXT CheckDoors
|
||||||
|
ACKEXT BuildSliceMulti
|
||||||
|
ACKEXT FindObject
|
||||||
|
|
||||||
|
ACKPUBS xRayCastMulti
|
||||||
|
ACKPUBS yRayCastMulti
|
||||||
|
ACKPUBS ShowColLow
|
||||||
|
ACKPUBS ShowColMaskLow
|
||||||
|
ACKPUBS BuildUpView
|
||||||
|
|
||||||
|
align 2
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowColLow
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov ebp,eax
|
||||||
|
mov [_scPtr],eax
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov edx,[_scPal]
|
||||||
|
mov ax,[_scwht]
|
||||||
|
mov [_scsavwht],ax
|
||||||
|
movsx ecx,[_sctopht]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,ecx
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ch,al
|
||||||
|
inc ch
|
||||||
|
mov eax,0
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
test [word ptr _scbNum],WALL_TYPE_UPPER
|
||||||
|
jz short toprun
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
zztoploop:
|
||||||
|
dec ch
|
||||||
|
jz short zzdomulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jge short zzdomulti
|
||||||
|
sub di,320
|
||||||
|
jmp zztoploop
|
||||||
|
|
||||||
|
zzdomulti:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
jmp chkmulti
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
toprun:
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
toploop:
|
||||||
|
movsx eax,bh
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
sub esi,eax
|
||||||
|
mov al,[esi]
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jg short botrun
|
||||||
|
dec ch
|
||||||
|
jz short botrun
|
||||||
|
sub edi,320
|
||||||
|
jmp toploop
|
||||||
|
|
||||||
|
botrun:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
mov [_VidTop],edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_scbotht]
|
||||||
|
mov bx,[_scsavwht]
|
||||||
|
mov ch,bl
|
||||||
|
mov ebx,0
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
inc esi
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
dec cl
|
||||||
|
|
||||||
|
botloop:
|
||||||
|
add edi,320
|
||||||
|
movsx ax,bh
|
||||||
|
mov al,[esi+eax]
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
dec ch
|
||||||
|
jz short chkmulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jl botloop
|
||||||
|
|
||||||
|
chkmulti:
|
||||||
|
mov [_VidBottom],edi
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov edi,[_scsavVid]
|
||||||
|
cmp [word ptr _scmulti],0
|
||||||
|
jz alldone
|
||||||
|
mov cx,[_scmulcnt]
|
||||||
|
|
||||||
|
mov ebx,[_scMulData] ;ptr to count and wall data
|
||||||
|
mov cl,[ebx] ;get count of data
|
||||||
|
inc ebx
|
||||||
|
mov al,[ebx] ;first wall to show
|
||||||
|
inc ebx
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
movsx ebx,al ;get wall number
|
||||||
|
shl ebx,2 ;x4 for index into wall bitmap array
|
||||||
|
mov eax,[_WallbMaps]
|
||||||
|
mov ebx,[eax+ebx]
|
||||||
|
add ebx,[dword ptr _scColumn] ;add in current column
|
||||||
|
add ebx,63 ;point to bottom of column
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
|
||||||
|
mov bx,[_scwht]
|
||||||
|
mov ch,bh
|
||||||
|
cmp ch,0
|
||||||
|
jz short alldone
|
||||||
|
|
||||||
|
mov ebx,0
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
mulloop:
|
||||||
|
sub edi,320
|
||||||
|
movsx eax,bh
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
sub esi,eax
|
||||||
|
mov al,[esi]
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
dec ch
|
||||||
|
jz short alldone
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,64
|
||||||
|
jge short nextlevel
|
||||||
|
jmp mulloop
|
||||||
|
|
||||||
|
nextlevel:
|
||||||
|
dec cl
|
||||||
|
jz short alldone
|
||||||
|
mov ebx,[_scMulData]
|
||||||
|
mov al,[ebx] ;next wall number
|
||||||
|
inc ebx
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
movsx ebx,al
|
||||||
|
shl ebx,2
|
||||||
|
mov eax,[_WallbMaps]
|
||||||
|
mov ebx,[eax+ebx]
|
||||||
|
add ebx,[dword ptr _scColumn] ;add in current column
|
||||||
|
add ebx,63 ;point to bottom of column
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ebx,0
|
||||||
|
jmp mulloop
|
||||||
|
|
||||||
|
alldone:
|
||||||
|
mov [_VidTop],edi
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
align 2
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowColMaskLow
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov ebp,eax
|
||||||
|
mov [_scPtr],eax
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov edx,[_scPal]
|
||||||
|
mov ax,[_scwht]
|
||||||
|
mov [_scsavwht],ax
|
||||||
|
movsx ecx,[_sctopht]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,ecx
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ch,al
|
||||||
|
mov eax,0
|
||||||
|
mov ebx,0
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
test [word ptr _scbNum],WALL_TYPE_UPPER
|
||||||
|
jz short m_toprun
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
m_zztoploop:
|
||||||
|
dec ch
|
||||||
|
jz short m_zzdomulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jge short m_zzdomulti
|
||||||
|
sub edi,320
|
||||||
|
jmp m_zztoploop
|
||||||
|
|
||||||
|
m_zzdomulti:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
jmp m_chkmulti
|
||||||
|
|
||||||
|
;--TEST------------------------------------------------------------------------
|
||||||
|
m_toprun:
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
m_toploop:
|
||||||
|
movsx eax,bh
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
sub esi,eax
|
||||||
|
mov al,[esi]
|
||||||
|
or al,al
|
||||||
|
jz m_blank1
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
|
||||||
|
m_blank1:
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jg short m_botrun
|
||||||
|
dec ch
|
||||||
|
jz short m_botrun
|
||||||
|
sub edi,320
|
||||||
|
jmp m_toploop
|
||||||
|
|
||||||
|
m_botrun:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
mov [_scwht],cx
|
||||||
|
mov [_scsavVid],edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_scbotht]
|
||||||
|
mov bx,[_scsavwht]
|
||||||
|
mov ch,bl
|
||||||
|
mov ebx,0
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
inc esi
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
m_botloop:
|
||||||
|
add edi,320
|
||||||
|
movsx ax,bh
|
||||||
|
mov al,[esi+eax]
|
||||||
|
or al,al
|
||||||
|
jz m_blank2
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
|
||||||
|
m_blank2:
|
||||||
|
dec ch
|
||||||
|
jz short m_chkmulti
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,cl
|
||||||
|
jl m_botloop
|
||||||
|
|
||||||
|
m_chkmulti:
|
||||||
|
mov ebp,[_scPtr]
|
||||||
|
cmp [word ptr _scmulti],0
|
||||||
|
jz short m_alldone
|
||||||
|
mov cx,[_scmulcnt]
|
||||||
|
mov bx,[_scwht]
|
||||||
|
mov ch,bh
|
||||||
|
cmp ch,0
|
||||||
|
jz short m_alldone
|
||||||
|
|
||||||
|
mov edi,[_scsavVid]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
add ebx,63
|
||||||
|
mov [_bmWall],ebx
|
||||||
|
mov ebx,0
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
|
||||||
|
m_mulloop:
|
||||||
|
sub edi,320
|
||||||
|
movsx eax,bh
|
||||||
|
mov esi,[_bmWall]
|
||||||
|
sub esi,eax
|
||||||
|
mov al,[esi]
|
||||||
|
or al,al
|
||||||
|
jz m_blank3
|
||||||
|
mov al,[edx+eax]
|
||||||
|
mov ah,al
|
||||||
|
mov [edi],ax
|
||||||
|
|
||||||
|
m_blank3:
|
||||||
|
dec ch
|
||||||
|
jz short m_alldone
|
||||||
|
add bx,bp
|
||||||
|
cmp bh,64
|
||||||
|
jge short m_nextlevel
|
||||||
|
jmp m_mulloop
|
||||||
|
|
||||||
|
m_nextlevel:
|
||||||
|
mov ebx,0
|
||||||
|
dec cl
|
||||||
|
jnz m_mulloop
|
||||||
|
|
||||||
|
m_alldone:
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC xRayCastMulti
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
sub esp,50
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
mov [word ptr retval],0
|
||||||
|
|
||||||
|
looptop:
|
||||||
|
|
||||||
|
mov edx,[dword ptr _x_xPos]
|
||||||
|
cmp edx,large 0
|
||||||
|
jl short getout
|
||||||
|
cmp edx,large 4096
|
||||||
|
jg short getout
|
||||||
|
mov eax,[_x_yPos]
|
||||||
|
cmp eax,large 0
|
||||||
|
jl short getout
|
||||||
|
cmp eax,large 010000000h
|
||||||
|
jle short inbounds
|
||||||
|
|
||||||
|
getout:
|
||||||
|
jmp loopdone
|
||||||
|
|
||||||
|
inbounds:
|
||||||
|
sar eax,16
|
||||||
|
and ax,-64
|
||||||
|
sar edx,6
|
||||||
|
add ax,dx
|
||||||
|
mov si,ax
|
||||||
|
|
||||||
|
shl ax,1
|
||||||
|
movsx eax,ax
|
||||||
|
mov ebx,[dword ptr _ObjGrid]
|
||||||
|
mov ax,[word ptr ebx+eax]
|
||||||
|
or ax,ax
|
||||||
|
jz short no_obj
|
||||||
|
|
||||||
|
and ax,0FFh
|
||||||
|
mov [word ptr Color],ax
|
||||||
|
|
||||||
|
movsx ecx,[_FoundObjectCount] ;// Get number of current objects seen
|
||||||
|
mov ebx,ecx
|
||||||
|
jcxz short nofound ;// None found yet, add this new one
|
||||||
|
mov edi,offset _ObjectsSeen
|
||||||
|
repne scasb ;// See if this object already seen
|
||||||
|
jz short no_obj ;// Yes, ignore this ray then
|
||||||
|
|
||||||
|
nofound:
|
||||||
|
mov edi,offset _ObjectsSeen
|
||||||
|
mov [edi+ebx],al
|
||||||
|
inc bx
|
||||||
|
mov [word ptr _FoundObjectCount],bx
|
||||||
|
|
||||||
|
no_obj:
|
||||||
|
movsx eax,si
|
||||||
|
|
||||||
|
shl eax,1
|
||||||
|
mov ebx,[dword ptr _xGridGlobal]
|
||||||
|
mov cx,[ebx+eax]
|
||||||
|
or cx,cx
|
||||||
|
jz short next_square
|
||||||
|
test cx,WALL_UPPER_MULTI
|
||||||
|
jz short next_square
|
||||||
|
cmp cl,[byte ptr _LastWallHeight]
|
||||||
|
jbe short next_square
|
||||||
|
|
||||||
|
mov [word ptr _xMapPosn],si
|
||||||
|
mov ebx,[dword ptr _x_xPos]
|
||||||
|
mov [dword ptr _iLastX],ebx
|
||||||
|
mov edx,[dword ptr _x_yPos]
|
||||||
|
mov [dword ptr _LastY1],edx
|
||||||
|
|
||||||
|
movsx eax,cx
|
||||||
|
jmp short xRayDone
|
||||||
|
|
||||||
|
next_square:
|
||||||
|
mov eax,[dword ptr _x_xNext]
|
||||||
|
add [dword ptr _x_xPos],eax
|
||||||
|
mov eax,[dword ptr _x_yNext]
|
||||||
|
add [dword ptr _x_yPos],eax
|
||||||
|
jmp looptop
|
||||||
|
|
||||||
|
loopdone:
|
||||||
|
movsx eax,[word ptr retval]
|
||||||
|
|
||||||
|
xRayDone:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
mov esp,ebp
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC yRayCastMulti
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
sub esp,50
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov [word ptr retval],0
|
||||||
|
|
||||||
|
y_looptop:
|
||||||
|
mov edx,[dword ptr _y_xPos]
|
||||||
|
cmp edx,large 0
|
||||||
|
jl short y_getout
|
||||||
|
cmp edx,large 010000000h
|
||||||
|
jg short y_getout
|
||||||
|
mov eax,[_y_yPos]
|
||||||
|
cmp eax,large 0
|
||||||
|
jl short y_getout
|
||||||
|
cmp eax,large 4096
|
||||||
|
jle short y_inbounds
|
||||||
|
|
||||||
|
y_getout:
|
||||||
|
jmp loopdone
|
||||||
|
|
||||||
|
y_inbounds:
|
||||||
|
sar edx,22
|
||||||
|
and ax,-64
|
||||||
|
add ax,dx
|
||||||
|
mov si,ax
|
||||||
|
|
||||||
|
shl ax,1
|
||||||
|
movsx eax,ax
|
||||||
|
mov ebx,[dword ptr _ObjGrid]
|
||||||
|
mov ax,[ebx+eax]
|
||||||
|
or ax,ax
|
||||||
|
jz short y_no_obj
|
||||||
|
|
||||||
|
and ax,0FFh
|
||||||
|
mov [word ptr Color],ax
|
||||||
|
|
||||||
|
movsx ecx,[_FoundObjectCount]
|
||||||
|
mov ebx,ecx
|
||||||
|
jcxz short y_nofound
|
||||||
|
mov edi,offset _ObjectsSeen
|
||||||
|
repne scasb
|
||||||
|
jz short y_no_obj
|
||||||
|
|
||||||
|
y_nofound:
|
||||||
|
mov edi,offset _ObjectsSeen
|
||||||
|
mov [edi+ebx],al
|
||||||
|
inc bx
|
||||||
|
mov [word ptr _FoundObjectCount],bx
|
||||||
|
|
||||||
|
y_no_obj:
|
||||||
|
movsx eax,si
|
||||||
|
|
||||||
|
shl eax,1
|
||||||
|
mov ebx,[dword ptr _yGridGlobal]
|
||||||
|
mov cx,[ebx+eax]
|
||||||
|
or cx,cx
|
||||||
|
jz short y_next_square
|
||||||
|
|
||||||
|
y_wall_here:
|
||||||
|
test cx,WALL_UPPER_MULTI
|
||||||
|
jz short y_next_square
|
||||||
|
cmp cl,[byte ptr _LastWallHeight]
|
||||||
|
jbe short y_next_square
|
||||||
|
mov [word ptr _yMapPosn],si
|
||||||
|
mov ebx,[dword ptr _y_xPos]
|
||||||
|
mov [dword ptr _LastX1],ebx
|
||||||
|
mov edx,[dword ptr _y_yPos]
|
||||||
|
mov [dword ptr _iLastY],edx
|
||||||
|
mov edx,ebx
|
||||||
|
|
||||||
|
movsx eax,cx
|
||||||
|
jmp short yRayDone
|
||||||
|
|
||||||
|
y_next_square:
|
||||||
|
mov eax,[dword ptr _y_xNext]
|
||||||
|
add [dword ptr _y_xPos],eax
|
||||||
|
mov eax,[dword ptr _y_yNext]
|
||||||
|
add [dword ptr _y_yPos],eax
|
||||||
|
jmp y_looptop
|
||||||
|
|
||||||
|
y_loopdone:
|
||||||
|
movsx eax,[word ptr retval]
|
||||||
|
|
||||||
|
yRayDone:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
mov esp,ebp
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC CheckHitMap
|
||||||
|
mov edi,offset _HitMap
|
||||||
|
mov edx,edi
|
||||||
|
mov ecx,4096
|
||||||
|
mov esi,[dword ptr _ObjGrid]
|
||||||
|
|
||||||
|
chmLoop:
|
||||||
|
xor eax,eax
|
||||||
|
repe scasb
|
||||||
|
jcxz chmDone
|
||||||
|
mov ebx,edi ;get current location
|
||||||
|
sub ebx,edx ;minus start for actual offset
|
||||||
|
dec ebx ;minus base 0 offset
|
||||||
|
shl ebx,1 ;times 2 for word array
|
||||||
|
mov ax,[word ptr esi+ebx]
|
||||||
|
or al,al ;is there an object there?
|
||||||
|
jz chmLoop ;nope, keep checking
|
||||||
|
movzx ebx,[word ptr _FoundObjectCount]
|
||||||
|
mov [byte ptr _ObjectsSeen+ebx],al
|
||||||
|
inc ebx
|
||||||
|
mov [word ptr _FoundObjectCount],bx
|
||||||
|
jmp chmLoop
|
||||||
|
|
||||||
|
chmDone:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC BuildUpView
|
||||||
|
push ebp ; Save registers used by this routine
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
ACKCALL CheckDoors ; Determine the state of the doors used in the view
|
||||||
|
|
||||||
|
mov edi,offset _HitMap ; Access the hit map
|
||||||
|
mov ecx,1024 ; Size of the hit map
|
||||||
|
xor eax,eax ; Clear each location
|
||||||
|
rep stosd ; Clear out entire hit map
|
||||||
|
|
||||||
|
; Check to see if moveable objects are found in the view. If so, access the object list
|
||||||
|
; and store the objects.
|
||||||
|
mov [word ptr _MaxDistance],0
|
||||||
|
movzx ecx,[word ptr _MoveObjectCount] ; Get # of moveable objects
|
||||||
|
mov [_FoundObjectCount],cx ; Store # of objects found in view
|
||||||
|
jcxz short buv010 ; No objects are used, jump ahead
|
||||||
|
mov edi,offset _ObjectsSeen ; Reference global object list
|
||||||
|
mov esi,offset _MoveObjectList ; List of movable objects
|
||||||
|
mov ebx,ecx ; # of moveable objects
|
||||||
|
sar ecx,2 ; Divide by 2
|
||||||
|
rep movsd
|
||||||
|
mov ecx,ebx ; # of moveable objects
|
||||||
|
and ecx,3
|
||||||
|
rep movsb ; Finish copying _ObjectSeen to
|
||||||
|
; _MoveObjectList
|
||||||
|
buv010:
|
||||||
|
movzx esi,[_gWinEndX] ; Get right side of viewport
|
||||||
|
cmp si,320 ; Is right coord. = 320?
|
||||||
|
jae short buv020
|
||||||
|
inc esi ; Adjust right viewport if not 320
|
||||||
|
|
||||||
|
buv020:
|
||||||
|
movzx eax,[_PlayerAngle] ; Get current player’s angle
|
||||||
|
sub eax,INT_ANGLE_32 ; Check with 32 degree point
|
||||||
|
jnc short buv030 ; Skip if in range
|
||||||
|
add eax,INT_ANGLE_360 ; Add 360 degrees to angle
|
||||||
|
|
||||||
|
buv030:
|
||||||
|
movzx ebx,[_gWinStartX] ; Get left side of viewport
|
||||||
|
mov [_ViewColumn],bx ; Save location in _ViewColumn
|
||||||
|
add eax,ebx ; Add angle to left side
|
||||||
|
cmp eax,INT_ANGLE_360 ; Are we out of range?
|
||||||
|
jl short buv040 ; We’re ok!
|
||||||
|
sub eax,INT_ANGLE_360 ; Reduce angle by 360 degrees
|
||||||
|
|
||||||
|
buv040:
|
||||||
|
mov [_ViewAngle],ax ; Store updated angle
|
||||||
|
|
||||||
|
; The start of the main loop that builds individual slices for the view.
|
||||||
|
; This loop continues until the entire view has been built. Each time through
|
||||||
|
; the loop, the player’s viewing angle is increased. This continues until a full
|
||||||
|
; 64 degre range is casted (assuming a full width screen is used).
|
||||||
|
buv050:
|
||||||
|
movzx ebx,[_ViewColumn] ; Get left column position
|
||||||
|
mov [dword ptr _WallDistTable+ebx*4],4096 ; Max distance to walls
|
||||||
|
mov eax,offset _Slice ; Access base adress of Slice structure
|
||||||
|
imul ebx,saSize ; Calculate offset into actual slice
|
||||||
|
add eax,ebx ; Add offset to base address
|
||||||
|
mov [_sPtr],eax ; Set up pointer to actual column slice
|
||||||
|
movzx edi,[_ViewAngle] ; Use current viewing angle
|
||||||
|
ACKCALL xRaySetup ; Set up x ray to start casting
|
||||||
|
|
||||||
|
buv060:
|
||||||
|
ACKCALL yRaySetup ; Set up y ray to start casting
|
||||||
|
|
||||||
|
buv070:
|
||||||
|
mov [word ptr _LastWallHeight],0 ; For checking mult-height walls
|
||||||
|
ACKCALL BuildSlice ; Build the current slice
|
||||||
|
cmp [word ptr _gMultiWalls],0 ; Are multi-height walls used?
|
||||||
|
jz short buv080 ; Nope, no need to check
|
||||||
|
|
||||||
|
cmp [word ptr _LastWallHeight],200 ; No need to check if > 200
|
||||||
|
jg short buv080
|
||||||
|
|
||||||
|
mov eax,[_sPtr] ; Get base address of column slice
|
||||||
|
cmp [dword ptr eax+saNext],0 ; Check for any more walls
|
||||||
|
je short buv080
|
||||||
|
cmp [word ptr eax+saDist],96 ; Distance from POV to slice is
|
||||||
|
jle short buv080 ; less than or equal to 96
|
||||||
|
|
||||||
|
ACKCALL BuildSliceMulti ; Build the current slice for
|
||||||
|
; a multi-height wall
|
||||||
|
buv080:
|
||||||
|
movzx eax,[_ViewColumn] ; Get current column
|
||||||
|
inc eax ; Advance to the next column
|
||||||
|
inc edi ; Increment the casting angle
|
||||||
|
cmp [word ptr _Resolution],RES_LOW ; Check for screen resolution
|
||||||
|
jne short buv090
|
||||||
|
inc edi ; Increment angle and position
|
||||||
|
inc eax ; for higher resolution casting
|
||||||
|
|
||||||
|
buv090:
|
||||||
|
cmp edi,INT_ANGLE_360 ; Did we go past 360 degrees?
|
||||||
|
jl short buv100 ; We’re ok
|
||||||
|
sub edi,INT_ANGLE_360 ; Adjust angle for building next slice
|
||||||
|
|
||||||
|
buv100:
|
||||||
|
mov [_ViewAngle],di ; Save current viewing angle
|
||||||
|
mov [_ViewColumn],ax ; Save column position
|
||||||
|
cmp eax,esi ; Are we done yet?
|
||||||
|
jl buv050 ; Nope; go build next slice
|
||||||
|
|
||||||
|
buv_exit:
|
||||||
|
ACKCALL CheckHitMap
|
||||||
|
ACKCALL FindObject ; Update slice structures with objects found
|
||||||
|
call [dword ptr _FloorCeilRtn] ; Build the floor and ceiling
|
||||||
|
ACKCALL DrawWalls ; Build the walls
|
||||||
|
|
||||||
|
pop edx ; Restore the registers used
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
412
ack_lib/ACKRTN4.ASM
Normal file
412
ack_lib/ACKRTN4.ASM
Normal file
|
@ -0,0 +1,412 @@
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387 ; Allow 386 processor
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT ;32-bit OS/2 model
|
||||||
|
|
||||||
|
.DATA
|
||||||
|
|
||||||
|
SVTABLE dd ?
|
||||||
|
|
||||||
|
SAVEVID dd ?
|
||||||
|
SAVEROW dd ?
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
|
||||||
|
include "ackrtn.inc"
|
||||||
|
|
||||||
|
extrn _BackDropRows:dword
|
||||||
|
extrn _PlayerAngle:word
|
||||||
|
extrn _BackArray:dword
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _bmDistance:dword
|
||||||
|
extrn _bmWall:dword
|
||||||
|
extrn _scPtr:dword
|
||||||
|
extrn _VidTop:dword
|
||||||
|
extrn _VidBottom:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
|
||||||
|
extrn _gPalTable:dword
|
||||||
|
extrn _gWinStartX:word
|
||||||
|
extrn _gWinStartY:word
|
||||||
|
extrn _gWinEndX:word
|
||||||
|
extrn _gWinEndY:word
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _ViewHeight:word
|
||||||
|
extrn _SysFlags:word
|
||||||
|
extrn _Slice:byte
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
extrn _gCenterRow:word
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _gWinStartOffset:dword
|
||||||
|
|
||||||
|
extrn _scVid:dword
|
||||||
|
extrn _scWall:dword
|
||||||
|
extrn _scPal:dword
|
||||||
|
extrn _scdst:word
|
||||||
|
extrn _scwht:word
|
||||||
|
extrn _scmulti:word
|
||||||
|
extrn _sctopht:word
|
||||||
|
extrn _scbotht:word
|
||||||
|
extrn _scsavwht:word
|
||||||
|
extrn _scmulcnt:word
|
||||||
|
extrn _scsavVid:dword
|
||||||
|
extrn _scbNum:word
|
||||||
|
extrn _scMulData:dword
|
||||||
|
extrn _scColumn:dword
|
||||||
|
extrn _WallbMaps:dword
|
||||||
|
extrn _LowerTable:dword
|
||||||
|
extrn _gBottomOff:dword
|
||||||
|
extrn _LightFlag:word
|
||||||
|
|
||||||
|
ACKEXT ShowCol
|
||||||
|
ACKEXT ShowColMask
|
||||||
|
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _Flooru:dword
|
||||||
|
extrn _Floorv:dword
|
||||||
|
extrn _Floordu:dword
|
||||||
|
extrn _Floordv:dword
|
||||||
|
extrn _Floorkx:dword
|
||||||
|
extrn _Floorky:dword
|
||||||
|
extrn _Floorku:dword
|
||||||
|
extrn _Floorkv:dword
|
||||||
|
extrn _Floorkdu:dword
|
||||||
|
extrn _Floorkdv:dword
|
||||||
|
extrn _Floorbm:dword
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
extrn _FloorscrTop:dword
|
||||||
|
extrn _Floorptr2:dword
|
||||||
|
extrn _Floorwt:dword
|
||||||
|
extrn _Floorvht:word
|
||||||
|
extrn _Flooreht:word
|
||||||
|
extrn _FloorMap:word
|
||||||
|
extrn _gScrnBufferCenter:dword
|
||||||
|
extrn _gWinHalfHeight:word
|
||||||
|
extrn _zdTable:dword
|
||||||
|
extrn _CosTable:dword
|
||||||
|
extrn _SinTable:dword
|
||||||
|
extrn _xPglobal:dword
|
||||||
|
extrn _yPglobal:dword
|
||||||
|
extrn _WallDistTable:dword
|
||||||
|
extrn _CeilMap:word
|
||||||
|
extrn _AckTimerCounter:dword
|
||||||
|
|
||||||
|
ACKPUBS Mymemset
|
||||||
|
ACKPUBS AckSpeedUp
|
||||||
|
ACKPUBS AckSlowDown
|
||||||
|
ACKPUBS ShowColNS
|
||||||
|
ACKPUBS ShowColMaskNS
|
||||||
|
ACKPUBS DrawBackDrop
|
||||||
|
ACKPUBS AckTimerHandler
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckTimerHandler
|
||||||
|
inc cs:[dword ptr _AckTimerCounter]
|
||||||
|
iretd
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC Mymemset
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov edi,eax
|
||||||
|
mov dh,dl
|
||||||
|
mov ax,dx
|
||||||
|
shl eax,16
|
||||||
|
mov ax,dx
|
||||||
|
mov ecx,ebx
|
||||||
|
sar ecx,2
|
||||||
|
rep stosd
|
||||||
|
mov ecx,ebx
|
||||||
|
and ecx,3
|
||||||
|
rep stosb
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSpeedUp
|
||||||
|
push ebx
|
||||||
|
push edx
|
||||||
|
mov bx,ax
|
||||||
|
mov ax,0FFFFH
|
||||||
|
xor dx,dx
|
||||||
|
idiv bx
|
||||||
|
mov bx,ax
|
||||||
|
mov dx,43h
|
||||||
|
mov al,36h
|
||||||
|
out dx,al
|
||||||
|
mov dx,40h
|
||||||
|
mov al,bl ; ffh = original value
|
||||||
|
out dx,al
|
||||||
|
mov dx,40h
|
||||||
|
mov al,bh ; 1fh = orignal value
|
||||||
|
out dx,al
|
||||||
|
pop edx
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckSlowDown
|
||||||
|
push edx
|
||||||
|
mov dx,43h
|
||||||
|
mov al,36h
|
||||||
|
out dx,al
|
||||||
|
mov dx,40h
|
||||||
|
mov al,0ffh
|
||||||
|
out dx,al
|
||||||
|
mov dx,40h
|
||||||
|
mov al,0ffh
|
||||||
|
out dx,al
|
||||||
|
pop edx
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawBackDrop
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
mov ax,[_PlayerAngle]
|
||||||
|
sub ax,INT_ANGLE_32
|
||||||
|
jnc ang_okay
|
||||||
|
add ax,INT_ANGLE_360
|
||||||
|
|
||||||
|
ang_okay:
|
||||||
|
mov cx,640
|
||||||
|
cwd
|
||||||
|
idiv cx ; Do mod 640 to get starting posn
|
||||||
|
|
||||||
|
; movsx ebx,dx
|
||||||
|
movzx ebx,dx
|
||||||
|
shl ebx,2 ; x 4 for memory pointers
|
||||||
|
mov edx,320
|
||||||
|
mov ebp,[_gScrnBuffer] ; get screen buffer
|
||||||
|
|
||||||
|
dbd010:
|
||||||
|
mov edi,ebp
|
||||||
|
mov esi,[dword ptr _BackArray+ebx] ;current image pointer
|
||||||
|
mov ecx,[_BackDropRows] ; rows to draw
|
||||||
|
|
||||||
|
dbd020:
|
||||||
|
; mov al,[esi]
|
||||||
|
; mov [edi],al
|
||||||
|
; inc esi
|
||||||
|
; lea edi,[edi+320]
|
||||||
|
movsb
|
||||||
|
lea edi,[edi+319]
|
||||||
|
dec ecx
|
||||||
|
jnz dbd020
|
||||||
|
|
||||||
|
inc ebp ;next screen column
|
||||||
|
lea ebx,[ebx+4]
|
||||||
|
cmp ebx,2560 ;see if 640x4 column yet
|
||||||
|
jb short dbd030 ;nope
|
||||||
|
mov ebx,0 ;else wrap to 0 column
|
||||||
|
|
||||||
|
dbd030:
|
||||||
|
dec edx ;see if done with all columns
|
||||||
|
jnz dbd010
|
||||||
|
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowColNS
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov cx,[_gCenterRow]
|
||||||
|
mov edx,1FFFh
|
||||||
|
xor eax,eax
|
||||||
|
|
||||||
|
sns_top:
|
||||||
|
mov al,dh
|
||||||
|
sub edx,ebp
|
||||||
|
mov al,[ebx+eax]
|
||||||
|
mov [edi],al
|
||||||
|
jc short sns_bot
|
||||||
|
sub edi,320
|
||||||
|
dec cx
|
||||||
|
jns sns_top
|
||||||
|
xor ecx,ecx
|
||||||
|
|
||||||
|
sns_bot:
|
||||||
|
mov [SAVEVID],edi
|
||||||
|
mov [SAVEROW],ecx
|
||||||
|
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_gCenterRow]
|
||||||
|
mov edx,2000h
|
||||||
|
|
||||||
|
sns_botloop:
|
||||||
|
mov al,dh
|
||||||
|
add edi,320
|
||||||
|
mov al,[ebx+eax]
|
||||||
|
add edx,ebp
|
||||||
|
mov [edi],al
|
||||||
|
cmp dh,64
|
||||||
|
jae short sns_exit
|
||||||
|
dec cx
|
||||||
|
jnz sns_botloop
|
||||||
|
|
||||||
|
sns_exit:
|
||||||
|
cmp [word ptr _scmulti],0
|
||||||
|
jz sns_alldone
|
||||||
|
mov esi,[SAVEROW]
|
||||||
|
or si,si
|
||||||
|
jz sns_alldone
|
||||||
|
|
||||||
|
mov ebx,[_scMulData] ;ptr to count and wall data
|
||||||
|
mov cl,[ebx] ;get number of walls to draw
|
||||||
|
inc ebx
|
||||||
|
mov al,[ebx] ;first wall to show
|
||||||
|
inc ebx
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
movzx ebx,al ;get wall number
|
||||||
|
mov eax,[_WallbMaps] ;Get array of bitmaps
|
||||||
|
mov ebx,[eax+ebx*4] ;Get the bitmap we are using
|
||||||
|
mov eax,[_scColumn]
|
||||||
|
add ebx,eax
|
||||||
|
mov edi,[SAVEVID]
|
||||||
|
mov edx,3FFFh
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov eax,0
|
||||||
|
|
||||||
|
sns_mulloop:
|
||||||
|
mov al,dh
|
||||||
|
sub edi,320
|
||||||
|
mov al,[ebx+eax]
|
||||||
|
dec si
|
||||||
|
mov [edi],al
|
||||||
|
jz short sns_alldone
|
||||||
|
sub edx,ebp
|
||||||
|
jnc sns_mulloop
|
||||||
|
|
||||||
|
sns_nextlevel:
|
||||||
|
dec cl ;Bump wall count
|
||||||
|
jz short sns_alldone ;br if no more walls
|
||||||
|
mov ebx,[_scMulData] ;Get pointer to the multi-ht data
|
||||||
|
movzx edx,[byte ptr ebx] ;next wall number
|
||||||
|
inc ebx ;Advance for next wall
|
||||||
|
mov [_scMulData],ebx
|
||||||
|
mov ebx,[_WallbMaps] ;Get wall array
|
||||||
|
mov ebx,[ebx+edx*4] ;Get wall bitmap to use
|
||||||
|
add ebx,[dword ptr _scColumn] ;add in current column
|
||||||
|
mov edx,3FFFh
|
||||||
|
jmp sns_mulloop
|
||||||
|
|
||||||
|
sns_alldone:
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC ShowColMaskNS
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov ebx,[_scWall]
|
||||||
|
mov ebp,[_bmDistance]
|
||||||
|
mov cx,[_gCenterRow]
|
||||||
|
mov edx,1FFFh
|
||||||
|
xor eax,eax
|
||||||
|
|
||||||
|
smns_top:
|
||||||
|
mov al,dh
|
||||||
|
mov al,[ebx+eax]
|
||||||
|
or al,al
|
||||||
|
jz short smns_blank
|
||||||
|
mov [edi],al
|
||||||
|
|
||||||
|
smns_blank:
|
||||||
|
sub edx,ebp
|
||||||
|
jc short smns_bot
|
||||||
|
sub edi,320
|
||||||
|
dec cx
|
||||||
|
jnz smns_top
|
||||||
|
|
||||||
|
smns_bot:
|
||||||
|
mov edi,[_scVid]
|
||||||
|
mov cx,[_gCenterRow]
|
||||||
|
mov edx,2000h
|
||||||
|
|
||||||
|
smns_botloop:
|
||||||
|
add edi,320
|
||||||
|
mov al,dh
|
||||||
|
mov al,[ebx+eax]
|
||||||
|
or al,al
|
||||||
|
jz short smns_blank1
|
||||||
|
mov [edi],al
|
||||||
|
|
||||||
|
smns_blank1:
|
||||||
|
add edx,ebp
|
||||||
|
cmp dh,64
|
||||||
|
jae short smns_exit
|
||||||
|
dec cx
|
||||||
|
jnz smns_botloop
|
||||||
|
|
||||||
|
smns_exit:
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
552
ack_lib/ACKRTN5.ASM
Normal file
552
ack_lib/ACKRTN5.ASM
Normal file
|
@ -0,0 +1,552 @@
|
||||||
|
|
||||||
|
IDEAL
|
||||||
|
JUMPS
|
||||||
|
P386
|
||||||
|
P387 ; Allow 386 processor
|
||||||
|
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.MODEL FLAT ;32-bit OS/2 model
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
|
||||||
|
include "ackrtn.inc"
|
||||||
|
|
||||||
|
extrn _WallDistTable:dword
|
||||||
|
extrn _FloorMap:word
|
||||||
|
extrn _CeilMap:word
|
||||||
|
extrn _LastWallHeight:word
|
||||||
|
extrn _ViewAngle:word
|
||||||
|
extrn _ScreenOffset:word
|
||||||
|
extrn _xPglobal:dword
|
||||||
|
extrn _yPglobal:dword
|
||||||
|
extrn _xBegGlobal:dword
|
||||||
|
extrn _yBegGlobal:dword
|
||||||
|
extrn _aeGlobal:dword
|
||||||
|
extrn _xGridGlobal:dword
|
||||||
|
extrn _yGridGlobal:dword
|
||||||
|
extrn _xPglobalHI:dword
|
||||||
|
extrn _yPglobalHI:dword
|
||||||
|
extrn _rbaTable:dword
|
||||||
|
extrn _rsHandle:word
|
||||||
|
extrn _LastX1:dword
|
||||||
|
extrn _LastY1:dword
|
||||||
|
extrn _iLastX:dword
|
||||||
|
extrn _iLastY;dword
|
||||||
|
extrn _MaxDistance:word
|
||||||
|
extrn _BackArray:dword
|
||||||
|
extrn _zdTable:dword
|
||||||
|
extrn _ErrorCode:word
|
||||||
|
extrn _xMapPosn:dword
|
||||||
|
extrn _yMapPosn:dword
|
||||||
|
extrn _Grid:dword
|
||||||
|
extrn _ObjGrid:dword
|
||||||
|
extrn _WallbMaps:dword
|
||||||
|
extrn _ViewHeight:word
|
||||||
|
extrn _CeilingHeight:word
|
||||||
|
extrn _gTopColor:byte
|
||||||
|
extrn _gBottomColor:byte
|
||||||
|
extrn _PlayerAngle:word
|
||||||
|
extrn _gScrnBuffer:dword
|
||||||
|
extrn _gBkgdBuffer:dword
|
||||||
|
extrn _gCenterOff:word
|
||||||
|
extrn _gWinStartOffset:dword
|
||||||
|
extrn _gWinHeight:word
|
||||||
|
extrn _gWinEndY:dword
|
||||||
|
extrn _SysFlags:word
|
||||||
|
extrn _sPtr:dword
|
||||||
|
extrn _mxGridGlobal:dword
|
||||||
|
extrn _myGridGlobal:dword
|
||||||
|
|
||||||
|
extrn _xSecretmPos:word
|
||||||
|
extrn _xSecretmPos1:word
|
||||||
|
extrn _xSecretColumn:word
|
||||||
|
|
||||||
|
extrn _ySecretmPos:word
|
||||||
|
extrn _ySecretmPos1:word
|
||||||
|
extrn _ySecretColumn:word
|
||||||
|
|
||||||
|
extrn _TotalSecret:word
|
||||||
|
extrn _ViewColumn:word
|
||||||
|
extrn _SinTable:dword
|
||||||
|
extrn _CosTable:dword
|
||||||
|
extrn _LongTanTable:dword
|
||||||
|
extrn _LongInvTanTable:dword
|
||||||
|
extrn _InvCosTable:byte
|
||||||
|
extrn _InvSinTable:byte
|
||||||
|
extrn _LongCosTable:dword
|
||||||
|
extrn _ViewCosTable:dword
|
||||||
|
extrn _xNextTable:dword
|
||||||
|
extrn _yNextTable:dword
|
||||||
|
|
||||||
|
extrn _LastMapPosn:word
|
||||||
|
extrn _LastObjectHit:word
|
||||||
|
extrn _TotalObjects:word
|
||||||
|
extrn _FoundObjectCount:word
|
||||||
|
extrn _ObjectsSeen:byte
|
||||||
|
extrn _MoveObjectCount:word
|
||||||
|
extrn _MoveObjectList:byte
|
||||||
|
extrn _ObjNumber:byte
|
||||||
|
extrn _ObjRelDist:byte
|
||||||
|
extrn _ObjColumn:byte
|
||||||
|
|
||||||
|
extrn _x_xPos:dword
|
||||||
|
extrn _x_yPos:dword
|
||||||
|
extrn _x_xNext:dword
|
||||||
|
extrn _x_yNext:dword
|
||||||
|
extrn _y_xPos:dword
|
||||||
|
extrn _y_yPos:dword
|
||||||
|
extrn _y_xNext:dword
|
||||||
|
extrn _y_yNext:dword
|
||||||
|
|
||||||
|
extrn _Resolution:word
|
||||||
|
extrn _Flooru:dword
|
||||||
|
extrn _Floorv:dword
|
||||||
|
extrn _Floordu:dword
|
||||||
|
extrn _Floordv:dword
|
||||||
|
extrn _Floorkx:dword
|
||||||
|
extrn _Floorky:dword
|
||||||
|
extrn _Floorku:dword
|
||||||
|
extrn _Floorkv:dword
|
||||||
|
extrn _Floorkdu:dword
|
||||||
|
extrn _Floorkdv:dword
|
||||||
|
extrn _Floorbm:dword
|
||||||
|
extrn _Floorscr:dword
|
||||||
|
extrn _Floors1:dword
|
||||||
|
extrn _Floors2:dword
|
||||||
|
extrn _FloorscrTop:dword
|
||||||
|
extrn _Floorptr2:dword
|
||||||
|
extrn _Floorht:dword
|
||||||
|
extrn _Floorwt:dword
|
||||||
|
extrn _Floorvht:word
|
||||||
|
extrn _Flooreht:word
|
||||||
|
extrn _FloorLastbNum:dword
|
||||||
|
extrn _FloorLastbm:dword
|
||||||
|
|
||||||
|
extrn _bmDistance:dword
|
||||||
|
extrn _scwht:word
|
||||||
|
extrn _scWall:dword
|
||||||
|
extrn _scPal:dword
|
||||||
|
extrn _scVid:dword
|
||||||
|
extrn _scantables:dword
|
||||||
|
|
||||||
|
ACKEXT AckDrawFloor
|
||||||
|
ACKEXT AckDrawFloorOnly
|
||||||
|
ACKEXT AckDrawCeilingOnly
|
||||||
|
ACKEXT DrawBackDrop
|
||||||
|
ACKEXT AckDrawCeilingOnlyNS
|
||||||
|
ACKEXT AckDrawFloorOnlyNS
|
||||||
|
|
||||||
|
ACKPUBS AckDrawFloorNS
|
||||||
|
ACKPUBS DrawSolidCeilAndFloorNS
|
||||||
|
ACKPUBS DrawSolidCeilAndFloor
|
||||||
|
ACKPUBS DrawSolidFloorAndCeilNS
|
||||||
|
ACKPUBS DrawSolidFloorAndCeil
|
||||||
|
ACKPUBS DrawSolidCeilSolidFloor
|
||||||
|
ACKPUBS AckDoubleBuffer
|
||||||
|
|
||||||
|
MASM
|
||||||
|
.DATA
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
; Globals used by the AckDrawFloor routine
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
even
|
||||||
|
|
||||||
|
BCOL dd ?
|
||||||
|
HEIGHT dd ?
|
||||||
|
VA dd ?
|
||||||
|
SY dd ?
|
||||||
|
EY dd ?
|
||||||
|
BFSCRN dd ?
|
||||||
|
BCSCRN dd ?
|
||||||
|
FSCRN dd ?
|
||||||
|
CSCRN dd ?
|
||||||
|
CV dd ?
|
||||||
|
SV dd ?
|
||||||
|
BA dd ?
|
||||||
|
BA1 dd ?
|
||||||
|
ZDPTR dd ?
|
||||||
|
POS dd ?
|
||||||
|
BMPOS dd ?
|
||||||
|
MPOS dd ?
|
||||||
|
MPOSHI dd ?
|
||||||
|
SCANTBL dd ?
|
||||||
|
ROWNUM dd ?
|
||||||
|
LASTDIST dd ?
|
||||||
|
LASTEBP dd ?
|
||||||
|
LASTEAX dd ?
|
||||||
|
LASTEDX dd ?
|
||||||
|
WALLDIST dd ?
|
||||||
|
DSTPTR dd ?
|
||||||
|
COLNUM dd ?
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
IDEAL
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckDrawFloorNS
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
movzx eax,[word ptr _PlayerAngle]
|
||||||
|
mov ecx,eax
|
||||||
|
sub eax,INT_ANGLE_32
|
||||||
|
jnc short adf_20
|
||||||
|
add eax,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_20:
|
||||||
|
mov ebx,640
|
||||||
|
cdq
|
||||||
|
idiv ebx
|
||||||
|
mov [BCOL],edx
|
||||||
|
|
||||||
|
;;; mov eax,89
|
||||||
|
;;; sub ax,[word ptr _ViewHeight]
|
||||||
|
;;; mov [HEIGHT],eax
|
||||||
|
|
||||||
|
sub ecx,INT_ANGLE_32
|
||||||
|
jnc short adf_30
|
||||||
|
add ecx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_30:
|
||||||
|
mov [VA],ecx
|
||||||
|
movzx eax,[word ptr _gWinHeight]
|
||||||
|
sar eax,1
|
||||||
|
movzx ebx,[word ptr _gWinEndY]
|
||||||
|
sub ebx,eax
|
||||||
|
inc ebx
|
||||||
|
sub ebx,5 ; 6
|
||||||
|
mov [EY],ebx
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx eax,[word ptr _gCenterOff]
|
||||||
|
mov ebx,eax
|
||||||
|
add eax,1920
|
||||||
|
add eax,edi
|
||||||
|
mov [BFSCRN],eax
|
||||||
|
sub ebx,1600 ;1920
|
||||||
|
add ebx,edi
|
||||||
|
mov [BCSCRN],ebx
|
||||||
|
mov eax,0
|
||||||
|
mov [DSTPTR],eax
|
||||||
|
mov ebx,[VA]
|
||||||
|
|
||||||
|
adf_loop:
|
||||||
|
|
||||||
|
;;; push ebp
|
||||||
|
|
||||||
|
even
|
||||||
|
|
||||||
|
mov [COLNUM],eax
|
||||||
|
mov eax,[dword ptr _WallDistTable+eax*4]
|
||||||
|
cmp eax,96
|
||||||
|
jb adf_ynext
|
||||||
|
mov [WALLDIST],eax
|
||||||
|
|
||||||
|
mov eax,[_CosTable]
|
||||||
|
shl ebx,2
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [CV],eax
|
||||||
|
mov eax,[_SinTable]
|
||||||
|
mov eax,[eax+ebx]
|
||||||
|
mov [SV],eax
|
||||||
|
|
||||||
|
|
||||||
|
mov eax,[BCSCRN]
|
||||||
|
mov [CSCRN],eax
|
||||||
|
|
||||||
|
mov ecx,[EY]
|
||||||
|
mov ebx,[BCOL]
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adf_l10
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adf_l10:
|
||||||
|
mov eax,[_BackArray+ebx*4]
|
||||||
|
add eax,ecx
|
||||||
|
mov [BA1],eax
|
||||||
|
inc ebx
|
||||||
|
cmp ebx,640
|
||||||
|
jb short adf_l20
|
||||||
|
sub ebx,ebx
|
||||||
|
|
||||||
|
adf_l20:
|
||||||
|
mov [BCOL],ebx
|
||||||
|
lea esi,[offset _zdTable]
|
||||||
|
mov ecx,[EY] ;Number of rows to draw
|
||||||
|
mov [ROWNUM],ecx
|
||||||
|
;; imul eax,ebp,800
|
||||||
|
mov eax,[DSTPTR]
|
||||||
|
|
||||||
|
add esi,eax
|
||||||
|
add esi,24 ;ebx
|
||||||
|
|
||||||
|
add eax,1600
|
||||||
|
mov [DSTPTR],eax
|
||||||
|
|
||||||
|
mov edi,[BFSCRN]
|
||||||
|
mov ecx,[_WallbMaps]
|
||||||
|
|
||||||
|
adf_yloop:
|
||||||
|
mov edx,[esi]
|
||||||
|
cmp edx,[WALLDIST]
|
||||||
|
lea esi,[esi+4]
|
||||||
|
ja adf_ycont
|
||||||
|
|
||||||
|
adf_distokay:
|
||||||
|
cmp [LASTDIST],edx
|
||||||
|
jne short adf_newdist
|
||||||
|
mov ebp,[LASTEBP]
|
||||||
|
mov eax,[LASTEAX]
|
||||||
|
mov edx,[LASTEDX]
|
||||||
|
jmp short adf_samedist
|
||||||
|
|
||||||
|
adf_newdist:
|
||||||
|
mov [LASTDIST],edx
|
||||||
|
|
||||||
|
mov eax,[CV]
|
||||||
|
mov ebx,[SV]
|
||||||
|
imul eax,edx
|
||||||
|
imul ebx,edx
|
||||||
|
sar eax,16
|
||||||
|
sar ebx,16
|
||||||
|
mov edx,[_xPglobal]
|
||||||
|
add eax,edx
|
||||||
|
mov edx,[_yPglobal]
|
||||||
|
add ebx,edx
|
||||||
|
mov edx,ebx
|
||||||
|
and edx,0FC0h
|
||||||
|
mov ebp,eax
|
||||||
|
sar ebp,6
|
||||||
|
add ebp,edx ;Pos within floor and ceiling maps
|
||||||
|
|
||||||
|
and ebx,63
|
||||||
|
shl ebx,6
|
||||||
|
and eax,63
|
||||||
|
add eax,ebx ;bitmap position
|
||||||
|
|
||||||
|
shl ebp,1
|
||||||
|
movzx ebx,[word ptr _FloorMap+ebp]
|
||||||
|
mov [LASTEBP],ebp
|
||||||
|
mov [LASTEAX],eax
|
||||||
|
mov edx,[ecx+ebx*4]
|
||||||
|
add edx,eax
|
||||||
|
mov dl,[edx]
|
||||||
|
mov dh,dl
|
||||||
|
mov [LASTEDX],edx
|
||||||
|
|
||||||
|
adf_samedist:
|
||||||
|
mov [edi],dx
|
||||||
|
|
||||||
|
movzx ebx,[word ptr _CeilMap+ebp]
|
||||||
|
mov ebp,[CSCRN]
|
||||||
|
test bx,bx
|
||||||
|
jz short adf_yback
|
||||||
|
|
||||||
|
mov edx,[ecx+ebx*4]
|
||||||
|
dec [dword ptr BA]
|
||||||
|
add edx,eax
|
||||||
|
mov al,[edx]
|
||||||
|
mov ah,al
|
||||||
|
lea edi,[edi+320]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
mov [ebp],ax
|
||||||
|
|
||||||
|
add ebp,-320
|
||||||
|
mov [CSCRN],ebp
|
||||||
|
dec [dword ptr ROWNUM]
|
||||||
|
jnz adf_yloop
|
||||||
|
|
||||||
|
jmp short adf_ynext
|
||||||
|
|
||||||
|
adf_yback:
|
||||||
|
mov eax,[BA]
|
||||||
|
mov dl,[eax]
|
||||||
|
mov eax,[BA1]
|
||||||
|
mov dh,[eax]
|
||||||
|
mov [ebp],dx
|
||||||
|
|
||||||
|
adf_ycont:
|
||||||
|
lea edi,[edi+320]
|
||||||
|
add [dword ptr CSCRN],-320
|
||||||
|
dec [dword ptr BA]
|
||||||
|
dec [dword ptr BA1]
|
||||||
|
dec [dword ptr ROWNUM]
|
||||||
|
jnz adf_yloop
|
||||||
|
|
||||||
|
adf_ynext:
|
||||||
|
mov ebx,[VA]
|
||||||
|
lea ebx,[ebx+2]
|
||||||
|
cmp ebx,INT_ANGLE_360
|
||||||
|
jb short adf_l90
|
||||||
|
sub ebx,INT_ANGLE_360
|
||||||
|
|
||||||
|
adf_l90:
|
||||||
|
mov [VA],ebx ;Note: EBX is used for VA at top of loop!
|
||||||
|
add [dword ptr BFSCRN],2
|
||||||
|
add [dword ptr BCSCRN],2
|
||||||
|
;;; pop ebp
|
||||||
|
;;; lea ebp,[ebp+2]
|
||||||
|
;;; cmp ebp,320
|
||||||
|
;;; jb adf_loop
|
||||||
|
mov eax,[COLNUM]
|
||||||
|
add eax,2
|
||||||
|
cmp eax,320
|
||||||
|
jb adf_loop
|
||||||
|
|
||||||
|
adf_exit:
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawSolidCeilAndFloor
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
mov al,[byte ptr _gTopColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
ACKCALL AckDrawFloorOnly
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawSolidCeilAndFloorNS
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
mov al,[byte ptr _gTopColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
ACKCALL AckDrawFloorOnlyNS
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawSolidFloorAndCeilNS
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
add edi,ecx
|
||||||
|
mov al,[byte ptr _gBottomColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
ACKCALL AckDrawCeilingOnlyNS
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawSolidFloorAndCeil
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
add edi,ecx
|
||||||
|
mov al,[byte ptr _gBottomColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
ACKCALL AckDrawCeilingOnly
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC DrawSolidCeilSolidFloor
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
mov al,[byte ptr _gTopColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
mov edi,[_gScrnBuffer]
|
||||||
|
movzx ecx,[word ptr _gCenterOff]
|
||||||
|
add edi,ecx
|
||||||
|
mov al,[byte ptr _gBottomColor]
|
||||||
|
mov ah,al
|
||||||
|
shr cx,1
|
||||||
|
rep stosw
|
||||||
|
rcl cx,1
|
||||||
|
rep stosb
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
;
|
||||||
|
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
ACKPROC AckDoubleBuffer
|
||||||
|
push ebp
|
||||||
|
mov ebp,esp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
|
||||||
|
mov esi,[ebp+8] ;Source buffer
|
||||||
|
mov edi,[ebp+12] ;Destination buffer
|
||||||
|
|
||||||
|
mov ecx,200 ;Rows to double
|
||||||
|
|
||||||
|
adb010:
|
||||||
|
mov edx,160 ;Cols to double
|
||||||
|
mov ebx,edi ;Hold onto start of row
|
||||||
|
adb020:
|
||||||
|
lodsw
|
||||||
|
stosb
|
||||||
|
stosb
|
||||||
|
mov al,ah ;Make word
|
||||||
|
stosw ;Store in dest
|
||||||
|
dec edx ;Bump column count
|
||||||
|
jnz adb020
|
||||||
|
sub esi,4
|
||||||
|
mov eax,esi ;Hold onto source
|
||||||
|
mov esi,ebx ;Point at start of row
|
||||||
|
mov edx,ecx ;hold onto row count
|
||||||
|
mov ecx,160 ;Number of dwords
|
||||||
|
rep movsd ;duplicate the row
|
||||||
|
mov esi,eax ;get back the source
|
||||||
|
mov ecx,edx ;get row count back
|
||||||
|
dec ecx
|
||||||
|
jnz adb010 ;loop for all rows
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
348
ack_lib/ACKSND.C
Normal file
348
ack_lib/ACKSND.C
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
/******************* ( Animation Construction Kit 3D ) ***********************/
|
||||||
|
/* Sound Routines: play CMF, VOC files in background on SB, Adlib or speaker */
|
||||||
|
/* CopyRight (c) 1993 Authors: Lary Myers & Frank Sachse */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
//***************************** WARNING **************************************
|
||||||
|
// NOTE: The Worx sound functions have NOT been converted to flat model.
|
||||||
|
// **** DO NOT USE THESE FUNCTIONS!!!! ****
|
||||||
|
//***************************** WARNING **************************************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
#include "acksnd.h"
|
||||||
|
#include "worx.h"
|
||||||
|
|
||||||
|
static short SoundDevice;
|
||||||
|
|
||||||
|
void AckPlayNoSound(short index);
|
||||||
|
void AckPlayPCSpeaker(short index);
|
||||||
|
void AckPlayAdlib(short index);
|
||||||
|
void AckPlaySoundBlaster(short index);
|
||||||
|
short AckPlayMusic(char *MusicFile);
|
||||||
|
|
||||||
|
short IRQ; /* SB */
|
||||||
|
char *Cmf;
|
||||||
|
char *VocTable[SOUND_MAX_INDEX+1];
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Call into here by the application before using any of the sound routines**
|
||||||
|
** The default sound device can be used as an overide, such as when the **
|
||||||
|
** application or user doesn't want any sound. **
|
||||||
|
****************************************************************************/
|
||||||
|
short AckSoundInitialize(short DefaultSoundDevice)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (DefaultSoundDevice == DEV_NOSOUND)
|
||||||
|
{
|
||||||
|
SoundDevice = DefaultSoundDevice;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks for sound board & sets SoundDevice to DEV_ define in ACKSND.H */
|
||||||
|
|
||||||
|
/* for use only with WORX lib, not WORXlite...
|
||||||
|
StartWorx();
|
||||||
|
*/
|
||||||
|
|
||||||
|
StartWorx();
|
||||||
|
|
||||||
|
if (DefaultSoundDevice == DEV_PCSPEAKER)
|
||||||
|
{
|
||||||
|
SoundDevice = DefaultSoundDevice;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AdlibDetect())
|
||||||
|
{
|
||||||
|
SoundDevice = DEV_ADLIB;
|
||||||
|
SetFMVolume(0xf,0xf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SoundDevice = DEV_PCSPEAKER;
|
||||||
|
|
||||||
|
if (DefaultSoundDevice == DEV_ADLIB)
|
||||||
|
{
|
||||||
|
SoundDevice = DEV_ADLIB;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
IRQ = DSPReset();
|
||||||
|
if (IRQ > 0)
|
||||||
|
{
|
||||||
|
SoundDevice = DEV_SOUNDBLASTER;
|
||||||
|
SetMasterVolume(0xf,0xf);
|
||||||
|
SetVOCVolume(0xf,0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* for use only with WORX lib, not WORXlite...
|
||||||
|
IRQ = DSPReset() - if > 0, then SB present
|
||||||
|
if (WorxPresent()) /* use only with WORXlite */
|
||||||
|
{
|
||||||
|
SoundDevice = DEV_SOUNDBLASTER;
|
||||||
|
SetMasterVolume(0xf,0xf);
|
||||||
|
SetVOCVolume(0xf,0xf);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Here the application can call in and load the VOC files that it needs **
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
short AckLoadSound(short VocIndex,char *VocFile)
|
||||||
|
{
|
||||||
|
char buf[81];
|
||||||
|
|
||||||
|
if (SoundDevice == DEV_NOSOUND)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (VocIndex < 0 || VocIndex > SOUND_MAX_INDEX)
|
||||||
|
return(-1); /* index out of range */
|
||||||
|
|
||||||
|
strcpy(buf,VocFile);
|
||||||
|
strtok(buf,".");
|
||||||
|
|
||||||
|
switch (SoundDevice)
|
||||||
|
{
|
||||||
|
case DEV_SOUNDBLASTER:
|
||||||
|
strcat(buf,".VOC"); /* force extension */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_ADLIB: /* adlib can't play voc's -> put thru pc spkr */
|
||||||
|
case DEV_PCSPEAKER:
|
||||||
|
#if 0
|
||||||
|
strcat(buf,".PWM"); /* force extension */
|
||||||
|
#endif
|
||||||
|
strcat(buf,".VOC"); /* force extension */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return(-2); /* Error if unknown device */
|
||||||
|
}
|
||||||
|
|
||||||
|
VocTable[VocIndex] = LoadOneShot(buf); /* load voc/pwm into mem */
|
||||||
|
|
||||||
|
if (VocTable[VocIndex] == NULL)
|
||||||
|
return(-2); /* file not found */
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
void AckStopBackground(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (SoundDevice)
|
||||||
|
{
|
||||||
|
|
||||||
|
case DEV_NOSOUND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_PCSPEAKER:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_SOUNDBLASTER:
|
||||||
|
if (SequencePlaying())
|
||||||
|
StopSequence();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_ADLIB:
|
||||||
|
if (SequencePlaying())
|
||||||
|
StopSequence();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** The Application would call this routine to begin playing background **
|
||||||
|
** music. **
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
short AckPlayBackground(char *MusicFile)
|
||||||
|
{
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
switch (SoundDevice)
|
||||||
|
{
|
||||||
|
|
||||||
|
case DEV_NOSOUND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_PCSPEAKER:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_SOUNDBLASTER:
|
||||||
|
result = AckPlayMusic(MusicFile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_ADLIB:
|
||||||
|
result = AckPlayMusic(MusicFile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Start the music file playing in this routine. **
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
short AckPlayMusic(char *MusicFile)
|
||||||
|
{
|
||||||
|
char *BufPtr;
|
||||||
|
char buf[81];
|
||||||
|
|
||||||
|
strcpy(buf,MusicFile);
|
||||||
|
strtok(buf,"."); /* force CMF extention */
|
||||||
|
strcat(buf,".CMF");
|
||||||
|
|
||||||
|
Cmf = GetSequence(buf); /* load cmf into mem */
|
||||||
|
|
||||||
|
if(Cmf==NULL)
|
||||||
|
return(1);
|
||||||
|
|
||||||
|
SetLoopMode(1); /* set for continuous play */
|
||||||
|
PlayCMFBlock(Cmf); /* play background cmf */
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Call into here to play a particular sound. The indexes available are **
|
||||||
|
** listed in ACKSND.H which will be included by the application. **
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
void AckPlaySound(short SoundIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (SoundDevice)
|
||||||
|
{
|
||||||
|
|
||||||
|
case DEV_NOSOUND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_PCSPEAKER:
|
||||||
|
AckPlayPCSpeaker(SoundIndex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_SOUNDBLASTER:
|
||||||
|
AckPlaySoundBlaster(SoundIndex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_ADLIB: /* can't play VOC's on Adlib -> play thru speaker */
|
||||||
|
AckPlayPCSpeaker(SoundIndex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** This routine is used for simple speaker sounds. The ones here are for **
|
||||||
|
** testing at this point. Better ones would be need to be in the final **
|
||||||
|
** version. **
|
||||||
|
****************************************************************************/
|
||||||
|
/* I will adjust this later to play VOC's thru speaker x*/
|
||||||
|
void AckPlayPCSpeaker(short index)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (VocTable[index] == NULL || index < 0 || index > SOUND_MAX_INDEX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayPWMBlock(VocTable[index]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Sound Blaster routines go here. **
|
||||||
|
** **
|
||||||
|
** **
|
||||||
|
****************************************************************************/
|
||||||
|
void AckPlaySoundBlaster(short index)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (VocTable[index] == NULL || index < 0 || index > SOUND_MAX_INDEX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlayVOCBlock(VocTable[index],255);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** Call into here by the application before exiting. **
|
||||||
|
****************************************************************************/
|
||||||
|
void AckSoundShutdown(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (SoundDevice)
|
||||||
|
{
|
||||||
|
|
||||||
|
case DEV_NOSOUND:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_PCSPEAKER:
|
||||||
|
CloseWorx();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_SOUNDBLASTER:
|
||||||
|
if (SequencePlaying())
|
||||||
|
StopSequence(); /* stop background CMF, if playing */
|
||||||
|
DSPClose(); /* free Sound Blaster DSP */
|
||||||
|
/* for use only with WORX lib, not WORXlite...
|
||||||
|
CloseWorx();
|
||||||
|
*/
|
||||||
|
CloseWorx();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEV_ADLIB:
|
||||||
|
if (SequencePlaying())
|
||||||
|
StopSequence();
|
||||||
|
/* for use only with WORX lib, not WORXlite...
|
||||||
|
CloseWorx();
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
35
ack_lib/ACKSND.H
Normal file
35
ack_lib/ACKSND.H
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* Header file to accompany ACKSND.C */
|
||||||
|
|
||||||
|
#define DEV_NOSOUND 0
|
||||||
|
#define DEV_PCSPEAKER 1
|
||||||
|
#define DEV_SOUNDBLASTER 2
|
||||||
|
#define DEV_ADLIB 3
|
||||||
|
|
||||||
|
#define SOUND_WALKING 0
|
||||||
|
#define SOUND_HITWALL 1
|
||||||
|
#define SOUND_HITOBJECT 2
|
||||||
|
#define SOUND_HITBADOBJECT 3
|
||||||
|
#define SOUND_DOOROPENING 4
|
||||||
|
#define SOUND_SECRETDOOROPENING 5
|
||||||
|
#define SOUND_FIRING 6
|
||||||
|
#define SOUND_DOORCLOSING 7
|
||||||
|
#define SOUND_LOST 8
|
||||||
|
#define SOUND_WON 9
|
||||||
|
#define SOUND_INTRO 10
|
||||||
|
#define SOUND_EXPLODE 11
|
||||||
|
#define SOUND_USER1 12
|
||||||
|
#define SOUND_USER2 13
|
||||||
|
#define SOUND_USER3 14
|
||||||
|
#define SOUND_USER4 15
|
||||||
|
|
||||||
|
#define SOUND_MAX_INDEX 15
|
||||||
|
|
||||||
|
|
||||||
|
short AckSoundInitialize(short DefaultSoundDevice);
|
||||||
|
short AckPlayBackground(char *MusicFile);
|
||||||
|
void AckPlaySound(short SoundIndex);
|
||||||
|
void AckSoundShutdown(void);
|
||||||
|
void AckStopBackground(void);
|
||||||
|
short AckLoadSound(short VocIndex,char *VocFileName);
|
||||||
|
|
||||||
|
|
296
ack_lib/ACKUTIL.C
Normal file
296
ack_lib/ACKUTIL.C
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sel;
|
||||||
|
int off;
|
||||||
|
} SELOFF;
|
||||||
|
|
||||||
|
void AckGetIntVector(int VecNum,int *sel,int *off);
|
||||||
|
void AckSetIntVector(int VecNum,int sel,void *VecOff);
|
||||||
|
void AckKbdInt(void);
|
||||||
|
void AckTimerHandler(void);
|
||||||
|
void AckSetTextMode(void);
|
||||||
|
|
||||||
|
long AckMemUsed;
|
||||||
|
short AckDisplayErrors;
|
||||||
|
SELOFF OldKeybdInt;
|
||||||
|
char AckKeyboardSetup;
|
||||||
|
SELOFF OldTimerInt;
|
||||||
|
char AckTimerSetup;
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Establish a hook into interrupt 9 for keyboard handling
|
||||||
|
// The application can access which key is pressed by looking at the
|
||||||
|
// AckKeys global array
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
void AckSetupKeyboard(void)
|
||||||
|
{
|
||||||
|
AckGetIntVector(9,&OldKeybdInt.sel,&OldKeybdInt.off);
|
||||||
|
AckSetIntVector(9,_CS,AckKbdInt);
|
||||||
|
AckKeyboardSetup = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Establish a hook into the user timer interrupt
|
||||||
|
// The application can access a counter by looking at the AckTimerCounter
|
||||||
|
// global variable.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void AckSetupTimer(void)
|
||||||
|
{
|
||||||
|
AckGetIntVector(0x1C,&OldTimerInt.sel,&OldTimerInt.off);
|
||||||
|
AckSetIntVector(0x1C,_CS,AckKbdInt);
|
||||||
|
AckTimerSetup = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Utility routine used to track memory usage by the ACK engine and
|
||||||
|
// applications.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void *AckMalloc(size_t mSize)
|
||||||
|
{
|
||||||
|
UCHAR *mBlock;
|
||||||
|
|
||||||
|
mSize += sizeof(long);
|
||||||
|
mSize++;
|
||||||
|
mBlock = malloc(mSize);
|
||||||
|
|
||||||
|
if (mBlock == NULL)
|
||||||
|
{
|
||||||
|
if (AckDisplayErrors)
|
||||||
|
{
|
||||||
|
AckSetTextMode();
|
||||||
|
printf("\n\nOut of memory on call to AckMalloc.\n");
|
||||||
|
printf("Memory used: %ld bytes.\n",AckMemUsed);
|
||||||
|
}
|
||||||
|
return(mBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*(UCHAR *)mBlock) = 0xF2;
|
||||||
|
mBlock += 1;
|
||||||
|
(*(long *)mBlock) = mSize;
|
||||||
|
mBlock += sizeof(long);
|
||||||
|
AckMemUsed += mSize;
|
||||||
|
|
||||||
|
return(mBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Matching routine for AckMalloc(). This routine MUST be used to free
|
||||||
|
// memory if AckMalloc() is used to allocate memory.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void AckFree(void *m)
|
||||||
|
{
|
||||||
|
UCHAR *mBlock;
|
||||||
|
long mSize;
|
||||||
|
|
||||||
|
mBlock = (UCHAR *)m;
|
||||||
|
mBlock -= sizeof(long);
|
||||||
|
mBlock -= 1;
|
||||||
|
if ((*(UCHAR *)mBlock) != 0xF2)
|
||||||
|
{
|
||||||
|
if (AckDisplayErrors)
|
||||||
|
{
|
||||||
|
AckSetTextMode();
|
||||||
|
printf("\n\nCorrupt memory block in AckFree.\n");
|
||||||
|
printf("Mem ptr: %p",mBlock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mBlock += 1;
|
||||||
|
mSize = (*(long *)mBlock);
|
||||||
|
mBlock -= 1;
|
||||||
|
AckMemUsed -= mSize;
|
||||||
|
free(mBlock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Read a palette from a file and immediately set it into the VGA regs.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckLoadAndSetPalette(char *PalName)
|
||||||
|
{
|
||||||
|
short handle,ErrCode;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
buf = AckMalloc(800);
|
||||||
|
if (buf == NULL)
|
||||||
|
return(ERR_NOMEMORY);
|
||||||
|
|
||||||
|
ErrCode = 0;
|
||||||
|
if (!rsHandle)
|
||||||
|
handle = _lopen(PalName,O_RDWR|O_BINARY);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = rsHandle;
|
||||||
|
_llseek(handle,rbaTable[(ULONG)PalName],SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle > 0)
|
||||||
|
{
|
||||||
|
read(handle,buf,768);
|
||||||
|
if (!rsHandle)
|
||||||
|
_lclose(handle);
|
||||||
|
|
||||||
|
memset(buf,0,3); // Make sure color 0 is always black
|
||||||
|
AckSetPalette(buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ErrCode = ERR_BADFILE;
|
||||||
|
|
||||||
|
AckFree(buf);
|
||||||
|
return(ErrCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Set up the palette range for light shading. The incoming ranges are in
|
||||||
|
// a 16 by 256 array where there are 16 different distance levels each
|
||||||
|
// having a full color tranlation table for light shading.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void AckSetupPalRanges(ACKENG *ae,ColorRange *ranges)
|
||||||
|
{
|
||||||
|
short i,j,k,found;
|
||||||
|
short rangenos;
|
||||||
|
UCHAR plotcolor;
|
||||||
|
|
||||||
|
if (ae->LightFlag == SHADING_OFF)
|
||||||
|
{
|
||||||
|
for ( i = 0;i<16;i++)
|
||||||
|
{
|
||||||
|
for (j=0;j<256;j++)
|
||||||
|
{
|
||||||
|
ae->PalTable[j+(i*256)] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rangenos = 0; rangenos < 64; rangenos++)
|
||||||
|
{
|
||||||
|
if (ranges[rangenos].start == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0;i<16;i++)
|
||||||
|
{
|
||||||
|
for (j=0;j<256;j++)
|
||||||
|
{
|
||||||
|
found = 0;
|
||||||
|
// find the range the color is in.
|
||||||
|
for ( k = 0; k < rangenos; k++ )
|
||||||
|
{
|
||||||
|
if (j >= ranges[k].start && j < ranges[k].start+ranges[k].length)
|
||||||
|
{
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
//=============================================================================
|
||||||
|
// add color + i;
|
||||||
|
// if color + i > color+range then plot color = 0;
|
||||||
|
// otherwise plotcolor = color+i
|
||||||
|
//=============================================================================
|
||||||
|
if (j+i >= ranges[k].start+ranges[k].length)
|
||||||
|
plotcolor = 0;
|
||||||
|
else
|
||||||
|
plotcolor = j+i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plotcolor = j;
|
||||||
|
}
|
||||||
|
ae->PalTable[j+(i*256)] = plotcolor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Returns the index of the last object hit by the POV.
|
||||||
|
// The variable LastObjectHit can also be accessed globally.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckGetObjectHit(void)
|
||||||
|
{
|
||||||
|
return(LastObjectHit);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Returns the map location of the last wall hit. LastMapPosn is a global
|
||||||
|
// variable.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckGetWallHit(void)
|
||||||
|
{
|
||||||
|
return(LastMapPosn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Sets the object to inactive. The memory used by the object is NOT
|
||||||
|
// freed by this routine.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckDeleteObject(ACKENG *ae,short ObjIndex)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ae->ObjList[ObjIndex] == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
if (!ae->ObjList[ObjIndex]->Active)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
ae->ObjList[ObjIndex]->Active = 0;
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Sets a new wall or object index into the map array specified.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckSetNewBitmap(short index,UCHAR **Maps,UCHAR *NewBitmap)
|
||||||
|
{
|
||||||
|
UCHAR *bPtr;
|
||||||
|
|
||||||
|
bPtr = Maps[index];
|
||||||
|
Maps[index] = NewBitmap;
|
||||||
|
|
||||||
|
if (bPtr != NULL)
|
||||||
|
AckFree(bPtr);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Obsolete routine for real mode. Flat model memory can be freed by the
|
||||||
|
// application. Real mode required XMS memory to be handled. This routine
|
||||||
|
// is maintained for backward compatability with the older versions.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckFreeBitmap(UCHAR *bmType)
|
||||||
|
{
|
||||||
|
short i;
|
||||||
|
UCHAR *Bmp;
|
||||||
|
|
||||||
|
if (bmType != NULL)
|
||||||
|
AckFree(bmType);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
851
ack_lib/ACKVIEW.C
Normal file
851
ack_lib/ACKVIEW.C
Normal file
|
@ -0,0 +1,851 @@
|
||||||
|
// This file contains the declarations and functions to set up views for the
|
||||||
|
// ray casting engine.
|
||||||
|
#include <windows.h> // Required for Windows version of engine
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "ack3d.h" // Main ACK-3D internal and interface data structures
|
||||||
|
#include "ackeng.h" // Intrnal structures and constants
|
||||||
|
#include "ackext.h" // Defines external (global) variables
|
||||||
|
|
||||||
|
extern long FloorCosTable[];
|
||||||
|
|
||||||
|
void (*FloorCeilRtn)(void);
|
||||||
|
void (*WallRtn)(void);
|
||||||
|
void (*WallMaskRtn)(void);
|
||||||
|
|
||||||
|
short gWinFullWidth; // Global variables for setting up a viewport
|
||||||
|
long gWinDWORDS; // These are the global variables used by the
|
||||||
|
long gWinStartOffset; // low-level assembly language routines to draw slices
|
||||||
|
short gWinStartX;
|
||||||
|
short gWinStartY;
|
||||||
|
short gWinEndX;
|
||||||
|
short gWinEndY;
|
||||||
|
short gWinHeight;
|
||||||
|
short gWinHalfHeight;
|
||||||
|
short gWinWidth;
|
||||||
|
short gCenterRow;
|
||||||
|
short gCenterOff;
|
||||||
|
long gBottomOff;
|
||||||
|
UCHAR *gScrnBufferCenter;
|
||||||
|
UCHAR *gScrnBuffer;
|
||||||
|
UCHAR *gBkgdBuffer;
|
||||||
|
UCHAR *gPalTable;
|
||||||
|
short gMultiWalls;
|
||||||
|
|
||||||
|
UCHAR **mxGridGlobal; // Global variables to reference the x and y
|
||||||
|
UCHAR **myGridGlobal; // map arrays
|
||||||
|
|
||||||
|
UCHAR gTopColor;
|
||||||
|
UCHAR gBottomColor;
|
||||||
|
|
||||||
|
UCHAR *scVid; // Variables used in low level routines for
|
||||||
|
UCHAR *scWall; // building and drawing slices
|
||||||
|
UCHAR *scPal;
|
||||||
|
short scdst;
|
||||||
|
short scwht;
|
||||||
|
short scmulti;
|
||||||
|
short sctopht;
|
||||||
|
short scbotht;
|
||||||
|
short scsavwht;
|
||||||
|
short scmulcnt;
|
||||||
|
UCHAR *scsavVid;
|
||||||
|
USHORT scbNum;
|
||||||
|
UCHAR *scMulData;
|
||||||
|
UCHAR *scColumn;
|
||||||
|
UCHAR *gPtr;
|
||||||
|
UCHAR *gmPtr;
|
||||||
|
short gBitmapNumber;
|
||||||
|
short gBitmapColumn;
|
||||||
|
short gyBitmapNumber;
|
||||||
|
short gyBitmapColumn;
|
||||||
|
long gWallDistance;
|
||||||
|
short gmPos;
|
||||||
|
DOORS *gDoor;
|
||||||
|
DOORS *gDoorPosn;
|
||||||
|
short wFound;
|
||||||
|
UCHAR *mgPtr;
|
||||||
|
|
||||||
|
short BegX,EndX;
|
||||||
|
|
||||||
|
extern long x_xPos; // Variables for tracking coordinates during
|
||||||
|
extern long x_yPos; // the ray casting process
|
||||||
|
extern long x_xNext;
|
||||||
|
extern long x_yNext;
|
||||||
|
extern long y_xPos;
|
||||||
|
extern long y_yPos;
|
||||||
|
extern long y_xNext;
|
||||||
|
extern long y_yNext;
|
||||||
|
|
||||||
|
short LastVht;
|
||||||
|
long WallDistTable[VIEW_WIDTH];
|
||||||
|
|
||||||
|
// Functions used to build views and perform the ray casting process
|
||||||
|
void AckSetupWindow(ACKENG *ae); // Sets up variables for viewport
|
||||||
|
void BuildUpView(void); // Main assemply language routine for building views
|
||||||
|
void BuildSlice(void); // Assembly language routines for building slices
|
||||||
|
void BuildSliceMulti(void); // Assembly language routine for building multi-slices
|
||||||
|
void CheckDoors(void); // Internal routines for locating and checking doors
|
||||||
|
void FindObject(void); // and objects
|
||||||
|
short FindDoor(short MapPosn);
|
||||||
|
|
||||||
|
void FloorLoop(void);
|
||||||
|
void CeilLoop(void);
|
||||||
|
void DrawSlices(void);
|
||||||
|
short BlankSlice(USHORT col,UCHAR *bmp);
|
||||||
|
void BuildSliceAsm(void);
|
||||||
|
|
||||||
|
void xRaySetup(void); // Routines for setting up and casting rays
|
||||||
|
USHORT xRayCast(void);
|
||||||
|
void yRaySetup(void);
|
||||||
|
USHORT yRayCast(void);
|
||||||
|
USHORT xRayCastMulti(void);
|
||||||
|
USHORT yRayCastMulti(void);
|
||||||
|
|
||||||
|
void ShowCol(void); // Routines for drawing a slice
|
||||||
|
void ShowColMask(void); // column by column
|
||||||
|
void ShowColNS(void);
|
||||||
|
void ShowColMaskNS(void);
|
||||||
|
void ShowColLow(void);
|
||||||
|
void ShowColMaskLow(void);
|
||||||
|
|
||||||
|
void DrawFloorCeiling(void); // Routines for drawing floors and ceilings
|
||||||
|
void AckDrawFloor(void);
|
||||||
|
void AckDrawFloorOnly(void);
|
||||||
|
void AckDrawCeilingOnly(void);
|
||||||
|
void AckDrawFloorNS(void);
|
||||||
|
void AckDrawFloorOnlyNS(void);
|
||||||
|
void AckDrawCeilingOnlyNS(void);
|
||||||
|
void AckDrawFloorHz(void);
|
||||||
|
void AckDrawOneFloor(void);
|
||||||
|
void DrawSolidCeilAndFloor(void);
|
||||||
|
void DrawSolidCeilAndFloorNS(void);
|
||||||
|
void DrawSolidFloorAndCeil(void);
|
||||||
|
void DrawSolidFloorAndCeilNS(void);
|
||||||
|
void DrawSolidCeilSolidFloor(void);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Transfers certain variables from the interface structure to global
|
||||||
|
// variables that can be accessed faster by the drawing functions. The
|
||||||
|
// interface structure is kept by the application and more than one of
|
||||||
|
// them can be used for different views. Each time a new view needs to
|
||||||
|
// be processed, this function MUST be called before calling the
|
||||||
|
// drawing routines.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void AckRegisterStructure(ACKENG *ae)
|
||||||
|
{
|
||||||
|
int mode,i;
|
||||||
|
|
||||||
|
aeGlobal = ae; // Global variable to reference ACKENG structure
|
||||||
|
AckSetupWindow(ae); // Assign window variables to ACKENG structure
|
||||||
|
xGridGlobal = ae->xGrid; // Global map for x walls
|
||||||
|
yGridGlobal = ae->yGrid; // Global map for y walls
|
||||||
|
mxGridGlobal = ae->mxGrid; // Wall data for multi-height walls
|
||||||
|
myGridGlobal = ae->myGrid;
|
||||||
|
WallbMaps = ae->bMaps; // Wall bitmap data
|
||||||
|
gWinStartX = ae->WinStartX; // Coordinates of viewport; upper-left
|
||||||
|
gWinStartY = ae->WinStartY;
|
||||||
|
gWinEndX = ae->WinEndX; // Lower-right viewport coordinates
|
||||||
|
gWinEndY = ae->WinEndY;
|
||||||
|
gWinHeight = ae->WinHeight; // Height of viewport
|
||||||
|
gWinWidth = ae->WinWidth; // Width of viewport
|
||||||
|
gWinHalfHeight = (gWinEndY - (gWinHeight >> 1)) + 1;
|
||||||
|
gCenterRow = ae->CenterRow; // Start of center row in viewport
|
||||||
|
gCenterOff = ae->CenterOffset; // Offset to center of viewport
|
||||||
|
gScrnBuffer = ae->ScreenBuffer; // Screen buffer access
|
||||||
|
gScrnBufferCenter = gScrnBuffer + gCenterOff;
|
||||||
|
gBkgdBuffer = ae->BkgdBuffer; // Buffer for ceiling and floors
|
||||||
|
gPalTable = ae->PalTable; // Palette of colors used
|
||||||
|
gDoor = &ae->Door[0]; // List of moving doors
|
||||||
|
gTopColor = ae->TopColor; // Base color of ceiling
|
||||||
|
gBottomColor = ae->BottomColor; // Base color of floor
|
||||||
|
LightFlag = ae->LightFlag; // Light shading on or off indicator
|
||||||
|
SysFlags = ae->SysFlags; // Scene display attributes (floors and ceilings)
|
||||||
|
|
||||||
|
mode = 0; // Draw both textured floor and ceiling
|
||||||
|
if (SysFlags & SYS_SOLID_CEIL) // Soild ceiling is selcted
|
||||||
|
{
|
||||||
|
mode = 1; // Draw floor only (ceiling will be solid)
|
||||||
|
if (SysFlags & SYS_SOLID_FLOOR) // Solid floor is selcted
|
||||||
|
mode = 2; // Draw solid floor and ceiling
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SysFlags & SYS_SOLID_FLOOR) // Solid floor is selected
|
||||||
|
{
|
||||||
|
if (!mode)
|
||||||
|
mode = 3; // Draw Ceiling only (floor will be solid)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LightFlag) // No light shading used
|
||||||
|
{
|
||||||
|
WallRtn = ShowColNS; // Assembly routines for drawing slices
|
||||||
|
WallMaskRtn = ShowColMaskNS; // using light shading
|
||||||
|
switch (mode) // Check floor and ceiling type
|
||||||
|
{
|
||||||
|
case 0: // Draw both solid floor and ceiling
|
||||||
|
if (ae->SysFlags & SYS_SINGLE_BMP)
|
||||||
|
FloorCeilRtn = AckDrawOneFloor; // Use the same bitmap for each
|
||||||
|
else
|
||||||
|
FloorCeilRtn = AckDrawFloorHz;
|
||||||
|
break;
|
||||||
|
case 1: // Draw solid ceiling and texture floor
|
||||||
|
FloorCeilRtn = DrawSolidCeilAndFloorNS;
|
||||||
|
break;
|
||||||
|
case 2: // Draw both solid floor and solid ceiling
|
||||||
|
FloorCeilRtn = DrawSolidCeilSolidFloor;
|
||||||
|
break;
|
||||||
|
case 3: // Draw solid floor and texture ceiling
|
||||||
|
FloorCeilRtn = DrawSolidFloorAndCeilNS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Light shading is used
|
||||||
|
{
|
||||||
|
WallRtn = ShowCol; // Assembly routines for drawing slices
|
||||||
|
WallMaskRtn = ShowColMask; // using light shading
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 0: // Draw both floor and ceiling
|
||||||
|
FloorCeilRtn = AckDrawFloor;
|
||||||
|
break;
|
||||||
|
case 1: // Draw solid ceiling and texture floor
|
||||||
|
FloorCeilRtn = DrawSolidCeilAndFloor;
|
||||||
|
break;
|
||||||
|
case 2: // Draw both solid floor and solid ceiling
|
||||||
|
FloorCeilRtn = DrawSolidCeilSolidFloor;
|
||||||
|
break;
|
||||||
|
case 3: // Draw solid floor and texture ceiling
|
||||||
|
FloorCeilRtn = DrawSolidFloorAndCeil;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test to see if viewport is full width (320 units)
|
||||||
|
gWinStartOffset = ae->WinStartOffset; // Offset to viewport
|
||||||
|
gBottomOff = (gWinEndY * 320);
|
||||||
|
gWinFullWidth = 0; // Set flag to indicate viewport is not full width
|
||||||
|
if (gWinStartX == 0 && gWinEndX == 319) // Viewport is full size
|
||||||
|
{
|
||||||
|
gWinFullWidth = 1; // Indicates viewport is full size
|
||||||
|
gWinDWORDS = (gWinEndY - gWinStartY) * 80; // Calculate number of double
|
||||||
|
} // words to access buffer
|
||||||
|
|
||||||
|
// Test to see if multi-height walls are used
|
||||||
|
gMultiWalls = 0;
|
||||||
|
for (i = 0; i < GRID_MAX; i++)
|
||||||
|
{
|
||||||
|
if ((xGridGlobal[i] & WALL_TYPE_MULTI) || (yGridGlobal[i] & WALL_TYPE_MULTI))
|
||||||
|
{
|
||||||
|
gMultiWalls = 1; // Indicates multi-height walls are used
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Render the current scene into the off-screen buffer based on the POV
|
||||||
|
// coordinates and angle. This function does NOT display the scene once
|
||||||
|
// it is rendered so the application can overlay graphics into the buffer
|
||||||
|
// before it is actually displayed.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void AckBuildView(void)
|
||||||
|
{
|
||||||
|
// Set up global variables to be used with assembly language routines
|
||||||
|
xPglobal = aeGlobal->xPlayer; // The player's x coordinate
|
||||||
|
xBegGlobal = xPglobal & GRID_MASK; // Upper left corner (x) of the grid
|
||||||
|
// square the player is in
|
||||||
|
xPglobalHI = ((long)xPglobal << FP_SHIFT); // Convert x coordinate to fixed point
|
||||||
|
yPglobal = aeGlobal->yPlayer; // The player's y coordinate
|
||||||
|
yBegGlobal = yPglobal & GRID_MASK; // Upper left corner (y) of grid square
|
||||||
|
yPglobalHI = ((long)yPglobal << FP_SHIFT); // Convert y coordinate to fixed point
|
||||||
|
PlayerAngle = aeGlobal->PlayerAngle; // The player's angle
|
||||||
|
SysFlags = aeGlobal->SysFlags; // Ceiling and floor attributes;
|
||||||
|
BuildUpView(); // Assembly routine defined in ACKRTN3.ASM. This routine
|
||||||
|
// kicks off the ray casting process.
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Stub function for drawing slices that do not contain walls.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void ShowNone(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Internal function to cast the x and y rays and build a slice structure
|
||||||
|
// for each column of the viewing window.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void BuildSlice(void)
|
||||||
|
{
|
||||||
|
short j,index,wFound;
|
||||||
|
long xBitmap,yBitmap,BitmapNumber;
|
||||||
|
short DoorOpenColumn;
|
||||||
|
ULONG xDistance,yDistance;
|
||||||
|
ULONG xd,yd,mf;
|
||||||
|
long WallDistance,UnAdjustDist;
|
||||||
|
long distance,LightAdj;
|
||||||
|
USHORT BitmapColumn,yBitmapColumn;
|
||||||
|
long OldMapPosn,OldMapPosn1;
|
||||||
|
long HoldAngle;
|
||||||
|
long offset;
|
||||||
|
long mPos;
|
||||||
|
|
||||||
|
USHORT *gPtr;
|
||||||
|
UCHAR *mgPtr;
|
||||||
|
SLICE *spNext;
|
||||||
|
|
||||||
|
WallDistance = 3000000; // Set to a ridiculous distance
|
||||||
|
sPtr->Distance = 200; // Initialize the distance from the POV to the slice
|
||||||
|
wFound = 0; // Wall not found yet
|
||||||
|
sPtr->Fnc = ShowNone; // Use the stub function for now for drawing the slice
|
||||||
|
|
||||||
|
// Call the low level ray casting function and see if anything is hit.
|
||||||
|
if ((BitmapNumber = xRayCast()) != 0) // Something has been hit while casting
|
||||||
|
{ // in the x plane
|
||||||
|
wFound = 1; // Set flag to indicate a hit
|
||||||
|
// Use the y intercept to determine the column of the slice
|
||||||
|
BitmapColumn = (LastY1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
|
||||||
|
// Keep the orientation the same no matter which side we're on
|
||||||
|
if ((short)iLastX < xPglobal)
|
||||||
|
BitmapColumn = (BITMAP_WIDTH-1) - BitmapColumn;
|
||||||
|
|
||||||
|
// Did we strike a door?
|
||||||
|
if ((BitmapNumber & (DOOR_TYPE_SLIDE+DOOR_TYPE_SPLIT)))
|
||||||
|
{
|
||||||
|
index = FindDoor(xMapPosn); // Locate the position of the door
|
||||||
|
if (index >= 0) // Is this is a valid door?
|
||||||
|
{
|
||||||
|
j = aeGlobal->Door[index].ColOffset; // Get the door's current pos
|
||||||
|
offset = 0;
|
||||||
|
if (BitmapNumber & DOOR_TYPE_SLIDE) // Is the door a slider?
|
||||||
|
{
|
||||||
|
DoorOpenColumn = BITMAP_WIDTH-1;
|
||||||
|
if ((short)iLastX > xPglobal) // Handle orientation
|
||||||
|
j = -j;
|
||||||
|
BitmapColumn += j; // Adjust column to show
|
||||||
|
}
|
||||||
|
if (BitmapNumber & DOOR_TYPE_SPLIT) // Is the door a split door?
|
||||||
|
{
|
||||||
|
DoorOpenColumn = (BITMAP_WIDTH/2)-1;
|
||||||
|
if (BitmapColumn < (BITMAP_WIDTH/2))
|
||||||
|
{
|
||||||
|
BitmapColumn += j;
|
||||||
|
if (BitmapColumn > (BITMAP_WIDTH/2)-1)
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BitmapColumn -= j;
|
||||||
|
if (BitmapColumn < (BITMAP_WIDTH/2))
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
} // End processing split door
|
||||||
|
|
||||||
|
if (offset == 1 || BitmapColumn > (BITMAP_WIDTH-1))
|
||||||
|
{
|
||||||
|
// Get the grid coordinates for this door
|
||||||
|
OldMapPosn = aeGlobal->Door[index].mPos;
|
||||||
|
OldMapPosn1 = aeGlobal->Door[index].mPos1;
|
||||||
|
// Fake the engine into thinking no door is there
|
||||||
|
xGridGlobal[OldMapPosn] = 0;
|
||||||
|
xGridGlobal[OldMapPosn1] = 0;
|
||||||
|
// Cast the ray to get walls beyond the door
|
||||||
|
BitmapNumber = xRayCast();
|
||||||
|
// Put back the door codes if not fully open
|
||||||
|
if (aeGlobal->Door[index].ColOffset < DoorOpenColumn)
|
||||||
|
{
|
||||||
|
xGridGlobal[OldMapPosn] = aeGlobal->Door[index].mCode;
|
||||||
|
xGridGlobal[OldMapPosn1] = aeGlobal->Door[index].mCode1;
|
||||||
|
}
|
||||||
|
// Calc the new bitmap column of wall behind door
|
||||||
|
BitmapColumn = (LastY1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
if ((short)iLastX < xPglobal)
|
||||||
|
BitmapColumn = (BITMAP_WIDTH-1) - BitmapColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // End processing doors
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// Calculate the distance to the wall. Since the x position was
|
||||||
|
// fixed to move 64 or -64 we can use it to determine the actual
|
||||||
|
// wall distance. The InvCosTable values were stored with a fixed
|
||||||
|
// point of 20 decimal places. At this time we'll knock off 14 of
|
||||||
|
// them so we can later multiply with a fixed point value of 16
|
||||||
|
//==============================================================
|
||||||
|
xd = iLastX - xPglobal; // x Distance to the found slice
|
||||||
|
mf = InvCosTable[ViewAngle]; // Get the cosine of the angle
|
||||||
|
WallDistance = (xd * mf) >> 10; // Calculate the actual distance to the slice
|
||||||
|
if (WallDistance > 33554432L) // Check for out of range
|
||||||
|
WallDistance = 1200000L;
|
||||||
|
gPtr = xGridGlobal; // Point to xGrid map
|
||||||
|
mgPtr = mxGridGlobal[xMapPosn]; // Point to grid map for multi-height walls
|
||||||
|
mPos = xMapPosn; // Access actual map position
|
||||||
|
} // End (if BitmapNumber = xRayCast() ...)
|
||||||
|
|
||||||
|
// Time to cast the ray in the y plane
|
||||||
|
if ((yBitmap = yRayCast()) != 0) // Something has been hit while casting
|
||||||
|
{
|
||||||
|
// Use the X intercept to determine the column of the bitmap
|
||||||
|
yBitmapColumn = (LastX1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
// Handle orientation from either side of the wall
|
||||||
|
if ((short)iLastY > yPglobal)
|
||||||
|
yBitmapColumn = (BITMAP_WIDTH-1) - yBitmapColumn;
|
||||||
|
|
||||||
|
// Did we strike a door?
|
||||||
|
if ((yBitmap & (DOOR_TYPE_SLIDE+DOOR_TYPE_SPLIT)))
|
||||||
|
{
|
||||||
|
index = FindDoor(yMapPosn);
|
||||||
|
if (index >= 0) // Is this is a valid door?
|
||||||
|
{
|
||||||
|
// Get the current door column offset
|
||||||
|
j = aeGlobal->Door[index].ColOffset;
|
||||||
|
offset = 0;
|
||||||
|
// Deal with orientation
|
||||||
|
if (yBitmap & DOOR_TYPE_SLIDE) // Is this a sliding door?
|
||||||
|
{
|
||||||
|
DoorOpenColumn = BITMAP_WIDTH-1;
|
||||||
|
if ((short)iLastY < yPglobal)
|
||||||
|
j = -j;
|
||||||
|
yBitmapColumn += j;
|
||||||
|
} // End processing sliding door
|
||||||
|
if (yBitmap & DOOR_TYPE_SPLIT) // Is this a split door?
|
||||||
|
{
|
||||||
|
DoorOpenColumn = (BITMAP_WIDTH/2)-1;
|
||||||
|
if (yBitmapColumn < (BITMAP_WIDTH/2))
|
||||||
|
{
|
||||||
|
yBitmapColumn += j;
|
||||||
|
if (yBitmapColumn > (BITMAP_WIDTH/2)-1)
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yBitmapColumn -= j;
|
||||||
|
if (yBitmapColumn < (BITMAP_WIDTH/2))
|
||||||
|
offset = 1;
|
||||||
|
}
|
||||||
|
} // End processing split door
|
||||||
|
// If beyond width of bitmap than cast again
|
||||||
|
if (offset == 1 || yBitmapColumn > (BITMAP_WIDTH-1))
|
||||||
|
{
|
||||||
|
// Get the yGrid coordinates for this door
|
||||||
|
OldMapPosn = aeGlobal->Door[index].mPos;
|
||||||
|
OldMapPosn1 = aeGlobal->Door[index].mPos1;
|
||||||
|
// Fool the engine into thinking no door is there
|
||||||
|
yGridGlobal[OldMapPosn] = 0;
|
||||||
|
yGridGlobal[OldMapPosn1] = 0;
|
||||||
|
// Cast again for walls beyond the door
|
||||||
|
yBitmap = yRayCast();
|
||||||
|
// Put door code back if not fully open
|
||||||
|
if (aeGlobal->Door[index].ColOffset < DoorOpenColumn)
|
||||||
|
{
|
||||||
|
yGridGlobal[OldMapPosn] = aeGlobal->Door[index].mCode;
|
||||||
|
yGridGlobal[OldMapPosn1] = aeGlobal->Door[index].mCode1;
|
||||||
|
}
|
||||||
|
// Get the bitmap column of wall beyond door
|
||||||
|
yBitmapColumn = (LastX1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
if ((short)iLastY > yPglobal)
|
||||||
|
yBitmapColumn = (BITMAP_WIDTH-1) - yBitmapColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// Calculate the distance to the wall. Since the y position was
|
||||||
|
// fixed to move 64 or -64 we can use it to determine the actual
|
||||||
|
// wall distance. The InvSinTable values were stored with a fixed
|
||||||
|
// point of 20 decimal places. At this time we'll knock off 14 of
|
||||||
|
// them so we can later multiply with a fixed point value of 16
|
||||||
|
//==============================================================
|
||||||
|
yd = iLastY - yPglobal; // Distance from player's position to intersection point
|
||||||
|
mf = InvSinTable[ViewAngle]; // Use angle with look up table
|
||||||
|
yDistance = (yd * mf) >> 8; // Calculate y distance
|
||||||
|
if (yDistance > 33554432L) // Distance is out of range, adjust
|
||||||
|
yDistance = 120000L;
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// At this point check the distance to the y wall against the x
|
||||||
|
// wall to see which one is closer. The closer one is the one
|
||||||
|
// we'll draw at this column of the screen.
|
||||||
|
//==============================================================
|
||||||
|
if (yDistance < WallDistance) // Use distance to y slice if this slice is closer
|
||||||
|
{
|
||||||
|
wFound = 1; // Indicates that a slice has been found
|
||||||
|
WallDistance = yDistance; // Use distance to y slice
|
||||||
|
BitmapNumber = yBitmap; // Transfer bitmap number
|
||||||
|
BitmapColumn = yBitmapColumn; // Transfer bitmap column
|
||||||
|
gPtr = yGridGlobal; // Store pointer to global y grid
|
||||||
|
mPos = yMapPosn; // Store position of y wall in map
|
||||||
|
mgPtr = myGridGlobal[mPos];
|
||||||
|
}
|
||||||
|
} // End (if yBitmap = yRayCast()) != 0)
|
||||||
|
|
||||||
|
// A slice has been found so process it
|
||||||
|
if (wFound)
|
||||||
|
{
|
||||||
|
//=============================================================
|
||||||
|
// To avoid a fishbowl affect we need to adjust the distance so
|
||||||
|
// it appears perpendicular to the center point of the display
|
||||||
|
// which is relative angle 0 from the players current angle. We
|
||||||
|
// started at -32 degrees for the first screen column and will
|
||||||
|
// cycle from -32 down to 0 then back up to +32 degrees. This
|
||||||
|
// cosine value was pre-calculated and placed in ViewCosTable.
|
||||||
|
//=============================================================
|
||||||
|
UnAdjustDist = WallDistance >> 5;
|
||||||
|
yd = ViewCosTable[ViewColumn] >> 3; // Use current column as look up index
|
||||||
|
WallDistance *= yd;
|
||||||
|
|
||||||
|
// Now we strip off somemore decimal points and check round-up
|
||||||
|
xd = WallDistance >> 12;
|
||||||
|
if (WallDistance - (xd << 12) >= 2048)
|
||||||
|
xd++;
|
||||||
|
|
||||||
|
// The last decimal points from the multiplication after the x and
|
||||||
|
// y rays is stripped off and checked for round-up
|
||||||
|
WallDistance = xd >> 5;
|
||||||
|
if (xd - (WallDistance << 5) >= 16)
|
||||||
|
WallDistance++;
|
||||||
|
|
||||||
|
// This is an arbitrary minimum distance to look for
|
||||||
|
if (WallDistance < 10)
|
||||||
|
WallDistance = 10; // Reset distance to minimum allowed
|
||||||
|
|
||||||
|
// Don't want it to go outside our table boundaries
|
||||||
|
if (WallDistance >= MAX_DISTANCE)
|
||||||
|
WallDistance = MAX_DISTANCE - 1; // Reset distance to max allowed
|
||||||
|
|
||||||
|
// Save the wall data to display when done with entire screen
|
||||||
|
sPtr->Distance = WallDistance; // Store the adjusted distance to the wall
|
||||||
|
sPtr->bNumber = BitmapNumber; // The bitmap number for the wall slice
|
||||||
|
sPtr->bColumn = BitmapColumn; // The screen column position to display the bitmap
|
||||||
|
sPtr->bMap = WallbMaps; // Pointer to the bitmap
|
||||||
|
sPtr->Active = 0; // Indicates slice is not displayable yetlast one
|
||||||
|
sPtr->Type = ST_WALL; // Indicates this slice is part of a wall
|
||||||
|
sPtr->Fnc = WallRtn; // Pointer to function to draw slice
|
||||||
|
sPtr->mPos = mPos; // Position of the slice in the grid map
|
||||||
|
sPtr->mPtr = mgPtr; // Grid pointer to reference multi-height wall
|
||||||
|
spNext = sPtr->Next; // Reference wall slice behind current slice
|
||||||
|
|
||||||
|
if (WallDistance > MaxDistance)
|
||||||
|
MaxDistance = WallDistance;
|
||||||
|
if (CeilMap[mPos])
|
||||||
|
LastWallHeight = 9000;
|
||||||
|
if (((BitmapNumber & WALL_TYPE_UPPER) || // Wall is above the floor level
|
||||||
|
(BitmapNumber & WALL_TYPE_TRANS)) && // or wall slice is transparent and it
|
||||||
|
spNext != NULL) // has something behind it
|
||||||
|
{
|
||||||
|
BitmapColumn = gPtr[mPos]; // Get position of the mult-height wall
|
||||||
|
gPtr[mPos] = 0;
|
||||||
|
sPtr->Active = 1; // More slices to follow if wall is displayable!
|
||||||
|
if (BitmapNumber & WALL_TYPE_TRANS) // The wall is transparent
|
||||||
|
{
|
||||||
|
sPtr->Type = ST_OBJECT; // We have an object
|
||||||
|
sPtr->Fnc = WallMaskRtn; // Using a different drawing routine
|
||||||
|
}
|
||||||
|
sPtr = spNext; // Point to slice behind
|
||||||
|
spNext->Active = 0; // Initialize the slice behind before building it
|
||||||
|
spNext->bNumber = 0;
|
||||||
|
BuildSlice(); // Call BuildSlice() again to build the slice behind
|
||||||
|
gPtr[mPos] = BitmapColumn; // Store position of slice
|
||||||
|
if (!sPtr->bNumber) // Slice behind is no longer visible
|
||||||
|
{
|
||||||
|
spNext = sPtr->Prev; // Link up slices
|
||||||
|
if (spNext != NULL)
|
||||||
|
spNext->Active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Keep tack of each distance to wall slice for drawing floor later on
|
||||||
|
if (UnAdjustDist < WallDistTable[ViewColumn])
|
||||||
|
WallDistTable[ViewColumn] = UnAdjustDist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Continues the ray cast for multi-height walls so that any wall that is
|
||||||
|
// taller than the walls in front of it will be displayed.
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
void BuildSliceMulti(void)
|
||||||
|
{
|
||||||
|
short j,index,wFound;
|
||||||
|
USHORT yHeight;
|
||||||
|
USHORT xBitmap,yBitmap,BitmapNumber;
|
||||||
|
short DoorOpenColumn;
|
||||||
|
short xWallHeight,yWallHeight;
|
||||||
|
ULONG xDistance,yDistance;
|
||||||
|
ULONG xd,yd,mf;
|
||||||
|
|
||||||
|
long WallDistance;
|
||||||
|
USHORT distance,LightAdj;
|
||||||
|
USHORT BitmapColumn,yBitmapColumn;
|
||||||
|
short OldMapPosn,OldMapPosn1;
|
||||||
|
short HoldAngle,HoldX,HoldY,xp1,yp1;
|
||||||
|
USHORT offset;
|
||||||
|
short mPos;
|
||||||
|
USHORT *gPtr;
|
||||||
|
UCHAR *mgPtr;
|
||||||
|
SLICE *spNext;
|
||||||
|
|
||||||
|
WallDistance = 3000000; // Set to a very far off distance
|
||||||
|
wFound = 0; // Indicates a slice has not been found
|
||||||
|
|
||||||
|
// Don't cast an x ray if its impossible to intercept any x walls
|
||||||
|
if (ViewAngle != INT_ANGLE_90 && ViewAngle != INT_ANGLE_270)
|
||||||
|
{
|
||||||
|
if ((BitmapNumber = xRayCastMulti()) != 0) // Cast the x ray and build multi-height slice
|
||||||
|
{
|
||||||
|
xBitmap = BitmapNumber & 0xFF; // Get the bitmap code
|
||||||
|
if (((BitmapNumber & WALL_TYPE_MULTI) || // Check for multi-height
|
||||||
|
(BitmapNumber & WALL_TYPE_UPPER)) && // or slice that is taller than one in front
|
||||||
|
(xBitmap > LastWallHeight))
|
||||||
|
{
|
||||||
|
// LastWallHeight = xBitmap;
|
||||||
|
wFound = 1; // Indicates a multi-slice wall has been found
|
||||||
|
// Use the y intercept to determine the wall column
|
||||||
|
BitmapColumn = (LastY1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
|
||||||
|
// Keep the orientation the same no matter which side we're on
|
||||||
|
if ((short)iLastX < xPglobal)
|
||||||
|
BitmapColumn = (BITMAP_WIDTH-1) - BitmapColumn;
|
||||||
|
xd = iLastX - xPglobal;
|
||||||
|
mf = InvCosTable[ViewAngle]; // Use angle to calculate distance to slice
|
||||||
|
WallDistance = (xd * mf) >> 10;
|
||||||
|
if (WallDistance > 33554432L) // Check for out of range
|
||||||
|
WallDistance = 1200000L;
|
||||||
|
gPtr = xGridGlobal; // Reference global map grid
|
||||||
|
mPos = xMapPosn; // Use position of slice
|
||||||
|
mgPtr = mxGridGlobal[mPos]; // Get pointer to multi-height slice found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't cast a y ray if its impossible to intercept any y walls
|
||||||
|
if (ViewAngle != 0 && ViewAngle != INT_ANGLE_180)
|
||||||
|
{
|
||||||
|
if ((yBitmap = yRayCastMulti()) != 0) // Cast the y ray to build multi-height slice
|
||||||
|
{
|
||||||
|
yHeight = yBitmap & 0xFF; // Get the bitmap code of slice
|
||||||
|
if (((yBitmap & WALL_TYPE_MULTI) ||
|
||||||
|
(yBitmap & WALL_TYPE_UPPER)) &&
|
||||||
|
(yHeight > LastWallHeight))
|
||||||
|
{
|
||||||
|
yWallHeight = yHeight;
|
||||||
|
// Use the x intercept to determine the column of the bitmap
|
||||||
|
yBitmapColumn = (LastX1 >> FP_SHIFT) & (BITMAP_WIDTH-1);
|
||||||
|
// Handle orientation from either side of the wall
|
||||||
|
if ((short)iLastY > yPglobal)
|
||||||
|
yBitmapColumn = (BITMAP_WIDTH-1) - yBitmapColumn;
|
||||||
|
yd = iLastY - yPglobal;
|
||||||
|
mf = InvSinTable[ViewAngle]; // Use angle to calculate distance to slice
|
||||||
|
yDistance = (yd * mf) >> 8;
|
||||||
|
if (yDistance > 33554432L) // Is distance in range?
|
||||||
|
yDistance = 120000L;
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// At this point check the distance to the Y wall against the
|
||||||
|
// wall to see which one is closer. The closer one is the one
|
||||||
|
// we'll draw at this column of the screen.
|
||||||
|
//==============================================================
|
||||||
|
if (yDistance < WallDistance) // Use distance to y slice if this slice is closer
|
||||||
|
{
|
||||||
|
wFound = 1; // Indicates that a slice has been found
|
||||||
|
WallDistance = yDistance; // Use distance to y slice
|
||||||
|
BitmapNumber = yBitmap; // Transfer bitmap number
|
||||||
|
BitmapColumn = yBitmapColumn; // Transfer bitmap column
|
||||||
|
gPtr = yGridGlobal; // Store pointer to global y grid
|
||||||
|
mPos = yMapPosn; // Store position of y wall in map
|
||||||
|
xBitmap = yHeight;
|
||||||
|
mgPtr = myGridGlobal[mPos]; // Store pointer to multi-height slice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wFound) // A multi-wall slice has been found so process it
|
||||||
|
{
|
||||||
|
LastWallHeight = xBitmap;
|
||||||
|
yd = ViewCosTable[ViewColumn] >> 2;
|
||||||
|
WallDistance *= yd;
|
||||||
|
// Now we strip off somemore decimal points and check round-up
|
||||||
|
xd = WallDistance >> 12;
|
||||||
|
if (WallDistance - (xd << 12) >= 2048)
|
||||||
|
xd++;
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// The last decimal points from the multiplication after the X and
|
||||||
|
// Y rays is stripped off and checked for round-up.
|
||||||
|
//==============================================================
|
||||||
|
WallDistance = xd >> 5;
|
||||||
|
if (xd - (WallDistance << 5) >= 16)
|
||||||
|
WallDistance++;
|
||||||
|
// Don't really need to, but put it into an integer for fast compare
|
||||||
|
distance = WallDistance;
|
||||||
|
// This is an arbitrary minimum distance to look for
|
||||||
|
if (distance < 10)
|
||||||
|
distance = 10;
|
||||||
|
|
||||||
|
// Don't want it to go outside our table boundaries
|
||||||
|
if (distance >= MAX_DISTANCE)
|
||||||
|
distance = MAX_DISTANCE - 1;
|
||||||
|
|
||||||
|
// Save the wall data to display when done with entire screen
|
||||||
|
sPtr->Active = 1;
|
||||||
|
sPtr = sPtr->Next;
|
||||||
|
if (sPtr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sPtr->Distance = distance; // Update slice data in slice structure
|
||||||
|
sPtr->bNumber = BitmapNumber;
|
||||||
|
sPtr->bColumn = BitmapColumn;
|
||||||
|
sPtr->bMap = WallbMaps;
|
||||||
|
sPtr->Active = 0;
|
||||||
|
sPtr->Type = ST_WALL;
|
||||||
|
sPtr->Fnc = WallRtn;
|
||||||
|
sPtr->mPos = mPos;
|
||||||
|
sPtr->mPtr = mgPtr;
|
||||||
|
spNext = sPtr->Next;
|
||||||
|
|
||||||
|
if (spNext != NULL)
|
||||||
|
{
|
||||||
|
BuildSliceMulti(); // Recursive call to build the slice behind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//********************************************************************
|
||||||
|
// Internal function called by AckCheckDoorOpen() to
|
||||||
|
// check for a collision with a wall within a certain distance.
|
||||||
|
//********************************************************************
|
||||||
|
short AckCheckHit(short xPlayer,short yPlayer,short vAngle)
|
||||||
|
{
|
||||||
|
short BitmapNumber,yBitmap;
|
||||||
|
short WallCode;
|
||||||
|
ULONG WallDistance;
|
||||||
|
ULONG xd,yd,mf,yDistance;
|
||||||
|
long CheckDist;
|
||||||
|
|
||||||
|
WallDistance = 3000000; // Set to a ridiculous value
|
||||||
|
WallCode = POV_NOTHING;
|
||||||
|
CheckDist = 56L; // (was 48) Initial minimum distance to look for
|
||||||
|
BitmapNumber = 0; // Initialize to no bitmap found
|
||||||
|
|
||||||
|
xPglobal = xPlayer;
|
||||||
|
xBegGlobal = xPglobal & GRID_MASK;
|
||||||
|
xPglobalHI = ((long)xPglobal << FP_SHIFT);
|
||||||
|
yPglobal = yPlayer;
|
||||||
|
yBegGlobal = yPglobal & GRID_MASK;
|
||||||
|
yPglobalHI = ((long)yPglobal << FP_SHIFT);
|
||||||
|
|
||||||
|
ViewAngle = vAngle;
|
||||||
|
|
||||||
|
if (MoveObjectCount)
|
||||||
|
memmove(ObjectsSeen,MoveObjectList,MoveObjectCount);
|
||||||
|
|
||||||
|
FoundObjectCount = MoveObjectCount;
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Don't allow one of these angles, causes either the X or Y ray to not be
|
||||||
|
// cast which gives a false reading about an obstacle.
|
||||||
|
//************************************************************************
|
||||||
|
if (ViewAngle == INT_ANGLE_45 ||
|
||||||
|
ViewAngle == INT_ANGLE_135 ||
|
||||||
|
ViewAngle == INT_ANGLE_225 ||
|
||||||
|
ViewAngle == INT_ANGLE_315)
|
||||||
|
{
|
||||||
|
ViewAngle++;
|
||||||
|
}
|
||||||
|
|
||||||
|
xRaySetup();
|
||||||
|
BitmapNumber = xRayCast();
|
||||||
|
|
||||||
|
if (BitmapNumber & (WALL_TYPE_UPPER+WALL_TYPE_PASS))
|
||||||
|
BitmapNumber = 0;
|
||||||
|
|
||||||
|
if (BitmapNumber)
|
||||||
|
{
|
||||||
|
xd = iLastX - xPlayer;
|
||||||
|
mf = InvCosTable[ViewAngle];
|
||||||
|
WallDistance = (xd * mf) >> 10;
|
||||||
|
if (WallDistance > 33554432L)
|
||||||
|
WallDistance = 1200000L;
|
||||||
|
// Set the wall struck code to an X wall
|
||||||
|
WallCode = POV_XWALL;
|
||||||
|
LastMapPosn = xMapPosn;
|
||||||
|
}
|
||||||
|
|
||||||
|
yRaySetup();
|
||||||
|
yBitmap = yRayCast();
|
||||||
|
|
||||||
|
if (yBitmap & (WALL_TYPE_UPPER+WALL_TYPE_PASS))
|
||||||
|
yBitmap = 0;
|
||||||
|
|
||||||
|
if (yBitmap)
|
||||||
|
{
|
||||||
|
yd = iLastY - yPlayer;
|
||||||
|
mf = InvSinTable[ViewAngle];
|
||||||
|
yDistance = (yd * mf) >> 8;
|
||||||
|
if (yDistance > 33554432L)
|
||||||
|
yDistance = 120000L;
|
||||||
|
// If Y wall closer than X wall then use Y wall data
|
||||||
|
if (yDistance < WallDistance)
|
||||||
|
{
|
||||||
|
WallDistance = yDistance;
|
||||||
|
// Indicate the wall struck was a Y wall
|
||||||
|
WallCode = POV_YWALL;
|
||||||
|
BitmapNumber = yBitmap;
|
||||||
|
LastMapPosn = yMapPosn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// Since doors appear in the middle of the wall, adjust the minimum distance
|
||||||
|
// to it. This handles walking up close to a door.
|
||||||
|
//************************************************************************
|
||||||
|
if (BitmapNumber & (DOOR_TYPE_SLIDE+DOOR_TYPE_SPLIT))
|
||||||
|
CheckDist += 64L;
|
||||||
|
BitmapNumber &= 0xFF;
|
||||||
|
if (WallCode)
|
||||||
|
{
|
||||||
|
yd = ViewCosTable[160] >> 3;
|
||||||
|
WallDistance *= yd;
|
||||||
|
// Now we strip off somemore decimal points and check round-up
|
||||||
|
xd = WallDistance >> 12;
|
||||||
|
if (WallDistance - (xd << 12) >= 2048)
|
||||||
|
xd++;
|
||||||
|
|
||||||
|
//*********************************************************************
|
||||||
|
// The last decimal points from the multiplication after the X and
|
||||||
|
// Y rays is stripped off and checked for round-up.
|
||||||
|
//*********************************************************************
|
||||||
|
WallDistance = xd >> 5;
|
||||||
|
if (xd - (WallDistance << 5) >= 16)
|
||||||
|
WallDistance++;
|
||||||
|
|
||||||
|
//*********************************************************************
|
||||||
|
// If the wall or object is further than the minimum distance, we can
|
||||||
|
// continue moving in this direction.
|
||||||
|
//*********************************************************************
|
||||||
|
if (WallDistance > CheckDist)
|
||||||
|
WallCode = POV_NOTHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(WallCode);
|
||||||
|
}
|
||||||
|
// **** End of Source ****
|
||||||
|
|
||||||
|
|
79
ack_lib/ACKWRAP.C
Normal file
79
ack_lib/ACKWRAP.C
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys\stat.h>
|
||||||
|
|
||||||
|
#include "ack3d.h"
|
||||||
|
#include "ackeng.h"
|
||||||
|
#include "ackext.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int sel;
|
||||||
|
int off;
|
||||||
|
} SELOFF;
|
||||||
|
|
||||||
|
extern char AckKeyboardSetup;
|
||||||
|
extern SELOFF OldKeybdInt;
|
||||||
|
extern char AckTimerSetup;
|
||||||
|
extern SELOFF OldTimerInt;
|
||||||
|
|
||||||
|
void AckSetIntVector(int VecNum,int sel,int VecOff);
|
||||||
|
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
// Frees up buffers and closes any resource file that may be open.
|
||||||
|
// After calling this function, do NOT call AckBuildView() or
|
||||||
|
// AckDisplayScreen()
|
||||||
|
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
|
||||||
|
short AckWrapUp (ACKENG * ae)
|
||||||
|
{
|
||||||
|
|
||||||
|
AckFree (LongTanTable);
|
||||||
|
AckFree (LongInvTanTable);
|
||||||
|
AckFree (CosTable);
|
||||||
|
AckFree (SinTable);
|
||||||
|
AckFree (LongCosTable);
|
||||||
|
AckFree (xNextTable);
|
||||||
|
AckFree (yNextTable);
|
||||||
|
AckFree (ViewCosTable);
|
||||||
|
AckFree (AdjustTable);
|
||||||
|
|
||||||
|
if (ae->OverlayBuffer != NULL)
|
||||||
|
AckFree (ae->OverlayBuffer);
|
||||||
|
ae->OverlayBuffer = NULL;
|
||||||
|
|
||||||
|
if (ae->BkgdBuffer != NULL)
|
||||||
|
AckFree (ae->BkgdBuffer);
|
||||||
|
ae->BkgdBuffer = NULL;
|
||||||
|
|
||||||
|
if (ae->ScreenBuffer != NULL)
|
||||||
|
AckFree (ae->ScreenBuffer);
|
||||||
|
ae->ScreenBuffer = NULL;
|
||||||
|
|
||||||
|
if (rsHandle)
|
||||||
|
{
|
||||||
|
close (rsHandle);
|
||||||
|
rsHandle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AckKeyboardSetup)
|
||||||
|
{
|
||||||
|
AckSetIntVector(9,OldKeybdInt.sel,OldKeybdInt.off);
|
||||||
|
AckKeyboardSetup = 0;
|
||||||
|
}
|
||||||
|
if (AckTimerSetup)
|
||||||
|
{
|
||||||
|
AckSetIntVector(0x1C,OldTimerInt.sel,OldTimerInt.off);
|
||||||
|
AckTimerSetup = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **** End of Source ****
|
||||||
|
|
98
ack_lib/IFF.H
Normal file
98
ack_lib/IFF.H
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LONG unsigned long
|
||||||
|
#define ULONG unsigned long
|
||||||
|
#define UBYTE unsigned char
|
||||||
|
#define UWORD unsigned short
|
||||||
|
#define DWORD unsigned long
|
||||||
|
|
||||||
|
long ByteFlipLong(long);
|
||||||
|
UCHAR *Readiff(char *); /* this returns back a bitmap with a picture in it*/
|
||||||
|
|
||||||
|
typedef LONG ID; /* An ID is four printable ASCII chars like FORM or DPPV */
|
||||||
|
|
||||||
|
/* original
|
||||||
|
#define MakeID(d,c,b,a) ((DWORD)(a)<<24 | (DWORD)(b)<<16 | (DWORD)(c)<<8 | (DWORD)(d) )*/
|
||||||
|
#define MakeID(d,c,b,a) (((DWORD)(a)<<24) | ((DWORD)(b)<<16) | ((DWORD)(c)<<8) | ((DWORD)(d)))
|
||||||
|
|
||||||
|
#define FORM MakeID('F','O','R','M')
|
||||||
|
#define PROP MakeID('P','R','O','P')
|
||||||
|
#define LIST MakeID('L','I','S','T')
|
||||||
|
#define CAT MakeID('C','A','T',' ')
|
||||||
|
#define FILLER MakeID(' ',' ',' ',' ')
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ID type;
|
||||||
|
long cksize;
|
||||||
|
ID subtype;
|
||||||
|
} form_chunk;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ID ckID;
|
||||||
|
LONG ckSize;
|
||||||
|
} ChunkHeader;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ID ckID;
|
||||||
|
LONG ckSize;
|
||||||
|
UBYTE ckData[ 1 /*REALLY: ckSize*/ ];
|
||||||
|
} Chunk;
|
||||||
|
|
||||||
|
#define ID_PBM MakeID('P','B','M',' ')
|
||||||
|
#define ID_ILBM MakeID('I','L','B','M')
|
||||||
|
#define ID_BMHD MakeID('B','M','H','D')
|
||||||
|
#define ID_CMAP MakeID('C','M','A','P')
|
||||||
|
#define ID_GRAB MakeID('G','R','A','B')
|
||||||
|
#define ID_DEST MakeID('D','E','S','T')
|
||||||
|
#define ID_SPRT MakeID('S','P','R','T')
|
||||||
|
#define ID_CAMG MakeID('C','A','M','G')
|
||||||
|
#define ID_BODY MakeID('B','O','D','Y')
|
||||||
|
|
||||||
|
/* ---------- BitMapHeader ---------------------------------------------*/
|
||||||
|
|
||||||
|
typedef UBYTE Masking; /* Choice of masking technique.*/
|
||||||
|
#define mskNone 0
|
||||||
|
#define mskHasMask 1
|
||||||
|
#define mskHasTransparentColor 2
|
||||||
|
#define mskLasso 3
|
||||||
|
|
||||||
|
#define cmpNone 0
|
||||||
|
#define cmpByteRun1 1
|
||||||
|
|
||||||
|
/* A BitMapHeader is stored in a BMHD chunk. */
|
||||||
|
typedef struct {
|
||||||
|
UWORD w, h; /* raster width & height in pixels */
|
||||||
|
UWORD x, y; /* position for this image */
|
||||||
|
UBYTE nPlanes; /* # source bitplanes */
|
||||||
|
UBYTE masking; /* masking technique */
|
||||||
|
UBYTE compression; /* compression algoithm */
|
||||||
|
UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
|
||||||
|
UWORD transparentColor; /* transparent "color number" */
|
||||||
|
UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
|
||||||
|
UWORD pageWidth, pageHeight; /* source "page" size in pixels */
|
||||||
|
} BitMapHeader;
|
||||||
|
/* RowBytes computes the number of bytes in a row, from the width in pixels.*/
|
||||||
|
#define RowBytes(w) (((w) + 15) >> 4 << 1)
|
||||||
|
|
||||||
|
/* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */
|
||||||
|
typedef struct {
|
||||||
|
UBYTE red, green, blue; /* MUST be UBYTEs so ">> 4" won't sign extend.*/
|
||||||
|
} ColorRegister;
|
||||||
|
|
||||||
|
/* Use this constant instead of sizeof(ColorRegister). */
|
||||||
|
#define sizeofColorRegister 3
|
||||||
|
|
||||||
|
long ByteFlipLong(long);
|
||||||
|
void ByteFlipShort(short *);
|
||||||
|
short iffswab(unsigned short);
|
||||||
|
short swab(unsigned short);
|
||||||
|
|
||||||
|
|
140
ack_lib/KIT.H
Normal file
140
ack_lib/KIT.H
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// Header file for 3D Construction Kit
|
||||||
|
// Started: 01/02/94
|
||||||
|
// Author: Lary Myers
|
||||||
|
// Module: KIT.H
|
||||||
|
// (c) CopyRight 1994 All Rights Reserved
|
||||||
|
|
||||||
|
#define MODE_GRAPHICS 0x13
|
||||||
|
#define MODE_TEXT 0x03
|
||||||
|
|
||||||
|
#define SCREEN_LENGTH 64000 // Bytes in one full screen
|
||||||
|
#define SCREEN_LEN_WORDS 32000 // Words in one screen
|
||||||
|
#define SCREEN_LEN_DWORDS 16000 // DWORDS in one screen
|
||||||
|
#define SCREEN_PLANES 1 // Number of planes for this mode
|
||||||
|
#define SCREEN_WIDTH 320 // Number of bytes in one row
|
||||||
|
#define SCREEN_HEIGHT 200 // Number of rows on screen
|
||||||
|
|
||||||
|
#define BUTTON_OK 0
|
||||||
|
#define BUTTON_OKCANCEL 1
|
||||||
|
#define BUTTON_YESNO 2
|
||||||
|
#define BUTTON_ABORTRETRY 3
|
||||||
|
|
||||||
|
#define BUTTON_RET_OK 0
|
||||||
|
#define BUTTON_RET_CANCEL 1
|
||||||
|
#define BUTTON_RET_YES 2
|
||||||
|
#define BUTTON_RET_NO 3
|
||||||
|
#define BUTTON_RET_ABORT 4
|
||||||
|
#define BUTTON_RET_RETRY 5
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short x1;
|
||||||
|
short y1;
|
||||||
|
short index;
|
||||||
|
} BUTTON;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short Count;
|
||||||
|
short List[4];
|
||||||
|
} INDEXES;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C list boxes
|
||||||
|
typedef struct _lcb {
|
||||||
|
struct _lcb *Back;
|
||||||
|
struct _lcb *Fwd;
|
||||||
|
char Data[1];
|
||||||
|
} LCB;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short ux;
|
||||||
|
short uy;
|
||||||
|
short ux1;
|
||||||
|
short uy1;
|
||||||
|
short dx;
|
||||||
|
short dy;
|
||||||
|
short dx1;
|
||||||
|
short dy1;
|
||||||
|
} ARROWRECT;
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in UTIL.C
|
||||||
|
//=============================================================================
|
||||||
|
UINT Inkey(void);
|
||||||
|
char *GetExtent(char *s);
|
||||||
|
char *StripEndOfLine(char *s);
|
||||||
|
char *SkipSpaces(char *s);
|
||||||
|
char *AddExtent(char *s,char *ext);
|
||||||
|
char *CopyToComma(char *dest,char *src);
|
||||||
|
short HasWildCards(char *s);
|
||||||
|
void SetCurrentPath(char *p);
|
||||||
|
void InitDiskList(void);
|
||||||
|
char *GetPath(char *s);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in GRAPHICS.C
|
||||||
|
//=============================================================================
|
||||||
|
void SetMode(short mode);
|
||||||
|
void ClearScreen(UCHAR color);
|
||||||
|
void PutPixel(short x,short y,UCHAR color);
|
||||||
|
void DrawVerticalLine(short x,short y,short y1,UCHAR color);
|
||||||
|
void DrawHorizontalLine(short x,short y,short x1,UCHAR color);
|
||||||
|
void DrawBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawRoundBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void Draw3DBox(short x,short y,short x1,short y1,UCHAR TopColor,UCHAR BottomColor);
|
||||||
|
void DrawSolidBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORRect(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawLine(short x1,short y1,short x2,short y2,UCHAR color);
|
||||||
|
void PutBitmap(short x,short y,short width,short height,UCHAR *Bitmap);
|
||||||
|
UCHAR *GetBitmap(short x,short y,short width,short height,UCHAR *buffer);
|
||||||
|
UINT GetBufferSize(short width,short height);
|
||||||
|
void PutBitmapAsIcon(short x,short y,UCHAR *bm);
|
||||||
|
void PutAckBitmap(short x,short y,UCHAR *bm);
|
||||||
|
UCHAR *ScreenToBuffer(UCHAR *buffer);
|
||||||
|
void BufferToScreen(UCHAR *buffer);
|
||||||
|
void SetPalette(UCHAR *PalBuf);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
UCHAR *LoadAndShowScreen(char *PicName);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in MOUSE.C
|
||||||
|
//=============================================================================
|
||||||
|
short MouseInstalled(void);
|
||||||
|
void ShowMouse(void);
|
||||||
|
void HideMouse(void);
|
||||||
|
short ReadMouseCursor(short *mrow,short *mcol);
|
||||||
|
short ReadMouseButtons(void);
|
||||||
|
void SetMouseCursor(short mrow,short mcol);
|
||||||
|
void SetMouseMinMaxColumns(short mincol,short maxcol);
|
||||||
|
void SetMouseMinMaxRows(short minrow,short maxrow);
|
||||||
|
void SetMouseShape(short hsrow,short hscol,char *mask);
|
||||||
|
void MouseReleased(void);
|
||||||
|
void MouseSetFunction(UCHAR,void *);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in READIFF.C
|
||||||
|
//=============================================================================
|
||||||
|
UCHAR *Readiff(char *picname);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in IO.C
|
||||||
|
//=============================================================================
|
||||||
|
void GetFontTable(void);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
short ShowMessageBox(char *Body,UINT Buttons);
|
||||||
|
void ShowListBox(short x,short y,short x1,short y1,short index,LCB *lcb);
|
||||||
|
char *FileBox(char *fName,char *Path,char *rBuf,char *Title,char *ActiveButton);
|
||||||
|
void TestListBox(void);
|
||||||
|
short PickList(short x,short y,short x1,short y1,LCB *Anchor);
|
||||||
|
short CreateSelectPickList(short x,short y,short x1,short y1,short count,char **List,short SortFlag);
|
||||||
|
short ShowPickList(char **p,short SortFlag);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in SETS.C
|
||||||
|
//=============================================================================
|
||||||
|
short LoadSet(char *fName);
|
||||||
|
|
||||||
|
|
78
ack_lib/WING.H
Normal file
78
ack_lib/WING.H
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*****************************************************************************\
|
||||||
|
*
|
||||||
|
* wing.h - WinG functions, types, and definitions
|
||||||
|
*
|
||||||
|
* Copyright (c) 1994 Microsoft Corp. All rights reserved.
|
||||||
|
*
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _INC_WING
|
||||||
|
#define _INC_WING
|
||||||
|
|
||||||
|
#ifndef _INC_WINDOWS
|
||||||
|
#include <windows.h> /* Include windows.h if not already included */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" { /* Assume C declarations for C++ */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32)
|
||||||
|
#define WINGAPI WINAPI
|
||||||
|
#else
|
||||||
|
#define WINGAPI WINAPI _loadds
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***** WingDC and WinGBitmap *************************************************/
|
||||||
|
|
||||||
|
HDC WINGAPI WinGCreateDC( void );
|
||||||
|
|
||||||
|
BOOL WINGAPI WinGRecommendDIBFormat( BITMAPINFO FAR *pFormat );
|
||||||
|
|
||||||
|
HBITMAP WINGAPI WinGCreateBitmap( HDC WinGDC, BITMAPINFO const FAR *pHeader,
|
||||||
|
void FAR *FAR *ppBits );
|
||||||
|
|
||||||
|
void FAR *WINGAPI WinGGetDIBPointer( HBITMAP WinGBitmap,
|
||||||
|
BITMAPINFO FAR *pHeader );
|
||||||
|
|
||||||
|
UINT WINGAPI WinGGetDIBColorTable( HDC WinGDC, UINT StartIndex,
|
||||||
|
UINT NumberOfEntries, RGBQUAD FAR *pColors );
|
||||||
|
|
||||||
|
UINT WINGAPI WinGSetDIBColorTable( HDC WinGDC, UINT StartIndex,
|
||||||
|
UINT NumberOfEntries, RGBQUAD const FAR *pColors );
|
||||||
|
|
||||||
|
|
||||||
|
/***** Halftoning ************************************************************/
|
||||||
|
|
||||||
|
HPALETTE WINGAPI WinGCreateHalftonePalette( void );
|
||||||
|
|
||||||
|
typedef enum WING_DITHER_TYPE
|
||||||
|
{
|
||||||
|
WING_DISPERSED_4x4,
|
||||||
|
WING_DISPERSED_8x8,
|
||||||
|
|
||||||
|
WING_CLUSTERED_4x4
|
||||||
|
|
||||||
|
} WING_DITHER_TYPE;
|
||||||
|
|
||||||
|
HBRUSH WINGAPI WinGCreateHalftoneBrush( HDC Context, COLORREF crColor,
|
||||||
|
WING_DITHER_TYPE DitherType );
|
||||||
|
|
||||||
|
|
||||||
|
/***** Blts ******************************************************************/
|
||||||
|
|
||||||
|
BOOL WINGAPI WinGBitBlt( HDC hdcDest, int nXOriginDest,
|
||||||
|
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
|
||||||
|
int nXOriginSrc, int nYOriginSrc );
|
||||||
|
|
||||||
|
BOOL WINGAPI WinGStretchBlt( HDC hdcDest, int nXOriginDest,
|
||||||
|
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
|
||||||
|
int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* End of extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _INC_WING
|
||||||
|
|
60
ack_lib/WINGDLL.H
Normal file
60
ack_lib/WINGDLL.H
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// WINGDLL.H
|
||||||
|
//
|
||||||
|
// Interface class for WinG.
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _INC_WINGDLL
|
||||||
|
#define _INC_WINGDLL
|
||||||
|
|
||||||
|
typedef HDC (WINAPI *wingCreateDC)( void );
|
||||||
|
typedef BOOL (WINAPI *wingRecommendDIBFormat)( BITMAPINFO FAR *pFormat );
|
||||||
|
typedef HBITMAP (WINAPI *wingCreateBitmap)( HDC WinGDC, BITMAPINFO const *pHeader,
|
||||||
|
void *ppBits );
|
||||||
|
typedef void FAR *(WINAPI *wingGetDIBPointer)( HBITMAP WinGBitmap,
|
||||||
|
BITMAPINFO FAR *pHeader );
|
||||||
|
typedef UINT (WINAPI *wingGetDIBColorTable)( HDC WinGDC, UINT StartIndex,
|
||||||
|
UINT NumberOfEntries, RGBQUAD FAR *pColors );
|
||||||
|
typedef UINT (WINAPI *wingSetDIBColorTable)( HDC WinGDC, UINT StartIndex,
|
||||||
|
UINT NumberOfEntries, RGBQUAD const FAR *pColors );
|
||||||
|
typedef HPALETTE (WINAPI *wingCreateHalftonePalette)( void );
|
||||||
|
typedef HBRUSH (WINAPI *wingCreateHalftoneBrush)( HDC, COLORREF,
|
||||||
|
WING_DITHER_TYPE);
|
||||||
|
typedef BOOL (WINAPI *wingBitBlt)( HDC hdcDest, int nXOriginDest,
|
||||||
|
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
|
||||||
|
int nXOriginSrc, int nYOriginSrc );
|
||||||
|
typedef BOOL (WINAPI *wingStretchBlt)( HDC hdcDest, int nXOriginDest,
|
||||||
|
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
|
||||||
|
int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc );
|
||||||
|
|
||||||
|
|
||||||
|
class WinGdll {
|
||||||
|
|
||||||
|
public:
|
||||||
|
WinGdll();
|
||||||
|
~WinGdll();
|
||||||
|
|
||||||
|
BOOL Load();
|
||||||
|
BOOL Free();
|
||||||
|
|
||||||
|
HINSTANCE m_hLib;
|
||||||
|
BOOL m_bLoaded;
|
||||||
|
|
||||||
|
//I would have used m_ prefix, but too laborious to type when using
|
||||||
|
//the class. Would have inlined the function pointers,
|
||||||
|
//without typedef's, but the compiler didn't like it.
|
||||||
|
//Anyway, this method makes casting GetProcAddress()
|
||||||
|
//easier.
|
||||||
|
wingCreateDC pCreateDC;
|
||||||
|
wingRecommendDIBFormat pRecommendDIBFormat;
|
||||||
|
wingCreateBitmap pCreateBitmap;
|
||||||
|
wingGetDIBPointer pGetDIBPointer;
|
||||||
|
wingGetDIBColorTable pGetDIBColorTable;
|
||||||
|
wingSetDIBColorTable pSetDIBColorTable;
|
||||||
|
wingCreateHalftonePalette pCreateHalftonePalette;
|
||||||
|
wingCreateHalftoneBrush pCreateHalftoneBrush;
|
||||||
|
wingBitBlt pBitBlt;
|
||||||
|
wingStretchBlt pStretchBlt;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif // _INC_WINGDLL
|
2310
fdemo/FDEMO.C
Normal file
2310
fdemo/FDEMO.C
Normal file
File diff suppressed because it is too large
Load diff
140
fdemo/KIT.H
Normal file
140
fdemo/KIT.H
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// Header file for 3D Construction Kit
|
||||||
|
// Started: 01/02/94
|
||||||
|
// Author: Lary Myers
|
||||||
|
// Module: KIT.H
|
||||||
|
// (c) CopyRight 1994 All Rights Reserved
|
||||||
|
|
||||||
|
#define MODE_GRAPHICS 0x13
|
||||||
|
#define MODE_TEXT 0x03
|
||||||
|
|
||||||
|
#define SCREEN_LENGTH 64000 // Bytes in one full screen
|
||||||
|
#define SCREEN_LEN_WORDS 32000 // Words in one screen
|
||||||
|
#define SCREEN_LEN_DWORDS 16000 // DWORDS in one screen
|
||||||
|
#define SCREEN_PLANES 1 // Number of planes for this mode
|
||||||
|
#define SCREEN_WIDTH 320 // Number of bytes in one row
|
||||||
|
#define SCREEN_HEIGHT 200 // Number of rows on screen
|
||||||
|
|
||||||
|
#define BUTTON_OK 0
|
||||||
|
#define BUTTON_OKCANCEL 1
|
||||||
|
#define BUTTON_YESNO 2
|
||||||
|
#define BUTTON_ABORTRETRY 3
|
||||||
|
|
||||||
|
#define BUTTON_RET_OK 0
|
||||||
|
#define BUTTON_RET_CANCEL 1
|
||||||
|
#define BUTTON_RET_YES 2
|
||||||
|
#define BUTTON_RET_NO 3
|
||||||
|
#define BUTTON_RET_ABORT 4
|
||||||
|
#define BUTTON_RET_RETRY 5
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short x1;
|
||||||
|
short y1;
|
||||||
|
short index;
|
||||||
|
} BUTTON;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short Count;
|
||||||
|
short List[4];
|
||||||
|
} INDEXES;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C list boxes
|
||||||
|
typedef struct _lcb {
|
||||||
|
struct _lcb *Back;
|
||||||
|
struct _lcb *Fwd;
|
||||||
|
char Data[1];
|
||||||
|
} LCB;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short ux;
|
||||||
|
short uy;
|
||||||
|
short ux1;
|
||||||
|
short uy1;
|
||||||
|
short dx;
|
||||||
|
short dy;
|
||||||
|
short dx1;
|
||||||
|
short dy1;
|
||||||
|
} ARROWRECT;
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in UTIL.C
|
||||||
|
//=============================================================================
|
||||||
|
UINT Inkey(void);
|
||||||
|
char *GetExtent(char *s);
|
||||||
|
char *StripEndOfLine(char *s);
|
||||||
|
char *SkipSpaces(char *s);
|
||||||
|
char *AddExtent(char *s,char *ext);
|
||||||
|
char *CopyToComma(char *dest,char *src);
|
||||||
|
short HasWildCards(char *s);
|
||||||
|
void SetCurrentPath(char *p);
|
||||||
|
void InitDiskList(void);
|
||||||
|
char *GetPath(char *s);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in GRAPHICS.C
|
||||||
|
//=============================================================================
|
||||||
|
void SetMode(short mode);
|
||||||
|
void ClearScreen(UCHAR color);
|
||||||
|
void PutPixel(short x,short y,UCHAR color);
|
||||||
|
void DrawVerticalLine(short x,short y,short y1,UCHAR color);
|
||||||
|
void DrawHorizontalLine(short x,short y,short x1,UCHAR color);
|
||||||
|
void DrawBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawRoundBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void Draw3DBox(short x,short y,short x1,short y1,UCHAR TopColor,UCHAR BottomColor);
|
||||||
|
void DrawSolidBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORRect(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawLine(short x1,short y1,short x2,short y2,UCHAR color);
|
||||||
|
void PutBitmap(short x,short y,short width,short height,UCHAR *Bitmap);
|
||||||
|
UCHAR *GetBitmap(short x,short y,short width,short height,UCHAR *buffer);
|
||||||
|
UINT GetBufferSize(short width,short height);
|
||||||
|
void PutBitmapAsIcon(short x,short y,UCHAR *bm);
|
||||||
|
void PutAckBitmap(short x,short y,UCHAR *bm);
|
||||||
|
UCHAR *ScreenToBuffer(UCHAR *buffer);
|
||||||
|
void BufferToScreen(UCHAR *buffer);
|
||||||
|
void SetPalette(UCHAR *PalBuf);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
UCHAR *LoadAndShowScreen(char *PicName);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in MOUSE.C
|
||||||
|
//=============================================================================
|
||||||
|
short MouseInstalled(void);
|
||||||
|
void ShowMouse(void);
|
||||||
|
void HideMouse(void);
|
||||||
|
short ReadMouseCursor(short *mrow,short *mcol);
|
||||||
|
short ReadMouseButtons(void);
|
||||||
|
void SetMouseCursor(short mrow,short mcol);
|
||||||
|
void SetMouseMinMaxColumns(short mincol,short maxcol);
|
||||||
|
void SetMouseMinMaxRows(short minrow,short maxrow);
|
||||||
|
void SetMouseShape(short hsrow,short hscol,char *mask);
|
||||||
|
void MouseReleased(void);
|
||||||
|
void MouseSetFunction(UCHAR,void *);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in READIFF.C
|
||||||
|
//=============================================================================
|
||||||
|
UCHAR *Readiff(char *picname);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in IO.C
|
||||||
|
//=============================================================================
|
||||||
|
void GetFontTable(void);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
short ShowMessageBox(char *Body,UINT Buttons);
|
||||||
|
void ShowListBox(short x,short y,short x1,short y1,short index,LCB *lcb);
|
||||||
|
char *FileBox(char *fName,char *Path,char *rBuf,char *Title,char *ActiveButton);
|
||||||
|
void TestListBox(void);
|
||||||
|
short PickList(short x,short y,short x1,short y1,LCB *Anchor);
|
||||||
|
short CreateSelectPickList(short x,short y,short x1,short y1,short count,char **List,short SortFlag);
|
||||||
|
short ShowPickList(char **p,short SortFlag);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in SETS.C
|
||||||
|
//=============================================================================
|
||||||
|
short LoadSet(char *fName);
|
||||||
|
|
||||||
|
|
BIN
fdemo/KIT.OVL
Normal file
BIN
fdemo/KIT.OVL
Normal file
Binary file not shown.
1166
fdemo/MODPLAY.ASM
Normal file
1166
fdemo/MODPLAY.ASM
Normal file
File diff suppressed because it is too large
Load diff
162
fdemo/MODPLAY.H
Normal file
162
fdemo/MODPLAY.H
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/* modplay.h - Tiny MOD Player V2.02 for Watcom C/C++32 and DOS/4GW header file
|
||||||
|
|
||||||
|
Module player for Sound Blaster and compatibles.
|
||||||
|
|
||||||
|
Copyright 1993,94 Carlos Hasan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
QUICK REFERENCE GUIDE:
|
||||||
|
|
||||||
|
MODPlayModule
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Start playing a Modulefile.
|
||||||
|
|
||||||
|
Prototype: int MODPlayModule(Song,Chans,Rate,Port,IRQ,DRQ)
|
||||||
|
|
||||||
|
Parameters: Song - Address of the Modulefile Image
|
||||||
|
Chans - Number of channels (1-8)
|
||||||
|
Rate - Mixing speed in Hertz (4kHz-22kHz)
|
||||||
|
Port - I/O Port address (220h..280h)
|
||||||
|
IRQ - IRQ level (2,3,5,7,11)
|
||||||
|
DRQ - DMA channel (0,1,3)
|
||||||
|
|
||||||
|
Returns: On success, return a zero value.
|
||||||
|
On error, return a non zero value.
|
||||||
|
|
||||||
|
Remarks: This function will initialize the Sound Blaster card and
|
||||||
|
will start playing the module file immediately. The module
|
||||||
|
file must be a 4,6 or 8 channels Protracker or FastTracker
|
||||||
|
music module file.
|
||||||
|
The player supports two kinds of channels, music and sample
|
||||||
|
audio channels. The music channels are used by the player
|
||||||
|
to play the module, and the sample channels are used for
|
||||||
|
sound effects and the like.
|
||||||
|
The channels voices 0 to N-1 are used for music channels,
|
||||||
|
where N is the number of channels of the module file.
|
||||||
|
|
||||||
|
|
||||||
|
MODStopModule
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Stop playing the current Modulefile.
|
||||||
|
|
||||||
|
Prototype: void MODStopModule()
|
||||||
|
|
||||||
|
Parameters: None.
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function shut down the playing system. Must be called
|
||||||
|
before exiting the user program.
|
||||||
|
|
||||||
|
|
||||||
|
MODPlaySample
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Play instrument at specified period and volume.
|
||||||
|
|
||||||
|
Prototype: void MODPlaySample(Voice,Instr)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Instr - Instrument address
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function is useful to play samples over music. The sample
|
||||||
|
structure holds the period, volume and the address of the 8-bit
|
||||||
|
signed samples to be played in the channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODPlayVoice
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample, period and volume for a sample channel.
|
||||||
|
|
||||||
|
Prototype: void MODPlayVoice(Voice,Instr,Period,Volume)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Instr - Instrument number (1-31)
|
||||||
|
Period - Amiga period value (113-856)
|
||||||
|
Volume - Volume value (0-64)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function is useful to play samples over music. You must
|
||||||
|
use a sample channel or the music system will override
|
||||||
|
these parameters when polling the current module.
|
||||||
|
The amiga period value can be translated to hertz using the
|
||||||
|
following formula: Hertz = 8363*428/Period
|
||||||
|
|
||||||
|
|
||||||
|
MODStopVoice
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Stop a sample channel.
|
||||||
|
|
||||||
|
Prototype: void MODStopVoice(Voice)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
|
||||||
|
Remarks: This function will stop the specified voice setting the channel
|
||||||
|
volume to zero. The voice should be a sample channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODSetPeriod
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample channel period value.
|
||||||
|
|
||||||
|
Prototype: void MODSetPeriod(Voice,Period)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Period - Amiga Period (113-856)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function will change the current frequency of the sample
|
||||||
|
channel. The voice should be a sample channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODSetVolume
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample channel volume.
|
||||||
|
|
||||||
|
Prototype: void MODSetVolume(Voice,Volume)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Volume - Volume (0-64)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function will change the channel volume. The voice should
|
||||||
|
be a sample channel.
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __MODPLAY_H
|
||||||
|
#define __MODPLAY_H
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef unsigned long dword;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
word Period;
|
||||||
|
word Volume;
|
||||||
|
dword Length;
|
||||||
|
void *Data;
|
||||||
|
} Sample;
|
||||||
|
|
||||||
|
#pragma aux MODPlayModule "_*" parm caller [];
|
||||||
|
#pragma aux MODStopModule "_*" parm caller [];
|
||||||
|
#pragma aux MODPlaySample "_*" parm caller [];
|
||||||
|
#pragma aux MODPlayVoice "_*" parm caller [];
|
||||||
|
#pragma aux MODStopVoice "_*" parm caller [];
|
||||||
|
#pragma aux MODSetPeriod "_*" parm caller [];
|
||||||
|
#pragma aux MODSetVolume "_*" parm caller [];
|
||||||
|
|
||||||
|
extern int MODPlayModule(void *Modulefile,word Chans,word Rate,word Port,byte IRQ,byte DRQ);
|
||||||
|
extern void MODStopModule(void);
|
||||||
|
extern void MODPlaySample(byte Voice,Sample *Instr);
|
||||||
|
extern void MODPlayVoice(byte Voice,byte Instr,word Period,byte Volume);
|
||||||
|
extern void MODStopVoice(byte Voice);
|
||||||
|
extern void MODSetPeriod(byte Voice,word Period);
|
||||||
|
extern void MODSetVolume(byte Voice,byte Volume);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
181
fdemo/MOUSE.C
Normal file
181
fdemo/MOUSE.C
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
// 3D Construction Kit
|
||||||
|
// Started: 01/02/94
|
||||||
|
// Author: Lary Myers
|
||||||
|
// Module: MOUSE.C
|
||||||
|
// (c) CopyRight 1994 All Rights Reserved
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
|
||||||
|
void Mymemset(void *,int,int);
|
||||||
|
|
||||||
|
int MouseModifier = 2;
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Check if mouse is installed, returns -1 if it IS installed
|
||||||
|
//=============================================================================
|
||||||
|
int MouseInstalled(void)
|
||||||
|
{
|
||||||
|
int yesno;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
intr(0x33,®s);
|
||||||
|
yesno = regs.w.ax;
|
||||||
|
|
||||||
|
return(yesno);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Show the mouse cursor
|
||||||
|
//=============================================================================
|
||||||
|
void ShowMouse(void)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 1;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Hide the mouse cursor
|
||||||
|
//=============================================================================
|
||||||
|
void HideMouse(void)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 2;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Returns button status, mouse row and column
|
||||||
|
//=============================================================================
|
||||||
|
int ReadMouseCursor(int *mrow,int *mcol)
|
||||||
|
{
|
||||||
|
int bstatus;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 3;
|
||||||
|
intr(0x33,®s);
|
||||||
|
bstatus = regs.w.bx;
|
||||||
|
*mrow = regs.w.dx;
|
||||||
|
*mcol = regs.w.cx / MouseModifier;
|
||||||
|
|
||||||
|
return(bstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Returns just the mouse button status
|
||||||
|
//=============================================================================
|
||||||
|
int ReadMouseButtons(void)
|
||||||
|
{
|
||||||
|
int bstatus;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 3;
|
||||||
|
intr(0x33,®s);
|
||||||
|
bstatus = regs.w.bx;
|
||||||
|
|
||||||
|
return(bstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Set mouse cursor to desired row and column
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseCursor(int mrow,int mcol)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 4;
|
||||||
|
regs.w.dx = mrow;
|
||||||
|
regs.w.cx = mcol * MouseModifier;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Defines left and right columns for mouse travel
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseMinMaxColumns(int mincol,int maxcol)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 7;
|
||||||
|
regs.w.cx = mincol * MouseModifier;
|
||||||
|
regs.w.dx = maxcol * MouseModifier;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Defines top and bottom rows for mouse travel
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseMinMaxRows(int minrow,int maxrow)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 8;
|
||||||
|
regs.w.cx = minrow;
|
||||||
|
regs.w.dx = maxrow;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Set shape of mouse cursor. 8 byte mask, hotspot row,col
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseShape(int hsrow,int hscol,char far *mask)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 9;
|
||||||
|
regs.w.dx = FP_OFF(mask);
|
||||||
|
regs.w.es = FP_SEG(mask);
|
||||||
|
regs.w.bx = hscol;
|
||||||
|
regs.w.cx = hsrow;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Wait for the mouse button to be released
|
||||||
|
//=============================================================================
|
||||||
|
void MouseReleased(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (ReadMouseButtons());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
void MouseSetFunction(unsigned char mFlag,void *Func)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 12;
|
||||||
|
regs.w.dx = FP_OFF(Func);
|
||||||
|
regs.w.es = FP_SEG(Func);
|
||||||
|
regs.w.cx = mFlag;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
BIN
fdemo/PICS.DTF
Normal file
BIN
fdemo/PICS.DTF
Normal file
Binary file not shown.
BIN
fdemo/SAHARA.MOD
Normal file
BIN
fdemo/SAHARA.MOD
Normal file
Binary file not shown.
140
mall/KIT.H
Normal file
140
mall/KIT.H
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
// Header file for 3D Construction Kit
|
||||||
|
// Started: 01/02/94
|
||||||
|
// Author: Lary Myers
|
||||||
|
// Module: KIT.H
|
||||||
|
// (c) CopyRight 1994 All Rights Reserved
|
||||||
|
|
||||||
|
#define MODE_GRAPHICS 0x13
|
||||||
|
#define MODE_TEXT 0x03
|
||||||
|
|
||||||
|
#define SCREEN_LENGTH 64000 // Bytes in one full screen
|
||||||
|
#define SCREEN_LEN_WORDS 32000 // Words in one screen
|
||||||
|
#define SCREEN_LEN_DWORDS 16000 // DWORDS in one screen
|
||||||
|
#define SCREEN_PLANES 1 // Number of planes for this mode
|
||||||
|
#define SCREEN_WIDTH 320 // Number of bytes in one row
|
||||||
|
#define SCREEN_HEIGHT 200 // Number of rows on screen
|
||||||
|
|
||||||
|
#define BUTTON_OK 0
|
||||||
|
#define BUTTON_OKCANCEL 1
|
||||||
|
#define BUTTON_YESNO 2
|
||||||
|
#define BUTTON_ABORTRETRY 3
|
||||||
|
|
||||||
|
#define BUTTON_RET_OK 0
|
||||||
|
#define BUTTON_RET_CANCEL 1
|
||||||
|
#define BUTTON_RET_YES 2
|
||||||
|
#define BUTTON_RET_NO 3
|
||||||
|
#define BUTTON_RET_ABORT 4
|
||||||
|
#define BUTTON_RET_RETRY 5
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short x;
|
||||||
|
short y;
|
||||||
|
short x1;
|
||||||
|
short y1;
|
||||||
|
short index;
|
||||||
|
} BUTTON;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C for message boxes
|
||||||
|
typedef struct {
|
||||||
|
short Count;
|
||||||
|
short List[4];
|
||||||
|
} INDEXES;
|
||||||
|
|
||||||
|
|
||||||
|
// Used in IORTN.C list boxes
|
||||||
|
typedef struct _lcb {
|
||||||
|
struct _lcb *Back;
|
||||||
|
struct _lcb *Fwd;
|
||||||
|
char Data[1];
|
||||||
|
} LCB;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short ux;
|
||||||
|
short uy;
|
||||||
|
short ux1;
|
||||||
|
short uy1;
|
||||||
|
short dx;
|
||||||
|
short dy;
|
||||||
|
short dx1;
|
||||||
|
short dy1;
|
||||||
|
} ARROWRECT;
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in UTIL.C
|
||||||
|
//=============================================================================
|
||||||
|
UINT Inkey(void);
|
||||||
|
char *GetExtent(char *s);
|
||||||
|
char *StripEndOfLine(char *s);
|
||||||
|
char *SkipSpaces(char *s);
|
||||||
|
char *AddExtent(char *s,char *ext);
|
||||||
|
char *CopyToComma(char *dest,char *src);
|
||||||
|
short HasWildCards(char *s);
|
||||||
|
void SetCurrentPath(char *p);
|
||||||
|
void InitDiskList(void);
|
||||||
|
char *GetPath(char *s);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in GRAPHICS.C
|
||||||
|
//=============================================================================
|
||||||
|
void SetMode(short mode);
|
||||||
|
void ClearScreen(UCHAR color);
|
||||||
|
void PutPixel(short x,short y,UCHAR color);
|
||||||
|
void DrawVerticalLine(short x,short y,short y1,UCHAR color);
|
||||||
|
void DrawHorizontalLine(short x,short y,short x1,UCHAR color);
|
||||||
|
void DrawBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawRoundBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void Draw3DBox(short x,short y,short x1,short y1,UCHAR TopColor,UCHAR BottomColor);
|
||||||
|
void DrawSolidBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORBox(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawXORRect(short x,short y,short x1,short y1,UCHAR color);
|
||||||
|
void DrawLine(short x1,short y1,short x2,short y2,UCHAR color);
|
||||||
|
void PutBitmap(short x,short y,short width,short height,UCHAR far *Bitmap);
|
||||||
|
UCHAR far *GetBitmap(short x,short y,short width,short height,UCHAR far *buffer);
|
||||||
|
UINT GetBufferSize(short width,short height);
|
||||||
|
void PutBitmapAsIcon(short x,short y,UCHAR far *bm);
|
||||||
|
void PutAckBitmap(short x,short y,UCHAR far *bm);
|
||||||
|
UCHAR far *ScreenToBuffer(UCHAR far *buffer);
|
||||||
|
void BufferToScreen(UCHAR far *buffer);
|
||||||
|
void SetPalette(UCHAR far *PalBuf);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
UCHAR far *LoadAndShowScreen(char *PicName);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in MOUSE.C
|
||||||
|
//=============================================================================
|
||||||
|
short MouseInstalled(void);
|
||||||
|
void ShowMouse(void);
|
||||||
|
void HideMouse(void);
|
||||||
|
short ReadMouseCursor(short *mrow,short *mcol);
|
||||||
|
short ReadMouseButtons(void);
|
||||||
|
void SetMouseCursor(short mrow,short mcol);
|
||||||
|
void SetMouseMinMaxColumns(short mincol,short maxcol);
|
||||||
|
void SetMouseMinMaxRows(short minrow,short maxrow);
|
||||||
|
void SetMouseShape(short hsrow,short hscol,char far *mask);
|
||||||
|
void MouseReleased(void);
|
||||||
|
void MouseSetFunction(UCHAR,void *);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in READIFF.C
|
||||||
|
//=============================================================================
|
||||||
|
UCHAR *Readiff(char *picname);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in IO.C
|
||||||
|
//=============================================================================
|
||||||
|
void GetFontTable(void);
|
||||||
|
void ShowChar(short x,short y,char ch);
|
||||||
|
void ShowString(short x,short y,char *s);
|
||||||
|
short ShowMessageBox(char *Body,UINT Buttons);
|
||||||
|
void ShowListBox(short x,short y,short x1,short y1,short index,LCB *lcb);
|
||||||
|
char *FileBox(char *fName,char *Path,char *rBuf,char *Title,char *ActiveButton);
|
||||||
|
void TestListBox(void);
|
||||||
|
short PickList(short x,short y,short x1,short y1,LCB *Anchor);
|
||||||
|
short CreateSelectPickList(short x,short y,short x1,short y1,short count,char **List,short SortFlag);
|
||||||
|
short ShowPickList(char **p,short SortFlag);
|
||||||
|
//=============================================================================
|
||||||
|
// Prototypes in SETS.C
|
||||||
|
//=============================================================================
|
||||||
|
short LoadSet(char *fName);
|
||||||
|
|
||||||
|
|
BIN
mall/KIT.OVL
Normal file
BIN
mall/KIT.OVL
Normal file
Binary file not shown.
2303
mall/MALL.C
Normal file
2303
mall/MALL.C
Normal file
File diff suppressed because it is too large
Load diff
1166
mall/MODPLAY.ASM
Normal file
1166
mall/MODPLAY.ASM
Normal file
File diff suppressed because it is too large
Load diff
162
mall/MODPLAY.H
Normal file
162
mall/MODPLAY.H
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
/* modplay.h - Tiny MOD Player V2.02 for Watcom C/C++32 and DOS/4GW header file
|
||||||
|
|
||||||
|
Module player for Sound Blaster and compatibles.
|
||||||
|
|
||||||
|
Copyright 1993,94 Carlos Hasan
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************************\
|
||||||
|
QUICK REFERENCE GUIDE:
|
||||||
|
|
||||||
|
MODPlayModule
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Start playing a Modulefile.
|
||||||
|
|
||||||
|
Prototype: int MODPlayModule(Song,Chans,Rate,Port,IRQ,DRQ)
|
||||||
|
|
||||||
|
Parameters: Song - Address of the Modulefile Image
|
||||||
|
Chans - Number of channels (1-8)
|
||||||
|
Rate - Mixing speed in Hertz (4kHz-22kHz)
|
||||||
|
Port - I/O Port address (220h..280h)
|
||||||
|
IRQ - IRQ level (2,3,5,7,11)
|
||||||
|
DRQ - DMA channel (0,1,3)
|
||||||
|
|
||||||
|
Returns: On success, return a zero value.
|
||||||
|
On error, return a non zero value.
|
||||||
|
|
||||||
|
Remarks: This function will initialize the Sound Blaster card and
|
||||||
|
will start playing the module file immediately. The module
|
||||||
|
file must be a 4,6 or 8 channels Protracker or FastTracker
|
||||||
|
music module file.
|
||||||
|
The player supports two kinds of channels, music and sample
|
||||||
|
audio channels. The music channels are used by the player
|
||||||
|
to play the module, and the sample channels are used for
|
||||||
|
sound effects and the like.
|
||||||
|
The channels voices 0 to N-1 are used for music channels,
|
||||||
|
where N is the number of channels of the module file.
|
||||||
|
|
||||||
|
|
||||||
|
MODStopModule
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Stop playing the current Modulefile.
|
||||||
|
|
||||||
|
Prototype: void MODStopModule()
|
||||||
|
|
||||||
|
Parameters: None.
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function shut down the playing system. Must be called
|
||||||
|
before exiting the user program.
|
||||||
|
|
||||||
|
|
||||||
|
MODPlaySample
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Play instrument at specified period and volume.
|
||||||
|
|
||||||
|
Prototype: void MODPlaySample(Voice,Instr)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Instr - Instrument address
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function is useful to play samples over music. The sample
|
||||||
|
structure holds the period, volume and the address of the 8-bit
|
||||||
|
signed samples to be played in the channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODPlayVoice
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample, period and volume for a sample channel.
|
||||||
|
|
||||||
|
Prototype: void MODPlayVoice(Voice,Instr,Period,Volume)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Instr - Instrument number (1-31)
|
||||||
|
Period - Amiga period value (113-856)
|
||||||
|
Volume - Volume value (0-64)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function is useful to play samples over music. You must
|
||||||
|
use a sample channel or the music system will override
|
||||||
|
these parameters when polling the current module.
|
||||||
|
The amiga period value can be translated to hertz using the
|
||||||
|
following formula: Hertz = 8363*428/Period
|
||||||
|
|
||||||
|
|
||||||
|
MODStopVoice
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Stop a sample channel.
|
||||||
|
|
||||||
|
Prototype: void MODStopVoice(Voice)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
|
||||||
|
Remarks: This function will stop the specified voice setting the channel
|
||||||
|
volume to zero. The voice should be a sample channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODSetPeriod
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample channel period value.
|
||||||
|
|
||||||
|
Prototype: void MODSetPeriod(Voice,Period)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Period - Amiga Period (113-856)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function will change the current frequency of the sample
|
||||||
|
channel. The voice should be a sample channel.
|
||||||
|
|
||||||
|
|
||||||
|
MODSetVolume
|
||||||
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||||
|
Function: Set the sample channel volume.
|
||||||
|
|
||||||
|
Prototype: void MODSetVolume(Voice,Volume)
|
||||||
|
|
||||||
|
Parameters: Voice - Audio channel number (0-7)
|
||||||
|
Volume - Volume (0-64)
|
||||||
|
|
||||||
|
Returns: None.
|
||||||
|
|
||||||
|
Remarks: This function will change the channel volume. The voice should
|
||||||
|
be a sample channel.
|
||||||
|
\******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __MODPLAY_H
|
||||||
|
#define __MODPLAY_H
|
||||||
|
|
||||||
|
typedef unsigned char byte;
|
||||||
|
typedef unsigned short word;
|
||||||
|
typedef unsigned long dword;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
word Period;
|
||||||
|
word Volume;
|
||||||
|
dword Length;
|
||||||
|
void *Data;
|
||||||
|
} Sample;
|
||||||
|
|
||||||
|
#pragma aux MODPlayModule "_*" parm caller [];
|
||||||
|
#pragma aux MODStopModule "_*" parm caller [];
|
||||||
|
#pragma aux MODPlaySample "_*" parm caller [];
|
||||||
|
#pragma aux MODPlayVoice "_*" parm caller [];
|
||||||
|
#pragma aux MODStopVoice "_*" parm caller [];
|
||||||
|
#pragma aux MODSetPeriod "_*" parm caller [];
|
||||||
|
#pragma aux MODSetVolume "_*" parm caller [];
|
||||||
|
|
||||||
|
extern int MODPlayModule(void *Modulefile,word Chans,word Rate,word Port,byte IRQ,byte DRQ);
|
||||||
|
extern void MODStopModule(void);
|
||||||
|
extern void MODPlaySample(byte Voice,Sample *Instr);
|
||||||
|
extern void MODPlayVoice(byte Voice,byte Instr,word Period,byte Volume);
|
||||||
|
extern void MODStopVoice(byte Voice);
|
||||||
|
extern void MODSetPeriod(byte Voice,word Period);
|
||||||
|
extern void MODSetVolume(byte Voice,byte Volume);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
181
mall/MOUSE.C
Normal file
181
mall/MOUSE.C
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
// 3D Construction Kit
|
||||||
|
// Started: 01/02/94
|
||||||
|
// Author: Lary Myers
|
||||||
|
// Module: MOUSE.C
|
||||||
|
// (c) CopyRight 1994 All Rights Reserved
|
||||||
|
|
||||||
|
#include <dos.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dos.h>
|
||||||
|
|
||||||
|
|
||||||
|
void Mymemset(void *,int,int);
|
||||||
|
|
||||||
|
int MouseModifier = 2;
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Check if mouse is installed, returns -1 if it IS installed
|
||||||
|
//=============================================================================
|
||||||
|
int MouseInstalled(void)
|
||||||
|
{
|
||||||
|
int yesno;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
intr(0x33,®s);
|
||||||
|
yesno = regs.w.ax;
|
||||||
|
|
||||||
|
return(yesno);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Show the mouse cursor
|
||||||
|
//=============================================================================
|
||||||
|
void ShowMouse(void)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 1;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Hide the mouse cursor
|
||||||
|
//=============================================================================
|
||||||
|
void HideMouse(void)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 2;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Returns button status, mouse row and column
|
||||||
|
//=============================================================================
|
||||||
|
int ReadMouseCursor(int *mrow,int *mcol)
|
||||||
|
{
|
||||||
|
int bstatus;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 3;
|
||||||
|
intr(0x33,®s);
|
||||||
|
bstatus = regs.w.bx;
|
||||||
|
*mrow = regs.w.dx;
|
||||||
|
*mcol = regs.w.cx / MouseModifier;
|
||||||
|
|
||||||
|
return(bstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Returns just the mouse button status
|
||||||
|
//=============================================================================
|
||||||
|
int ReadMouseButtons(void)
|
||||||
|
{
|
||||||
|
int bstatus;
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 3;
|
||||||
|
intr(0x33,®s);
|
||||||
|
bstatus = regs.w.bx;
|
||||||
|
|
||||||
|
return(bstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Set mouse cursor to desired row and column
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseCursor(int mrow,int mcol)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 4;
|
||||||
|
regs.w.dx = mrow;
|
||||||
|
regs.w.cx = mcol * MouseModifier;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Defines left and right columns for mouse travel
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseMinMaxColumns(int mincol,int maxcol)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 7;
|
||||||
|
regs.w.cx = mincol * MouseModifier;
|
||||||
|
regs.w.dx = maxcol * MouseModifier;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Defines top and bottom rows for mouse travel
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseMinMaxRows(int minrow,int maxrow)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 8;
|
||||||
|
regs.w.cx = minrow;
|
||||||
|
regs.w.dx = maxrow;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Set shape of mouse cursor. 8 byte mask, hotspot row,col
|
||||||
|
//=============================================================================
|
||||||
|
void SetMouseShape(int hsrow,int hscol,char far *mask)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 9;
|
||||||
|
regs.w.dx = FP_OFF(mask);
|
||||||
|
regs.w.es = FP_SEG(mask);
|
||||||
|
regs.w.bx = hscol;
|
||||||
|
regs.w.cx = hsrow;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Wait for the mouse button to be released
|
||||||
|
//=============================================================================
|
||||||
|
void MouseReleased(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (ReadMouseButtons());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
void MouseSetFunction(unsigned char mFlag,void *Func)
|
||||||
|
{
|
||||||
|
union REGPACK regs;
|
||||||
|
|
||||||
|
Mymemset(®s,0,sizeof(union REGPACK));
|
||||||
|
regs.w.ax = 12;
|
||||||
|
regs.w.dx = FP_OFF(Func);
|
||||||
|
regs.w.es = FP_SEG(Func);
|
||||||
|
regs.w.cx = mFlag;
|
||||||
|
intr(0x33,®s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
BIN
mall/PICS.DTF
Normal file
BIN
mall/PICS.DTF
Normal file
Binary file not shown.
BIN
mall/WALK.MOD
Normal file
BIN
mall/WALK.MOD
Normal file
Binary file not shown.
Loading…
Reference in a new issue