// C Header File // Created 11/30/2002; 5:11:55 PM static void InitForLevel(void); static inline short InitGlobals(char *lcd); static inline short InitScroller(void); static inline void CleanupScroller(void); static inline void FreeButtons(void); static inline void FreeLevel(void); static inline void FreeOnly(void); static inline void CleanAndFree(void); static inline short AllocateMemory(void); static inline void ResetHUD(void); static inline short LoadDataFiles(void); static inline void LoadExternalLevel (void); static inline void waitMsec(unsigned long msec); static inline void contrast(void); void PreHUDCallback (FATCONFIG *fc,unsigned short *p0,unsigned short *p1); static inline void ConfigureGameKeys (void); static inline BOOL checkArchived (SYM_STR filestr); static inline void LoadConfig (void); static inline void SaveConfig (void); static inline void copyDoorsNF(PartialDoor *dest, FATDOOR *src, short c); static inline void copyDoorsFN(FATDOOR *dest, PartialDoor *src, short c); static inline void TransparentAutoSaveBeginning(void); static inline void TransparentAutoSaveMid(void); static inline void TransparentAutoLoad(void); static inline void TransparentAutoSave(void); static inline void TransparentAutoRefreshBeginning(void); static inline void TransparentAutoRefreshMid(void); void Fix3(char *buffer, short value); //static inline void copySprite(FATSPRITE *dest, FATSPRITE *src); extern short IsVTI(void); static inline char *stringIdx(short set, short i); static inline short ResetProgress(void); static inline void PromptToResetProgress(void); void Predraw_LightEffects(FATCONFIG* fc,DEPTHDATA* dd); #ifndef __SYS_H__ #define __SYS_H__ static void InitPreLevel(void) { register GameGlobals *ggg asm("a4") = gg; ggg->buttoncount = 0; ggg->doorcount = 0; ggg->panel_count = 0; ggg->monitor_count = 0; ggg->playerHasKeycard = FALSE; ggg->oldPlayerHasKeycard = TRUE; } static void InitForLevel(void) { register GameGlobals *ggg asm("a4") = gg; ggg->sprite_count = 0; ggg->projectile_count = 0; ggg->turning = FALSE; ggg->weapon_count = 0; ggg->automove = FALSE; ggg->autoturn = FALSE; ggg->autokeys = FALSE; ggg->lights = LIGHTS_ON; ggg->levelstyle = level_normal; ggg->canExit = TRUE; } static inline short InitGlobals(char *lcd) { register GameGlobals *ggg asm("a4"); if(!(gg = malloc_special(sizeof(GameGlobals)))) return 0; ggg = gg; memset(gg,0x00,sizeof(GameGlobals)); int1_counter = 0; int5_counter = 0; ggg->glcd = lcd; ggg->zoffset = ZOFFSET; ggg->cfg.keys[KEY_FIRE] = CALCULATOR==3 ? (RowKey) {RR_HAND} : (CALCULATOR? (RowKey) {RR_F1}: (RowKey){RR_2ND}); ggg->cfg.keys[KEY_STRAFE] = CALCULATOR==3 ? (RowKey) {RR_Q} : (CALCULATOR? (RowKey) {RR_F2}: (RowKey){RR_DIAMOND}); ggg->cfg.keys[KEY_PRESSBUTTON] = CALCULATOR==3 ? (RowKey) {RR_A} : (CALCULATOR? (RowKey) {RR_F3}: (RowKey){ RR_HOME}); ggg->cfg.keys[KEY_SWITCHWEAPON] = CALCULATOR==3 ? (RowKey) {RR_F1} : (CALCULATOR? (RowKey) {RR_F5}: (RowKey){RR_SHIFT}); ggg->cfg.keys[KEY_SPEEDUP] = CALCULATOR==3 ? (RowKey) {RR_W} : (CALCULATOR? (RowKey) {RR_F6}: (RowKey){RR_ALPHA}); ggg->cfg.keys[KEY_PAUSE] = CALCULATOR==3 ? (RowKey) {RR_F2} : (CALCULATOR? (RowKey) {RR_HAND}: (RowKey){RR_F1}); ggg->cfg.keys[KEY_BOSS] = CALCULATOR==3 ? (RowKey) {RR_F8} : (CALCULATOR? (RowKey) {RR_F8}: (RowKey){RR_F5}); ggg->cfg.keys[KEY_SAVE] = CALCULATOR==1 ? (RowKey) {RR_F4} : (RowKey) {RR_F3};//F3 for 89 (C==1) and V200 (C==3) ggg->cfg.keys[KEY_LOAD] = CALCULATOR==3 ? (RowKey) {RR_F5} : (CALCULATOR? (RowKey) {RR_F7}: (RowKey){RR_F4}); ggg->cfg.intro = TRUE; ggg->current_level = STARTLEVEL; ggg->player.life = STARTHEALTH; ggg->player.armor = STARTARMOR; return 1; } #define freeNull(a) {free_special(a);a=NULL;} /*static void freeNull(static void *ptr) { register GameGlobals *ggg asm("a4") = gg; free_special(ptr); ptr = NULL; }*/ //============================================================================= // allocates space for textplane //============================================================================= static inline short InitScroller(void) { register GameGlobals *ggg asm("a4") = gg; if (!(ggg->textplane = (unsigned long*)malloc_special(LCD_SIZE/*20*(100+ADDITIONALLY_LINES)*/))) { return 0; } return 1; } //============================================================================= // frees allocated space again //============================================================================= static inline void CleanupScroller(void) { register GameGlobals *ggg asm("a4") = gg; if (ggg->textplane) { freeNull(ggg->textplane); } PortRestore(); } static inline void FreeButtons(void) { register GameGlobals *ggg asm("a4") = gg; short a; for(a=0;alight_data[a]) freeNull(ggg->light_data[a]); if(ggg->dark_data[a]) freeNull(ggg->dark_data[a]); if(ggg->light_data2[a]) freeNull(ggg->light_data2[a]); if(ggg->dark_data2[a]) freeNull(ggg->dark_data2[a]); } } static inline void FreeLevel(void) { register GameGlobals *ggg asm("a4") = gg; if(ggg->ext_level_data) freeNull(ggg->ext_level_data); } static inline void FreeOnly(void) { register GameGlobals *ggg asm("a4") = gg; short a; for(a=0;abg_img[a]) freeNull(ggg->bg_img[a]); } FreeButtons(); if (ggg->HUDlight) freeNull(ggg->HUDlight); if (ggg->HUDdark) freeNull(ggg->HUDdark); if (ggg->HUDmask) freeNull(ggg->HUDmask); if (ggg->BGlight) freeNull(ggg->BGlight); if (ggg->BGdark) freeNull(ggg->BGdark); if(ggg->button) freeNull(ggg->button); //if(ggg->black) freeNull(ggg->black); if(ggg->stars) freeNull(ggg->stars); if(ggg->load_data) freeNull(ggg->load_data); #ifdef COMPRESSED_TEXTURES if(ggg->texspace) freeNull(ggg->texspace); #endif if(ggg->textures) freeNull(ggg->textures); if(ggg->doortimers) freeNull(ggg->doortimers); if(ggg->marquee) freeNull(ggg->marquee); if(ggg->textbuf) freeNull(ggg->textbuf); //if(sprites_extra) freeNull(sprites_extra); FreeLevel(); CleanupScroller(); } static inline void CleanAndFree(void) { register GameGlobals *ggg asm("a4") = gg; if(GrayCheckRunning()) { dissolveGSFromTo(ggg->glcd,ggg->glcd,ggg->plane1,ggg->plane2); GrayOff(); } else FastCopyScreen(ggg->glcd,LCD_MEM); if(ggg->quitting!=FORCE_QUIT) ST_helpMsg(FAT_GetPoweredByString()); SaveConfig(); if(ggg->midSaveIsLoaded && ggg->beginningSaveIsLoaded) TransparentAutoSave(); FreeOnly(); if(int1_counter) { RestoreHandlerForINTs(); } if (ggg->texfile0) FAT_UnlockHandleOfFile(ggg->texfile0); if (ggg->texfile) FAT_UnlockHandleOfFile(ggg->texfile); if (ggg->texfile2) FAT_UnlockHandleOfFile(ggg->texfile2); if (ggg->texfile3) FAT_UnlockHandleOfFile(ggg->texfile3); if (ggg->texfile4) FAT_UnlockHandleOfFile(ggg->texfile4); if(ggg->textfile) FAT_UnlockHandleOfFile(ggg->textfile); FAT_UnloadEngine(); OSqclear(kbd_queue()); if(gg) freeNull(gg); } #define SafeMalloc(a) ok = ok && (a); static inline short AllocateMemory(void) { register GameGlobals *ggg asm("a4") = gg; short a; short ok = 1; register short HUDsize = 576 * sizeof (short); register short a512 = 512; for(a=0;abg_img[a] = (unsigned char*)malloc_special(HUDsize<<1)); SafeMalloc(ggg->button = malloc_special(MAX_BUTTONS * sizeof(Button))); SafeMalloc(ggg->BGlight = malloc_special(LCD_SIZE)); SafeMalloc(ggg->BGdark = malloc_special(LCD_SIZE)); //Mem for HUD SafeMalloc(ggg->HUDlight = malloc_special (HUDsize)); SafeMalloc(ggg->HUDdark = malloc_special (HUDsize)); SafeMalloc(ggg->HUDmask = malloc_special (HUDsize)); if(ok) { memset(ggg->HUDlight,0x00,HUDsize); memset(ggg->HUDdark,0x00,HUDsize); memset(ggg->HUDmask,0xFF,HUDsize); } SafeMalloc(ggg->doortimers = malloc_special(MAX_DOORS*sizeof(short))); if(ok) memset(ggg->doortimers,0x00,MAX_DOORS*sizeof(short)); SafeMalloc(ggg->ext_level_data = malloc_special(sizeof(MAP_HEADER)+ MAX_DOORS*sizeof(DoorInfo)+MAX_BUTTONS*sizeof(ButtonInfo)+64*64)); //SafeMalloc(ggg->black = malloc_special(a512)); SafeMalloc(ggg->stars = malloc_special(sizeof(star_type)*NR_STARS)); SafeMalloc(ggg->load_data = malloc_special(sizeof(LSdata))); SafeMalloc(ggg->marquee = malloc_special(MARQUEE_SIZE)); SafeMalloc(ggg->textbuf = malloc_special(MARQUEE_SIZE)); if(ok) ResetMarquee(); SafeMalloc(ggg->textures = malloc_special(NR_TEXTURES*sizeof(TEXCONFIG))); if(ok) memset(ggg->textures,0,sizeof(TEXCONFIG)*NR_TEXTURES); SafeMalloc(InitScroller()); #ifdef COMPRESSED_TEXTURES SafeMalloc(ggg->texspace = malloc_special(1024*MAX_TEXTURES)); #endif for(a=0;alight_data[a] = malloc_special(a512)); SafeMalloc(ggg->dark_data[a] = malloc_special(a512)); SafeMalloc(ggg->light_data2[a] = malloc_special(a512)); SafeMalloc(ggg->dark_data2[a] = malloc_special(a512)); } if(!ok) return 0; return 1; } static inline void ResetHUD(void) { register GameGlobals *ggg asm("a4") = gg; short HUDsize = 576 * sizeof (short); memset(ggg->HUDlight,0x00,HUDsize); memset(ggg->HUDdark,0x00,HUDsize); memset(ggg->HUDmask,0xFF,HUDsize); } /* #ifdef DEBUG #define QuitBecauseOfGFX()\ {\ if(GrayCheckRunning()) PortSet(plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ OblivionShowError(OBLIVION_GFX_FILE_ERROR);\ printf_xy(0,30,"GFX Failed on oblvgfx%i",-gfxerror);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ goto ending;\ } #else*/ #define QuitBecauseOfGFX()\ {\ if(GrayCheckRunning()) PortSet(gg->plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ OblivionShowError(OBLIVION_GFX_FILE_ERROR);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ FAT_AllKeysReleased();\ goto ending;\ } //#endif /* #ifdef DEBUG #define QuitBecauseOfData()\ {\ if(GrayCheckRunning()) PortSet(plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ OblivionShowError(OBLIVION_DATA_FILE_ERROR);\ printf_xy(0,30,"Data Failed on oblv%s",datastrings[E2Q(dataerror)]);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ goto ending;\ } #else*/ #define QuitBecauseOfData()\ {\ if(GrayCheckRunning()) PortSet(gg->plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ OblivionShowError(OBLIVION_DATA_FILE_ERROR);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ FAT_AllKeysReleased();\ goto ending;\ } //#endif #define QuitBecauseOfMemory()\ {\ if(GrayCheckRunning()) PortSet(gg->plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ OblivionShowError(OBLIVION_OUT_OF_MEM);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ FAT_AllKeysReleased();\ goto ending;\ } #define SetUpCalculatorScreen() \ {\ lfc.dest_plane0 = (void*)((BYTE*)gg->plane1+30*2);\ lfc.dest_plane1 = (void*)((BYTE*)gg->plane2+30*2);\ \ if (TI89) {\ /*display_offsetx = 0;*/\ /*display_offsety = 0;*/\ }\ else {\ /* TI92p or V200 */ \ /*display_offsetx = 48;*/\ /*display_offsety = 14;*/\ lfc.dest_plane0 += (14*30+6)/2;\ lfc.dest_plane1 += (14*30+6)/2;\ } \ } #define QuitIfNecessary()\ {if(gg->quitting)\ {\ if(GrayCheckRunning()) PortSet(gg->plane2,239,127);\ else PortRestore();\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ /*{if(gg->quitting!=END_OF_GAME) {*/OblivionShowError(E2Q(gg->quitting));/*}*/\ /*else {DrawStr(1,51,"END OF GAME",A_NORMAL);}}*/\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ FAT_AllKeysReleased();\ goto ending;\ }} static inline short LoadDataFiles(void) { register GameGlobals *ggg asm("a4") = gg; unsigned char* src = 0; if ((ggg->textfile = FAT_GetHandleOfFile(textname))) { if ((src = FAT_LockHandleOfFile(ggg->textfile))) { ggg->text = src+2; } } if(!(ggg->textfile && src)) return 0; return 1; } static inline void LoadExternalLevel (void) { register GameGlobals *ggg asm("a4") = gg; short total_maps = 0; short cur = ggg->current_level - 1; SYM_ENTRY *symptr = NULL; unsigned char *archive; symptr = DerefSym (SymFind (SYMSTR (mapname))); if (symptr) { archive = HLock (symptr->handle); archive += 2; total_maps = ttarchive_entries(archive); if(ggg->current_level > total_maps) { ggg->quitting = END_OF_GAME; HeapUnlock(symptr->handle); return; } if (ttarchive_valid(archive)) { unsigned char* pointer_to_entry = ttarchive_data(archive,cur); //----------------------------------------------------------------------- // If the entry is compressed we could easily decompress it like this: //----------------------------------------------------------------------- if (ttunpack_valid(pointer_to_entry)) { // this entry is compressed ... if (ttunpack_decompress(pointer_to_entry,ggg->ext_level_data) == TTUNPACK_OKAY) { //--------------------------------- // entry successfully decompressed. // do something with it. //--------------------------------- //next comes a list of MAP_HEADERS MAP_HEADER *header = (MAP_HEADER *)ggg->ext_level_data; //next comes the actual tilemaps unsigned char *map_data = (unsigned char *) (ggg->ext_level_data + sizeof (MAP_HEADER)); fc->map_width = header->xsize; fc->map_height = header->ysize; ggg->doorcount = header->doorcount; ggg->buttoncount = header->buttoncount; ggg->door_data = (DoorInfo *)map_data; ggg->button_data = (ButtonInfo *)(map_data + sizeof(DoorInfo) * ggg->doorcount); fc->map_data = map_data + sizeof(DoorInfo) * ggg->doorcount + sizeof(ButtonInfo) * ggg->buttoncount; ggg->ceilmode = header->ceilmode; ggg->floormode = header->floormode; ggg->ceilmode2 = ggg->ceilmode; ggg->floormode2 = ggg->floormode; HeapUnlock(symptr->handle); } else { ggg->quitting = E2Q (OBLIVION_MAP_FILE_ERROR); HeapUnlock(symptr->handle); } } else { // this entry is NOT compressed. Do something else with it .... ggg->quitting = E2Q (OBLIVION_MAP_FILE_ERROR); HeapUnlock(symptr->handle); } } else { //not even a TTarchive... ggg->quitting = E2Q (OBLIVION_MAP_FILE_ERROR); HeapUnlock(symptr->handle); } } else ggg->quitting = E2Q(OBLIVION_MAP_FILE_ERROR); } static inline void waitMsec(unsigned long msec) { unsigned long end; msec = (msec*7)/20; end = int1_counter + msec; while(int1_counter < end); } // Adjusts contrast if +/- pressed. static inline void contrast(void) { register GameGlobals *ggg asm("a4") = gg; if (_keytest(RR_PLUS)) { ggg->contrastcur++; if (ggg->contrastcur == 2) { ggg->contrastcur = 0; OSContrastUp(); } } if (_keytest(RR_MINUS)) { ggg->contrastcur++; if (ggg->contrastcur == 2) { ggg->contrastcur = 0; OSContrastDn(); } } } #define LoadFatEngineOrExit() \ if ((result = FAT_LoadEngine ()) != FAT_LOADOKAY)\ {\ LCD_save(lcd);\ ClrScr();\ FontSetSys(F_4x6);\ DrawStr(1,1,SEE_README_STRING1,A_NORMAL);\ DrawStr(1,9,SEE_README_STRING2,A_NORMAL);\ ShowFatLoadError ((result < 0 && result >= -4) ? -result : 0);\ FAT_AllKeysReleased();\ FAT_WaitKeyPressed();\ FAT_AllKeysReleased();\ LCD_restore(lcd);\ return; \ } #define SetupFC(a)\ a = (FATCONFIG)\ {\ 0, \ 0,\ NULL, \ gg->textures, \ 0, \ gg->sprites, \ 96, \ 96, \ ANGLE_EAST,\ NULL, \ NULL, \ (unsigned short*)gg->bg_img[BGMAX-1],\ 0 \ };\ fc = &a; static inline char *stringIdx(short set, short i) { unsigned char *ptr = gg->text; ptr += oblvtext_count*sizeof(short) + (*((unsigned short*)ptr+set)); short nr_lines = *(unsigned short*)ptr; short ptroffset = sizeof(short)*(nr_lines+1); short *offsets = (unsigned short*)(ptr+2); unsigned char *strings = ptr+ptroffset; return strings+offsets[i]; } static inline void ConfigureGameKeys (void) { register GameGlobals *ggg asm("a4") = gg; short a; short row; short col; RowKey cur; FAT_AllKeysReleased(); BlackGrayScreen (); DrawGrayStrExt (2+display_offsetx, 2+display_offsety, stringIdx(gamestrings,ePressAppsToChangeKeys),A_REVERSE, F_6x8); for (a = 0; a < 9; a++) { memcpy (&cur, &ggg->cfg.keys[a], sizeof (RowKey)); sprintf (ggg->textbuf, "%s: %s", stringIdx(gameKeyFuncs,a), CALCULATOR ? stringIdx(TI92plus_rowread,cur.row*8+cur.key) : stringIdx(TI89_rowread,cur.row*8+cur.key)); DrawGrayStrExt (2+display_offsetx, 15 + a * 9+display_offsety, ggg->textbuf, A_REVERSE, F_6x8); } FAT_AllKeysReleased (); FAT_WaitKeyPressed (); if(_keytest(RR_APPS)) { FAT_AllKeysReleased (); BlackGrayScreen (); for (a = 0; a < 9; a++) { DrawGrayStrExt (display_offsetx, 39+display_offsety, stringIdx(gameKeyFuncs,a), A_REVERSE | A_CENTERED, F_6x8); FAT_AllKeysReleased (); FAT_WaitKeyPressed (); for (row = 0; row < (CALCULATOR ? 10 : 7); row++) { BEGIN_KEYTEST for (col = 0; col < 8; col++) { if (_keytest_optimized (row, col)) { cur.row = row; cur.key = col; memcpy(&ggg->cfg.keys[a], &cur, sizeof (RowKey)); } END_KEYTEST } } } BlackGrayScreen (); for (a = 0; a < 9; a++) { memcpy (&cur, &ggg->cfg.keys[a], sizeof (RowKey)); sprintf (ggg->textbuf, "%s: %s", stringIdx(gameKeyFuncs,a), CALCULATOR ? stringIdx(TI92plus_rowread,cur.row*8+cur.key) : stringIdx(TI89_rowread,cur.row*8+cur.key)); DrawGrayStrExt (2+display_offsetx, 15 + a * 9+display_offsety, ggg->textbuf, A_REVERSE, F_6x8); } FAT_AllKeysReleased (); FAT_WaitKeyPressed (); } FAT_AllKeysReleased (); } //These routines were written by JimRandomH, and are licensed under //the GPL. unsigned short fwrite_fast(const void *ptr, short size, short n, FILE *f) { /* The only error condition is out of memory, in which case the entire file * is futzed anyways, so no worries about getting the return value right. */ unsigned short oldpos; unsigned short newsize; //short tmode=!(f->flags&_F_BIN); size *= n; if(peek_w(f->base) + size > f->alloc) { oldpos = (char*)f->fpos - (char*)f->base; HeapUnlock(f->handle); f->alloc += f->buffincrement * (size/f->buffincrement + 1); if(!HeapRealloc(f->handle,f->alloc)) __FERROR(f); f->base=HLock(f->handle); f->fpos=(char*)f->base + oldpos; } memcpy(f->fpos, ptr, size); f->fpos += size; newsize = (char*)f->fpos - (char*)f->base - 2; if(newsize > peek_w(f->base)) poke_w(f->base, newsize); if((char*)f->base+peek_w(f->base)+(/*tmode?0:*/2)==f->fpos) { f->flags|=_F_EOF; /*if(tmode) { poke(f->fpos,0); poke(f->fpos+1,0xE0); }*/ } return n; } unsigned short fread_fast(void *ptr, short size, short n, FILE *f) { unsigned int num_bytes; unsigned int bytes_remaining = peek_w(f->base) + (char*)f->base - (char*)f->fpos + 2; if(f->flags&_F_ERR) return 0; if(!(f->flags&_F_READ)) __FERROR(f); if((unsigned)size*n > bytes_remaining) // More data requested than available n = bytes_remaining/size; if((unsigned)size*n == bytes_remaining) f->flags|=_F_EOF; num_bytes = size*n; memcpy(ptr, f->fpos, num_bytes); f->fpos += num_bytes; return n; } ////end by JimRandomH static inline BOOL checkArchived (SYM_STR filestr) { SYM_ENTRY *symptr; symptr = SymFindPtr (filestr, 0); if (symptr->flags.bits.archived == 1) return 1; return 0; } // Loads the config file static inline void LoadConfig (void) { short n; FILE *f; f = fopen (cfgname, "rb"); // we must check to see if we opened the file successfully if (f) { //Reads stuff n = fread_fast (&gg->cfg, sizeof (Config), 1, f); fclose (f); } /* else { //Error, oh well }*/ } static inline void SaveConfig (void) { FILE *f; if (checkArchived(SYMSTR(cfgname))) return; f = fopen (cfgname, "wb"); // we must check to see if we opened the file successfully if (f) { //Writes stuff fwrite_fast (&gg->cfg, sizeof (Config), 1, f); fwrite_fast (suffix,sizeof(char),7,f); } /*else { //Error, oh well }*/ } static inline void TransparentAutoSaveBeginning(void) { register GameGlobals *ggg asm("a4") = gg; short a; memcpy(&ggg->load_data->beginning.player,&ggg->player,sizeof(Player)); ggg->load_data->beginning.current_level = ggg->current_level; memcpy(ggg->load_data->beginning.WeaponsValid,WeaponsValid,WEAPON_COUNT); for(a=0;aload_data->beginning.ammo[a] = weapons[a].ammo; } ggg->load_data->beginning.cur_weapon = ggg->cur_weapon; ggg->beginningSaveIsLoaded = TRUE; } static inline void TransparentAutoSave(void) { register GameGlobals *ggg asm("a4") = gg; FILE *f; SYM_STR name = SYMSTR(savename); short archiveSave = checkArchived(name); if(archiveSave) if(!EM_moveSymFromExtMem(name,HS_NULL)) return; //Quit if error f = fopen(savename,"wb"); if(!f) return; fwrite_fast(ggg->load_data,sizeof(LSdata),1,f); fwrite_fast(suffix,sizeof(char),7,f); fclose(f); if(archiveSave) { //IMPORTANT: If you don't check if there's room in Flash //ROM for the file, a garbage collection box could come //up, which apparently crashes the program. if(!EM_findEmptySlot(9077)) EM_GC(FALSE); //Even though we did run a garbage collection, make sure //that there's room in Flash ROM now. if(EM_findEmptySlot(9077)) EM_moveSymToExtMem(name,HS_NULL); } } static inline void copyDoorsNF(PartialDoor *dest, FATDOOR *src, short c) { short a; for(a=0;aposition = src->position; dest->state = src->state; } } static inline void copyDoorsFN(FATDOOR *dest, PartialDoor *src, short c) { short a; for(a=0;aposition = src->position; dest->state = src->state; } } static inline void TransparentAutoSaveMid(void) { register GameGlobals *ggg asm("a4") = gg; short a; memcpy(&ggg->load_data->mid.player,&ggg->player,sizeof(Player)); memcpy(ggg->load_data->mid.WeaponsValid,WeaponsValid,WEAPON_COUNT); for(a=0;aload_data->mid.ammo[a] = weapons[a].ammo; } ggg->load_data->mid.cur_weapon = ggg->cur_weapon; copyDoorsNF(ggg->load_data->mid.doors,FAT_GetDoorsArray(),ggg->doorcount); memcpy(ggg->load_data->mid.buttons,ggg->button,ggg->buttoncount*sizeof(Button)); memcpy(ggg->load_data->mid.button_data,ggg->button_data,sizeof(ButtonInfo)*ggg->buttoncount); memcpy(ggg->load_data->mid.sprites,ggg->sprites,sizeof(FATSPRITE)*ggg->sprite_count); memcpy(ggg->load_data->mid.sprites_extra,ggg->sprites_extra,sizeof(SpriteStruct)*ggg->sprite_count); memcpy(ggg->load_data->mid.map,fc->map_data,fc->map_width*fc->map_height); memcpy(&ggg->load_data->mid.lights,&ggg->lights,32); ggg->load_data->mid.cam_xpos = fc->cam_xpos; ggg->load_data->mid.cam_ypos = fc->cam_ypos; ggg->load_data->mid.cam_orientation = fc->cam_orientation; memcpy(ggg->load_data->mid.projectiles,ggg->projectiles,sizeof(ProjectileStruct)*MAX_PROJECTILES); memcpy(ggg->load_data->mid.doortimers,ggg->doortimers,ggg->doorcount*sizeof(short)); ggg->midSaveIsLoaded = TRUE; } static inline void TransparentAutoLoad(void) { register GameGlobals *ggg asm("a4") = gg; FILE *f = fopen(savename,"rb"); if(f) { fread_fast(ggg->load_data,sizeof(LSdata),1,f); ggg->current_level = ggg->load_data->mid.current_level; ggg->loadmid = TRUE; ggg->midSaveIsLoaded = TRUE; ggg->beginningSaveIsLoaded = TRUE; fclose(f); } } static inline void TransparentAutoRefreshBeginning(void) { register GameGlobals *ggg asm("a4") = gg; short a; memcpy(&ggg->player,&(ggg->load_data->beginning.player),sizeof(Player)); memcpy(WeaponsValid,ggg->load_data->beginning.WeaponsValid,WEAPON_COUNT); for(a=0;aload_data->beginning.ammo[a]; } ResetWeaponArea(); ggg->cur_weapon = ggg->load_data->beginning.cur_weapon; current_weapon = &weapons[ggg->cur_weapon]; ggg->current_level = ggg->load_data->beginning.current_level; if(ggg->levelstyle==level_vehicle) DrawVehicle(); else DrawWeapon(ggg->cur_weapon,W_OFF); } static inline void TransparentAutoRefreshMid(void) { register GameGlobals *ggg asm("a4") = gg; short a; memcpy(&ggg->player,&(ggg->load_data->mid.player),sizeof(Player)); memcpy(WeaponsValid,ggg->load_data->mid.WeaponsValid,WEAPON_COUNT); for(a=0;aload_data->mid.ammo[a]; } ResetWeaponArea(); ggg->cur_weapon = ggg->load_data->mid.cur_weapon; current_weapon = &weapons[ggg->cur_weapon]; copyDoorsFN(FAT_GetDoorsArray(),ggg->load_data->mid.doors,ggg->doorcount); memcpy(ggg->button,ggg->load_data->mid.buttons,ggg->buttoncount*sizeof(Button)); memcpy(ggg->button_data,ggg->load_data->mid.button_data,sizeof(ButtonInfo)*ggg->buttoncount); memcpy(&ggg->lights,&ggg->load_data->mid.lights,32); memcpy(ggg->sprites,ggg->load_data->mid.sprites,sizeof(FATSPRITE)*ggg->sprite_count); memcpy(ggg->sprites_extra,ggg->load_data->mid.sprites_extra,sizeof(SpriteStruct)*ggg->sprite_count); memcpy(fc->map_data,ggg->load_data->mid.map,fc->map_width*fc->map_height); fc->cam_xpos = ggg->load_data->mid.cam_xpos; fc->cam_ypos = ggg->load_data->mid.cam_ypos; fc->cam_orientation = ggg->load_data->mid.cam_orientation; memcpy(ggg->projectiles,ggg->load_data->mid.projectiles,sizeof(ProjectileStruct)*MAX_PROJECTILES); memcpy(ggg->doortimers,ggg->load_data->mid.doortimers,MAX_DOORS*sizeof(short)); if(ggg->levelstyle==level_vehicle) DrawVehicle(); else DrawWeapon(ggg->cur_weapon,W_OFF); } void Fix3(char *buffer, short value) { buffer[3] = 0; if(value == -1) strcpy(buffer,"---"); else { buffer[2] = '0' + value % 10; buffer[1] = '0' + (value/10) % 10; buffer[0] = '0' + (value/100) % 10; } } /* static inline void copySprite(FATSPRITE *dest, FATSPRITE *src) { asm volatile (" movem.l (%0),%%d1-%%d7/%%a2-%%a5; movem.l %%d1-%%d7/%%a2-%%a5,(%1); " : "=a" (src), "=a" (dest) : "0" (src), "1" (dest) :"a2","a3","a4","a5","d1","d2","d3","d4","d5","d6","d7" ); } */ //============================================================================= // VTI detection routine (thanx, Julien Muchembled) // // this routine utilizes a bug in VTI: you can set even non-existing flags in // the status register and query them later! //============================================================================= //extern short IsVTI(void); asm(" .even IsVTI: trap #12 /* enter supervisor mode. returns old (%sr) in %d0.w */ move.w #0x3000,%sr /* set a non-existing flag in %sr (but keep s-flag !!) */ swap %d0 /* save %d0.w content in upper part of %d0 */ move.w %sr,%d0 /* get %sr content and check for non-existing flag */ btst #12,%d0 /* this non-existing flag can only be set on the VTI */ bne __VTI swap %d0 /* restore old %sr content and return 0 */ move.w %d0,%sr moveq #0,%d0 rts __VTI: swap %d0 /* restore old %sr content and return 1 */ move.w %d0,%sr moveq #1,%d0 rts "); static inline short ResetProgress(void) { register GameGlobals *ggg asm("a4") = gg; SYM_STR name = SYMSTR(savename); if(SymFind(name).folder) { if(checkArchived(name)) { if(!EM_moveSymFromExtMem(name,HS_NULL)) return 1; //Error 1 } if(!SymDel(name)) return 2; //Error 2 } /*ggg->loadmid = FALSE; ggg->loadbeginning = FALSE; ggg->beginningSaveIsLoaded = FALSE; ggg->midSaveIsLoaded = FALSE;*/ // is equivalent to *(long*)&(ggg->loadbeginning) = 0L; ggg->current_level = STARTLEVEL; ggg->player.life = STARTHEALTH; ggg->player.armor = STARTARMOR; ResetWeapons(); current_weapon = &weapons[ggg->cur_weapon]; ResetWeaponArea(); return 0; } static inline void PromptToResetProgress(void) { //register GameGlobals *ggg asm("a4") = gg; short c = getNrLines(gg->text,resetWarn); short i = 0; //short err = 0; BlackGrayScreen(); FAT_AllKeysReleased(); for(i=0;itextbuf,"(%i)",err); DrawGrayStrExt(0,92,ggg->textbuf, A_REVERSE|A_CENTERED|A_SHADOWED,F_6x8);*/ FAT_AllKeysReleased(); FAT_WaitKeyPressed(); } FAT_AllKeysReleased(); } /* #define CheckForNonfatalMem() \ {\ if(quitting == E2Q(OBLIVION_NONFATAL_MEM))\ {\ BlackGrayScreen();\ DrawGrayStrExt(0,46,(char*)OblivionErrorStrings[OBLIVION_NONFATAL_MEM],\ A_REVERSE|A_CENTERED,F_6x8);\ DrawGrayStrExt(0,60,(char*)"(Cannot show Intro)",\ A_REVERSE|A_CENTERED,F_6x8);\ DrawGrayStrExt(0,70,(char*)"Free More RAM.",A_REVERSE|A_CENTERED,F_4x6);\ DrawGrayStrExt(0,80,(char*)"Wait...",A_REVERSE|A_CENTERED,F_4x6);\ waitMsec(3500);\ quitting = FALSE;\ }\ } */ #define SetGlobalPointers()\ {gg->sprites_s = _sprites_s;\ gg->projectilemodels = _projectilemodels;\ gg->enemysprites = _enemysprites;\ gg->sprites = _sprites;\ gg->sprites_extra = _sprites_extra;\ gg->projectiles = _projectiles;\ } /* #define ResetGlobalPointers()\ {ggg->sprites_s = NULL;\ ggg->projectilemodels = NULL;\ ggg->enemysprites = NULL;\ ggg->sprites = NULL;\ ggg->sprites_extra = NULL;\ ggg->projectiles = NULL;\ }*/ //============================================================================= // our Predraw callback which simulates the fade-in-the-distance effect by // modifying the textures used to render the view (if lights are off) //============================================================================= void Predraw_LightEffects(FATCONFIG* fc,DEPTHDATA* dd) { register GameGlobals *ggg asm("a4") = gg; short i; register const long val = 0xffffffffL; if(ggg->lights==LIGHTS_ON) { return; } fc = fc; // just to make the compiler happy. otherwise it will complain // about the unused parameter fc //0-100: nothing //101-200: light //201-300: dark //301+: black for (i=0;idistance[i] < 101) continue; if (dd->distance[i] < 201) { dd->lightdata[i<<1] = val; dd->lightdata[(i<<1)+1] = val; } else if (dd->distance[i] < 301) { dd->darkdata[i<<1] = val; dd->darkdata[(i<<1)+1] = val; } else { dd->lightdata[i<<1] = val; dd->lightdata[(i<<1)+1] = val; dd->darkdata[i<<1] = val; dd->darkdata[(i<<1)+1] = val; } } } void PreHUDCallback (FATCONFIG *fc,unsigned short *p0,unsigned short *p1) { register GameGlobals *ggg asm("a4") = gg; short i; register unsigned short *_p0,*_p1; if (ggg->invert) { _p0=p0;_p1=p1; for (i = 6 * 96; i--;) { *_p0 = ~*_p0, *_p1 = ~*_p1; _p0++, _p1++; } ggg->invert--; } fc = fc; // to make the compiler happy ... } #endif