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