/*********************************** Sandstorm SPRITE.C ************************************/ /**** INCLUDES ****/ #include #include "main.h" #include "graphics.h" #include "pad.h" #include "control.h" #include "debug.h" #include "sprite.h" #include "collide.h" #include "fire.h" #include "ai.h" #include "cdread.h" #include "sound.h" /**** GLOBALS ****/ int spottimer[9]; //for recharching items after time period /**** DRAW_3DSPRITE ****/ void draw_3dsprite (GsSPRITE *sprite,VECTOR spritePosition,int scale) { // The spritePosition is the point in 3D space (world coords) that your sprite lies at. VECTOR transformedPosition; extern MATRIX GsWSMATRIX; ApplyMatrixLV(&GsWSMATRIX,&spritePosition,&transformedPosition); transformedPosition.vx += GsWSMATRIX.t[0]; transformedPosition.vy += GsWSMATRIX.t[1]; transformedPosition.vz += GsWSMATRIX.t[2]; // Only draw sprite if it's in front of the camera. if ( transformedPosition.vz>5 ){ // Scales the sprite according to the distance. sprite->scalex = sprite->scaley = ((ONE/scale) << 12) / transformedPosition.vz; sprite->x = transformedPosition.vx * PROJ / transformedPosition.vz; sprite->y = transformedPosition.vy * PROJ / transformedPosition.vz; GsSortSprite(sprite,&wot[out_buf],transformedPosition.vz >> (14-OTLENGTH)); //14-OTLENGTH } } //end draw_3dsprite /**** INITSPRITE ****/ void InitSprite( GsSPRITE *sprite, u_long attribute, short x, short y, u_short w, u_short h, u_short tpage, u_char u, u_char v, short cx, short cy, u_char r, u_char g, u_char b, short mx, short my, short scalex, short scaley, long rotate ) { sprite->attribute = attribute; sprite->x = x; sprite->y = y; sprite->w = w; sprite->h = h; sprite->tpage = tpage; sprite->u = u; sprite->v = v; sprite->cx = cx; sprite->cy = cy;; sprite->r = r; sprite->g = g; sprite->b = b; sprite->mx = mx; sprite->my = my; sprite->scalex = scalex; sprite->scaley = scaley; sprite->rotate = rotate; }//end InitSprite /**** SCROLLBG ****/ void ScrollBG( void ) { static int scroll=0; static int speed=1; if(gamemode==1) speed=10; else speed=1; scroll-=speed; if(scroll<-(480)) scroll=-160; leftbg.x=scroll; //draw only if gamemode==2 if(gamemode==2) { GsSortFastSprite( &leftbg, &wot[out_buf], 255 ); } rightbg.x=scroll+(BGWIDTH/2); if(gamemode==2) { GsSortFastSprite( &rightbg, &wot[out_buf], 255 ); } //each bg sprite is being registered into the OT twice for wrap-around effect leftbg.x=scroll+(BGWIDTH); if(gamemode==2) { GsSortFastSprite( &leftbg, &wot[out_buf], 255 ); } //same as above comment rightbg.x=scroll+BGWIDTH+(BGWIDTH/2); if(gamemode==2) { GsSortFastSprite( &rightbg, &wot[out_buf], 255 ); } } //end ScrollBG /**** INITOBJECT2D ****/ void InitObject2D( u_long *addr, GsSPRITE *sprite, u_long attribute, int x, int y, u_short w, u_short h, u_char u, u_char v ) { GsIMAGE *image; u_short tpage; image=InitTex((u_long*)addr); tpage=GetTPage(1,0,image->px, image->py); InitSprite( sprite, attribute, x, y, w, h, tpage, u, v, image->cx, image->cy, 0x80, 0x80, 0x80, 0, 0, ONE, ONE, 0 ); } //end INITOBJECT2D /**** INITBOX ****/ void InitBox( GsBOXF *box, u_long attribute, short x, short y, short w, short h, u_char r, u_char g, u_char b ) { box->attribute=attribute; box->x=x; box->y=y; box->w=w; box->h=h; box->r=r; box->g=g; box->b=b; } //end InitBox /**** RENDERFLARE ****/ void RenderFlare( GsBOXF *flare, int lx, int ly, short cx, short cy, short pos ) { //do effect only if the sun is visible onscreen if(lx>-161 && lx<161 && ly>-121 && ly<121) { int xdiff=lx-cx; int ydiff=ly-cy; flare->x=(xdiff/4)*pos; flare->y=(ydiff/4)*pos; //send to OT GsSortBoxFill( flare, &wot[out_buf], 0 ); } } //end RenderFlare /**** MANAGEITEMS ****/ void ManageItems( void ) { int x; //working variable int timer; timer++; for(x=0; x<10; x++) { if(spot[x]==0) //if the spot is empty... { if(spottimer[x]>=timelimit[x]) //and if time has passed { spot[x]=1; //restore item spottimer[x]=0; } } if(spot[x]==0) spottimer[x]++; //increment item timers when not visible } } /**** PICKUPITEM ****/ //note: number of wins are displayed also in this function void PickUpItem( void ) { static int pickup_c; //counter static int pickup; if(pickup>0) pickup_c++; if(pickup_c>99) { pickup_c=0; pickup=0; } if(pickup==1) FntPrint("\n~c009Item Pickup\t\t\t~c111%d Wins", wincount); //display pickup message else FntPrint("\n\t\t\t\t\t ~c111%d Wins", wincount); //pick up upg if(CheckCollisionItem(&truck[0].coord, greencar.radius, &upg_ico_pos, item.radius)==1) { pickup=1; if( spot[0]==1 ) { if(p1items.upg<81) p1items.upg+=20; } spot[0]=0; } //pick up mine if(CheckCollisionItem(&truck[0].coord, greencar.radius, &mine_ico_pos, item.radius)==1) { pickup=1; if( spot[1]==1 ) { if(p1items.minex=(((truck[1].coord.coord.t[2]*-147)/2742)/4)-107; box1->y=(((truck[1].coord.coord.t[0]*-109)/2988)/4)-80; box2->x=(((truck[2].coord.coord.t[2]*-147)/2742)/4)-107; box2->y=(((truck[2].coord.coord.t[0]*-109)/2988)/4)-80; } /**** DRAWENEMYHEALTH ****/ void DrawEnemyHealth( GsCOORDINATE2 *fromobj, GsBOXF *box, GsCOORDINATE2 *obj ) { VECTOR transformedPosition; VECTOR position; extern MATRIX GsWSMATRIX; position.vx=obj->coord.t[0]; position.vy=obj->coord.t[1]-100; position.vz=obj->coord.t[2]; ApplyMatrixLV(&GsWSMATRIX,&position,&transformedPosition); transformedPosition.vx += GsWSMATRIX.t[0]; transformedPosition.vy += GsWSMATRIX.t[1]; transformedPosition.vz += GsWSMATRIX.t[2]; // Only draw sprite if it's in front of the camera. if ( transformedPosition.vz>0 ){ box->x = transformedPosition.vx * PROJ / transformedPosition.vz; box->y = transformedPosition.vy * PROJ / transformedPosition.vz; //draw if you are within 900 units X and Z from the enemy if((fromobj->coord.t[0]<(obj->coord.t[0]+700)) && (fromobj->coord.t[0]>(obj->coord.t[0]-700)) && (fromobj->coord.t[2]<(obj->coord.t[2]+700)) && (fromobj->coord.t[2]>(obj->coord.t[2]-700)) ) { GsSortBoxFill(box,&wot[out_buf],transformedPosition.vz >> (14-OTLENGTH)); //14-OTLENGTH } } } //end DRAWENEMYHEALTH