Commit 2fa9feb4 authored by Steven Fuller's avatar Steven Fuller

Added Mac Wolf3D to CVS

parent 7af3c59d
This diff is collapsed.
typedef unsigned int Word;
typedef unsigned long LongWord;
#ifndef __MACTYPES__
typedef unsigned char Byte;
typedef unsigned char Boolean;
#endif
#define BLACK 255
#define DARKGREY 250
#define BROWN 101
#define PURPLE 133
#define BLUE 210
#define DARKGREEN 229
#define ORANGE 23
#define RED 216
#define BEIGE 14
#define YELLOW 5
#define GREEN 225
#define LIGHTBLUE 150
#define LILAC 48
#define PERIWINKLE 120
#define LIGHTGREY 43
#define WHITE 0
#define __MAC__
#define __BIGENDIAN__
#define SfxActive 1
#define MusicActive 2
#define VideoSize 64000
#define SetAuxType(x,y)
#define SetFileType(x,y)
extern unsigned char *VideoPointer;
extern Word KeyModifiers;
extern Word ScanCode;
extern Word KilledSong;
extern Word SystemState;
extern Word VideoWidth;
extern LongWord LastTick;
extern LongWord YTable[480];
extern Handle RezHandle;
void DLZSS(Byte *Dest, Byte *Src,LongWord Length);
void DLZB(Byte *Dest, Byte *Src,LongWord Length);
LongWord SwapLong(LongWord Val);
unsigned short SwapUShort(unsigned short Val);
short SwapShort(short Val);
void WaitTick(void);
void WaitTicks(Word TickCount);
Word WaitTicksEvent(Word TickCount);
Word WaitEvent(void);
LongWord ReadTick(void);
void *AllocSomeMem(LongWord Size);
void FreeSomeMem(void *MemPtr);
Word GetAKey(void);
Word AllKeysUp(void);
Word WaitKey(void);
void FlushKeys(void);
Word FixMacKey(EventRecord *MyRecord);
void SoundOff(void);
void PlaySound(Word SndNum);
void StopSound(Word SndNum);
void PlaySong(Word SongNum);
void ClearTheScreen(Word Color);
void ShowPic(Word PicNum);
void InitYTable(void);
void InstallAFont(Word FontNum);
void FontUseMask(void);
void FontUseZero(void);
void SetFontXY(Word x,Word y);
void FontSetColor(Word Index,Word Color);
void DrawAString(char *TextPtr);
void DrawAChar(Word Letter);
void ultoa(LongWord Val,char *TextPtr);
Word GetRandom(Word Range);
void Randomize(void);
void DrawShape(Word x,Word y,void *ShapePtr);
void DrawXMShape(Word x,Word y,void *ShapePtr);
void DrawMShape(Word x,Word y,void *ShapePtr);
void EraseMBShape(Word x,Word y, void *ShapePtr,void *BackPtr);
Word TestMShape(Word x,Word y,void *ShapePtr);
Word TestMBShape(Word x,Word y,void *ShapePtr,void *BackPtr);
void SetAPalette(Word PalNum);
void SetAPalettePtr(unsigned char *PalPtr);
void FadeTo(Word PalNum);
void FadeToBlack(void);
void FadeToPtr(unsigned char *PalPtr);
void *LoadAResource(Word RezNum);
void ReleaseAResource(Word RezNum);
void KillAResource(Word RezNum);
void *LoadAResource2(Word RezNum,LongWord Type);
void ReleaseAResource2(Word RezNum,LongWord Type);
void KillAResource2(Word RezNum,LongWord Type);
void SaveJunk(void *AckPtr,Word Length);
#include "wolfdef.h"
/**********************************
Global data used by Wolfenstein 3-D
**********************************/
Word tilemap[MAPSIZE][MAPSIZE]; /* Main tile map */
Word ConnectCount; /* Number of valid interconnects */
connect_t areaconnect[MAXDOORS]; /* Is this area mated with another? */
Boolean areabyplayer[MAXAREAS]; /* Which areas can I see into? */
Word numstatics; /* Number of active static objects */
static_t statics[MAXSTATICS]; /* Data for the static items */
Word numdoors; /* Number of active door objects */
door_t doors[MAXDOORS]; /* Data for the door items */
Word nummissiles; /* Number of active missiles */
missile_t missiles[MAXMISSILES]; /* Data for the missile items */
Word numactors; /* Number of active actors */
actor_t actors[MAXACTORS]; /* Data for the actors */
unsigned char **GameShapes; /* Pointer to the game shape array */
Word difficulty; /* 0 = easy, 1= normal, 2=hard*/
gametype_t gamestate; /* Status of the game (Save game) */
exit_t playstate; /* Current status of the game */
Word killx,killy; /* X,Y of the thing that killed you! */
Boolean madenoise; /* True when shooting or screaming*/
Boolean playermoving; /* Is the player in motion? */
Boolean useheld; /* Holding down the use key? */
Boolean selectheld; /* Weapon select held down? */
Boolean attackheld; /* Attack button held down? */
Boolean buttonstate[NUMBUTTONS]; /* Current input */
Word joystick1; /* Joystick value */
int mousex; /* Mouse x movement */
int mousey; /* Mouse y movement */
int mouseturn; /* Mouse turn movement */
Word nextmap; /* Next map to warp to */
Word facecount; /* Time to show a specific head */
Word faceframe; /* Head pic to show */
Word elevatorx,elevatory; /* x,y of the elevator */
Word firstframe; /* if non 0, the screen is still faded out */
Word OldMapNum; /* Currently loaded map # */
loadmap_t *MapPtr; /* Pointer to current loaded map */
int clipshortangle; /* Angle for the left edge of the screen */
int clipshortangle2; /* clipshortangle * 2 */
Word viewx; /* X coord of camera */
Word viewy; /* Y coord of camera */
fixed_t viewsin; /* Base sine for viewing angle */
fixed_t viewcos; /* Base cosine for viewing angle */
Word normalangle; /* Normalized angle for view (NSEW) */
Word centerangle; /* viewangle in fineangles*/
Word centershort; /* viewangle in 64k angles*/
Word topspritescale; /* Scale of topmost sprite */
Word topspritenum; /* Shape of topmost sprite */
Word xscale[1024]; /* Scale factor for width of the screen */
Word numvisspr; /* Number of valid visible sprites */
vissprite_t vissprites[MAXVISSPRITES]; /* Buffer for sprite records */
Word xevents[MAXVISSPRITES]; /* Scale events for sprite sort */
Word sortbuffer[MAXVISSPRITES]; /* mergesort requires an extra buffer*/
Word *firstevent; /* First event in sorted list */
Boolean areavis[MAXAREAS]; /* Area visible */
Word bspcoord[4]; /* Rect for the BSP search */
Word TicCount; /* Ticks since last screen draw */
Word LastTicCount; /* Tick value at start of render */
Boolean IntermissionHack; /* Hack for preventing double score drawing during intermission */
Word rw_maxtex;
Word rw_mintex;
LongWord rw_scalestep;
Word rw_midpoint;
Boolean rw_downside;
int rw_centerangle;
Byte *rw_texture;
LongWord rw_scale;
Byte *ArtData[64];
void *SpriteArray[S_LASTONE];
Word MacVidSize = -1;
Word SlowDown = 1; /* Force the game to 15 hz */
Word MouseEnabled = 0; /* Allow mouse control */
Word GameViewSize = 0; /* Size of the game screen */
Word NoWeaponDraw=1; /* Flag to not draw the weapon on the screen */
maplist_t *MapListPtr; /* Pointer to map info record */
unsigned short *SongListPtr; /* Pointer to song list record */
unsigned short *WallListPtr; /* Pointer to wall list record */
Word MaxScaler = 1; /* Maximum number of VALID scalers */
Boolean ShowPush; /* Cheat for pushwalls */
Byte textures[MAPSIZE*2+5][MAPSIZE]; /* Texture indexes */
Word NaziSound[] = {SND_ESEE,SND_ESEE2,SND_ESEE3,SND_ESEE4};
classinfo_t classinfo[] = { /* Info for all the bad guys */
{SND_ESEE,SND_EDIE, /* Nazi */
ST_GRD_WLK1, ST_GRD_STND, ST_GRD_ATK1,ST_GRD_PAIN,ST_GRD_DIE,
100, 5, 0x0F, 6},
{SND_ESEE,SND_EDIE, /* Blue guard */
ST_OFC_WLK1, ST_OFC_STND, ST_OFC_ATK1,ST_OFC_PAIN,ST_OFC_DIE,
400, 10, 0x01, 12},
{SND_ESEE,SND_EDIE, /* White officer */
ST_SS_WLK1, ST_SS_STND, ST_SS_ATK1,ST_SS_PAIN,ST_SS_DIE,
500, 6, 0x07, 25},
{SND_DOGBARK,SND_DOGDIE, /* Dog */
ST_DOG_WLK1,ST_DOG_STND,ST_DOG_ATK1,ST_DOG_WLK1,ST_DOG_DIE,
200, 9, 0x07, 1},
{SND_NOSOUND,SND_EDIE, /* Mutant */
ST_MUTANT_WLK1, ST_MUTANT_STND, ST_MUTANT_ATK1,ST_MUTANT_PAIN,ST_MUTANT_DIE,
400, 7, 0x01, 18},
{SND_GUTEN,SND_EDIE, /* Hans */
ST_HANS_WLK1, ST_HANS_STND, ST_HANS_ATK1,ST_GRD_STND,ST_HANS_DIE,
5000,7, 0x01, 250},
{SND_SHITHEAD,SND_EDIE, /* Dr. Schabbs */
ST_SCHABBS_WLK1, ST_SCHABBS_STND, ST_SCHABBS_ATK1,ST_GRD_STND,ST_SCHABBS_DIE,
5000, 5,0x01, 350},
{SND_GUTEN,SND_EDIE, /* Trans */
ST_TRANS_WLK1, ST_TRANS_STND, ST_TRANS_ATK1,ST_GRD_STND,ST_TRANS_DIE,
5000, 7,0x01, 300},
{SND_DOGBARK,SND_EDIE, /* Uber knight */
ST_UBER_WLK1, ST_UBER_STND, ST_UBER_ATK1,ST_GRD_STND,ST_UBER_DIE,
5000, 8,0x01, 400},
{SND_COMEHERE,SND_EDIE, /* Dark knight */
ST_DKNIGHT_WLK1, ST_DKNIGHT_STND, ST_DKNIGHT_ATK1,ST_GRD_STND,ST_DKNIGHT_DIE,
5000, 7,0x01, 450},
{SND_SHIT,SND_EDIE, /* Mechahitler */
ST_MHITLER_WLK1, ST_MHITLER_STND, ST_MHITLER_ATK1,ST_GRD_STND, ST_HITLER_DIE,
5000, 7,0x01, 500},
{SND_HITLERSEE,SND_EDIE, /* Hitler */
ST_HITLER_WLK1, ST_MHITLER_STND, ST_HITLER_ATK1,ST_GRD_STND,ST_HITLER_DIE,
5000, 8,0x01, 500},
};
#include "Wolfdef.h"
#include <string.h>
/**********************************
Rules for door operation
door->position holds the amount the door is open, ranging from 0 to TILEGLOBAL-1
The number of doors is limited to 64 because various fields are only 6 bits
Open doors conect two areas, so sounds will travel between them and sight
will be checked when the player is in a connected area.
areaconnect has a list of connected area #'s, used to create the table areabyplayer
Every time a door opens or closes the areabyplayer matrix gets recalculated.
An area is True if it connects with the player's current spor.
**********************************/
/**********************************
Insert a connection between two rooms
Note: I can have MORE than one connection between rooms
so it is VALID to have duplicate entries (1,6) & (1,6)
Each call to AddConnection must be balanced with a call to RemoveConnection
**********************************/
void AddConnection(Word Area1,Word Area2)
{
connect_t *DestPtr;
DestPtr = &areaconnect[ConnectCount]; /* Make pointer to the last record */
DestPtr->Area1 = Area1; /* Init the struct */
DestPtr->Area2 = Area2;
++ConnectCount; /* Add 1 to the valid list */
}
/**********************************
Remove a connection between two rooms
Note: I can have MORE than one connection between rooms
so it is VALID to have duplicate entries (1,6) & (1,6)
**********************************/
void RemoveConnection(Word Area1,Word Area2)
{
Word i;
connect_t *DestPtr;
DestPtr = &areaconnect[0]; /* Init the scan pointer */
i = ConnectCount; /* Init the count */
if (!i) {
return;
}
do {
if (DestPtr->Area1 == Area1 && /* Match? */
DestPtr->Area2 == Area2) {
--ConnectCount; /* Remove the count */
DestPtr[0] = areaconnect[ConnectCount]; /* Copy last to current */
break; /* I'm done! */
}
++DestPtr; /* Next entry to scan */
} while (--i); /* Should NEVER fall out! */
}
/**********************************
Recursive routine to properly set the areabyplayer array by
using the contents of the areaconnect array.
Scans outward from playerarea, marking all connected areas.
**********************************/
void RecursiveConnect(Word areanumber)
{
Word i;
Word j;
connect_t *AreaPtr;
areabyplayer[areanumber] = TRUE; /* Mark this spot (Prevent overflow) */
i = ConnectCount; /* Init index */
if (i) { /* No doors available? */
AreaPtr = &areaconnect[0]; /* Get a local pointer */
do {
if (AreaPtr->Area1 == areanumber) { /* Am I in this pair? */
j = AreaPtr->Area2; /* Follow this path */
goto TryIt;
}
if (AreaPtr->Area2 == areanumber) { /* The other side? */
j = AreaPtr->Area1; /* Follow this side */
TryIt:
if (!areabyplayer[j]) { /* Already been here? */
RecursiveConnect(j); /* Link it in... */
}
}
++AreaPtr; /* Next entry */
} while (--i); /* All done? */
}
}
/**********************************
Properly set the areabyplayer record
**********************************/
void ConnectAreas(void)
{
memset(areabyplayer,0,sizeof(areabyplayer)); /* Zap the memory */
RecursiveConnect(MapPtr->areasoundnum[actors[0].areanumber]); /* Start here */
}
/**********************************
Start a door opening
**********************************/
void OpenDoor(door_t *door)
{
if (door->action == DR_OPEN) { /* Already open? */
door->ticcount = 0; /* Reset open time (Keep open) */
} else {
door->action = DR_OPENING; /* start it opening*/
} /* The door will be made passable when it is totally open */
}
/**********************************
Start a door closing
**********************************/
void CloseDoor(door_t *door)
{
Word tile,tilex,tiley;
Word *TilePtr;
int delta;
/* don't close on anything solid */
tilex = door->tilex; /* Get the current tile */
tiley = door->tiley;
TilePtr = &tilemap[tiley][tilex]; /* Get pointer to tile map */
if (door->action != DR_OPENING) { /* In the middle of opening? */
/* don't close on an actor or bonus item */
tile = TilePtr[0]; /* What's the tile? */
if (tile & TI_BODY) {
door->action = DR_WEDGEDOPEN; /* bodies never go away */
return;
}
if (tile & (TI_ACTOR | TI_GETABLE) ) { /* Removable? */
door->ticcount = 60; /* wait a while before trying to close again */
return;
}
/* Don't close on the player */
delta = actors[0].x - ((tilex<<8)|0x80);
if (w_abs(delta) <= (0x82+PLAYERSIZE)) {
delta = actors[0].y - ((tiley<<8)|0x80);
if (w_abs(delta) <= (0x82+PLAYERSIZE)) {
return; /* It's touching the player! */
}
}
}
door->action = DR_CLOSING; /* Close the door */
TilePtr[0] |= (TI_BLOCKMOVE|TI_BLOCKSIGHT); /* make the door space a solid tile*/
}
/**********************************
Open or Close a door (Press space at a door)
**********************************/
void OperateDoor(Word dooron)
{
Word type;
door_t *door;
door = &doors[dooron]; /* Which door? */
type = door->info>>1; /* Get the door type */
if ( (type==1 && !(gamestate.keys&1)) || (type==2 && !(gamestate.keys&2)) ) {
PlaySound(SND_LOCKEDDOOR); /* The door is locked */
return;
}
switch (door->action) {
case DR_CLOSED:
case DR_CLOSING:
OpenDoor(door); /* Open the door */
break;
case DR_OPEN:
case DR_OPENING:
CloseDoor(door); /* Close the door */
}
}
/**********************************
Close the door after a few seconds
**********************************/
void DoorOpen(door_t *door)
{
door->ticcount+=TicCount; /* Inc the tic value */
if (door->ticcount >= OPENTICS) { /* Time up? */
door->ticcount = OPENTICS-1; /* So if the door can't close it will keep trying*/
CloseDoor(door); /* Try to close the door */
}
}
/**********************************
Step the door animation for open, mark as DR_OPEN if all the way open
**********************************/
void DoorOpening(door_t *door)
{
Word position;
Word area1,area2;
Byte *SoundNumPtr;
position = door->position; /* Get the pixel position */
if (!position) { /* Fully closed? */
/* door is just starting to open, so connect the areas*/
SoundNumPtr = MapPtr->areasoundnum;
area1 = SoundNumPtr[door->area1];
area2 = SoundNumPtr[door->area2];
AddConnection(area1,area2); /* Link the two together */
ConnectAreas(); /* Link the map */
if (areabyplayer[area1] || areabyplayer[area2]) { /* Can I hear it? */
PlaySound(SND_OPENDOOR); /* Play the door sound */
}
}
/* slide the door open a bit */
position += DOORSPEED*TicCount; /* Move the door a bit */
if (position >= TILEGLOBAL-1) { /* Fully open? */
/* Door is all the way open */
position = TILEGLOBAL-1; /* Set to maximum */
door->ticcount = 0; /* Reset the timer for closing */
door->action = DR_OPEN; /* Mark as open */
tilemap[door->tiley][door->tilex] &= ~(TI_BLOCKMOVE|TI_BLOCKSIGHT); /* Mark as enterable */
}
door->position = position; /* Set the new position */
}
/**********************************
Step the door animation for close,
mark as DR_CLOSED if all the way closed
**********************************/
void DoorClosing(door_t *door)
{
int position;
Byte *SoundNumPtr;
position = door->position-(DOORSPEED*TicCount); /* Close a little more */
if (position <= 0) { /* Will I close now? */
/* door is closed all the way, so disconnect the areas*/
SoundNumPtr = MapPtr->areasoundnum; /* Unlink the sound areas */
RemoveConnection(SoundNumPtr[door->area1],SoundNumPtr[door->area2]);
ConnectAreas(); /* Reset areabyplayer */
door->action = DR_CLOSED; /* It's closed */
position = 0; /* Mark as closed */
}
door->position = position; /* Set the new position */
}
/**********************************
Process all the doors each game loop
**********************************/
void MoveDoors(void)
{
Word dooron; /* Which door am I on? */
door_t *door; /* Pointer to current door */
dooron = numdoors; /* How many doors to scan? */
if (dooron) { /* Any doors at all? */
door = doors; /* Pointer to the first door */
do {
switch (door->action) { /* Call the action code */
case DR_OPEN:
DoorOpen(door); /* Check to close the door */
break;
case DR_OPENING: /* Continue the door opening */
DoorOpening(door);
break;
case DR_CLOSING: /* Close the door */
DoorClosing(door);
}
++door; /* Next pointer */
} while (--dooron); /* All doors done? */
}
}
This diff is collapsed.
This diff is collapsed.
#include "hidemenubar.h"
static Boolean MenuBarHidden = FALSE; /* Current state of the menu bar. */
static Rect OldeMBarRect; /* Saves rectangle enclosing real menu bar. */
static RgnHandle OldeGrayRgn; /* Saves the region defining the desktop */
static short OldMBarHeight; /* Previous menu bar height */
extern GDHandle gMainGDH;
/********************************
Hide the menu bar (If visible)
********************************/
void HideMenuBar(void)
{
RgnHandle menuRgn;
WindowPeek theWindow;
GDHandle TempHand;
TempHand = GetMainDevice();
if (TempHand!=gMainGDH) { /* Main graphics handle */
return;
}
if (!MenuBarHidden) { /* Already hidden? */
OldMBarHeight = LMGetMBarHeight(); /* Get the height in pixels */
OldeGrayRgn = NewRgn(); /* Make a new region */
CopyRgn(GetGrayRgn(), OldeGrayRgn); /* Copy the background region */
OldeMBarRect = qd.screenBits.bounds; /* Make a region from the rect or the monitor width */
OldeMBarRect.bottom = OldeMBarRect.top + OldMBarHeight; /* Top to bottom of menu */
menuRgn = NewRgn(); /* Convert to region */
RectRgn(menuRgn, &OldeMBarRect);
UnionRgn(GetGrayRgn(), menuRgn, GetGrayRgn()); /* Add the menu area to background */
theWindow = (WindowPeek)FrontWindow();
PaintOne((WindowPtr)theWindow, menuRgn); /* Redraw the front window */
PaintBehind((WindowPtr)theWindow, menuRgn); /* Redraw all other windows */
CalcVis((WindowPtr)theWindow); /* Resize the visible region */
CalcVisBehind((WindowPtr)theWindow, menuRgn); /* Resize the visible regions for all others */
DisposeRgn(menuRgn); /* Release the menu region */
MenuBarHidden = TRUE; /* It is now hidden */
ZapMHeight(); /* Zap the height */
}
}
/********************************
Show the menu bar (If hidden)
********************************/
void ShowMenuBar(void)
{
WindowPeek theWindow;
if (MenuBarHidden) { /* Hidden? */
FixMHeight();
MenuBarHidden = FALSE; /* The bar is here */
CopyRgn(OldeGrayRgn, GetGrayRgn()); /* Get the region */
RectRgn(OldeGrayRgn, &OldeMBarRect); /* Convert menu rect to region */
theWindow = (WindowPeek)FrontWindow(); /* Get the front window */
CalcVis((WindowPtr)theWindow); /* Reset the visible region */
CalcVisBehind((WindowPtr)theWindow,OldeGrayRgn); /* Remove the menu bar from windows */
DisposeRgn(OldeGrayRgn); /* Bye bye region */
OldeGrayRgn = 0; /* Zap the handle */
HiliteMenu(0); /* Don't hilite any menu options */
DrawMenuBar(); /* Redraw the menu bar */
}
}
/********************************
Restore the menu bar height so that
the OS can handle menu bar events
********************************/
void FixMHeight(void)
{
if (MenuBarHidden) { /* Hidden? */
LMSetMBarHeight(OldMBarHeight); /* Reset the height */
}
}
/********************************
Zap the menu bar height so that things
like MenuClock won't draw
********************************/
void ZapMHeight(void)
{
if (MenuBarHidden) { /* Hidden? */
LMSetMBarHeight(0); /* Zap the height */
}
}
extern void HideMenuBar(void);
extern void ShowMenuBar(void);
extern void FixMHeight(void);
extern void ZapMHeight(void);
\ No newline at end of file
This diff is collapsed.
#include "wolfdef.h"
#include <ctype.h>
#include <stdlib.h>
/**********************************
Main game introduction
**********************************/
void Intro(void)
{
LongWord *PackPtr;
LongWord PackLength;
Byte *ShapePtr;
NewGameWindow(1); /* Set to 512 mode */
FadeToBlack(); /* Fade out the video */
PackPtr = LoadAResource(rMacPlayPic);
PackLength = PackPtr[0];
ShapePtr = AllocSomeMem(PackLength);
DLZSS(ShapePtr,(Byte *) &PackPtr[1],PackLength);
DrawShape(0,0,ShapePtr);
FreeSomeMem(ShapePtr);
ReleaseAResource(rMacPlayPic);
BlastScreen();
StartSong(SongListPtr[0]); /* Play the song */
FadeTo(rMacPlayPal); /* Fade in the picture */
WaitTicksEvent(240); /* Wait for event */
FadeTo(rIdLogoPal);
if (toupper(WaitTicksEvent(240))=='B') { /* Wait for event */
FadeToBlack();
ClearTheScreen(BLACK);
BlastScreen();
PackPtr = LoadAResource(rYummyPic);
PackLength = PackPtr[0];
ShapePtr = AllocSomeMem(PackLength);
DLZSS(ShapePtr,(Byte *) &PackPtr[1],PackLength);
DrawShape((SCREENWIDTH-320)/2,(SCREENHEIGHT-200)/2,ShapePtr);
FreeSomeMem(ShapePtr);
ReleaseAResource(rYummyPic);
BlastScreen();
FadeTo(rYummyPal);
WaitTicksEvent(600);
}
}
This diff is collapsed.
This diff is collapsed.
#include "wolfdef.h"
/**********************************
Returns a pointer to an empty missile record
**********************************/
missile_t *GetNewMissile(void)
{
Word Count;
Count = nummissiles;
if (Count < MAXMISSILES) { /* Already full? */
++Count; /* Next entry */
nummissiles = Count; /* Save the new missile count */
}
return &missiles[Count-1]; /* Get pointer to empty missile */
}
/**********************************
Explode a missile
**********************************/
void ExplodeMissile(missile_t *MissilePtr)
{
MissilePtr->flags = 0; /* Can't harm anyone! */
if (MissilePtr->type == MI_PMISSILE) {
MissilePtr->pic = S_MISSBOOM; /* Rocket explosion */
MissilePtr->type = 16; /* Tics to stay in explosion*/
} else {
MissilePtr->pic = S_FIREBOOM; /* Fire explosion */
MissilePtr->type = 8; /* Tics to stay in explosion*/
}
PlaySound(SND_BOOM|0x8000); /* BOOM! */
MissilePtr->x -= MissilePtr->xspeed; /* Undo the last motion */
MissilePtr->y -= MissilePtr->yspeed;
MissilePtr->xspeed = 0; /* Don't move anymore */
MissilePtr->yspeed = 0;
}
/**********************************
Take damage from the player
Damage is 8,16...64, pass the x,y for a kill x,y
**********************************/
void MissileHitPlayer(missile_t *MissilePtr)
{
TakeDamage((w_rnd()&0x38)+8,MissilePtr->x,MissilePtr->y); /* Inflict damage */
}
/**********************************
Take damage from the enemy
Detonate if not killed (return True)
**********************************/
Boolean MissileHitEnemy(missile_t *MissilePtr, actor_t *ActorPtr)
{
Word Damage;
if (MissilePtr->type == MI_PMISSILE) { /* Rocket? */
Damage = (w_rnd()&0x30)+16; /* Hit'm hard! */
} else {
Damage = (w_rnd()&0x0f)+1; /* Burn a little */
}
DamageActor(Damage,ActorPtr); /* Hit'em! */
return !(ActorPtr->flags & FL_DEAD); /* Not dead? */
}
/**********************************
Did the missile impact on an actor
**********************************/
Boolean CheckMissileActorHits(missile_t *MissilePtr)
{
Word xl,xh,yh;
Word x,y;
Word Bang;
Word tile;
actor_t *ActorPtr;
Bang = 0; /* Assume the missile is OK */
xl = (MissilePtr->x>>FRACBITS)-1; /* Create the kill rect */
xh = xl+3;
y = (MissilePtr->y>>FRACBITS)-1;
yh = y+3;
if (xl>=MAPSIZE) { /* Clip the attack rect to STAY on the map! */
xl = 0;
}
if (y>=MAPSIZE) {
y = 0;
}
if (xh>=MAPSIZE) {
xh = MAPSIZE;
}
if (yh>=MAPSIZE) {
yh = MAPSIZE;
}
do {
x = xl; /* Begin the X scan */
do {
tile = tilemap[y][x]; /* Actor here? */
if (tile&TI_ACTOR) {
ActorPtr = &actors[MapPtr->tilemap[y][x]]; /* Check for impact */
if ( (w_abs(ActorPtr->x - MissilePtr->x) < MISSILEHITDIST) &&
(w_abs(ActorPtr->y - MissilePtr->y) < MISSILEHITDIST)) {
Bang |= MissileHitEnemy(MissilePtr,ActorPtr); /* Detonate? */
}
}
} while (++x<xh); /* Scan the x's */
} while (++y<yh); /* Scan the y's */
return Bang; /* Return detonation value */
}
/**********************************
Move the missiles each game frame
**********************************/
void MoveMissiles(void)
{
Word Count; /* Current missile # */
missile_t *MissilePtr; /* Pointer to missile record */
Word i,x,y,tile; /* Tile position */
Count = nummissiles; /* How many active missiles? */
if (!Count || !TicCount) { /* No missiles? (Or elapsed time?) */
return; /* Exit now */
}
MissilePtr = &missiles[0]; /* Init pointer to the first missile */
do {
if (!MissilePtr->flags) { /* inert explosion*/
if (MissilePtr->type>TicCount) { /* Time up? */
MissilePtr->type-=TicCount; /* Remove some time */
++MissilePtr; /* Go to the next entry */
} else {
--nummissiles; /* Remove this missile */
MissilePtr[0] = missiles[nummissiles]; /* Copy the FINAL record here */
}
continue; /* Next! */
}
/* move position*/
i = TicCount; /* How many times to try this? */
do {
MissilePtr->x += MissilePtr->xspeed;
MissilePtr->y += MissilePtr->yspeed;
/* check for contact with player*/
if (MissilePtr->flags & MF_HITPLAYER) {
if (w_abs(MissilePtr->x - actors[0].x) < MISSILEHITDIST
&& w_abs(MissilePtr->y - actors[0].y) < MISSILEHITDIST) {
MissileHitPlayer(MissilePtr); /* Take damage */
goto BOOM; /* Boom! */
}
}
/* check for contact with actors*/
if (MissilePtr->flags & MF_HITENEMIES) {
if (CheckMissileActorHits(MissilePtr)) { /* Did it detonate? */
goto BOOM; /* Boom! */
}
}
/* check for contact with walls and get new area */
x = MissilePtr->x >> FRACBITS;
y = MissilePtr->y >> FRACBITS;
tile = tilemap[y][x];
if (tile & TI_BLOCKMOVE) { /* Can be a solid static or a wall*/
BOOM:
ExplodeMissile(MissilePtr); /* Detonate a missile */
break;
}
if (!(tile&TI_DOOR) ) { /* doorways don't have real area numbers*/
MissilePtr->areanumber = tile&TI_NUMMASK;
}
} while (--i);
++MissilePtr; /* Pointer to the next entry */
} while (--Count); /* No more entries? */
}
#include "Wolfdef.h"
/**********************************
Stop the current song from playing
**********************************/
void StopSong(void)
{
PlaySong(0);
}
/**********************************
Play a new song
**********************************/
void StartSong(Word songnum)
{
PlaySong(songnum); /* Stop the previous song (If any) */
}
#include "WolfDef.h"
#include <Palettes.h>
#include <gestalt.h>
#include "PickAMonitor.h"
#define PAMStrings 2001
#define NoColorString 1
#define NoDepthString 2
#define NoSizeString 3
#define NoProblemString 4
void CheckMonitor(DialogPtr theWindow, int bitDepth, Boolean colorRequired, short minWidth, short minHeight);
void OutlineOK(DialogPtr theDialog, Boolean enabled);
/**********************************
Take a window pointer and center it onto the
current video device
**********************************/
void CenterWindowOnMonitor(WindowPtr theWindow, GDHandle theMonitor)
{
short newH, newV;
Rect mRect;
mRect = (**theMonitor).gdRect; /* Get the rect of the monitor */
/* Find the difference between the two monitors' sizes */
newH = (mRect.right - mRect.left) - (theWindow->portRect.right - theWindow->portRect.left);
newV = (mRect.bottom - mRect.top) - (theWindow->portRect.bottom - theWindow->portRect.top);
/* Half the difference so that it's centered top-to-bottom and left-to-right */
/* Add that offset to the upper-left of the monitor */
MoveWindow(theWindow,(newH>>1)+mRect.left,(newV>>1)+mRect.top,TRUE); /* Move and bring to front */
}
/**********************************
Returns true if the device supports color
**********************************/
Boolean SupportsColor(GDHandle theMonitor)
{
return TestDeviceAttribute(theMonitor,gdDevType); /* Is it color? */
}
/**********************************
Returns true if the device supports a specific color depth
**********************************/
short SupportsDepth(GDHandle theMonitor, int theDepth, Boolean needsColor)
{
return HasDepth(theMonitor,theDepth,1<<gdDevType,needsColor);
}
/**********************************
Returns true if the device supports a specific video size
**********************************/
Boolean SupportsSize(GDHandle theMonitor, short theWidth, short theHeight)
{
Rect theRect;
/* Grab the dimensions of the monitor */
theRect = (**theMonitor).gdRect;
/* Offset it to (0, 0) references */
OffsetRect(&theRect, -theRect.left, -theRect.top);
/* Check the dimensions to see if they are large enough */
if ((theRect.right < theWidth) || (theRect.bottom < theHeight)) {
return FALSE; /* No good! */
}
return TRUE;
}
/**********************************
Return the GDevice from a specific quickdraw point
**********************************/
GDHandle MonitorFromPoint(Point *thePoint)
{
GDHandle theMonitor;
/* Loop through the list of monitors to see one encompasses the point */
theMonitor = GetDeviceList(); /* Get the first monitor */
do {
if (PtInRect(*thePoint,&(**theMonitor).gdRect)) { /* Is this it? */
break; /* Exit now */
}
theMonitor = GetNextDevice(theMonitor); /* Get the next device in list */
} while (theMonitor); /* All done now? */
/* Just in case some weird evil happened, return a fail value (THEORETICALLY can't happen) */
return theMonitor;
}
// ---------------------------------------- PickAMonitor
GDHandle PickAMonitor(int theDepth, Boolean colorRequired, short minWidth, short minHeight)
{
GDHandle theMonitor;
GDHandle tempMonitor;
Point thePoint;
EventRecord theEvent;
DialogPtr theDialog;
short itemHit;
char theChar;
Word validCount;
GrafPtr savedPort;
/* Loop through the monitor list once to make sure there is at least one good monitor */
theMonitor = GetDeviceList(); /* Get the first monitor */
tempMonitor = 0; /* No monitor found */
validCount = 0; /* None found */
do {
if (colorRequired && !SupportsColor(theMonitor)) { /* Check for color? */
continue;
}
if (!SupportsDepth(theMonitor, theDepth, colorRequired)) { /* Check for bit depth */
continue;
}
if (!SupportsSize(theMonitor, minWidth, minHeight)) { /* Check for monitor size */
continue;
}
tempMonitor = theMonitor; /* Save the valid record */
++validCount; /* Inc the count */
} while ((theMonitor = GetNextDevice(theMonitor)) != 0);
/* If there was only one valid monitor, goodMonitor will be referencing it. Return it immediately. */
if (validCount == 1) {
return (tempMonitor); /* Exit now */
}
/* If there are no valid monitors then put up a dialog saying so. Then return nil. */
if (!validCount) {
StopAlert(2001, nil);
return 0;
}
// Start an event loop going. Rather than using modalDialog with a gnarly filter, we'll just display the dialog
// then use a gnarly event loop to accommodate it. This will go on until the user selects either "This Monitor"
// (ok) or "Quit" (cancel).
theDialog = GetNewDialog(2000, nil, (WindowPtr) -1L);
CenterWindowOnMonitor((WindowPtr) theDialog, GetMainDevice());
InitCursor();
GetPort(&savedPort);
SetPort(theDialog);
ShowWindow(theDialog);
CheckMonitor(theDialog, theDepth, colorRequired, minWidth, minHeight);
do {
itemHit = 0;
/* Get next event from the event queue */
if (WaitNextEvent2(everyEvent&(~highLevelEventMask), &theEvent, 30, nil)) {
switch (theEvent.what) {
case keyDown:
theChar = theEvent.message & charCodeMask;
if ((theEvent.modifiers & cmdKey) && ((theChar == '.') || (theChar == 'q') || (theChar == 'Q'))) {
itemHit = cancel;
break;
}
if (theChar == 0x1B) {
itemHit = cancel;
break;
}
if ((theChar == 0x0D) || (theChar == 0x03)) {
itemHit = ok;
break;
}
break;
// Did we mouse-down in the dialogs drag-bar?
case mouseDown:
if (FindWindow(theEvent.where, (WindowPtr *) &theDialog) == inDrag)
{
DragWindow((WindowPtr) theDialog, theEvent.where, &qd.screenBits.bounds);
GetMouse(&thePoint);
LocalToGlobal(&thePoint);
tempMonitor = MonitorFromPoint(&thePoint);
CenterWindowOnMonitor((WindowPtr) theDialog, tempMonitor);
CheckMonitor(theDialog, theDepth, colorRequired, minWidth, minHeight);
break;
}
default:
// If not, perform regular dialog event processing
DialogSelect(&theEvent, &theDialog, &itemHit);
}
}
} while ((itemHit != ok) && (itemHit != cancel));
// Ok, the dialog is still the active grafport so all coordinates are in its local system. If I define a point
// as (0, 0) now it will be the upper left corner of the dialog's drawing area. I then turn this to a global screen
// coordinate and call GetMonitorFromPoint.
SetPt(&thePoint, 0, 0);
LocalToGlobal(&thePoint);
theMonitor = MonitorFromPoint(&thePoint);
// Restore our current graphics environment and return the monitor reference.
SetPort(savedPort);
DisposeDialog(theDialog);
if (itemHit == ok) {
return (theMonitor);
}
return (nil);
}
// ---------------------------------------- CheckMonitor
void CheckMonitor(DialogPtr theDialog, int bitDepth, Boolean colorRequired, short minWidth, short minHeight)
{
GDHandle theMonitor;
Point thePoint;
short theType;
Handle theHandle;
Rect theRect;
Str255 message;
Boolean badMonitor = FALSE;
GrafPtr savedPort;
GetPort(&savedPort);
SetPort((WindowPtr) theDialog);
SetPt(&thePoint, 0, 0);
LocalToGlobal(&thePoint);
theMonitor = MonitorFromPoint(&thePoint);
GetDialogItem(theDialog, 4, &theType, &theHandle, &theRect);
if (colorRequired && ! SupportsColor(theMonitor)) {
GetIndString(message, PAMStrings, NoColorString);
SetDialogItemText(theHandle, message);
badMonitor = TRUE;
}
if (!SupportsDepth(theMonitor, bitDepth, colorRequired)) {
GetIndString(message, PAMStrings, NoDepthString);
SetDialogItemText(theHandle, message);
badMonitor = TRUE;
}
if (! SupportsSize(theMonitor, minWidth, minHeight)) {
GetIndString(message, PAMStrings, NoDepthString);
SetDialogItemText(theHandle, message);
badMonitor = TRUE;
}
SetPort(savedPort);
if (badMonitor) {
// Gray-out the "This Monitor" button
GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
HiliteControl((ControlHandle) theHandle, 255);
OutlineOK(theDialog, FALSE);
BeginUpdate((WindowPtr) theDialog);
UpdateDialog(theDialog, theDialog->visRgn);
EndUpdate((WindowPtr) theDialog);
return;
}
// Activate the "This Monitor" button and put up the no problem text.
GetIndString(message, PAMStrings, NoProblemString);
SetDialogItemText(theHandle, message);
GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
HiliteControl((ControlHandle) theHandle, 0);
OutlineOK(theDialog, TRUE);
BeginUpdate((WindowPtr) theDialog);
UpdateDialog(theDialog, theDialog->visRgn);
EndUpdate((WindowPtr) theDialog);
}
// ---------------------------------------- OutlineOK
void OutlineOK(DialogPtr theDialog, Boolean enabled)
{
GrafPtr savedPort;
ColorSpec saveColor;
PenState savedState;
short theType;
Handle theHandle;
Rect theRect;
GetPenState(&savedState);
PenMode(patCopy);
PenSize(2, 2);
SaveFore(&saveColor);
ForeColor(blackColor);
GetPort(&savedPort);
SetPort((WindowPtr) theDialog);
GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
InsetRect(&theRect, -4, -4);
if (enabled)
PenPat(&qd.black);
else
PenPat(&qd.gray);
FrameRoundRect(&theRect, 16, 16);
SetPort(savedPort);
RestoreFore(&saveColor);
SetPenState(&savedState);
}
extern void CenterWindowOnMonitor(WindowPtr theWindow, GDHandle theMonitor);
extern Boolean SupportsColor(GDHandle theMonitor);
extern short SupportsDepth(GDHandle theMonitor, int theDepth, Boolean needsColor);
extern Boolean SupportsSize(GDHandle theMonitor, short theWidth, short theHeight);
extern GDHandle MonitorFromPoint(Point *thePoint);
extern GDHandle PickAMonitor(int bitDepth, Boolean colorRequired, short minWidth, short minHeight);
extern Boolean WaitNextEvent2(short EventMask,EventRecord *theEvent,long sleep,RgnHandle mouseRgn);
\ No newline at end of file
#include "wolfdef.h"
/**********************************
See if players current position is ok
returns True if move ok
All coordinates are stored in 8.8 fractions (8 bits integer, 8 bits fraction)
**********************************/
static Boolean TryMove(Word Checkx,Word Checky)
{
actor_t *ActorPtr; /* Pointer to actor record */
Word xl,yl,xh,yh; /* Rect to scan */
Word tile; /* Tile being tested */
Word x,y; /* Working x,y */
xl = (Checkx - PLAYERSIZE)>>FRACBITS; /* Make the rect for the player in tiles */
xh = ((Checkx + PLAYERSIZE)>>FRACBITS)+1;
yl = (Checky - PLAYERSIZE)>>FRACBITS;
yh = ((Checky + PLAYERSIZE)>>FRACBITS)+1;
/* check for solid walls*/
y = yl;
do {
x=xl;
do {
tile = tilemap[y][x]; /* Test the tile */
if (tile & TI_GETABLE) { /* Can I get this? */
GetBonus(x,y); /* Get the item */
}
if (tile & TI_BLOCKMOVE) { /* Motion blocked */
return FALSE; /* Can't go this way! */
}
} while (++x<xh); /* Scan the x */
} while (++y<yh); /* Scan the y */
/* check for actors */
yl--; /* Increase the rect for actor hits */
yh++;
xl--;
xh++;
y = yl;
do {
x = xl;
do {
tile = tilemap[y][x]; /* Get the tile */
if (tile&TI_ACTOR) { /* Actor here? */
ActorPtr = &actors[MapPtr->tilemap[y][x]];
if (w_abs(ActorPtr->x - Checkx) < MINACTORDIST) {
if (w_abs(ActorPtr->y - Checky) < MINACTORDIST)
return FALSE; /* I hit the actor! */
}
}
} while (++x<xh); /* Scan the x */
} while (++y<yh); /* Scan the y */
playermoving = TRUE; /* I am moving (Harder to hit) */
return TRUE; /* Way is clear */
}
/**********************************
Clip the player's motion
I will also try to use as much motion as I have
**********************************/
static void ClipMove(int xmove,int ymove)
{
int Checkx,Checky;
/* Try complete move */
Checkx = xmove; /* Save the current motion offset */
Checky = ymove;
do {
if (TryMove(actors[0].x+Checkx,actors[0].y+Checky)) { /* Can I move here? */
actors[0].x += Checkx; /* Save it */
actors[0].y += Checky;
if (Checkx==xmove) { /* Use all the motion? */
return; /* Exit now! */
}
xmove-=Checkx; /* Remove the used motion */
ymove-=Checky;
break; /* Exit now */
}
if (Checkx==-1) { /* Minimum motion */
Checkx = 0;
}
Checkx>>=1; /* Reduce the amount of motion */
if (Checky==-1) { /* Minimum motion */
Checky=0;
}
Checky>>=1;
} while (Checkx || Checky); /* Is there ANY motion? */
/* Try horizontal motion */
Checkx = actors[0].x + xmove;
if (TryMove(Checkx,actors[0].y)) {
actors[0].x = Checkx; /* Set new x */
return;
}
/* try just vertical*/
Checky = actors[0].y + ymove;
if (TryMove(actors[0].x,Checky)) {
actors[0].y = Checky; /* Set new y */
}
}
/**********************************
Adds movement to xmove & ymove
**********************************/
static void Thrust(Word angle,Word speed,Word *xmove, Word *ymove)
{
angle &= ANGLES-1; /* Mask the angle range */
if (speed >= TILEGLOBAL) {
speed = TILEGLOBAL-1; /* Force maximum speed */
}
*xmove += FixedByFrac(speed,costable[angle]); /* Add x motion */
*ymove -= FixedByFrac(speed,sintable[angle]); /* Add y motion */
}
/**********************************
Changes the player's angle and position
**********************************/
#define TURNSPEED 4 /* Turning while moving */
#define FASTTURN 6 /* Turning in place */
#define WALKSPEED 25
#define RUNSPEED 45
void ControlMovement(void)
{
Word turn,total;
Word tile;
Word xmove,ymove;
Word move;
playermoving = FALSE; /* No motion (Yet) */
xmove = 0; /* Init my deltas */
ymove = 0;
if (buttonstate[bt_run]) {
turn = FASTTURN*TicCount; /* Really fast turn */
move = RUNSPEED*TicCount;
} else {
turn = TURNSPEED*TicCount; /* Moderate speed turn */
move = WALKSPEED*TicCount;
}
/* turning */
gamestate.viewangle += mouseturn; /* Add in the mouse movement verbatim */
if (buttonstate[bt_east]) {
gamestate.viewangle -= turn; /* Turn right */
}
if (buttonstate[bt_west]) {
gamestate.viewangle += turn; /* Turn left */
}
gamestate.viewangle &= (ANGLES-1); /* Fix the viewing angle */
/* Handle all strafe motion */
if (mousex) { /* Side to side motion (Strafe mode) */
mousex<<=3;
if (mousex>0) {
Thrust(gamestate.viewangle - ANGLES/4,mousex,&xmove,&ymove);
} else {
Thrust(gamestate.viewangle + ANGLES/4,-mousex,&xmove,&ymove);
}
}
if (buttonstate[bt_right]) { /* Slide right keyboard */
Thrust(gamestate.viewangle - ANGLES/4, move>>1,&xmove,&ymove);
}
if (buttonstate[bt_left]) { /* Slide left keyboard */
Thrust(gamestate.viewangle + ANGLES/4, move>>1,&xmove,&ymove);
}
/* Handle all forward motion */
total = buttonstate[bt_north] ? move : 0; /* Move ahead? */
if (mousey < 0) { /* Moved the mouse ahead? */
total -= mousey<<3; /* Add it in */
}
if (total) {
Thrust(gamestate.viewangle, total,&xmove,&ymove); /* Move ahead */
}
total = buttonstate[bt_south] ? move : 0; /* Reverse direction */
if (mousey > 0) {
total += mousey<<3;
}
if (total) {
Thrust(gamestate.viewangle+ANGLES/2, total,&xmove,&ymove);
}
mousex = 0;
mousey = 0; /* Reset the mouse motion */
mouseturn = 0;
if (xmove || ymove) { /* Any motion? */
ClipMove(xmove,ymove); /* Move ahead (Clipped) */
tile = tilemap[actors[0].y>>FRACBITS][actors[0].x>>FRACBITS];
if (!(tile&TI_DOOR) ) { /* Normal tile? */
actors[0].areanumber = tile & TI_NUMMASK; /* Set my new area */
}
}
}
This diff is collapsed.
This diff is collapsed.
void InitPrefsFile(OSType creator,Byte *PrefsName);
OSErr LoadPrefsFile(Byte *PrefsPtr,Word PrefsLen);
OSErr SavePrefsFile(Byte *PrefsPtr,Word PrefsLen);
This diff is collapsed.
#include "wolfdef.h"
#define PWALLSPEED 4 /* Micropixels per 60th of a second */
pushwall_t PushWallRec; /* Record for the single pushwall in progress */
/**********************************
Set pwallychange and pwallxchange
Uses pwallpos,pwalldir
**********************************/
void SetPWallChange(void)
{
Word pos;
pos = PushWallRec.pwallpos&(FRACUNIT-1); /* Get the pixel fraction */
PushWallRec.pwallxchange = 0; /* No motion yet */
PushWallRec.pwallychange = 0;
switch (PushWallRec.pwalldir) { /* Which way? */
case CD_NORTH:
PushWallRec.pwallychange = -pos; /* Y motion */
return;
case CD_EAST:
PushWallRec.pwallxchange = pos; /* X motion */
return;
case CD_SOUTH:
PushWallRec.pwallychange = pos; /* Y motion */
return;
case CD_WEST:
PushWallRec.pwallxchange = -pos; /* X motion */
}
}
/**********************************
Marks the dest tile as blocked and begins a push wall sequence
Uses pwallx,pwally,pwalldir
**********************************/
void PushWallOne(void)
{
PushWallRec.pwallcheckx = PushWallRec.pwallx;
PushWallRec.pwallchecky = PushWallRec.pwally;
switch (PushWallRec.pwalldir) {
case CD_NORTH:
PushWallRec.pwallchecky--;
break;
case CD_EAST:
PushWallRec.pwallcheckx++;
break;
case CD_SOUTH:
PushWallRec.pwallchecky++;
break;
case CD_WEST:
PushWallRec.pwallcheckx--;
}
tilemap[PushWallRec.pwallchecky][PushWallRec.pwallcheckx] |= TI_BLOCKMOVE | TI_BLOCKSIGHT;
StartPushWall(); /* let the refresh do some junk*/
}
/**********************************
Initiate a pushwall sequence
Call with x,y,dir of wall to push
**********************************/
void PushWall(Word x,Word y,Word dir)
{
PlaySound(SND_PWALL); /* Play the wall sound */
PushWallRec.pwallx = x; /* Save the x,y in my globals */
PushWallRec.pwally = y;
PushWallRec.pwalldir = dir; /* Save the wall direction */
PushWallOne(); /* Initiate the animation */
PushWallRec.pwallcount = 2; /* Move two cells */
++gamestate.secretcount; /* Secret area found */
PushWallRec.pwallpos = PWALLSPEED/2; /* Begin the move */
/* mark the segs that are being moved */
tilemap[y][x] &= ~TI_PUSHWALL; /* Clear the pushwall bit */
SetPWallChange(); /* Set pwallchange */
}
/**********************************
Continue any pushwall animations, called by the main loop
**********************************/
void MovePWalls (void)
{
if (!PushWallRec.pwallcount) { /* Any walls to push? */
return; /* Nope, get out */
}
PushWallRec.pwallpos += PWALLSPEED*TicCount; /* Move the wall a little */
SetPWallChange(); /* Set the wall for the renderer */
if (PushWallRec.pwallpos<256) { /* Crossed a tile yet? */
return; /* Exit now */
}
PushWallRec.pwallpos -= 256; /* Mark as crossed */
/* the tile can now be walked into */
tilemap[PushWallRec.pwally][PushWallRec.pwallx] &= ~TI_BLOCKMOVE; /* The movable block is gone */
AdvancePushWall(); /* Remove the bsp seg */
if (!--PushWallRec.pwallcount) { /* Been pushed 2 blocks?*/
StopSound(SND_PWALL); /* Play the wall sound */
PlaySound(SND_PWALL2); /* Play the wall stop sound */
return; /* Don't do this anymore! */
}
PushWallRec.pwallx = PushWallRec.pwallcheckx; /* Set the tile to the next cell */
PushWallRec.pwally = PushWallRec.pwallchecky;
PushWallOne(); /* Push one more record */
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* generated by sndlink.exe */
enum {
SND_NOSOUND,
SND_THROWSWITCH, /* Throw end level switch */
SND_GETKEY, /* Pick up a key */
SND_BONUS, /* Score ding */
SND_OPENDOOR, /* Open a door */
SND_DOGBARK, /* Dog bite */
SND_DOGDIE, /* Dog die */
SND_ESEE, /* Ahtung! */
SND_ESEE2, /* Halt! */
SND_EDIE, /* Nazi died */
SND_EDIE2, /* Nazi died 2 */
SND_BODYFALL, /* Body hit the ground */
SND_PAIN, /* Hit bad guy */
SND_GETAMMO, /* Pick up ammo */
SND_KNIFE, /* Knife attack */
SND_GUNSHT, /* 45 Shoot */
SND_MGUN, /* Sub machine gun */
SND_CHAIN, /* Chain gun */
SND_FTHROW, /* Flame thrower */
SND_ROCKET, /* Rocket launcher */
SND_PWALL, /* Start pushwall */
SND_PWALL2, /* Stop pushwall */
SND_GUTEN, /* Guten tag */
SND_SHIT, /* Shit! */
SND_HEAL, /* Healed a bit */
SND_THUMBSUP, /* You stud you! */
SND_EXTRA, /* Extra guy */
SND_OUCH1, /* BJ has beed injured */
SND_OUCH2, /* Second sound */
SND_PDIE, /* BJ has died */
SND_HITWALL, /* Tried to open a wall */
SND_KNIFEMISS, /* Knife missed */
SND_BIGGUN, /* Boss's gun */
SND_COMEHERE, /* Come here! */
SND_ESEE3, /* Nazi sees you */
SND_ESEE4, /* Nazi sees you */
SND_OK, /* Hit start game */
SND_MENU, /* New game menu */
SND_HITLERSEE, /* Hitler sees you */
SND_SHITHEAD, /* Big boss sees you */
SND_BOOM, /* Explosion */
SND_LOCKEDDOOR, /* Locked door */
SND_MECHSTEP, /* Mech step */
NUMSOUNDS };
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
History of Wolfenstein 3D: First & Second Encounter
Programming and Project Lead: Bill Heineman
Additional programming: Chris DeSalvo
Producer: Bill Dugan
Wolfenstein 3D for MacOS was released on October 1st, 1994 by Interplay Productions under license from id software. The code was based not on the PC version but of a Super NES version that was done at id software. This version of the game differs greatly from the PC version since it used BSP trees to help determine which walls were to be drawn instead of the ray-casting method.
The fixed point number system was 8.8 format so that it could fit in a 65816 register for the SNES and Apple IIgs version of Wolf 3D. (8 bits of integer and 8 bits of fraction)
The mac version also has two modes of drawing. In the 68000 version, 68000 code is generated at runtime to draw the vertical lines very quickly. The source file SetupScalers68k.c creates the 68000 code and then issues calls to it via a little 68000 assembly glue code. This is how the game got its speed. The powerpc version originally had this method as well but the performance sucked. So it was changed to a simple assembly loop and the game ran fine. This is why there is SetupScalersPPC.c and SetupScalers68k.c.
I took the code from Codewarrion DR/4 which was the development system at the time and updated the project to Codewarrior PRO 5 (Which is what I use today). I've compiled, tested and ran the game and the code runs fine. The sound code is copyright Steve Hales and Jim Nitchals. You cannot use the music driver in your own programs unless you get a license from Steve Hales. (Jim Nitchals sadly has passed on, may he rest in peace).
Yes, there is a level editor that I wrote. It sucks. I suggest you get WolfEdit that is available on the web from WolfAddict software instead. It doesn't suck.
Here it is 1/21/2000. Over 5 years since I did the mac version of Wolf 3D. Seems like yesterday. I hope you enjoy looking over this code and making little changes for your own pleasure and learning. If someone makes any improvements to this code like adding Sprocket support or GL support, please send me the new source. I can be found at burger@logicware.com
I want to thank those who helped make this project a reality. John Carmack, Jay Wilbur, John Romero, Brian Luzietti and my wife Lorenza.
Bill Heineman
Logicware Inc.
20628 E. Arrow Hwy. #6
burger@logicware.com
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment