/* */ // this define allows the player to move the viewpoint freely #define ALLOW_VIEWPOINT_MOVE 1 /* these are the predefined viewpoints R1, R2, L1 & L2 change them if you want */ #define VD_1 2700 #define VH_1 2560 #define VD_2 960 #define VH_2 660 #define VD_3 2320 #define VH_3 800 #define VD_4 1400 #define VH_4 800 /**/ /************************************************************ * * Coneman! :) * - Automatisk generering av level fra 2d-map * - Kollisjons testing mot vegger * - Kan spise opp trekanter/stjerner * - Spøkelse-intelligens * - Kollisjonstesting mot spøkelser * ***********************************************************/ #include #include #include "pad.h" #include "libmath.h" #include "tmdtype.h" #define NUM_LIVES 2 #define NUM_LEVELS 13 #define SPEED_INC 0 #define PAL 1 #define GLIDE_FRAMES 80 #define SCREEN_WIDTH 320 #ifdef PAL #define SCREEN_HEIGHT 256 #else #define SCREEN_HEIGHT 240 #endif #define LEFT 0 #define RIGHT 1 #define UP 2 #define DOWN 3 //#define SOUND 1 #define COLLECT_SOUND 0 #define COLLECT_STAR_SOUND 1 #define DIE_SOUND 2 #define LEVEL_COMPLETE_SOUND 3 #define BACKGROUND_LOOP 4 #define SOUND_FX 1 #define MVOL 127 /* Main volume level*/ #define SVOL 64 //127 /* SEQ volume level*/ #define DFILE 3 /* File number*/ #ifdef SOUND_FX #define VHAddr (u_char *)0x800a4000 //cda00 //cda00 #define VBAddr (u_char *)0x800a6000 ///d0000 //d0320 /*#define VHAddr2 (u_char *)0x800a28ab //cda00 #define VBAddr2 (u_char *)0x800a34cb //d0320 */ #endif #ifdef SOUND #define VH_ADDR 0x80114000 #define VB_ADDR 0x80130990 #define SEQ_ADDR 0x80124000 typedef struct { char *fname; void *addr; CdlFILE finfo; } FILE_INFO; static FILE_INFO dfile[DFILE] = { {"\\DATA\\SOUND\\GOGO.SEQ;1", (void *)SEQ_ADDR, 0}, {"\\DATA\\SOUND\\STD0.VH;1", (void *)VH_ADDR, 0}, {"\\DATA\\SOUND\\STD0.VB;1", (void *)VB_ADDR, 0}, }; /* Sound related variables */ short vab, seq; #endif short progno; short wait; #define PACKETMAX2 (8000*24) /* Max GPU packets */ static PACKET packetArea[2][PACKETMAX2]; /* GPU PACKETS AREA */ #define OT_LENGTH 9 static GsOT Wot[2]; /* Handler of OT */ static GsOT_TAG wtags[2][1< 0); */ /* GsGetTimInfo((u_long *)TITLE_ADDR+1, &cone_title); LoadImage((RECT *)&cone_title.px, cone_title.pixel); */ //DrawSync(0); /* ny_count = 30; //60*5; do { _pad = PadRead(); side = GsGetActiveBuff(); GsSetWorkBase((PACKET*)packetArea[side]); GsClearOt(0,0,&Wot[side]); DrawSync(0); VSync(2); GsSwapDispBuff(); Bg.y = (1-side)*SCREEN_HEIGHT; LoadImage(&Bg, cone_title.pixel); DrawSync(0); GsDrawOt(&Wot[side]); ny_count--; } while (ny_count > 0); */ #endif // transfer vab #ifdef SOUND_FX #ifdef PRINTF printf("before bkvab"); #endif vab = SsVabTransfer( (u_char*)VHAddr, (u_char*)VBAddr, -1, 1 ); #ifdef PRINTF printf("after bkvab"); #endif if (vab < 0) { #ifdef PRINTF printf("SsVabTransfer failed (%d)\n", vab); #endif } if (vab >= 0) SsUtKeyOn(vab, BACKGROUND_LOOP, 0, 60, 0, 127, 127); // background noise // if (vab >= 0) SsUtKeyOn(vab, COLLECT_STAR_SOUND, 0, 60, 0, 100, 100); // background noise /* printf("before bkvab"); bkvab = SsVabTransfer( (u_char*)VHAddr2, (u_char*)VBAddr2, -1, 1 ); printf("after bkvab"); if (bkvab < 0) { printf("SsVabTransfer failed (%d)\n", vab); } if (bkvab >= 0) SsUtKeyOn(vab, 0, 0, 60, 0, 100, 100); // background noise */ #endif #ifdef TITLE_SCREEN /* GsGetTimInfo((u_long *)TITLE_ADDR+1, &cone_title); LoadImage((RECT *)&cone_title.px, cone_title.pixel); Bg.x = 0; Bg.y = 0; Bg.w = cone_title.pw*4; Bg.h = SCREEN_HEIGHT; //240; */ #endif for(;;) { #ifdef TITLE_SCREEN if ((lives == -1) && (gameoverwait == 0)) { blinkcount++; if (blinkcount == BLINK_COUNT*2) blinkcount = 0; _pad = PadRead(); if (_pad & PADstart && _pad & PADselect) break; if (_pad & PADstart) { lives = NUM_LIVES; //_ospeed = 48; currentlevel = 0; currenttexture = 0; LoadMapTextures(); invisible = 1*60; coneman.handler.attribute |= GsALON; } side = GsGetActiveBuff(); GsSetWorkBase((PACKET*)packetArea[side]); GsClearOt(0,0,&Wot[side]); /* GsSortSprite(&sprTitle1, &Wot[side], 4); GsSortSprite(&sprTitle2, &Wot[side], 5);*/ if (blinkcount < BLINK_COUNT) { GsSortSprite( &start, &Wot[side], 3); } DrawSync(0); VSync(0); GsSwapDispBuff(); Bg.y = (1-side)*SCREEN_HEIGHT; LoadImage(&Bg, cone_title.pixel); DrawSync(0); GsDrawOt(&Wot[side]); } else { #endif // levelcount++; // if (levelcount == 50) { // levelcount == 0; // ghostspeed += 10; // } /*if (playing == 0) { playing = 1; SsSetSerialVol(SS_CD,127,127); CdPlay(1,(int *) &tracks,0); printf("cdplay"); }*/ if (invisible > 0) invisible--; if (invisible == 1) { coneman.handler.attribute -= GsALON; speed = _ospeed + (currentlevel * SPEED_INC); } if (gameoverwait == 0) if (DealWithControllerPad() == 0) { /* copy screen to buffer */ /* Bg.y = (1-side)*SCREEN_HEIGHT; StoreImage(&Bg, title.pixel); //(u_long *) TITLE_ADDR); */ break; // quitting } /* collision detection */ if (abs(movement.vx) < abs(movement.vz)) { if (CheckCollisionX() == 0) conemanpos.vx += movement.vx; if (CheckCollisionY() == 0) conemanpos.vz += movement.vz; } else { if (CheckCollisionY() == 0) conemanpos.vz += movement.vz; if (CheckCollisionX() == 0) conemanpos.vx += movement.vx; } conemanpos.vy += movement.vy; EatBricks(); /* move view-reference point (follow object) */ view.vrx = conemanpos.vx; view.vry = conemanpos.vy; view.vrz = conemanpos.vz; /* if camera is in "follow" mode, set viewpoint */ if (cameraMode == 1) { headx = MySin(coneman.rotate.vy); headz = MyCos(coneman.rotate.vy); movement.vx = (((headx*dist)+0x200) >> 10); movement.vz = (((headz*dist)+0x200) >> 10); /* if glide, interpolate cameraposition towards the correct location */ if (glide != 0) { if (glide < 0) { /* tempx = (revglidex-glidex)/glide; view.vpx = glidex+=tempx; tempy = (revglidey-glidey)/glide; view.vpy = glidey+=tempy; tempz = (revglidez-glidez)/glide; view.vpz = glidez+=tempz;*/ tempx = (revglidex-glidex)/(-glide); view.vpx = glidex+=tempx; tempy = ((revglidey)-glidey)/(-glide); view.vpy = glidey+=tempy; tempz = (revglidez-glidez)/(-glide); view.vpz = glidez+=tempz; glide++; } else { tempx = (conemanpos.vx-movement.vx-glidex)/glide; view.vpx = glidex+=tempx; tempy = ((conemanpos.vy-height)-glidey)/glide; view.vpy = glidey+=tempy; tempz = (conemanpos.vz-movement.vz-glidez)/glide; view.vpz = glidez+=tempz; glide--; } // if glide < 0 } else { view.vpx = conemanpos.vx-movement.vx; view.vpy = conemanpos.vy-height; view.vpz = conemanpos.vz-movement.vz; } } /* reset movement vector */ movement.vx = 0; movement.vy = 0; movement.vz = 0; /* set viewpoint */ GsSetRefView2(&view); side = GsGetActiveBuff(); GsSetWorkBase((PACKET*)packetArea[side]); GsClearOt(0,0,&Wot[side]); GsClearOt(0,0,&groundot[side]); /* rotate star & strawberry */ straw.rotate.vy += ONE/64; if (straw.rotate.vy > ONE) straw.rotate.vy -= ONE; star.rotate.vy += ONE/128; if (star.rotate.vy == ONE) star.rotate.vy = 0; numstraws = 0; numstars = 0; /* draw all objects on level (strawberries, stars) */ for (mapz=0; mapz<24; mapz++) for (mapx=0; mapx<24; mapx++) switch (map[((mapz)*24)+mapx]) { case 5 : /* strawberry */ if (numstraws < MAXSTRAWS) { numstraws++; DrawObject(&straw, (mapx*200)-(xValue/2) + 200,0, ((((MAPSIZE-1)-mapz)*200) - (MAPSIZE_WORLD/2) + 200),side); } break; case 6 : /* star */ if (numstars < MAXSTARS) { numstars++; DrawObject(&star, (mapx*200)-(xValue/2) + 200,-150, ((((MAPSIZE-1)-mapz)*200) - (MAPSIZE_WORLD/2) + 200),side); } break; } if ((numstraws == 0) && (numstars == 0) && (gameoverwait == 0)) { gameoverwait = GLIDE_FRAMES; //60*3; /* set positions for glide... */ glide = -GLIDE_FRAMES; revglidex = 5000; revglidey = -4000; revglidez = 9000; glidex = conemanpos.vx; glidey = conemanpos.vy-height; glidez = conemanpos.vz; } /* if ((gameoverwait != 0) && (glide != 0)) { levelwalls.rotate.vy += (4096/GLIDE_FRAMES); levelfloor.rotate.vy += (4096/GLIDE_FRAMES); UpdateObjectCoordinates(&levelwalls.rotate, &levelwalls.coord); UpdateObjectCoordinates(&levelfloor.rotate, &levelfloor.coord); } */ /* draw map walls */ GsGetLs(&(levelwalls.coord), &tmpls); GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(levelwalls.handler), &Wot[side], 3, getScratchAddr(0)); /* draw map floor */ GsGetLs(&(levelfloor.coord), &tmpls); GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(levelfloor.handler), &groundot[side], 3, getScratchAddr(0)); /* GsGetLs(&(level.coord), &tmpls); GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(level.handler), &groundot[side], 3, getScratchAddr(0)); */ /* update player position, set rotation & draw */ DrawObject(&coneman,conemanpos.vx, conemanpos.vy, conemanpos.vz, side); /* draw ghost */ for (i=0; i= 200) { ghostcount[i] = 0; switch (ghostdir[i]) { case 0 : ghostmap[i*2]--; break; case 1 : ghostmap[i*2]++; break; case 2 : ghostmap[(i*2)+1]--; break; case 3 : ghostmap[(i*2)+1]++; break; case -1: break; } MoveGhost(i); } // ghostcount[i]+=GHOST_STEP; ghostcount[i]+=ghostspeed; //GHOST_STEP; gx = 0; gz = 0; switch (ghostdir[i]) { case 0 : gx = -ghostcount[i]; ghost[i].rotate.vy = (4096/4)*1; break; case 1 : gx = ghostcount[i]; ghost[i].rotate.vy = (4096/4)*3; break; case 2 : gz = ghostcount[i]; ghost[i].rotate.vy = (4096/4)*2; break; case 3 : gz = -ghostcount[i]; ghost[i].rotate.vy = 0; //4096/4; break; } ghostpos[i*2] =((ghostmap[i*2])*200)-(MAPSIZE_WORLD/2)+gx+200; ghostpos[(i*2)+1] = (((MAPSIZE-1)-(ghostmap[(i*2)+1]))*200)-(MAPSIZE_WORLD/2)+gz+200; if ( (abs(((ghostpos[i*2])-(conemanpos.vx))) < GHOST_DISTANCE) && (abs(((ghostpos[(i*2)+1])-(conemanpos.vz))) < GHOST_DISTANCE) && (invisible == 0)) { //if ((invisible == 0) && (ghost[i].alive == 1)) { #ifdef PRINTF printf("Eaten by ghost!\n"); #endif if (gameoverwait == 0) { #ifdef SOUND_FX PlayFX(DIE_SOUND); //if (vab >= 0) SsUtKeyOn(vab, DIE_SOUND, 0, 60, 0, 100, 100); // background noise #endif lives--; if (lives == -1) { //currentlevel = 0; gameoverwait = GLIDE_FRAMES; //60*3; glide = -GLIDE_FRAMES; revglidex = 5000; revglidey = -4000; revglidez = 9000; glidex = conemanpos.vx; glidey = conemanpos.vy-height; glidez = conemanpos.vz; } else { invisible = 1*60; coneman.handler.attribute |= GsALON; conemanpos.vx = 0; conemanpos.vz = 0; } // if lives } // if gameover /*} else { printf("Ghost Eaten!\n"); // if invisible ghost[i].alive = 0; }*/ } ghost[i].coord.coord.t[0] = ghostpos[i*2]; //((ghostmap[i*2])*200)-(MAPSIZE_WORLD/2)+gx+200; ghost[i].coord.coord.t[2] = ghostpos[(i*2)+1]; //(((MAPSIZE-1)-(ghostmap[(i*2)+1]))*200)-(MAPSIZE_WORLD/2)+gz+200; ghost[i].coord.flg = 0; UpdateObjectCoordinates(&ghost[i].rotate, &ghost[i].coord); if (ghost[i].alive == 1) { GsGetLs(&(ghost[i].coord), &tmpls); GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(ghost[i].handler), &Wot[side], 3, getScratchAddr(0)); } } for (i=0; i<3; i++) GsSortSprite( &symbolspr[i], &Wot[side], 3); if (gameoverwait > 0) { if (lives == -1){ gameoverwait--; if (gameoverwait == 0) InitialiseLevel(0); blinkcount++; if (blinkcount > BLINK_COUNT) blinkcount = 0; if (blinkcount < BLINK_COUNT/2) GsSortSprite(&gameover, &Wot[side], 3); } else { gameoverwait--; if (gameoverwait == 0) { currentlevel++; for (i=0; i= 0) SsUtKeyOn(vab, LEVEL_COMPLETE_SOUND, 0, 60, 0, 100, 100); // background noise #endif /// _ospeed += SPEED_INC; //GHOST_STEP += SPEED_INC; if (currentlevel>=NUM_LEVELS) currentlevel=0; InitialiseLevel(currentlevel); } // printf("gameoverwait : %d\n",gameoverwait); blinkcount++; if (blinkcount > BLINK_COUNT) blinkcount = 0; if (blinkcount < BLINK_COUNT/2) GsSortSprite(&complete, &Wot[side], 3); } } /* wait for drawing to complete */ DrawSync(0); // count = GetRCnt(1); // printf("count : %d\n",count); /* wait for vertical sync */ VSync(2); // ResetRCnt(1); GsSwapDispBuff(); // GsSortClear(28,121,248,&groundot[side]); // erase background Bg.y = (1-side)*256; area.x = 960; area.w = 64; area.h = 256; area.y = 256; MoveImage(&area,0,Bg.y); MoveImage(&area,64,Bg.y); MoveImage(&area,128,Bg.y); MoveImage(&area,192,Bg.y); MoveImage(&area,256,Bg.y); //LoadImage(&BgPos, TexInfo.pixel); DrawSync(0); GsDrawOt(&groundot[side]); GsDrawOt(&Wot[side]); font = FntOpen(-130,-110,160,20,1,55); if (lives == -1) FntPrint(" 0 %d %2d Level : %2d",numstars,numstraws,currentlevel+1); else FntPrint(" %d %d %2d Level : %2d",lives,numstars,numstraws,currentlevel+1); FntFlush(font); /* FntLoad(320,0); font = FntOpen(130,-110,30,20,1,55); FntPrint("Level: %d",currentlevel+1); FntFlush(font); */ #ifdef TITLE_SCREEN } #endif } #ifdef SOUND stop_sound(); /* Sound playback termination */ #endif // CleanUpSound(); } #ifdef SOUND_FX SsUtAllKeyOff(0); // switch off sounds SsVabClose(vab); // close sound //SsVabClose(bkvab); #endif ResetGraph(1); // cleanup // printf("end of program\n"); } void SetUpGhosts() { u_long *pointer; u_long objnum; int i; pointer = (u_long *) GHOST_ADDR; pointer++; GsMapModelingData(pointer); pointer++; objnum = *pointer; pointer++; // printf("objnum : %d\n",objnum); for (i=0; iattribute = 0; sprite->x = 0; sprite->y = 0; sprite->w = 0; sprite->h = 0; sprite->tpage = 0; sprite->u = 0; sprite->v = 0; sprite->cx = 0; sprite->cy = 0; sprite->r = 128; sprite->g = 128; sprite->b = 128; sprite->mx = 0; sprite->my = 0; sprite->scalex = ONE; sprite->scaley = ONE; sprite->rotate = 0; } /* NB! This is not an all purpose sprite routine, it just sets the parameters I use in Coneman (parameters needed for displaying standard 2 sprites with no rotation etc) */ void SetSpriteParams(GsSPRITE* sprite, unsigned long attribute, short x, short y, unsigned short w, unsigned short h, short tpage, unsigned char u, unsigned char v, short cx, short cy) { // set the parameters sprite->u = u; sprite->v = v; sprite->tpage = tpage; sprite->cx = cx; sprite->cy = cy; sprite->attribute = attribute; sprite->x = x; sprite->y = y; sprite->w = w; sprite->h = h; // set the defaults sprite->r = 128; sprite->g = 128; sprite->b = 128; sprite->mx = 0; sprite->my = 0; sprite->scalex = ONE; sprite->scaley = ONE; sprite->rotate = 0; } void SetupSprites() { int i; // set up gameover, level complete & press start sprites SetSpriteParams(&start,1 << 24,-110,45,startimg.pw*2,startimg.ph,10,0,64,startimg.cx,startimg.cy); SetSpriteParams(&gameover,1 << 24,-110,45,gameoverimg.pw*2,gameoverimg.ph,10,0,96,gameoverimg.cx,gameoverimg.cy); SetSpriteParams(&complete,1 << 24,-110,45,completeimg.pw*2,completeimg.ph,10,0,128,completeimg.cx,completeimg.cy); /* // set up title screen sprites SetSpriteParams(&sprTitle1,1 << 24,-160,-132,title.pw*2,title.ph,21,0,0,title.cx,title.cy); SetSpriteParams(&sprTitle2,1 << 24,0,-132,title2.pw*2,title2.ph,22,32,0,title2.cx,title2.cy); */ // set up icons (numlives, numstars, numstraws) for (i=0; i<3; i++) SetSpriteParams(&symbolspr[i],1 << 24,(-150)+(i*40),-122,symbols[i].pw*2,symbols[i].ph,11,(i*28),0,symbols[i].cx,symbols[i].cy); } void DrawObject(ObjectHandler * object, short tx, short ty, short tz, int side) { MATRIX tmpls; object->coord.coord.t[0] = tx; //(mapx*200) - (xValue/2) + 200; object->coord.coord.t[1] = ty; //0; object->coord.coord.t[2] = tz; //((((MAPSIZE-1)-mapz)*200) - (MAPSIZE_WORLD/2) + 200); object->coord.flg = 0; UpdateObjectCoordinates(&object->rotate, &object->coord); GsGetLs(&(object->coord), &tmpls); GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(object->handler), &Wot[side], 3, getScratchAddr(0)); } void MoveGhost(int i) { int choice; int startval; int val; int mappos; int direction[] = {0,0,0,0}; int numpaths = 0; mappos = (ghostmap[(i*2)+1]*MAPSIZE) + ghostmap[(i*2)]; /* check left */ if ((map[mappos-1] != 1) && (map[mappos-MAPSIZE-1] != 1)) { direction[LEFT] = 1; numpaths++; } /* check right */ if ((map[mappos+2] != 1) && (map[mappos-MAPSIZE+2] != 1)) { direction[RIGHT] = 1; numpaths++; } /* check up */ if ((map[mappos-(MAPSIZE*2)] != 1) && (map[mappos-(MAPSIZE*2)+1] != 1)) { direction[UP] = 1; numpaths++; } /* check down */ if ((map[mappos+(MAPSIZE*1)] != 1) && (map[mappos+(MAPSIZE*1)+1] != 1)) { direction[DOWN] = 1; numpaths++; } /* if there is only one possible exit, ghost MUST change direction if there are multiple exits, assume ghost is not going to change direction */ if (numpaths != 1) choice = 0; else choice = 1; if (ghostdir[i] == -1) choice = 1; if ((ghostdir[i] == LEFT) || (ghostdir[i] == RIGHT)) { /* spøkelse beveger seg horisontalt, for at spøkelse skal velge ny vei må det være mulig å bevege seg vertikalt */ if ((direction[UP] == 1) || (direction[DOWN] == 1)) choice = 1; } else { /* spøkelse beveger seg vertikalt, for at spøkelse skal velge ny vei må det være mulig å bevege seg horisontalt */ if ((direction[LEFT] == 1) || (direction[RIGHT] == 1)) choice = 1; } // end if if (numpaths != 1) switch (ghostdir[i]) { case 0 : direction[1] = 0; break; case 1 : direction[0] = 0; break; case 2 : direction[3] = 0; break; case 3 : direction[2] = 0; break; } if (choice == 1) { /* select new path */ val = rand()/8192; if (val==4) val = 0; startval = val; while (direction[val] == 0) { val++; if (val==4) val = 0; } ghostdir[i] = val; } } void EatBricks() { int index; int mapx, mapz, maprx, maprz, x, z; int posx, posz; mapx = ((4800/2)+conemanpos.vx)/200; mapz = (MAPSIZE-1)-(((4800/2)+conemanpos.vz)/200); maprx = ((4800/2)+conemanpos.vx) % 200; maprz = 200-(((4800/2)+conemanpos.vz) % 200); mapx--; for (z=0; z<2; z++) for (x=0; x<2; x++) { index = ((mapz+z)*MAPSIZE)+mapx+x; if (map[index] >= 5) { posx = ((mapx+x)*200) - (MAPSIZE_WORLD/2) + 200; posz = ((((MAPSIZE-1)-(mapz+z))*200) - (MAPSIZE_WORLD/2) + 200); if ( (abs(((posx)-(conemanpos.vx))) < STRAW_DISTANCE) && (abs(((posz)-(conemanpos.vz))) < STRAW_DISTANCE)) { /* eat strawberry */ #ifdef SOUND // SsUtKeyOn(vab,progno,0,60,0,64,64); #endif // printf("eat!! %d,%d - %d,%d\n",posx,posz,conemanpos.vx,conemanpos.vz); if (map[index] == 6) { #ifdef SOUND_FX PlayFX(COLLECT_STAR_SOUND); //if (vab >= 0) SsUtKeyOn(vab, COLLECT_STAR_SOUND, 0, 60, 0, 100, 100); // background noise #endif coneman.handler.attribute |= GsALON; speed = (_ospeed + (currentlevel * SPEED_INC)) *2; invisible = 4*30; } else { #ifdef SOUND_FX PlayFX(COLLECT_SOUND); //if (vab >= 0) SsUtKeyOn(vab, COLLECT_SOUND, 0, 60, 0, 100, 100); // background noise #endif SOUND_FX } map[index] = 0; } // } } } /* left/right refers to left & right direction in the world;*/ int CheckCollisionX() { int second; int mapx, mapz, maprx, maprz; /* player is not moving in x-direction, return 0 */ if (movement.vx == 0) return 0; mapx = ((4800/2)+conemanpos.vx+movement.vx)/200; mapz = (4800-((4800/2)+conemanpos.vz+movement.vz))/200; maprx = ((4800/2)+conemanpos.vx+movement.vx) % 200; maprz = (4800-((4800/2)+conemanpos.vz+movement.vz)) % 200; second = 0; if (maprz > 100) second = 24; else if (maprz < 100) second = -24; if (movement.vx > 0) { /* player is moving right */ if (((map[(mapz*24)+mapx+1] == 1) && (maprx > DIAMETER)) || ((map[(mapz*24)+second+mapx+1] == 1) && (maprx > DIAMETER))) { /* kollisjon høyre vegg */ movement.vx = 0; return 1; } } else { /* player is moving left */ if (((map[(mapz*24)+mapx-1] == 1) && (maprx < DIAMETER)) || ((map[(mapz*24)+second+mapx-1] == 1) && (maprx < DIAMETER))) { /* kollisjon venstre vegg */ movement.vx = 0; return 1; } } return 0; // conemanpos.vx } /* up/down refers to up & down direction in the world;*/ int CheckCollisionY() { int second; int mapx, mapz, maprx, maprz; /* player is not moving in x-direction, return 0 */ if (movement.vz == 0) return 0; mapx = ((4800/2)+conemanpos.vx+movement.vx)/200; mapz = (4800-((4800/2)+conemanpos.vz+movement.vz))/200; maprx = ((4800/2)+conemanpos.vx+movement.vx) % 200; maprz = (4800-((4800/2)+conemanpos.vz+movement.vz)) % 200; second = 0; if (maprx > 100) second = 1; else if (maprx < 100) second = -1; if (movement.vz > 0) { /* player is moving up */ if (((map[(mapz*24)+mapx-(24)] == 1) && (maprz < DIAMETER)) || ((map[(mapz*24)+second+mapx-(24)] == 1) && (maprz < DIAMETER))) { /* kollisjon øvre vegg */ movement.vz = 0; return 1; } } else { /* player is moving down */ if (((map[(mapz*24)+mapx+(24)] == 1) && (maprz > DIAMETER)) || ((map[(mapz*24)+second+mapx+(24)] == 1) && (maprz > DIAMETER))) { /* kollisjon nedre vegg */ movement.vz = 0; return 1; } } return 0; } void LoadTexture(u_long * addr, GsIMAGE * image) { GsGetTimInfo(addr+1, image); LoadImage((RECT *)&image->px, image->pixel); if((image->pmode>>3)&0x01) { LoadImage((RECT *)&image->cx, image->clut); } DrawSync(0); } int DealWithControllerPad (void) { long pad = PadRead(); short headx,headz; if (pad & PADstart && pad & PADselect) return 0; if (pad & PADselect) { lives = -1; gameoverwait = 1; } /* move the player */ if (pad & PADLup) { headx = MySin(coneman.rotate.vy); headz = MyCos(coneman.rotate.vy); movement.vx = (((headx*speed)+0x200) >> 10); movement.vz = (((headz*speed)+0x200) >> 10); } if (pad & PADLdown) { headx = MySin(coneman.rotate.vy); headz = MyCos(coneman.rotate.vy); movement.vx = -(((headx*speed)+0x200) >> 10); movement.vz = -(((headz*speed)+0x200) >> 10); } if (wait>0) wait--; /* cameramode 0 -> viewpoint always in center cameramode 1 -> viewpoint follows object */ /* if ((pad & PADR1) && (glide == 0) && (wait==0)){ wait = 5; cameraMode ^= 1; // printf("cameramode : %d\n",cameraMode); if (cameraMode == 1) { glide = 20; glidex = view.vpx; glidez = view.vpz; } } */ // predefined viewpoints if (pad & PADR1) { dist = VD_1; height = VH_1; } if (pad & PADL1) { dist = VD_2; height = VH_2; /*lives+=2;*/ #ifdef PRINTF //printf("Height : %d Distance : %d",height,dist); #endif } if (pad & PADL2) { dist = VD_3; height = VH_3; /* numstars = 0; gameoverwait = 1; numstraws = 0;*/ } if (pad & PADR2) { dist = VD_4; height = VH_4; } #ifdef ALLOW_VIEWPOINT_MOVE // the following lines allow the player to move the viewpoint freely if (pad & PADRleft) dist -= 20; if (pad & PADRright) dist+=20; if (pad & PADRup) if (height > 550) height -= 20; if (pad & PADRdown) height+=20; #endif /* turn player */ if (pad & PADLleft) coneman.rotate.vy -= ONE/64; if (pad & PADLright) coneman.rotate.vy += ONE/64; /* if player rotate value is to high, wrap it */ if (coneman.rotate.vy < -ONE) coneman.rotate.vy += ONE; if (coneman.rotate.vy > ONE) coneman.rotate.vy -= ONE; return 1; } void InitialiseLevel(int level) { int i; // reset player position & rotation conemanpos.vx = conemanpos.vy = conemanpos.vz = 0; coneman.rotate.vy = 0; for (i=0; i= 0) voice = SsUtKeyOn(vab, prog, 0, 60, 0, 100, 100); // background noise prevprog = prog; } void LoadMapTextures() { LoadTexture((u_long *)textures[(currenttexture*3)], &tex1); LoadTexture((u_long *)textures[(currenttexture*3)+1], &tex2); LoadTexture((u_long *)textures[(currenttexture*3)+2], &tex3); currenttexture++; if (currenttexture == TEXTURE_SETS) currenttexture = 0; } void InitialiseAll (void) { int i; int df; #ifdef PAL SetVideoMode( MODE_PAL ); #else SetVideoMode( MODE_NTSC ); #endif GetPadBuf(&bb0, &bb1); // Get controller reception buffer PadInit(); // init controller pad /* load textures */ //LoadMapTextures(); /* LoadTexture((u_long *)TEX4_ADDR, &tex1); LoadTexture((u_long *)TEX5_ADDR, &tex2); LoadTexture((u_long *)TEX6_ADDR, &tex3); */ LoadTexture((u_long *)TITLE_ADDR, &cone_title); // LoadTexture((u_long *)TITLE_ADDR2, &title2); #ifdef NY_TITLE_SCREEN LoadTexture((u_long *)NY_TITLE_ADDR, &ny_title); #endif LoadTexture((u_long *)CONEMANTEX_ADDR, &symbols[0]); LoadTexture((u_long *)STARTEX_ADDR, &symbols[1]); LoadTexture((u_long *)STRAWTEX_ADDR, &symbols[2]); LoadTexture((u_long *)GAMEOVER_ADDR, &gameoverimg); LoadTexture((u_long *)START_ADDR, &startimg); LoadTexture((u_long *)COMPLETE_ADDR, &completeimg); /* initialise all models */ SetUpObject(&star,(u_long *) STAR_ADDRESS,1); SetUpObject(&straw,(u_long *) STRAW_ADDRESS,1); SetUpObject(&coneman,(u_long *) CONEMAN_ADDRESS,1); SetUpGhosts(); SetupSprites(); conemanpos.vx = conemanpos.vy = conemanpos.vz = 0; movement.vx = movement.vy = movement.vz = 0; GsInitGraph(SCREEN_WIDTH,SCREEN_HEIGHT,GsNONINTER|GsOFSGPU,1,0); GsDefDispBuff(0,0,0,SCREEN_HEIGHT); GsInit3D(); Wot[0].length=OT_LENGTH; Wot[0].org=wtags[0]; Wot[1].length=OT_LENGTH; Wot[1].org=wtags[1]; GsClearOt(0,0,&Wot[0]); GsClearOt(0,0,&Wot[1]); groundot[0].length=OT_LENGTH; groundot[0].org=groundtags[0]; groundot[1].length=OT_LENGTH; groundot[1].org=groundtags[1]; GsClearOt(0,0,&groundot[0]); GsClearOt(0,0,&groundot[1]); ProjectionDistance = 200; // screen to viewpoint distance GsSetProjection(ProjectionDistance); view.vrx = 0; view.vry = 0; view.vrz = 0; view.vpx = 0; view.vpy = cameraPosY; view.vpz = 0; view.rz = 0; view.super = WORLD; GsSetRefView2(&view); // three flat lights TheLights[0].vx = ONE; TheLights[0].vy = 0; TheLights[0].vz = 0; TheLights[0].r = 128; //128; TheLights[0].g = 0; //128; TheLights[0].b = 0; //128; GsSetFlatLight(0, &TheLights[0]); GsSetAmbient(ONE,ONE,ONE); TheLights[1].vx = 0; TheLights[1].vy = ONE; TheLights[1].vz = 0; TheLights[1].r = 0; TheLights[1].g = 128; TheLights[1].b = 0; GsSetFlatLight(1, &TheLights[1]); TheLights[2].vx = 0; TheLights[2].vy = 0; TheLights[2].vz = ONE; TheLights[2].r = 0; TheLights[2].g = 0; TheLights[2].b = 128; GsSetFlatLight(2, &TheLights[2]); } void SetUpObject (ObjectHandler * object, u_long * obj_addr, short link) { u_long *pointer; object->position.vx = 0; object->position.vy = 0; object->position.vz = 0; object->rotate.vx = 0; object->rotate.vy = 0; object->rotate.vz = 0; GsInitCoordinate2(WORLD, &object->coord); object->handler.coord2 = &(object->coord); pointer = obj_addr; pointer++; if (link == 1) GsMapModelingData(pointer); pointer += 2; GsLinkObject4( (u_long)pointer, &object->handler, 0); } void UpdateObjectCoordinates (SVECTOR* rotationVector, GsCOORDINATE2* coordSystem) { MATRIX tempMatrix; tempMatrix.t[0] = coordSystem->coord.t[0]; tempMatrix.t[1] = coordSystem->coord.t[1]; tempMatrix.t[2] = coordSystem->coord.t[2]; RotMatrix(rotationVector, &tempMatrix); // get rotation matrix from rotation vector coordSystem->coord = tempMatrix; // assign new matrix to coordinate system coordSystem->flg = 0; // tell GTE that coordinate system has been updated } void PadInit (void) { GetPadBuf(&bb0, &bb1); } u_long PadRead(void) { return(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); } void CreatePrimitive(TMDPRIM_FLT4 * prim, short type, short normal, short v0, short v1, short v2, short v3) { short ofs; short yofs; //currentlevel++; yofs = 0; //64*currentlevel; //yofs = 0; ofs = type*64; prim->mode = 0x2c00; prim->ilen = 0x07; prim->olen = 0x09; prim->cba = ((240+type) << 6) + (640 >> 4); prim->tsb = 10; prim->u0 = ofs+0; prim->v0 = yofs+(texsize-1); prim->u1 = ofs+0; prim->v1 = 0+yofs; prim->u2 = ofs+(texsize-1); prim->v2 = (texsize-1)+yofs; prim->u3 = ofs+(texsize-1); prim->v3 = yofs+0; prim->vertex0 = v0; prim->vertex1 = v1; prim->vertex2 = v2; prim->vertex3 = v3; prim->normal0 = normal; //currentlevel--; } void CreateMap() { short mx,mz; short x,y,z; int vertbase; int px,pz,vx,vz; int index,index2; int no,ofs; long mapval; #ifdef PRINTF printf("Creating level...\n"); #endif /* set tmd header */ mapobject.header.id = 0x00000041; mapobject.header.flag = 1; mapobject.header.nobj = 1; mapobject.objtable.vert_top = (u_long*) &mapobject.vertex; mapobject.objtable.n_vert = (numVertexX*numVertexZ*2); mapobject.objtable.normal_top = (u_long*) &mapobject.normal; mapobject.objtable.n_normal = 5; mapobject.objtable.primitive_top = (u_long*) &mapobject.packets; mapobject.objtable.n_primitive = (numVertexX-1)*(numVertexZ-1)*1; mapobject.objtable.scale = 0; mapfloor.header.id = 0x00000041; mapfloor.header.flag = 1; mapfloor.header.nobj = 1; mapfloor.objtable.vert_top = (u_long*) &mapobject.vertex; mapfloor.objtable.n_vert = (numVertexX*numVertexZ*2); mapfloor.objtable.normal_top = (u_long*) &mapobject.normal; mapfloor.objtable.n_normal = 1; mapfloor.objtable.primitive_top = (u_long*) &mapfloor.packets; mapfloor.objtable.n_primitive = 0; mapfloor.objtable.scale = 0; /* create vertex-list */ for (vz = 0; vz < numVertexZ; vz++) for (vx = 0; vx < numVertexX; vx++) { index = (vz*numVertexX*2)+(vx*2); x = (vx*(xValue/(numVertexX-1)))-(xValue/2); z = (vz*(zValue/(numVertexZ-1)))-(zValue/2); y = 0; mapobject.vertex[index].vx = (short) x; mapobject.vertex[index].vz = (short) z; mapobject.vertex[index].vy = (short) y; index++; y = wallheight; mapobject.vertex[index].vx = (short) x; mapobject.vertex[index].vz = (short) z; mapobject.vertex[index].vy = (short) y; } /* normal til tak/gulv */ crossProduct(mapobject.vertex[0],mapobject.vertex[2],mapobject.vertex[(numVertexX*2)], &mapobject.normal[0]); /* normal til fremre/bakre vegg */ crossProduct(mapobject.vertex[0],mapobject.vertex[1],mapobject.vertex[2], &mapobject.normal[1]); crossProduct(mapobject.vertex[1],mapobject.vertex[0],mapobject.vertex[2], &mapobject.normal[3]); /* normal til sidevegger*/ crossProduct(mapobject.vertex[(numVertexX*2)],mapobject.vertex[0],mapobject.vertex[1], &mapobject.normal[2]); crossProduct(mapobject.vertex[0],mapobject.vertex[1],mapobject.vertex[(numVertexX*2)], &mapobject.normal[4]); index = 0; index2 = 0; /* for each row of primitives */ for (pz = 0; pz < (numVertexZ-1); pz++) /* for each quad in a row */ for (px = 0; px < (numVertexX-1); px++) { vertbase = (pz*(numVertexX*2))+(px*2); mx = px; mz = (numVertexX-2)-pz; mapval = map[(mz*(numVertexX-1))+mx]; if (mapval == 1) { /* tak/vegg */ vertbase++; CreatePrimitive(&mapobject.packets[index],0,0, vertbase+2,vertbase+0, vertbase + 2 +(numVertexX*2), vertbase + 0 +(numVertexX*2)); vertbase--; index++; if ((px == 0) || (map[((mz)*(numVertexX-1))+mx-1] != 1)) { // plasser venstre vegg CreatePrimitive(&mapobject.packets[index],1,3, vertbase + 1, vertbase + 0, vertbase + 1 +(numVertexX*2), vertbase + 0 + ((numVertexX)*2)); index++; } if ((px == (numVertexX-2)) || (map[(mz*(numVertexX-1))+mx+1] != 1)){ // plasser høyre vegg vertbase+=2; CreatePrimitive(&mapobject.packets[index],1,4, vertbase + 1 +(numVertexX*2), vertbase + 0 + ((numVertexX)*2), vertbase + 1, vertbase + 0); vertbase-=2; mapobject.packets[index].normal0 = 0; //index; //(pz*(numVertexX-1))+px; index++; } if ((pz == 0) || (map[((mz*(numVertexX-1))+mx+(numVertexX-1))] != 1)) { // plasser fremre vegg CreatePrimitive(&mapobject.packets[index],1,1, vertbase + 3, vertbase + 2, vertbase + 1, vertbase + 0); mapobject.packets[index].normal0 = 0; //index; //(pz*(numVertexX-1))+px; index++; } if ((pz == (numVertexX-2)) || (map[((mz*(numVertexX-1))+mx-(numVertexX-1))] != 1)) { // plasser fremre vegg CreatePrimitive(&mapobject.packets[index],1,2, vertbase + ((numVertexX)*2)+ 1, vertbase + ((numVertexX)*2)+ 0, vertbase + ((numVertexX)*2)+ 3, vertbase + ((numVertexX)*2)+ 2); mapobject.packets[index].normal0 = 0; //index; //(pz*(numVertexX-1))+px; index++; } } else { /* gulv */ CreatePrimitive(&mapfloor.packets[index2],2,0, vertbase+2,vertbase,vertbase + (numVertexX*2) + 2, vertbase + ((numVertexX)*2)); mapfloor.packets[index2].normal0 = 0; //index; //(pz*(numVertexX-1))+px; index2++; } } // create primitive loop mapobject.objtable.n_primitive = index; mapfloor.objtable.n_primitive = index2; #ifdef PRINTF printf("Wall polygons: %d Floor polygons: %d\n",index,index2); #endif } void crossProduct(SVECTOR p1, SVECTOR p2, SVECTOR p3, SVECTOR *p4) { VECTOR u,v; double x,y,z,len; /* regn ut u */ u.vx = p2.vx - p1.vx; u.vy = p2.vy - p1.vy; u.vz = p2.vz - p1.vz; /* regn ut v */ v.vx = p3.vx - p1.vx; v.vy = p3.vy - p1.vy; v.vz = p3.vz - p1.vz; /* regn ut normal */ x = (double) ((u.vy*v.vz) - (u.vz*v.vy) << 12); y = (double) ((u.vz*v.vx) - (u.vx*v.vz) << 12); z = (double) ((u.vx*v.vy) - (u.vy*v.vx) << 12); len = x * x + y * y + z * z; len = sqrt( len ); /* normaliser n */ p4->vx = (short) (x / len); p4->vy = (short) (y / len); p4->vz = (short) (z / len); } #ifdef SOUND /*---------------------------------------------------------------------- Reading the file on CD-ROM (DFILE) ----------------------------------------------------------------------*/ /* Retrieving file on CD-ROM */ static void datafile_search() { int i, j; for (i = 0; i < DFILE; i++) { /* Deal with DFILE file */ for (j = 0; j < 10; j++) { /* Return loop */ if (CdSearchFile(&(dfile[i].finfo), dfile[i].fname) != 0) break; /* Retry loop interruption on normal termination */ else #ifdef PRINTF printf("%s not found.\n", dfile[i].fname); #endif } } } /* CD-ROM file reading */ static void datafile_read() { int i, j; int cnt; #ifdef PRINTF printf("Reading...."); #endif for (i = 0; i < DFILE; i++) { /* Deal with DFILE file */ for (j = 0; j < 10; j++) { /* Retry loop */ // printf("Reading.... %d\n",i); CdReadFile(dfile[i].fname, dfile[i].addr,dfile[i].finfo.size); /* Normal processing can be executed by other side of read */ /* Here, remaining sector number is monitored until Read terminated */ while ((cnt = CdReadSync(1, 0)) > 0 ) VSync(0); /* Waiting for vertical synchronisation interrupt (for time adjustment */ if (cnt == 0) break; /* Retry loop interruption on normal termination*/ } } #ifdef PRINTF printf("done!\n"); #endif } /*---------------------------------------------------------------------- Sound related ----------------------------------------------------------------------*/ /* Sound data on memory playback preparation */ static void init_sound() { /* VAB opening and transmission to sound buffer */ vab = SsVabTransfer( (u_char*)VH_ADDR, (u_char*)VB_ADDR, -1, 1 ); if (vab < 0) { #ifdef PRINTF printf("SsVabTransfer failed (%d)\n", vab); #endif return; } /* SEQ opening */ seq = SsSeqOpen((u_long *)SEQ_ADDR, vab); #ifdef PRINTF if (seq < 0) printf("SsSeqOpen failed (%d)\n", seq); #endif } /* Sound playback start */ static void play_sound() { SsSetMVol(MVOL, MVOL); /* Main volume setting*/ SsSeqSetVol(seq, SVOL, SVOL); /* Volume setting for each SEQ */ SsSeqPlay(seq, SSPLAY_PLAY, SSPLAY_INFINITY);/* Playback switch ON */ } /* Sound playback termination */ static void stop_sound() { SsSeqStop(seq); /* Playback switch OFF */ VSync(0); VSync(0); SsSeqClose(seq); /* SEQ close */ SsVabClose(vab); /* VAB close */ } #endif static void read_tim(char * fname, void * addr) { int j; int cnt; CdlFILE finfo; // check if file exists for (j = 0; j < 10; j++) { /* Return loop */ if (CdSearchFile(&(finfo), fname) != 0) break; /* Retry loop interruption on normal termination */ #ifdef PRINTF else printf("%s not found.\n", fname); #endif } for (j = 0; j < 10; j++) { /* Retry loop */ // printf("Reading.... %d\n",i); CdReadFile(fname,addr,finfo.size); /* Normal processing can be executed by other side of read */ /* Here, remaining sector number is monitored until Read terminated */ while ((cnt = CdReadSync(1, 0)) > 0 ) VSync(0); if (cnt == 0) break; /* Retry loop interruption on normal termination*/ } }