This repository has been archived by the owner on Mar 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Burger.c
1137 lines (900 loc) · 22.2 KB
/
Burger.c
1
/********************************** 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 1void 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);}