Commit 80de8bfd authored by Steven Fuller's avatar Steven Fuller

minor changes

parent 0c2226af
......@@ -6,304 +6,10 @@
**********************************/
#include "WolfDef.h" /* Get the prototypes */
#include "wolfdef.h" /* Get the prototypes */
#include <string.h>
#include <sound.h>
#include <stdio.h>
#include <palettes.h>
#include "SoundMusicSystem.h"
#include "PickAMonitor.h"
/**********************************
Variables used by my global library
**********************************/
Word DoEvent(EventRecord *event);
void DoMacEvents(void);
void BlastScreen(void);
static Word FreeStage(Word Stage,LongWord Size);
extern Boolean MouseHit; /* True if a mouse down event occured */
Word NoSystemMem;
unsigned char *VideoPointer; /* Pointer to video memory */
extern Word QuitFlag; /* Did the application quit? */
Word VideoWidth; /* Width to each video scan line */
Word SystemState=3; /* Sound on/off flags */
Word KilledSong; /* Song that's currently playing */
Word KeyModifiers; /* Keyboard modifier flags */
LongWord LastTick; /* Last system tick (60hz) */
Word FontX; /* X Coord of font */
Word FontY; /* Y Coord of font */
unsigned char *FontPtr; /* Pointer to font image data */
unsigned char *FontWidths; /* Pointer to font width table */
Word FontHeight; /* Point size of current font */
Word FontLast; /* Number of font entries */
Word FontFirst; /* ASCII value of first char */
Word FontLoaded; /* Rez number of loaded font (0 if none) */
Word FontInvisible; /* Allow masking? */
unsigned char FontOrMask[16]; /* Colors for font */
LongWord YTable[480]; /* Offsets to the screen */
SndChannelPtr myPaddleSndChan; /* Sound channel */
Word ScanCode;
CWindowPtr GameWindow;
CGrafPtr GameGWorld;
extern GDHandle gMainGDH;
extern CTabHandle MainColorHandle;
extern Boolean DoQuickDraw;
/**********************************
Wait a single system tick
**********************************/
static Word QuickTicker;
void DoMacEvents(void)
{
EventRecord MyEvent;
if (!DoQuickDraw) {
if ((ReadTick() - QuickTicker) < 30) {
return;
}
QuickTicker = ReadTick();
}
PurgeAllSounds(85000); /* Try to keep some memory free */
if (WaitNextEvent2(updateMask|diskMask|driverMask|networkMask|activMask|app4Mask,&MyEvent,0,0)) {
DoEvent(&MyEvent);
}
}
/**********************************
Wait a single system tick
**********************************/
void WaitTick(void)
{
do {
DoMacEvents(); /* Allow backgrounding */
} while (ReadTick()==LastTick); /* Tick changed? */
LastTick=ReadTick(); /* Save it */
}
/**********************************
Wait a specific number of system ticks
from a time mark before you get control
**********************************/
void WaitTicks(Word Count)
{
LongWord TickMark; /* Temp tick mark */
do {
DoMacEvents(); /* Allow other tasks to execute */
TickMark = ReadTick(); /* Get the mark */
} while ((TickMark-LastTick)<=Count); /* Time up? */
LastTick = TickMark; /* Save the new time mark */
}
/**********************************
Get the current system tick
**********************************/
LongWord ReadTick(void)
{
return(TickCount()); /* Just get it from the Mac OS */
}
/**********************************
Wait for a mouse/keyboard event
**********************************/
Word WaitEvent(void)
{
Word Temp;
do {
Temp = WaitTicksEvent(6000); /* Wait 10 minutes */
} while (!Temp); /* No event? */
return Temp; /* Return the event code */
}
/**********************************
Wait for an event or a timeout
**********************************/
Word WaitTicksEvent(Word Time)
{
LongWord TickMark;
LongWord NewMark;
Word RetVal;
MouseHit = FALSE;
TickMark = ReadTick(); /* Get the initial time mark */
for (;;) {
DoMacEvents(); /* Allow other tasks a shot! */
NewMark = ReadTick(); /* Get the new time mark */
if (Time) {
if ((NewMark-TickMark)>=Time) { /* Time up? */
RetVal = 0; /* Return timeout */
break;
}
}
RetVal = GetAKey();
if (RetVal) {
break;
}
if (MouseHit) {
RetVal = 1; /* Hit the mouse */
break;
}
}
LastTick = NewMark;
return RetVal;
}
/**********************************
Get a key from the keyboard
**********************************/
Word GetAKey(void)
{
EventRecord MyRecord;
if (WaitNextEvent2(everyEvent,&MyRecord,0,0)) {
if (!DoEvent(&MyRecord)) {
KeyModifiers = MyRecord.modifiers;
return 0;
}
return FixMacKey(&MyRecord);
}
return 0;
}
/**********************************
Check if all keys are released
**********************************/
Word WaitKey(void)
{
Word Key;
do {
Key = GetAKey();
} while (!Key);
return (Key);
}
/**********************************
Check if all keys are released
**********************************/
Word AllKeysUp(void)
{
KeyMap KeyArray;
GetKeys(KeyArray);
if (KeyArray[0] || KeyArray[1] || KeyArray[2] || KeyArray[3]) {
return 0;
}
return 1;
}
Word FixMacKey(EventRecord *Event)
{
Word NewKey;
NewKey = Event->message & 0xff;
ScanCode = (Event->message>>8) & 0xff;
switch (NewKey) {
case 0x1c :
NewKey = 0x08;
break;
case 0x1d :
NewKey = 0x15;
break;
case 0x1e :
NewKey = 0x0b;
break;
case 0x1f :
NewKey = 0x0a;
break;
}
KeyModifiers = Event->modifiers;
if (NewKey == 'Q' || NewKey == 'q') {
if (KeyModifiers & cmdKey) {
QuitFlag = 1;
}
}
return NewKey;
}
/**********************************
Flush out the keyboard buffer
**********************************/
void FlushKeys(void)
{
while (GetAKey()) {}
}
/**********************************
Convert a long value into a ascii string
**********************************/
static LongWord Tens[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000};
void ultoa(LongWord Val,char *Text)
{
Word Index; /* Index to Tens table */
Word Hit; /* Printing? */
Word Letter; /* Letter to print */
LongWord LongVal; /* Tens value */
Index = 9; /* Start at the millions */
Hit = 0; /* Didn't print anything yet! */
do {
Letter = '0'; /* Init the char */
LongVal = Tens[Index]; /* Init the value into a local */
while (Val >= LongVal) { /* Is the number in question larger? */
Val -= LongVal; /* Sub the tens value */
++Letter; /* Inc the char */
Hit=1; /* I must draw! */
}
if (Hit) { /* Remove the leading zeros */
Text[0] = Letter; /* Save char in the string */
++Text; /* Inc dest */
}
} while (--Index); /* All the tens done? */
Text[0] = Val + '0'; /* Must print FINAL digit */
Text[1] = 0; /* End the string */
}
/**********************************
......@@ -931,24 +637,8 @@ void *LoadAResource(Word RezNum)
**********************************/
Handle RezHandle;
void *LoadAResource2(Word RezNum,LongWord Type)
{
Handle MyHand;
Word Stage;
Stage = 0;
do {
Stage = FreeStage(Stage,128000);
MyHand = GetResource(Type,RezNum);
if (MyHand) {
RezHandle = MyHand;
HLock(MyHand);
return *MyHand;
}
} while (Stage);
return 0;
}
/**********************************
......@@ -970,11 +660,6 @@ void ReleaseAResource(Word RezNum)
void ReleaseAResource2(Word RezNum,LongWord Type)
{
Handle MyHand;
MyHand = GetResource(Type,RezNum); /* Get the resource if available */
HUnlock(MyHand);
HPurge(MyHand); /* Mark handle as purgeable */
}
/**********************************
......@@ -996,9 +681,6 @@ void KillAResource(Word RezNum)
void KillAResource2(Word RezNum,LongWord Type)
{
Handle MyHand;
MyHand = GetResource(Type,RezNum); /* Get the resource if available */
ReleaseResource(MyHand);
}
void SaveJunk(void *AckPtr,Word Length)
......@@ -1030,7 +712,6 @@ unsigned short SwapUShort(unsigned short Val)
**********************************/
#if 1
void DLZSS(Byte *Dest,Byte *Src,LongWord Length)
{
Word BitBucket;
......@@ -1071,7 +752,6 @@ void DLZSS(Byte *Dest,Byte *Src,LongWord Length)
}
} while (Length);
}
#endif
/**********************************
......@@ -1081,21 +761,7 @@ void DLZSS(Byte *Dest,Byte *Src,LongWord Length)
void *AllocSomeMem(LongWord Size)
{
void *MemPtr;
Word Stage;
Stage = 0;
do {
Stage = FreeStage(Stage,Size);
MemPtr = NewPtr(Size); /* Get some memory */
if (MemPtr) {
return MemPtr; /* Return it */
}
} while (Stage);
if (!NoSystemMem) {
MemPtr = NewPtrSys(Size);
}
return MemPtr;
return (void *)malloc(Size);
}
/**********************************
......@@ -1133,5 +799,5 @@ static Word FreeStage(Word Stage,LongWord Size)
void FreeSomeMem(void *MemPtr)
{
DisposePtr(MemPtr);
free(MemPtr);
}
......@@ -9,7 +9,7 @@ CFLAGS = -g
OBJS = Data.o Doors.o EnMove.o EnThink.o Intro.o Level.o \
Missiles.o Music.o PlMove.o PlStuff.o PlThink.o PushWall.o \
RefBsp.o RefSprite.o Refresh.o Refresh2.o Sight.o Main.o \
StateDef.o WolfMain.o WolfIO.o InterMis.o
StateDef.o WolfMain.o WolfIO.o InterMis.o Burger.o
SOBJS = $(OBJS)
XOBJS = $(OBJS)
GOBJS = $(OBJS)
......
#include "WolfDef.h"
#include <string.h>
#include <stdlib.h>
LongWord ScaleDiv[2048];
/**********************************
Create the compiled scalers
**********************************/
Boolean SetupScalers(void)
{
Word i;
if (!ScaleDiv[1]) { /* Divide table inited already? */
i = 1;
do {
ScaleDiv[i] = 0x400000UL/(LongWord)i; /* Get the recipocal for the scaler */
} while (++i<2048);
}
MaxScaler = 2048;
return TRUE;
}
void ReleaseScalers(void)
{
}
/**********************************
Draw a vertical line with a scaler
(Used for WALL drawing)
**********************************/
void ScaleGlue(void *a,LongWord scale,void *c,LongWord d,LongWord e,LongWord f,LongWord g);
#if 0
void IO_ScaleWallColumn(Word x,Word scale,LongWord column)
{
LongWord TheFrac;
LongWord TheInt;
LongWord y;
Byte *ArtStart;
if (scale) { /* Uhh.. Don't bother */
TheFrac = ScaleDiv[scale];
scale*=2;
ArtStart = &ArtData[(column>>7)&0x3f][(column&127)<<7];
if (scale<VIEWHEIGHT) {
y = (VIEWHEIGHT-scale)/2;
TheInt = TheFrac>>24;
TheFrac <<= 8;
ScaleGlue(ArtStart,scale,
&VideoPointer[(y*VideoWidth)+x],
TheFrac,
TheInt,
VideoWidth,
0
);
return;
}
y = (scale-VIEWHEIGHT)/2; /* How manu lines to remove */
y = y*TheFrac;
TheInt = TheFrac>>24;
TheFrac <<= 8L;
ScaleGlue(&ArtStart[y>>24L],VIEWHEIGHT,
&VideoPointer[x],
TheFrac,
TheInt,
VideoWidth,
y<<8L
);
}
}
#endif
/**********************************
Draw a vertical line with a masked scaler
(Used for SPRITE drawing)
**********************************/
typedef struct {
unsigned short Topy;
unsigned short Boty;
unsigned short Shape;
} SpriteRun;
void SpriteGlue(Byte *a,LongWord b,Byte *c,Word d,Word e);
/*
SGArtStart EQU A0 ;Pointer to the 6 byte run structure
SGFrac EQU D2 ;Pointer to the scaler
SGInteger EQU D3 ;Pointer to the video
SGScreenPtr EQU A1 ;Pointer to the run base address
SGCount EQU D6
SGDelta EQU D4
*/
void IO_ScaleMaskedColumn(Word x,Word scale,unsigned short *CharPtr,Word column)
{
Byte * CharPtr2;
int Y1,Y2;
Byte *Screenad;
SpriteRun *RunPtr;
LongWord TheFrac;
Word RunCount;
Word TopY;
Word Index;
LongWord Delta;
if (!scale) {
return;
}
CharPtr2 = (Byte *) CharPtr;
TheFrac = ScaleDiv[scale]; /* Get the scale fraction */
RunPtr = (SpriteRun *) &CharPtr[CharPtr[column+1]/2]; /* Get the offset to the RunPtr data */
Screenad = &VideoPointer[x]; /* Set the base screen address */;
TopY = (VIEWHEIGHT/2)-scale; /* Number of pixels for 128 pixel shape */
while (RunPtr->Topy != (unsigned short) -1) { /* Not end of record? */
Y1 = (LongWord)scale*RunPtr->Topy/128+TopY;
if (Y1<(int)VIEWHEIGHT) { /* Clip top? */
Y2 = (LongWord)scale*RunPtr->Boty/128+TopY;
if (Y2>0) {
if (Y2>(int)VIEWHEIGHT) {
Y2 = VIEWHEIGHT;
}
Index = RunPtr->Shape+(RunPtr->Topy/2);
Delta = 0;
if (Y1<0) {
Delta = (LongWord)(0-Y1)*TheFrac;
Index += (Delta>>16);
Y1 = 0;
}
RunCount = Y2-Y1; /* How many lines to draw?*/
if (RunCount) {
SpriteGlue(
&CharPtr2[Index], /* Pointer to art data */
TheFrac, /* Fixed point fractional value */
&Screenad[YTable[Y1]], /* Pointer to screen */
RunCount, /* Number of lines to draw */
Delta /* Delta value */
);
}
}
}
RunPtr++; /* Next record */
}
}
/**********************************
Draw an automap tile
**********************************/
Byte *SmallFontPtr;
void DrawSmall(Word x,Word y,Word tile)
{
Byte *Screenad;
Byte *ArtStart;
Word Width,Height;
if (!SmallFontPtr) {
return;
}
x*=16;
y*=16;
Screenad = &VideoPointer[YTable[y]+x];
ArtStart = &SmallFontPtr[tile*(16*16)];
Height = 0;
do {
Width = 16;
do {
Screenad[0] = ArtStart[0];
++Screenad;
++ArtStart;
} while (--Width);
Screenad+=VideoWidth-16;
} while (++Height<16);
}
void MakeSmallFont(void)
{
Word i,j,Width,Height;
Byte *DestPtr,*ArtStart;
Byte *TempPtr;
SmallFontPtr = AllocSomeMem(16*16*65);
if (!SmallFontPtr) {
return;
}
memset(SmallFontPtr,0,16*16*65); /* Erase the font */
i = 0;
DestPtr = SmallFontPtr;
do {
ArtStart = &ArtData[i][0];
if (!ArtStart) {
DestPtr+=(16*16);
} else {
Height = 0;
do {
Width = 16;
j = Height*8;
do {
DestPtr[0] = ArtStart[j];
++DestPtr;
j+=(WALLHEIGHT*8);
} while (--Width);
} while (++Height<16);
}
} while (++i<64);
TempPtr = LoadAResource(MyBJFace);
memcpy(DestPtr,TempPtr,16*16);
ReleaseAResource(MyBJFace);
}
void KillSmallFont(void)
{
if (SmallFontPtr) {
FreeSomeMem(SmallFontPtr);
SmallFontPtr=0;
}
}
#include "WolfDef.h"
#include <string.h>
#include "SoundMusicSystem.h"
#include "mixedmode.h"
Word ScaleDiv[2048]; /* Divide table for scalers */
/**********************************
Create the compiled scalers
**********************************/
Boolean SetupScalers(void)
{
Word i;
if (!ScaleDiv[1]) { /* Divide table inited already? */
i = 1;
do {
ScaleDiv[i] = 0x40000000/i; /* Get the recipocal for the scaler */
} while (++i<2048);
}
MaxScaler = 2048; /* Init the highest scaler value */
return TRUE; /* No errors possible */
}
/**********************************
Release the memory from the scalers
**********************************/
void ReleaseScalers(void)
{
}
/**********************************
Draw a vertical line with a scaler
(Used for WALL drawing)
This is now in assembly language
**********************************/
/* void ScaleGlue(void *a,t_compscale *b,void *c); */
void ScaleGlue(void *a,Word b,void *c,Word d,Word e,Word f,Word g);
/*
; R3 = ArtPtr
; R4 = Maxlines
; R5 = ScreenPtr
; R6 = Frac
; R7 = Integer
; R8 = VideoWidth
; R9 = Delta
*/
#if 0
void IO_ScaleWallColumn(Word x,Word scale,LongWord column)
{
Word TheFrac;
Word TheInt;
Word y;
Byte *ArtStart;
if (scale) { /* Uhh.. Don't bother */
scale*=2;
TheFrac = 0x80000000UL / scale;
ArtStart = &ArtData[(column>>7)&0x3f][(column&127)<<7];
if (scale<VIEWHEIGHT) {
y = (VIEWHEIGHT-scale)/2;
TheInt = TheFrac>>24;
TheFrac <<= 8;
ScaleGlue(ArtStart,scale,
&VideoPointer[(y*VideoWidth)+x],
TheFrac,
TheInt,
VideoWidth,
0
);
return;
}
y = (scale-VIEWHEIGHT)/2; /* How manu lines to remove */
y = y*TheFrac;
TheInt = TheFrac>>24;
TheFrac <<= 8;
ScaleGlue(&ArtStart[y>>24],VIEWHEIGHT,
&VideoPointer[x],
TheFrac,
TheInt,
VideoWidth,
y<<8
);
}
}
#endif
/**********************************
Draw a vertical line with a masked scaler
(Used for SPRITE drawing)
**********************************/
typedef struct {
unsigned short Topy;
unsigned short Boty;
unsigned short Shape;
} SpriteRun;
void SpriteGlue(Byte *a,Word b,Word c,Byte *d,Word e,Word f);
/*
SGArtStart EQU R3 ;Pointer to the 6 byte run structure
SGFrac EQU R4 ;Pointer to the scaler
SGInteger EQU R5 ;Pointer to the video
SGScreenPtr EQU R6 ;Pointer to the run base address
SGCount EQU R7
SGDelta EQU R8
*/
void IO_ScaleMaskedColumn(Word x,Word scale,unsigned short *CharPtr,Word column)
{
Byte * CharPtr2;
int Y1,Y2;
Byte *Screenad;
SpriteRun *RunPtr;
Word TheFrac;
Word TFrac;
Word TInt;
Word RunCount;
int TopY;
Word Index;
Word Delta;
if (!scale) {
return;
}
CharPtr2 = (Byte *) CharPtr;
TheFrac = ScaleDiv[scale]; /* Get the scale fraction */
RunPtr = (SpriteRun *) &CharPtr[CharPtr[column+1]/2]; /* Get the offset to the RunPtr data */
Screenad = &VideoPointer[x]; /* Set the base screen address */
TFrac = TheFrac<<8;
TInt = TheFrac>>24;
TopY = (VIEWHEIGHT/2)-scale; /* Number of pixels for 128 pixel shape */
while (RunPtr->Topy != (unsigned short) -1) { /* Not end of record? */
Y1 = scale*(LongWord)RunPtr->Topy/128+TopY;
if (Y1<(int)VIEWHEIGHT) { /* Clip top? */
Y2 = scale*(LongWord)RunPtr->Boty/128+TopY;
if (Y2>0) {
if (Y2>(int)VIEWHEIGHT) {
Y2 = VIEWHEIGHT;
}
Index = RunPtr->Shape+(RunPtr->Topy/2);
Delta = 0;
if (Y1<0) {
Delta = (0-(Word)Y1)*TheFrac;
Index += (Delta>>24);
Delta <<= 8;
Y1 = 0;
}
RunCount = Y2-Y1;
if (RunCount) {
SpriteGlue(
&CharPtr2[Index], /* Pointer to art data */
TFrac, /* Fractional value */
TInt, /* Integer value */
&Screenad[Y1*VideoWidth], /* Pointer to screen */
RunCount, /* Number of lines to draw */
Delta /* Delta value */
);
}
}
}
RunPtr++; /* Next record */
}
}
/**********************************
Draw an automap tile
**********************************/
Byte *SmallFontPtr;
void DrawSmall(Word x,Word y,Word tile)
{
Byte *Screenad;
Byte *ArtStart;
Word Width,Height;
if (!SmallFontPtr) {
return;
}
x*=16;
y*=16;
Screenad = &VideoPointer[YTable[y]+x];
ArtStart = &SmallFontPtr[tile*(16*16)];
Height = 0;
do {
Width = 16;
do {
Screenad[0] = ArtStart[0];
++Screenad;
++ArtStart;
} while (--Width);
Screenad+=VideoWidth-16;
} while (++Height<16);
}
void MakeSmallFont(void)
{
Word i,j,Width,Height;
Byte *DestPtr,*ArtStart;
Byte *TempPtr;
SmallFontPtr = AllocSomeMem(16*16*65);
if (!SmallFontPtr) {
return;
}
memset(SmallFontPtr,0,16*16*65); /* Erase the font */
i = 0;
DestPtr = SmallFontPtr;
do {
ArtStart = &ArtData[i][0];
if (!ArtStart) {
DestPtr+=(16*16);
} else {
Height = 0;
do {
Width = 16;
j = Height*8;
do {
DestPtr[0] = ArtStart[j];
++DestPtr;
j+=(WALLHEIGHT*8);
} while (--Width);
} while (++Height<16);
}
} while (++i<64);
TempPtr = LoadAResource(MyBJFace);
memcpy(DestPtr,TempPtr,16*16);
ReleaseAResource(MyBJFace);
#if 0
TempPtr = AllocSomeMem(16*16*128);
memset(TempPtr,-1,16*16*128);
i = 0;
do {
memcpy(&TempPtr[(i+1)*256],&SmallFontPtr[(i*2)*256],256);
} while (++i<29);
i = 0;
do {
memcpy(&TempPtr[((i*2)+90)*256],&SmallFontPtr[(i+59)*256],256);
memcpy(&TempPtr[((i*2)+91)*256],&SmallFontPtr[(i+59)*256],256);
} while (++i<4);
SaveJunk(TempPtr,256*128);
FreeSomeMem(TempPtr);
#endif
}
void KillSmallFont(void)
{
if (SmallFontPtr) {
FreeSomeMem(SmallFontPtr);
SmallFontPtr=0;
}
}
;
; Assembly language functions for wolf 3-D
; By Bill Heineman
; 9-12-94 (Rev to use tight loop for scale code)
;
; Call the compiled scaler
; void ScaleGlue(void *TextPtr,t_compscale *CodePtr);
;
CASE ON
WALLHEIGHT EQU 128+1
EXPORT IO_ScaleWallColumn
EXPORT SpriteGlue
IMPORT VideoPointer:DATA
IMPORT VideoWidth:DATA
IMPORT ScaleDiv:DATA
IMPORT ArtData:DATA
IMPORT MacViewHeight:DATA
IO_ScaleWallColumn PROC
Adder1 EQU 20
ParmX EQU 4+Adder1
ParmScale EQU 6+Adder1
ParmTile EQU 8+Adder1
ParmColumn EQU 10+Adder1
;
; D0 = Temp, A0 = Temp
;
RegScrn EQU A0 ;Pointer to the screen
RegArt2 EQU A1 ;True pointer to art
RegArt EQU D1 ;Offset into the shape
RegDelta EQU D2 ;Delta counter
RegFrac EQU D3 ;Fixed point fraction
RegInt EQU D4 ;Fixed point integer
RegVidWidth EQU D5 ;Width of the screen in bytes
RegScale EQU D6 ;Scale factor
MOVEM.L D2-D6,-(A7) ;Save my registers
MOVE.L #0,RegScale ;Force scale to a long value
MOVE.W ParmScale(A7),RegScale ;Preload the scale factor
CMP.W #0,RegScale ;Scale of zero?
BEQ.S ByeBye ;Exit now! (Can't draw zero height)
MOVE.W ParmX(A7),D0 ;Get the X coord
MOVE.L VideoPointer,RegScrn ;Init the screen pointer
ADD.W D0,RegScrn ;Add the X coord
MOVE.W VideoWidth,RegVidWidth ;Init the video width
LEA ScaleDiv,RegArt2 ;Get pointer to the scaler recipocal table
MOVE.W RegScale,D0 ;Place scale value in temp
LSL.W #2,D0 ;Mul by 4 for longword index
MOVE.L (RegArt2,D0.W),RegFrac ;Get the precalced fraction
ADD.W RegScale,RegScale ;Convert scale to pixel value
MOVE.W ParmColumn(A7),RegArt ;Get the column index to the art
LSL.W #7,RegArt ;I have the pixel index
MOVE.W ParmTile(A7),D0
LSL.W #2,D0 ;Shift down 7 up 2
LEA ArtData,RegArt2 ;Get pointer to my shape ptr array
MOVE.L (RegArt2,D0.W),RegArt2 ;Get the base pointer to the art in A2
MOVE.W MacViewHeight,D0 ;Get the height
CMP.W D0,RegScale ;Clipping needed?
BCC.S ClipTop ;Do the clipped version
SUB.W RegScale,D0 ;How many line are clear?
LSR.W #1,D0 ;Number of lines to jump DOWN (Center it)
MULU.W RegVidWidth,D0 ;Mul by bytes per line
ADD.L D0,RegScrn ;Add to the screen pointer
MOVE.L RegFrac,RegInt ;Copy the full fixed point number
SWAP RegInt ;Isolate the integer
MOVE.W #0,RegDelta ;Zap the delta
SUB.W #1,RegScale ;-1 from the count for DBF
;
; This is the tight loop that draws the scaled line
; RegArt2/RegArt = Source ptr
; RegScrn = Video pointer
; RegFrac = Scale fraction
; RegInt = Scale integer
; RegDelta = Scale delta
; RegScale = Pixel count (Max MacViewHeight)
;
Loopy
MOVE.B (RegArt2,RegArt.W),D0 ;Move shape byte
MOVE.B D0,(RegScrn)
ADD.W RegFrac,RegDelta ;Adjust the delta
ADDX.W RegInt,RegArt ;Adjust the source byte offset
ADD.W RegVidWidth,RegScrn ;Next dest scan line
DBF RegScale,Loopy ;Still more?
ByeBye ;Exit
MOVEM.L (A7)+,D2-D6
RTS
ClipTop
SUB.W D0,RegScale ;Number of lines clipped
LSR.W #1,RegScale ;True number of lines skipped from top
MOVE.W RegFrac,RegDelta ;Init the delta for the mul
MULU.W RegScale,RegDelta ;Make the new delta for skipped lines
MOVE.L RegDelta,D0 ;Copy the delta
SWAP D0 ;Isolate the integer
ADD.W D0,RegArt ;Skip the hidden lines
MOVE.L RegFrac,D0
SWAP D0
MULU.W RegScale,D0
ADD.W D0,RegArt
MOVE.L RegFrac,RegInt ;Copy the full fixed point number
SWAP RegInt ;Isolate the integer
MOVE.W MacViewHeight,RegScale ;Use maximum height
SUB.W #1,RegScale ;Adjust for DBF
JMP Loopy
;
; Call the compiled scaler to draw a run of the line
;
;void SpriteGlue(Byte *a,LongWord b,Byte *c,Word d,Word e);
SpriteGlue PROC
Off EQU 20
ParmSGArt EQU 4+Off ;Pointer to the 6 byte run structure
ParmTFrac EQU 8+Off ;Pointer to the scaler
ParmScrn EQU 12+Off ;Pointer to the run base address
ParmCnt EQU 16+Off ;Line count
ParmDelta EQU 18+Off ;Initial delta
SGArt2 EQU A0 ;Pointer to the 6 byte run structure
SGScrn EQU A1 ;Pointer to the run base address
SGArt EQU D1
SGFrac EQU D2 ;Pointer to the scaler
SGInt EQU D3 ;Pointer to the video
SGCount EQU D6
SGDelta EQU D4
SGVidWidth EQU D5
MOVEM.L D2-D6,-(A7)
MOVE.L ParmSGArt(A7),SGArt2
MOVE.L ParmScrn(A7),SGScrn
MOVE.L ParmTFrac(A7),SGFrac ;Get pointer to the run structure
MOVE.L SGFrac,SGInt
SWAP SGInt
MOVE.W ParmCnt(A7),SGCount
MOVE.W ParmDelta(A7),SGDelta
MOVE.W VideoWidth,SGVidWidth ;Init the video width
MOVE.L #0,SGArt
SUB.W #1,SGCount ;Adjust for count used in DBF
Loopy2
MOVE.B (SGArt2,SGArt.W),D0 ;Get shape byte
MOVE.B D0,(SGScrn)
ADD.W SGFrac,SGDelta ;Adjust the delta
ADDX.W SGInt,SGArt ;Adjust the source byte offset
ADD.W SGVidWidth,SGScrn ;Next dest scan line
DBF SGCount,Loopy2 ;Still more?
MOVEM.L (A7)+,D2-D6
RTS
END
;
; Assembly language functions for wolf 3-D PPC version
; Written by Bill Heineman
; 9-12-94 (Rev for removing scalers and using direct code)
;
;
; Bullshit to make the PPC Mac environment know I'm here
;
import VideoWidth ; global variable from C program
import MacViewHeight
import ArtData
import VideoPointer
import ScaleDiv
toc
tc VideoWidth[TC],VideoWidth
tc MacViewHeight[TC],MacViewHeight
tc ArtData[TC],ArtData
tc VideoPointer[TC],VideoPointer
tc ScaleDiv[TC],ScaleDiv
export IO_ScaleWallColumn[DS]
export .IO_ScaleWallColumn[PR]
export SpriteGlue[DS]
export .SpriteGlue[PR]
toc ;Table of contents for the subroutines
tc IO_ScaleWallColumn[TC], IO_ScaleWallColumn[DS]
tc SpriteGlue[TC], SpriteGlue[DS]
csect IO_ScaleWallColumn[DS]
dc.l .IO_ScaleWallColumn[PR]
dc.l TOC[tc0]
csect SpriteGlue[DS]
dc.l .SpriteGlue[PR]
dc.l TOC[tc0]
;
; This routine will draw a scaled wall column.
;
; void IO_ScaleWallColumn(Word x,Word scale,LongWord column)
;
WALLHEIGHT EQU 128+1
; Passed from "C"
X equ R3 ;X coord
Scale equ R4 ;Scale factor
Tile equ R5 ;Tile to draw
Column equ R6 ;Packed wall column #
; Locals
ArtStart EQU R7 ;Pointer to wall art
ScreenPtr EQU R8 ;Pointer to screen memory column
Frac EQU R9 ;Fractional scaler
Integer EQU R10 ;Fractional integer
VWidth EQU R11 ;Video of the video screen in bytes
Delta EQU R6 ;Delta factor and temp
VHeight EQU R12 ;Height of mac screen
Temp EQU R3 ;Temp (Use AFTER X is added)
csect .IO_ScaleWallColumn[PR]
CMPLWI Scale,0 ;Is the scale factor zero?
BEQLR ;Exit NOW!
LWZ ScreenPtr,VideoPointer[TC](RTOC) ;Get handle to video
LWZ ArtStart,ArtData[TC](RTOC) ;Get handle to art data list
LWZ VWidth,VideoWidth[TC](RTOC) ;Get handle to video width
LWZ Frac,ScaleDiv[TC](RTOC)
LWZ VHeight,MacViewHeight[TC](RTOC) ;Get pointer to view height
LWZ ScreenPtr,0(ScreenPtr) ;I have the base pointer
LWZ VWidth,0(VWidth) ;Init video width
LWZ VHeight,0(VHeight) ;Get the number of lines visible
SLWI Scale,Scale,1 ;Mul scale by 2 (Get true pixel value
ADD ScreenPtr,ScreenPtr,X ;Add the X coord (Frees Temp)
SLWI Temp,Scale,1 ;Get low word index
SLWI Tile,Tile,2 ;Get the wall shape pointer
LWZX Frac,Frac,Temp ;Get the scale factor
SLWI Column,Column,7 ;Mul by 128 pixels
LWZX ArtStart,ArtStart,Tile ;Get pointer to the shape
ADD ArtStart,ArtStart,Column ;I have the shape ptr
CMPLW Scale,VHeight ;Too big?
BGE ClipTop ;Clip the top
;
; No clipping needed!
; Adjust the dest screen for the starting Y coord
;
MTCTR Scale ;Init counter
SUB Temp,VHeight,Scale ;How many lines to jump down?
LI Delta,0 ;Init the delta factor
SRWI Temp,Temp,1 ;Divide by to center vertically
SRWI Integer,Frac,24 ;Isolate the integer
MULLW Temp,VWidth,Temp ;Adjust the Y coord
SLWI Frac,Frac,8 ;Isolate the fraction
ADD ScreenPtr,ScreenPtr,Temp ;Create the dest screen pointer
;
; Tight loop
; Grab byte, adjust fractional scaler values and store to screen
;
More:
LBZ R0,0(ArtStart) ;Fetch a shape byte
ADDC. Delta,Delta,Frac ;Add the scaler fractional
STB R0,0(ScreenPtr) ;Store on the screen
ADDE ArtStart,ArtStart,Integer ;Add the constant
ADD ScreenPtr,ScreenPtr,VWidth ;Go down a line
BDNZ More ;All lines done?
BLR ;Exit routine
;
; Clip the top and bottom
; Calc the number of lost lines by clipping and "Fake"
; the numbers as if I processed those missing lines
;
ClipTop:
MTCTR VHeight ;I will draw a screen line full
SUB Temp,Scale,VHeight ;How many lines to jump down?
SRWI Integer,Frac,24 ;Isolate the integer
SRWI Temp,Temp,1 ;Divide by to center vertically
MULLW Temp,Frac,Temp ;Adjust the scaler by lost lines
SRWI Delta,Temp,24 ;How many bytes are lost?
ADD ArtStart,ArtStart,Delta ;Create the SOURCE art pointer
SLWI Frac,Frac,8 ;Isolate the fraction
SLWI Delta,Temp,8 ;Init the adjusted delta
B More ;Jump to the code
;
; Call the compiled scaler to draw a run of the line
;
csect .SpriteGlue[PR]
SGArtStart EQU R3 ;Pointer to the 6 byte run structure
SGFrac EQU R4 ;Pointer to the scaler
SGInteger EQU R5 ;Pointer to the video
SGScreenPtr EQU R6 ;Pointer to the run base address
SGCount EQU R7
SGDelta EQU R8
SGVWidth EQU R9
LWZ SGVWidth,VideoWidth[TC](RTOC)
LWZ SGVWidth,0(SGVWidth)
MTCTR SGCount
SMore:
LBZ R0,0(SGArtStart) ;Fetch a shape byte
ADDC. SGDelta,SGDelta,SGFrac ;Add the scaler fractional
STB R0,0(SGScreenPtr) ;Store on the screen
ADDE SGArtStart,SGArtStart,SGInteger ;Add the constant
ADD SGScreenPtr,SGScreenPtr,SGVWidth ;Go down a line
BDNZ SMore ;All lines done?
BLR ;Exit routine
......@@ -8,6 +8,13 @@
#define FALSE 0
#endif
typedef struct {
int left;
int top;
int right;
int bottom;
} Rect;
/* an angle_t occupies an entire 16 bits so wraparound is automatically handled */
#define SHORTTOANGLESHIFT 7 /* 0x10000 to ANGLES */
......
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