#include #include #include #include #include #include "biglut1.h" #include "cntrl.h" #define SCREEN_MODE MODE_PAL #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 256 #define OT_LENGTH 4 #define PACKETMAX (sizeof(GsSPRITE)*640) /* Max GPU packets */ #define PI 3.14159265358979323846 #define TRUE 1 #define FALSE 0 static PACKET packetArea[4][PACKETMAX]; /* GPU PACKETS AREA */ static GsOT Wot[2]; static GsOT_TAG wtags[2][1<ANGLE_360) view_angle=ANGLE_0; dx=0;dy=0; if(PAD_PRESS(buffer1,PAD_UP)) { dx=(int)(cos_lut[view_angle])<<1; dy=(int)(sin_lut[view_angle])<<1; } if(PAD_PRESS(buffer1,PAD_DOWN)) { dx=(int)(-cos_lut[view_angle])<<1; dy=(int)(-sin_lut[view_angle])<<1; } x+=dx; y+=dy; x_cell = x/CELL_X_SIZE; y_cell = y/CELL_Y_SIZE; x_sub_cell = x % CELL_X_SIZE; y_sub_cell = y % CELL_Y_SIZE; if (dx>0 ) { if ( (world[y_cell][x_cell+1] != 0) && (x_sub_cell > (CELL_X_SIZE-OVERBOARD ) ) ) { x-= (x_sub_cell-(CELL_X_SIZE-OVERBOARD )); } } else { if ( (world[y_cell][x_cell-1] != 0) && (x_sub_cell < (OVERBOARD) ) ) { x+= (OVERBOARD-x_sub_cell) ; } } if (dy>0 ) { if ( (world[(y_cell+1)][x_cell] != 0) && (y_sub_cell > (CELL_Y_SIZE-OVERBOARD ) ) ) { y-= (y_sub_cell-(CELL_Y_SIZE-OVERBOARD )); } } else { if ( (world[(y_cell-1)][x_cell] != 0) && (y_sub_cell < (OVERBOARD) ) ) { y+= (OVERBOARD-y_sub_cell); } } Ray_Caster(x,y,view_angle); GsSortBoxFill(&BOX,&Wot[side],10); DrawSync(0); hsync = VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&Wot[side]); GsDrawOt(&Wot[side]); } } void do_movement(void) { /* if(PAD_PRESS(buffer1,PAD_RIGHT)) if ((view_angle-=ANGLE_6)ANGLE_360) view_angle=ANGLE_0; if(PAD_PRESS(buffer1,PAD_UP)) { dx=cos(6.28*view_angle/ANGLE_360)*10; dy=sin(6.28*view_angle/ANGLE_360)*10; } if(PAD_PRESS(buffer1,PAD_DOWN)) { dx=-cos(6.28*view_angle/ANGLE_360)*10; dy=-sin(6.28*view_angle/ANGLE_360)*10; } x+=dx; y+=dy;*/ } void cleanup(void) { ResetGraph(3); } GsLINE LINE; void Ray_Caster(long x,long y,long view_angle) { int xray=0, yray=0, next_y_cell, next_x_cell, cell_x, cell_y, x_bound, y_bound, xb_save, yb_save, x_delta, y_delta, ray, casting=2, x_hit_type, y_hit_type, top, bottom, xi_save=0, yi_save=0, dist_x=0, dist_y=0, scale; float xi, yi; int max_shade_sub=0; if ( (view_angle-=ANGLE_30) < 0) { view_angle=ANGLE_360 + view_angle; } for (ray=0; ray<320; ray++) { if (view_angle >= ANGLE_0 && view_angle < ANGLE_180) { y_bound = (int)(CELL_Y_SIZE + (y & 0xffc0)); y_delta = CELL_Y_SIZE; xi = inv_tan_table[view_angle] * (y_bound - y) + x; next_y_cell = 0; } else { y_bound = (int)(y & 0xffc0); y_delta = -CELL_Y_SIZE; xi = inv_tan_table[view_angle] * (y_bound - y) + x; next_y_cell = -1; } if (view_angle < ANGLE_90 || view_angle >= ANGLE_270) { x_bound = (int)(CELL_X_SIZE + (x & 0xffc0)); x_delta = CELL_X_SIZE; yi = tan_table[view_angle] * (x_bound - x) + y; next_x_cell = 0; } else { x_bound = (int)(x & 0xffc0); x_delta = -CELL_X_SIZE; yi = tan_table[view_angle] * (x_bound - x) + y; next_x_cell = -1; } casting = 2; // two rays to cast simultaneously xray=yray = 0; // reset intersection flags while(casting) { if (xray!=INTERSECTION_FOUND) { cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP); cell_y = (int)yi; cell_y>>=CELL_Y_SIZE_FP; if ((x_hit_type = world[cell_y][cell_x])!=0) { dist_x = (int)((yi - y) * inv_sin_table[view_angle])>>7; yi_save = (int)yi; xb_save = x_bound; xray = INTERSECTION_FOUND; casting--; } else { yi += y_step[view_angle]; x_bound += x_delta; } } if (yray!=INTERSECTION_FOUND) { cell_x = xi; cell_x>>=CELL_X_SIZE_FP; cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP); if ((y_hit_type = world[cell_y][cell_x])!=0) { dist_y = (int)((xi - x) * inv_cos_table[view_angle])>>7; xi_save = (int)xi; yb_save = y_bound; yray = INTERSECTION_FOUND; casting--; } else { xi += x_step[view_angle]; y_bound += y_delta; } } } if (dist_x < dist_y) { scale = (int)(cos_table[ray]/dist_x)>>6; if(scale>320) scale=320; top = 128 - scale/2; if ( (bottom = top+scale) > 255) bottom=255; max_shade_sub=scale; if(max_shade_sub>112) max_shade_sub=112; if(x_hit_type==1) { texture1.x = ray; texture1.y = top; texture1.scaley = scale*16; texture1.u = (yi_save & 0x003f); texture1.r = 16+max_shade_sub; texture1.g = 16+max_shade_sub; texture1.b = 16+max_shade_sub; GsSortSprite (&texture1, &Wot[side], 1); } if(x_hit_type==2) { texture2.x = ray; texture2.y = top; texture2.scaley = scale*16; texture2.u = 64+(yi_save & 0x003f); texture2.r = 16+max_shade_sub; texture2.g = 16+max_shade_sub; texture2.b = 16+max_shade_sub; GsSortSprite (&texture2, &Wot[side], 1); } if(x_hit_type==3) { texture3.x = ray; texture3.y = top; texture3.scaley = scale*16; texture3.u = 128+(yi_save & 0x003f); texture1.r = 16+max_shade_sub; texture1.g = 16+max_shade_sub; texture1.b = 16+max_shade_sub; GsSortSprite (&texture3, &Wot[side], 1); } } else { scale = (int)(cos_table[ray]/dist_y)>>6; if(scale>320) scale=320; top = 128 - scale/2; if ( (bottom = top+scale) > 255) bottom=255; max_shade_sub=scale; if(max_shade_sub>112) max_shade_sub=112; if(y_hit_type==1) { texture1.x = ray; texture1.y = top; texture1.scaley = scale*16; texture1.u = (xi_save & 0x003f); texture1.r = 16+max_shade_sub; texture1.g = 16+max_shade_sub; texture1.b = 16+max_shade_sub; GsSortSprite (&texture1, &Wot[side], 1); } if(y_hit_type==2) { texture2.x = ray; texture2.y = top; texture2.scaley = scale*16; texture2.u = 64+(xi_save & 0x003f); texture2.r = 16+max_shade_sub; texture2.g = 16+max_shade_sub; texture2.b = 16+max_shade_sub; GsSortSprite (&texture2, &Wot[side], 1); } if(y_hit_type==3) { texture3.x = ray; texture3.y = top; texture3.scaley = scale*16; texture3.u = 128+(xi_save & 0x003f); texture3.r = 16+max_shade_sub; texture3.g = 16+max_shade_sub; texture3.b = 16+max_shade_sub; GsSortSprite (&texture3, &Wot[side], 1); } } if (++view_angle>=ANGLE_360) { view_angle=0; } } } 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 = 0;//tSprite->w/2; // set handle of sprite to the center tSprite->my = 0;//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 };