// *********************************************************************************** // Programs written by R.Swan - rs108@mdx.ac.uk - www.netyaroze-europe.com/~middex2 // Code for displaying a sprite // The code for handling the joypad (InitialisePad and ReadPad) are in PAD.C // The #defines for analysing the joypad output are in PAD.H // *********************************************************************************** // *********************************************************************************** // Preprocessor functions // *********************************************************************************** // **** include files #include // include standard Yaroze lib #include "pad.c" // normally the joypad handling // routine would be compiled as a // seperate .o file, but to make // the makefile simpler the code is // included here. (As it never changes // there should be no problem) // **** definitions #define SpriteAdd (0x80090000) // location of TIM in main memory #define SCREEN_WIDTH (320) #define SCREEN_HEIGHT (240) #define OTABLE_LENGTH (1) // define length of OTable #define MAX_PACKETS (128000) // guess at length for scratchpad // **** create global variables, structures, headers and arrays (mostly system stuff) static GsOT OTable_Header[2]; // Header files holding OTable info static GsOT_TAG OTable_Array[2][1< 0) GameRunning = 0; // if any thing happens, set to quit FntPrint(FntOne, "DISPLAYING 256 COLOUR SPRITE"); // output a standard font message TestSprite.rotate = (TestSprite.rotate+ONE) % (ONE*360); // rotate sprite (purely to prove // sprite is constantly updating) RenderWorld(); // draw the screen }; }; // *********************************************************************************** // Function definitions // *********************************************************************************** // **** Setup up screen void InitialiseScreen() { SetVideoMode(MODE_PAL); // define screen as PAL GsInitGraph(SCREEN_WIDTH, SCREEN_HEIGHT, GsOFSGPU, 1, 0); // define screen resolution, whether // interlaced, dithered & colour depth GsDefDispBuff(0, 0, 0, SCREEN_HEIGHT); // define top left corners of // both screen buffers in memory OTable_Header[0].length = OTABLE_LENGTH; // notify OTable headers of OTable OTable_Header[1].length = OTABLE_LENGTH; // array lengths OTable_Header[0].org = OTable_Array[0]; // notify OTable headers of OTable OTable_Header[1].org = OTable_Array[1]; // array memory locations GsClearOt(0, 0, &OTable_Header[0]); // clear out OTable sorting info GsClearOt(0, 0, &OTable_Header[1]); // ready for use (not strictly necessary) }; // **** This function transfers a .TIM form main memory to video memory void LoadTIMData(u_long tMemAddress) { RECT tRect; // rectangular area to be used for TIM GsIMAGE tTim; // TIM image information tMemAddress += 4; // advance memory pointer to data GsGetTimInfo((u_long *) tMemAddress, &tTim); // fill tTim with info from TIM tRect.x = tTim.px; // tell GPU where graphics data is tRect.y = tTim.py; tRect.w = tTim.pw; tRect.h = tTim.ph; LoadImage(&tRect, tTim.pixel); // load video memory with TIM data tRect.x = tTim.cx; // tell GPU where colour table is tRect.y = tTim.cy; tRect.w = tTim.cw; tRect.h = tTim.ch; LoadImage(&tRect, tTim.clut); // load video memory with CLUT data DrawSync(0); // force LoadImages to complete }; // **** This sets up sprite information, such as x,y, what .TIM data to use etc. etc. void SetSpriteInfo(GsSPRITE *tSprite, u_long tMemAddress, long tX, long tY) { u_long tTexturePageX, tTexturePageY; // four variables to clear up u_long tTexturePageXOffset, tTexturePageYOffset; // assignment of texture pages GsIMAGE tTim; // TIM image information u_long tCLUT; tMemAddress += 4; // advance memory pointer to data GsGetTimInfo((u_long *) tMemAddress, &tTim); // fill tTim with info from TIM tSprite->x = tX; // set sprites screen coordinates tSprite->y = tY; // based on values passed if (tTim.pmode& 0x01) { tSprite->attribute = (1<<24); // set up for 256 colour sprite tSprite->w = tTim.pw*2; tCLUT = 1; } else { tSprite->attribute = 0; // set up for 16 colour sprite tSprite->w = tTim.pw*4; tCLUT = 0; }; tSprite->h = tTim.ph; tTexturePageX = (tTim.px/64) *64; // calculate texture page tTexturePageY = (tTim.py/256) *256; tTexturePageXOffset = tTim.px % 64; tTexturePageYOffset = tTim.py % 256; tSprite->tpage = GetTPage(tCLUT, 0, tTim.px, tTim.py); // calculate correct texture page tSprite->u = tTexturePageXOffset*4; // offset for sprite from left of tpage tSprite->v = tTexturePageYOffset; // offset for sprite from top of tpage tSprite->cx = tTim.cx; // set sprite to use correct CLUT tSprite->cy = tTim.cy; tSprite->r = tSprite->g = tSprite->b = 128; // make sure the sprite is set to // normal colour intensity tSprite->mx = tSprite->w/2; // set handle of sprite to the center tSprite->my = tSprite->h/2; // (this does not need to be done if // you would rather move the objects // by their top left corner) tSprite->scalex = tSprite->scaley = ONE; // make sure the sprite isn't scaled tSprite->rotate = 0; // make sure its pointing up }; // *********************************************************************************** // Screen drawing routine. Sets up ordering table, and holds commands for which // sprites to b drawn, etc. // *********************************************************************************** // **** Draw all the screen void RenderWorld() { u_long currentBuffer = GsGetActiveBuff(); // determine which buffer is to be used GsClearOt(0, 0, &OTable_Header[currentBuffer]); // clear out OTable sorting info GsSetWorkBase((PACKET*)Packet_Memory[currentBuffer]); // set scratchpad area for the OT GsSortSprite( &TestSprite, &OTable_Header[currentBuffer], 0); // send request to draw sprite to the // ordering table // **** REAL DRAWING STUFF DrawSync(0); // wait for completion of all output VSync(0); // wait for blank and time it GsSwapDispBuff(); // swap buffer information GsSortClear(31, 0, 31, &OTable_Header[currentBuffer]); // send a request to clear the screen // to the ordering table GsDrawOt(&OTable_Header[currentBuffer]); // draw commands in queue FntFlush(FntOne); // output any text onto the screen };