update example project (cleanups, enhancements, comments, etc)

This commit is contained in:
Gered 2019-11-10 13:43:40 -05:00
parent de3232a474
commit 6f75f4284a
4 changed files with 193 additions and 34 deletions

View file

@ -1,4 +1,17 @@
// Function to process and ACK resource file
/*
* ACK-3D Resource File Processing
* -------------------------------
*
* This source file is basically a copy of the ACKINFO.CPP file from the
* Windows example project discussed in chapter 14 of the book.
*
* There are some slight modifications that I've made though:
* - A global ACKENG structure is not assumed. You must pass one in to
* ProcessInfoFile()
* - Functions for processing a scrolling backdrop have been copied from the
* FDEMO/MALL demo projects and are included here since they are useful.
* - A function for loading a palette is included.
*/
#include <stdio.h>
#include <io.h>
@ -6,10 +19,6 @@
#include "ackeng.h"
#include "ackext.h"
// The application MUST have a global variable called ae for use by this
// routine.
extern ACKENG *ae;
// Globals
int LineNumber;
char LineBuffer[200];
@ -43,17 +52,57 @@ void ProcessBackDrop(UCHAR *bPtr) {
}
}
// Loads a bitmap (wall, object, screen/backdrop, etc) and returns a
// pointer to the bitmap data. The first 4-bytes of the returned pointer
// are the width and height (2 shorts) followed by the raw pixel data.
// The filename passed can be either a string specifying a file or an
// integer specifying a resource from the currently open resource file.
UCHAR* LoadBitmap(UCHAR bitmapType, char *fName) {
UCHAR *bPtr = NULL;
switch (bitmapType) {
case BMLOAD_BBM:
bPtr = AckReadiff(fName);
break;
case BMLOAD_GIF:
bPtr = AckReadgif(fName);
break;
case BMLOAD_PCX:
bPtr = AckReadPCX(fName);
break;
}
return bPtr;
}
// Loads a 256 color palette and returns a pointer to the raw color data.
UCHAR* LoadPalette(int resource) {
UCHAR *ptr = NULL;
FILE *fp;
fp = fdopen(rsHandle,"rb");
if (!fp)
return NULL;
fseek(fp, rbaTable[(int)resource], SEEK_SET);
ptr = (UCHAR*)AckMalloc(768);
fread(ptr, 768, 1, fp);
return ptr;
}
// Loads a background image and processes the image into the
// separate slices for use at display time. Currently a background image
// can be 640 columns wide. This number can be made dynamic if needbe and would
// need to be changed in the routine below and in the DrawBackground routine
// in the ACK engine.
int LoadBackDrop(void) {
int LoadBackDrop(ACKENG *ae) {
UCHAR *bPtr;
if (ResScrollBack) {
bPtr = AckReadiff((char*)ResScrollBack);
bPtr = LoadBitmap(ae->bmLoadType, (char*)ResScrollBack);
if (bPtr == NULL)
return 8;
@ -64,6 +113,7 @@ int LoadBackDrop(void) {
return 0;
}
// Reads a text line from the resource file
int ReadLine(void) {
int len;
@ -110,7 +160,7 @@ char *GetNextParm(char *s) {
}
// Loads a wall bitmap specified in info file
int LoadWall(void) {
int LoadWall(ACKENG *ae) {
int wnum, rnum, result;
long pos;
char *lb;
@ -133,7 +183,7 @@ int LoadWall(void) {
}
// Loads an object bitmap specified in info file
int LoadObject(void) {
int LoadObject(ACKENG *ae) {
int onum, rnum, result;
long pos;
char *lb;
@ -164,7 +214,7 @@ char *SkipSpaces(char *s) {
}
// Creates and object of the desired style
int CreateObject(void) {
int CreateObject(ACKENG *ae) {
short onum, vnum;
short result, oType;
short NumViews, bmPerView;
@ -289,7 +339,7 @@ int CreateObject(void) {
}
// Reads the ASCII info file and processes the commands.
int ProcessInfoFile(void) {
int ProcessInfoFile(ACKENG *ae) {
int result;
int mode;
long pos;
@ -323,7 +373,7 @@ int ProcessInfoFile(void) {
if (!strnicmp(LineBuffer, "ENDBITMAPS:", 11))
mode = 4;
else
result = LoadWall();
result = LoadWall(ae);
break;
case 2: // Object bitmaps
@ -335,14 +385,14 @@ int ProcessInfoFile(void) {
if (!strnicmp(LineBuffer, "ENDBITMAPS:", 11))
mode = 5;
else
result = LoadObject();
result = LoadObject(ae);
break;
case 3: // Create Object
if (!strnicmp(LineBuffer, "ENDDESC:", 8))
mode = 5;
else
result = CreateObject();
result = CreateObject(ae);
break;
case 4: // Walls topic

28
example/assets.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef ASSETS_H_INCLUDED
#define ASSETS_H_INCLUDED
#include "ack3d.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int LineNumber;
extern char LineBuffer[];
extern int MapResource;
extern int PalResource;
extern int ResScreenBack;
extern int ResScrollBack;
UCHAR* LoadBitmap(UCHAR bitmapType, char *fName);
UCHAR* LoadPalette(int resource);
int LoadBackDrop(ACKENG *ae);
int ProcessInfoFile(ACKENG *ae);
#ifdef __cplusplus
};
#endif
#endif

View file

@ -24,6 +24,7 @@
#include "ack3d.h"
#include "ackeng.h"
#include "ackext.h"
#include "assets.h"
#define KEY_RIGHT 77
#define KEY_UP 72
@ -33,23 +34,55 @@
#define KEY_ESCAPE 1
#define TURN_SPEED 5
#define TURN_SPEED_DECAY 3
#define MOVE_SPEED 5
#define MOVE_SPEED_DECAY 3
#define BASE_MOVE_AMOUNT 8
#define BASE_TURN_AMOUNT INT_ANGLE_4
#define TURN_SPEED_DECAY 2
#define MOVE_SPEED 4
#define MOVE_SPEED_DECAY 1
#define BASE_MOVE_AMOUNT 5
#define BASE_TURN_AMOUNT INT_ANGLE_2
// ACK3D bitmap loading routines, such as AckReadiff(), will automatically
// populate (and re-populate) this array with palette found in that image
// file. still, this must be manually set with AckSetPalette()
// file. still, this (or any other palette color data) must be manually set
// with AckSetPalette()
extern unsigned char colordat[];
int ProcessInfoFile(void);
// These are the ranges used for distance shading. Will need to be modified
// for the new color palette used.
// For ACK-3D's distance-based light shading to look best, your palette really
// needs to be designed with this in mind (and your bitmaps too). Many of the
// ACK-3D demo assets don't look so good with it.
ColorRange ranges[64] = {
1,15,
16,16,
32,16,
48,16,
64,16,
80,16,
96,8,
104,8,
112,8,
120,8,
136,8,
144,8,
152,8,
160,8,
168,8,
176,8,
184,8,
192,16,
208,16,
224,16,
240,15,
0,0
};
// this is the main ACK3D engine structure. holds the map, bitmaps, objects,
// and also the current state of the game world (as far as ACK3D is concerned)
ACKENG *ae;
UCHAR *uiFrame = NULL;
UCHAR *palette = NULL;
// this game loop made semi-overcomplicated by rudimentary turn/movement
// acceleration logic
void GameLoop(void) {
@ -101,6 +134,7 @@ void GameLoop(void) {
}
if (AckKeys[KEY_SPACE]) {
AckKeys[KEY_SPACE] = 0;
AckCheckDoorOpen(ae->xPlayer, ae->yPlayer, ae->PlayerAngle);
}
@ -141,14 +175,10 @@ int main(int argc, char *argv[]) {
// ack3d renderer viewport size. on 486 and lower-spec machines, you
// probably do not want this to be at full 320x200 for performance reasons
// even reducing 320x200 by 20% makes a nice, noticeable difference!
ae->WinStartX = 0;
ae->WinStartY = 0;
ae->WinEndX = 319;
ae->WinEndY = 199;
// various other flags that can be set too
ae->LightFlag = SHADING_ON;
ae->DoorSpeed = 3;
ae->WinStartX = 16;
ae->WinStartY = 12;
ae->WinEndX = 303;
ae->WinEndY = 158;
printf("Initializing ACK-3D\n");
@ -184,19 +214,48 @@ int main(int argc, char *argv[]) {
return 1;
}
result = ProcessInfoFile();
result = ProcessInfoFile(ae);
if (result) {
printf("Error while processing. Result code %d\n", result);
printf("Error while processing pics.dtf\n");
printf("Result code %d\nLine number: %d\nLine: %s\n", result, LineNumber, LineBuffer);
return 1;
}
printf("Processing scrolling backdrop\n");
// processes any (optional) scrolling backdrop that was loaded so it is
// ready to be rendered
LoadBackDrop();
LoadBackDrop(ae);
// if the resource file specified a screen/ui bitmap, then load it
if (ResScreenBack) {
uiFrame = LoadBitmap(ae->bmLoadType, (char*)ResScreenBack);
}
// if the resource file specified a palette, then load it
if (PalResource) {
palette = LoadPalette(PalResource);
}
// we won't be loading anything else from the resource file now, so we
// can close it
AckCloseResource();
// various other flags that can be set too.
// many of these can be set by the .INF file found in pics.dtf, so
// setting any of the ACKENG properties here would override the .INF
// settings.
ae->xPlayer = 32 *GRID_SIZE+(GRID_SIZE/2); // x = middle of grid 32
ae->yPlayer = 32 *GRID_SIZE+(GRID_SIZE/2); // y = middle of grid 32
ae->PlayerAngle = 0;
ae->LightFlag = SHADING_OFF;
ae->DoorSpeed = 3;
// Set palette for shading if needed
if (ae->LightFlag) {
AckSetupPalRanges(ae, ranges);
}
printf("Finished initializing\n");
// the main ack3d rendering functions all assume that the various fields
@ -212,10 +271,32 @@ int main(int argc, char *argv[]) {
AckSetupKeyboard();
AckSetVGAmode();
AckSetPalette(colordat);
if (palette) {
// we loaded an explicitly specified palette from the resource file,
// so we'll set that one
AckSetPalette(palette);
} else {
// default to whatever the palette was from the last loaded bitmap
AckSetPalette(colordat);
}
// draw the full screen/ui frame. ACK-3D won't overwrite this because
// our WinStart/WinEnd was set to only draw to the viewport box that our
// screen/ui frame bitmap should have (so we only need to render this
// bitmap once)
if (uiFrame) {
memcpy((void*)0xA0000, uiFrame+4, 64000);
}
GameLoop();
// anything allocated with AckMalloc can only be free'd with AckFree!
if (uiFrame)
AckFree(uiFrame);
if (palette)
AckFree(palette);
AckWrapUp(ae);
AckSetTextMode();

View file

@ -7,7 +7,7 @@ acklib_lib = ..\ack_lib\acklib.lib
object_files = &
example.obj &
ackinfo.obj
assets.obj
cc_flags_debug = /d2 /zp1 /4r /fp3 /j
cc_flags_release = /d1+ /zp1 /4r /fp3 /onetx /j