// Demo Recorder Save Utility for Gravitation v1.3DR, with MetroWerks' // CodeWarrior. Only needed for those who cannot use the SIOCONS // batch files "savepal" or "saventsc" with Grav v1.3DR to save their // demos to a PC file // // *** PAL by default, but press CROSS to change to NTSC upon startup *** // // // Having created your records in Grav V1.3DR (DemoRecorder version) // quit to the brick comms screen and then run "CW_DSAVE" to save // your PAL or NTSC replays as "MYPAL.DAT" or "MYNTSC.DAT" // respectively, using the on-screen menu. // // Made possible with help from Andreas Weissl and Dennis Brinkhuis // For the CodeWarrior-specific code and testing. // // Jim 9th Oct 1998 // ----------------------------------------- // James Shaughnessy james@manc.u-net.com // http://www.netyaroze-europe.com/~shaughnj // ----------------------------------------- #include #include // for file I/O stuff #include #include "pad.h" #include <__rts_info_t__.h> // just do it for Metrowerks #define YOFFS (32) // Y offset #define OT_LENGTH (1) // Global Variables // Two Ordering Tables, one for each buffer GsOT WorldOT[2]; // Two Ordering Table Tags, one for each buffer GsOT_TAG OTTag[2][1< 20 && (!(timer%5))) padStatus2 = padStatus; activeBuff = GsGetActiveBuff(); // Set packet work base GsSetWorkBase((PACKET *)GpuPacketArea[activeBuff]); // Clear the Ordering Table GsClearOt(0, 0, &WorldOT[activeBuff]); // Pad up/down moves menuitem if (padStatus2 & PADup) if (menuitem > 0) menuitem--; else menuitem = 3; if (padStatus2 & PADdown) if (menuitem < 3) menuitem++; else menuitem = 0; FntPrint("CW_DSAVE v1.0 - CodeWarrior Demo\nSave Utility for Grav v1.3DR\n\n\n\n"); if (GetVideoMode()) FntPrint("Video Mode: PAL\n\n\n"); else FntPrint("Video Mode: NTSC\n\n\n"); FntPrint("Save PAL Replays -> MYPAL.DAT\n\n"); FntPrint("Save NTSC Replays -> MYNTSC.DAT\n\n\n"); FntPrint("Quit\n\n\n"); switch (menuitem) { case 0 : boxf.y = YOFFS + 54; break; case 1 : boxf.y = YOFFS + 78; break; case 2 : boxf.y = YOFFS + 94; break; case 3 : boxf.y = YOFFS + 118; break; default : break; } if (padStatus2 & PADcross) { switch (menuitem) { case 0 : VidModeChange(); break; case 1 : SaveRecordToHost(MODE_PAL); FntPrint("Saving MYPAL.DAT ..."); pause = 1; break; case 2 : SaveRecordToHost(MODE_NTSC); FntPrint("Saving MYNTSC.DAT ..."); pause = 1; break; case 3 : quit = 1; break; default : break; } } FntFlush(-1); GsSortBoxFill(&boxf, &WorldOT[activeBuff], 0); // Wait for end of drawing, a vertical blank then swap buffers DrawSync(0); VSync(0); GsSwapDispBuff(); if (pause) Pause(); // Register Clear in OT GsSortClear(0, 0, 0, &WorldOT[activeBuff]); // Draw the Ordering Table GsDrawOt(&WorldOT[activeBuff]); timer++; } ResetGraph(0); } // Initialises Video and the Frame Buffer // using double buffers at 0,0 and 384,0 so as not to corrupt // any graphics in Gravitation, allowing "QUICK" reruns void InitGraphics() { int i; SetVideoMode(MODE_PAL); GsInitGraph(320, 240, GsOFSGPU|GsNONINTER, 0, 0); GsDefDispBuff(0, 0, 384, 0); // Init Ordering Tables for (i = 0; i < 2; i++) { WorldOT[i].length = OT_LENGTH; WorldOT[i].org = OTTag[i]; GsClearOt(0, 0, &WorldOT[i]); } // Loads the font into Frame Buffer FntLoad(960, 256); // Font printing location FntOpen(32, 16 + YOFFS, 280, 224 - YOFFS, 0, 256); } // Toggle PAL / NTSC void VidModeChange() { SetVideoMode(1-GetVideoMode()); GsInitGraph(320, 240, GsOFSGPU|GsNONINTER, 0, 0); GsDefDispBuff(0, 0, 384, 0); } // Pause for a second void Pause() { int i; for (i=0; i<50; i++) VSync(0); pause = 0; } // Saves memory block to host in MetroWerks CodeWarrior void SaveRecordToHost(char mode) { int fd; int bytes; char *filename1 = "mypal.dat"; char *filename2 = "myntsc.dat"; void *data; if (mode == MODE_PAL) { data = (void *)(0x80196000); fd = MWopen(filename1, O_WRONLY|O_CREAT); // overwrites files with the same name // assert(fd > 0); bytes = MWwrite(fd, data, 0x12000); // assert (bytes == 0x12000); MWclose(fd); } else { data = (void *)(0x80184000); fd = MWopen(filename2, O_WRONLY|O_CREAT); // overwrites files with the same name // assert(fd > 0); bytes = MWwrite(fd, data, 0x12000); // assert (bytes == 0x12000); MWclose(fd); } } void DoInitHeap(void) { // heap starts after the main program on a 16-byte boundary u_long lclHeapStart=(_end & 0xFFFFFFF0L)+0x10; // heap extends to the bottom of the stack. u_long lclHeapSize=((_stack_addr-(_stack_size<<10)) & 0xFFFFFFF0L)-lclHeapStart; InitHeap((unsigned long *)lclHeapStart, lclHeapSize); } // ****** PAD routines ****** // call once only in program initialisation void PadInit (void) { GetPadBuf(&bb0, &bb1); } // call once per VSync(0) // puts controller pad status into unsigned long integer // please refer to the manuals if you want explanation // of the internals of this function u_long PadRead(void) { return(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); }