mirror of
https://github.com/Blzut3/Wolf3D-Mac.git
synced 2024-11-28 15:50:19 +00:00
1 line
22 KiB
C
1 line
22 KiB
C
/**********************************
|
|
|
|
Burger library for the Macintosh.
|
|
Use Think.c or Code Warrior to compile.
|
|
Use SMART linking to link in just what you need
|
|
|
|
**********************************/
|
|
|
|
#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 */
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Sound sub-system
|
|
|
|
**********************************/
|
|
|
|
/**********************************
|
|
|
|
Shut down the sound
|
|
|
|
**********************************/
|
|
|
|
void SoundOff(void)
|
|
{
|
|
PlaySound(0);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Play a sound resource
|
|
|
|
**********************************/
|
|
|
|
void PlaySound(Word SoundNum)
|
|
{
|
|
if (SoundNum && (SystemState&SfxActive)) {
|
|
SoundNum+=127;
|
|
if (SoundNum&0x8000) { /* Mono sound */
|
|
EndSound(SoundNum&0x7fff);
|
|
}
|
|
BeginSound(SoundNum&0x7fff,11127<<17L);
|
|
} else {
|
|
EndAllSound();
|
|
}
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Stop playing a sound resource
|
|
|
|
**********************************/
|
|
|
|
void StopSound(Word SoundNum)
|
|
{
|
|
EndSound(SoundNum+127);
|
|
}
|
|
|
|
static Word LastSong = -1;
|
|
|
|
void PlaySong(Word Song)
|
|
{
|
|
if (Song) {
|
|
KilledSong = Song;
|
|
if (SystemState&MusicActive) {
|
|
if (Song!=LastSong) {
|
|
BeginSongLooped(Song);
|
|
LastSong = Song;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
EndSong();
|
|
LastSong = -1;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Graphics subsystem
|
|
|
|
**********************************/
|
|
|
|
/**********************************
|
|
|
|
Draw a masked shape
|
|
|
|
**********************************/
|
|
|
|
void InitYTable(void)
|
|
{
|
|
Word i;
|
|
LongWord Offset;
|
|
|
|
i = 0;
|
|
Offset = 0;
|
|
do {
|
|
YTable[i] = Offset;
|
|
Offset+=VideoWidth;
|
|
} while (++i<480);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Draw a shape
|
|
|
|
**********************************/
|
|
|
|
void DrawShape(Word x,Word y,void *ShapePtr)
|
|
{
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *ShapePtr2;
|
|
unsigned short *ShapePtr3;
|
|
Word Width;
|
|
Word Height;
|
|
Word Width2;
|
|
|
|
ShapePtr3 = ShapePtr;
|
|
Width = ShapePtr3[0]; /* 16 bit width */
|
|
Height = ShapePtr3[1]; /* 16 bit height */
|
|
ShapePtr2 = (unsigned char *) &ShapePtr3[2];
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
|
|
do {
|
|
Width2 = Width;
|
|
Screenad = ScreenPtr;
|
|
do {
|
|
*Screenad++ = *ShapePtr2++;
|
|
} while (--Width2);
|
|
ScreenPtr +=VideoWidth;
|
|
} while (--Height);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Draw a masked shape
|
|
|
|
**********************************/
|
|
|
|
void DrawMShape(Word x,Word y,void *ShapePtr)
|
|
{
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *MaskPtr;
|
|
unsigned char *ShapePtr2;
|
|
Word Width;
|
|
Word Height;
|
|
Word Width2;
|
|
|
|
ShapePtr2 = ShapePtr;
|
|
Width = ShapePtr2[1];
|
|
Height = ShapePtr2[3];
|
|
ShapePtr2 +=4;
|
|
MaskPtr = &ShapePtr2[Width*Height];
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
|
|
do {
|
|
Width2 = Width;
|
|
Screenad = ScreenPtr;
|
|
do {
|
|
*Screenad = (*Screenad & *MaskPtr++) | *ShapePtr2++;
|
|
++Screenad;
|
|
} while (--Width2);
|
|
ScreenPtr +=VideoWidth;
|
|
} while (--Height);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Draw a masked shape with an offset
|
|
|
|
**********************************/
|
|
|
|
void DrawXMShape(Word x,Word y,void *ShapePtr)
|
|
{
|
|
unsigned short *ShapePtr2;
|
|
ShapePtr2 = ShapePtr;
|
|
x += ShapePtr2[0];
|
|
y += ShapePtr2[1];
|
|
DrawMShape(x,y,&ShapePtr2[2]);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Erase a masked shape
|
|
|
|
**********************************/
|
|
|
|
void EraseMBShape(Word x,Word y, void *ShapePtr, void *BackPtr)
|
|
{
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *Backad;
|
|
unsigned char *BackPtr2;
|
|
unsigned char *MaskPtr;
|
|
Word Width;
|
|
Word Height;
|
|
Word Width2;
|
|
|
|
MaskPtr = ShapePtr; /* Get the pointer to the mask */
|
|
Width = MaskPtr[1]; /* Get the width of the shape */
|
|
Height = MaskPtr[3]; /* Get the height of the shape */
|
|
MaskPtr = &MaskPtr[(Width*Height)+4]; /* Index to the mask */
|
|
/* Point to the screen */
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
|
|
BackPtr2 = BackPtr;
|
|
BackPtr2 = &BackPtr2[(y*SCREENWIDTH)+x]; /* Index to the erase buffer */
|
|
do {
|
|
Width2 = Width; /* Init width count */
|
|
Screenad = ScreenPtr;
|
|
Backad = BackPtr2;
|
|
do {
|
|
if (!*MaskPtr++) {
|
|
*Screenad = *Backad;
|
|
}
|
|
++Screenad;
|
|
++Backad;
|
|
} while (--Width2);
|
|
ScreenPtr +=VideoWidth;
|
|
BackPtr2 += SCREENWIDTH;
|
|
} while (--Height);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Test for a shape collision
|
|
|
|
**********************************/
|
|
|
|
Word TestMShape(Word x,Word y,void *ShapePtr)
|
|
{
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *MaskPtr;
|
|
unsigned char *ShapePtr2;
|
|
Word Width;
|
|
Word Height;
|
|
Word Width2;
|
|
|
|
ShapePtr2 = ShapePtr;
|
|
Width = ShapePtr2[0];
|
|
Height = ShapePtr2[1];
|
|
ShapePtr2 +=2;
|
|
MaskPtr = &ShapePtr2[Width*Height];
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
|
|
do {
|
|
Width2 = Width;
|
|
Screenad = ScreenPtr;
|
|
do {
|
|
if (!*MaskPtr++) {
|
|
if (*Screenad != *ShapePtr2) {
|
|
return 1;
|
|
}
|
|
}
|
|
++ShapePtr2;
|
|
++Screenad;
|
|
} while (--Width2);
|
|
ScreenPtr +=VideoWidth;
|
|
} while (--Height);
|
|
return 0;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Test for a masked shape collision
|
|
|
|
**********************************/
|
|
|
|
Word TestMBShape(Word x,Word y,void *ShapePtr,void *BackPtr)
|
|
{
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *Backad;
|
|
unsigned char *BackPtr2;
|
|
unsigned char *MaskPtr;
|
|
Word Width;
|
|
Word Height;
|
|
Word Width2;
|
|
|
|
MaskPtr = ShapePtr; /* Get the pointer to the mask */
|
|
Width = MaskPtr[0]; /* Get the width of the shape */
|
|
Height = MaskPtr[1]; /* Get the height of the shape */
|
|
MaskPtr = &MaskPtr[(Width*Height)+2]; /* Index to the mask */
|
|
/* Point to the screen */
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[y]+x];
|
|
BackPtr2 = BackPtr;
|
|
BackPtr2 = &BackPtr2[(y*SCREENWIDTH)+x]; /* Index to the erase buffer */
|
|
do {
|
|
Width2 = Width; /* Init width count */
|
|
Screenad = ScreenPtr;
|
|
Backad = BackPtr2;
|
|
do {
|
|
if (!*MaskPtr++) {
|
|
if (*Screenad != *Backad) {
|
|
return 1;
|
|
}
|
|
}
|
|
++Screenad;
|
|
++Backad;
|
|
} while (--Width2);
|
|
ScreenPtr +=VideoWidth;
|
|
BackPtr2 += SCREENWIDTH;
|
|
} while (--Height);
|
|
return 0;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Show a full screen picture
|
|
|
|
**********************************/
|
|
|
|
void ShowPic(Word PicNum)
|
|
{
|
|
DrawShape(0,0,LoadAResource(PicNum)); /* Load the resource and show it */
|
|
ReleaseAResource(PicNum); /* Release it */
|
|
BlastScreen();
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Clear the screen to a specific color
|
|
|
|
**********************************/
|
|
|
|
void ClearTheScreen(Word Color)
|
|
{
|
|
Word x,y;
|
|
unsigned char *TempPtr;
|
|
|
|
TempPtr = VideoPointer;
|
|
y = SCREENHEIGHT; /* 200 lines high */
|
|
do {
|
|
x = 0;
|
|
do {
|
|
TempPtr[x] = Color; /* Fill color */
|
|
} while (++x<SCREENWIDTH);
|
|
TempPtr += VideoWidth; /* Next line down */
|
|
} while (--y);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Draw a text string
|
|
|
|
**********************************/
|
|
|
|
void DrawAString(char *TextPtr)
|
|
{
|
|
while (TextPtr[0]) { /* At the end of the string? */
|
|
DrawAChar(TextPtr[0]); /* Draw the char */
|
|
++TextPtr; /* Continue */
|
|
}
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Set the X/Y to the font system
|
|
|
|
**********************************/
|
|
|
|
void SetFontXY (Word x,Word y)
|
|
{
|
|
FontX = x;
|
|
FontY = y;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Make color zero invisible
|
|
|
|
**********************************/
|
|
|
|
void FontUseMask(void)
|
|
{
|
|
FontInvisible = 0;
|
|
FontSetColor(0,0);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Make color zero a valid color
|
|
|
|
**********************************/
|
|
|
|
void FontUseZero(void)
|
|
{
|
|
FontInvisible = -1;
|
|
FontSetColor(0,BLACK);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Set the color entry for the font
|
|
|
|
**********************************/
|
|
|
|
void FontSetColor(Word Num,Word Color)
|
|
{
|
|
FontOrMask[Num] = Color;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Install a font into memory
|
|
|
|
**********************************/
|
|
|
|
typedef struct FontStruct {
|
|
unsigned short FHeight;
|
|
unsigned short FLast;
|
|
unsigned short FFirst;
|
|
unsigned char FData;
|
|
} FontStruct;
|
|
|
|
void InstallAFont(Word FontNum)
|
|
{
|
|
FontStruct *FPtr;
|
|
|
|
if (FontLoaded) {
|
|
if (FontLoaded == FontNum) {
|
|
return;
|
|
}
|
|
ReleaseAResource(FontLoaded);
|
|
}
|
|
FontLoaded = FontNum;
|
|
FPtr = LoadAResource(FontNum);
|
|
FontHeight = SwapUShort(FPtr->FHeight);
|
|
FontLast = SwapUShort(FPtr->FLast);
|
|
FontFirst = SwapUShort(FPtr->FFirst);
|
|
FontWidths = &FPtr->FData;
|
|
FontPtr = &FontWidths[FontLast];
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Draw a char to the screen
|
|
|
|
**********************************/
|
|
|
|
void DrawAChar(Word Letter)
|
|
{
|
|
Word XWidth;
|
|
Word Offset;
|
|
Word Width;
|
|
Word Height;
|
|
int Width2;
|
|
unsigned char *Font;
|
|
unsigned char *ScreenPtr;
|
|
unsigned char *Screenad;
|
|
unsigned char *FontOr;
|
|
Word Temp;
|
|
Word Temp2;
|
|
|
|
Letter -= FontFirst; /* Offset from the first entry */
|
|
if (Letter>=FontLast) { /* In the font? */
|
|
return; /* Exit then! */
|
|
}
|
|
XWidth = FontWidths[Letter]; /* Get the pixel width of the entry */
|
|
Width = (XWidth-1)/2;
|
|
Font = &FontPtr[Letter*2];
|
|
Offset = (Font[1]*256) + Font[0];
|
|
Font = &FontPtr[Offset];
|
|
ScreenPtr = (unsigned char *) &VideoPointer[YTable[FontY]+FontX];
|
|
FontX+=XWidth;
|
|
Height = FontHeight;
|
|
FontOr = &FontOrMask[0];
|
|
|
|
do {
|
|
Screenad = ScreenPtr;
|
|
Width2 = Width;
|
|
do {
|
|
Temp = *Font++;
|
|
Temp2 = Temp>>4;
|
|
if (Temp2 != FontInvisible) {
|
|
Screenad[0] = FontOr[Temp2];
|
|
}
|
|
Temp &= 0x0f;
|
|
if (Temp != FontInvisible) {
|
|
Screenad[1] = FontOr[Temp];
|
|
}
|
|
Screenad+=2; /* Next address */
|
|
} while(--Width2>=0);
|
|
ScreenPtr += VideoWidth;
|
|
} while (--Height);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Palette Manager
|
|
|
|
**********************************/
|
|
|
|
/**********************************
|
|
|
|
Load and set a palette resource
|
|
|
|
**********************************/
|
|
|
|
void SetAPalette(Word PalNum)
|
|
{
|
|
SetAPalettePtr(LoadAResource(PalNum)); /* Set the current palette */
|
|
ReleaseAResource(PalNum); /* Release the resource */
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Load and set a palette from a pointer
|
|
|
|
**********************************/
|
|
|
|
Byte CurrentPal[768];
|
|
|
|
void SetAPalettePtr(unsigned char *PalPtr)
|
|
{
|
|
CTabHandle ColorHandle; /* Handle to the main palette */
|
|
Handle PalHand; /* Handle to palette */
|
|
Word i; /* Temp */
|
|
CSpecArray *Colors; /* Pointer to color array */
|
|
GDHandle OldDevice;
|
|
|
|
memcpy(CurrentPal,PalPtr,768);
|
|
ColorHandle = MainColorHandle;
|
|
HLock((Handle) ColorHandle);
|
|
Colors = &(*ColorHandle)->ctTable;
|
|
++Colors; /* Go to color #0 */
|
|
i = 1; /* Skip color #0 */
|
|
PalPtr+=3;
|
|
do { /* Fill in all the color entries */
|
|
Colors[0]->rgb.red = (Word) (PalPtr[0]<<8) | PalPtr[0];
|
|
Colors[0]->rgb.green = (Word) (PalPtr[1]<<8) | PalPtr[1];
|
|
Colors[0]->rgb.blue = (Word) (PalPtr[2]<<8) | PalPtr[2];
|
|
if (!Colors[0]->rgb.blue) {
|
|
Colors[0]->rgb.blue = 0x0101;
|
|
}
|
|
PalPtr+=3;
|
|
++Colors;
|
|
} while (++i<255); /* All done? */
|
|
OldDevice = GetGDevice();
|
|
SetGDevice(gMainGDH);
|
|
SetEntries(0,255-1,(*ColorHandle)->ctTable); /* Set the color entries */
|
|
PalHand = (Handle) (**(*GameGWorld).portPixMap).pmTable;
|
|
PtrToXHand(*ColorHandle,PalHand,8+(8*256));
|
|
PalHand = (Handle) (**(*GameWindow).portPixMap).pmTable;
|
|
PtrToXHand(*ColorHandle,PalHand,8+(8*256));
|
|
HUnlock((Handle)ColorHandle); /* Release the main handle */
|
|
MakeITable(0,0,0); /* Create the proper color table */
|
|
SetGDevice(OldDevice);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Fade the screen to black
|
|
|
|
**********************************/
|
|
|
|
void FadeToBlack(void)
|
|
{
|
|
unsigned char MyPal[768];
|
|
|
|
memset(MyPal,0,sizeof(MyPal)); /* Fill with black */
|
|
MyPal[0] = MyPal[1] = MyPal[2] = 255;
|
|
FadeToPtr(MyPal);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Fade the screen to a palette
|
|
|
|
**********************************/
|
|
|
|
void FadeTo(Word RezNum)
|
|
{
|
|
FadeToPtr(LoadAResource(RezNum));
|
|
ReleaseAResource(RezNum);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Fade the palette
|
|
|
|
**********************************/
|
|
|
|
void FadeToPtr(unsigned char *PalPtr)
|
|
{
|
|
int DestPalette[768]; /* Dest offsets */
|
|
Byte WorkPalette[768]; /* Palette to draw */
|
|
Byte SrcPal[768];
|
|
Word Count;
|
|
Word i;
|
|
|
|
if (!memcmp(PalPtr,&CurrentPal,768)) { /* Same palette? */
|
|
return;
|
|
}
|
|
memcpy(SrcPal,CurrentPal,768);
|
|
i = 0;
|
|
do { /* Convert the source palette to ints */
|
|
DestPalette[i] = PalPtr[i];
|
|
} while (++i<768);
|
|
|
|
i = 0;
|
|
do {
|
|
DestPalette[i] -= SrcPal[i]; /* Convert to delta's */
|
|
} while (++i<768);
|
|
|
|
Count = 1;
|
|
do {
|
|
i = 0;
|
|
do {
|
|
WorkPalette[i] = ((DestPalette[i] * (int)(Count)) / 16) + SrcPal[i];
|
|
} while (++i<768);
|
|
SetAPalettePtr(WorkPalette);
|
|
WaitTicks(1);
|
|
} while (++Count<17);
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Resource manager subsystem
|
|
|
|
**********************************/
|
|
|
|
/**********************************
|
|
|
|
Load a personal resource
|
|
|
|
**********************************/
|
|
|
|
void *LoadAResource(Word RezNum)
|
|
{
|
|
return(LoadAResource2(RezNum,'BRGR'));
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Load a global resource
|
|
|
|
**********************************/
|
|
|
|
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;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Allow a resource to be purged
|
|
|
|
**********************************/
|
|
|
|
void ReleaseAResource(Word RezNum)
|
|
{
|
|
ReleaseAResource2(RezNum,'BRGR');
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Release a global resource
|
|
|
|
**********************************/
|
|
|
|
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 */
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Force a resource to be destroyed
|
|
|
|
**********************************/
|
|
|
|
void KillAResource(Word RezNum)
|
|
{
|
|
KillAResource2(RezNum,'BRGR');
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Kill a global resource
|
|
|
|
**********************************/
|
|
|
|
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)
|
|
{
|
|
static Word Count=1;
|
|
FILE *fp;
|
|
char SaveName[40];
|
|
sprintf(SaveName,"SprRec%d",Count);
|
|
fp = fopen(SaveName,"wb");
|
|
fwrite(AckPtr,1,Length,fp);
|
|
fclose(fp);
|
|
++Count;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Kill a global resource
|
|
|
|
**********************************/
|
|
|
|
unsigned short SwapUShort(unsigned short Val)
|
|
{
|
|
return ((Val<<8) | (Val>>8));
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Decompress using LZSS
|
|
|
|
**********************************/
|
|
|
|
#if 1
|
|
void DLZSS(Byte *Dest,Byte *Src,LongWord Length)
|
|
{
|
|
Word BitBucket;
|
|
Word RunCount;
|
|
Word Fun;
|
|
Byte *BackPtr;
|
|
|
|
if (!Length) {
|
|
return;
|
|
}
|
|
BitBucket = (Word) Src[0] | 0x100;
|
|
++Src;
|
|
do {
|
|
if (BitBucket&1) {
|
|
Dest[0] = Src[0];
|
|
++Src;
|
|
++Dest;
|
|
--Length;
|
|
} else {
|
|
RunCount = (Word) Src[0] | ((Word) Src[1]<<8);
|
|
Fun = 0x1000-(RunCount&0xfff);
|
|
BackPtr = Dest-Fun;
|
|
RunCount = ((RunCount>>12) & 0x0f) + 3;
|
|
if (Length >= RunCount) {
|
|
Length -= RunCount;
|
|
} else {
|
|
Length = 0;
|
|
}
|
|
do {
|
|
*Dest++ = *BackPtr++;
|
|
} while (--RunCount);
|
|
Src+=2;
|
|
}
|
|
BitBucket>>=1;
|
|
if (BitBucket==1) {
|
|
BitBucket = (Word)Src[0] | 0x100;
|
|
++Src;
|
|
}
|
|
} while (Length);
|
|
}
|
|
#endif
|
|
|
|
/**********************************
|
|
|
|
Allocate some memory
|
|
|
|
**********************************/
|
|
|
|
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;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Allocate some memory
|
|
|
|
**********************************/
|
|
|
|
static Word FreeStage(Word Stage,LongWord Size)
|
|
{
|
|
switch (Stage) {
|
|
case 1:
|
|
PurgeAllSounds(Size); /* Kill off sounds until I can get memory */
|
|
break;
|
|
case 2:
|
|
PlaySound(0); /* Shut down all sounds... */
|
|
PurgeAllSounds(Size); /* Purge them */
|
|
break;
|
|
case 3:
|
|
PlaySong(0); /* Kill music */
|
|
FreeSong(); /* Purge it */
|
|
PurgeAllSounds(Size); /* Make SURE it's gone! */
|
|
break;
|
|
case 4:
|
|
return 0;
|
|
}
|
|
return Stage+1;
|
|
}
|
|
|
|
/**********************************
|
|
|
|
Release some memory
|
|
|
|
**********************************/
|
|
|
|
void FreeSomeMem(void *MemPtr)
|
|
{
|
|
DisposePtr(MemPtr);
|
|
}
|