/********************** height.c **********************/ #include "addrs.h" #include "height.h" #include #include #include "arctan.h" // create a dynamic TMD for a tile/cell. u_long CreateTileTMD(long h1, long h2, long h3, long h4) { static u_long firstStart=0; u_long returnValue; // set position of vertices TMD_setVERTEX(¤tMap->tile[0].vert[0], -TILE_LENGTH, h1, TILE_WIDTH); TMD_setVERTEX(¤tMap->tile[0].vert[1], TILE_LENGTH, h2, TILE_WIDTH); TMD_setVERTEX(¤tMap->tile[0].vert[2], TILE_LENGTH, h3,-TILE_WIDTH); TMD_setVERTEX(¤tMap->tile[0].vert[3], -TILE_LENGTH, h4,-TILE_WIDTH); // set colour to be used. TMD_setCOLOUR(¤tMap->tile[0].col[0], 255,255,0); TMD_setCOLOUR(¤tMap->tile[0].col[1], 255,0,0); TMD_setCOLOUR(¤tMap->tile[0].col[2], 0,255,0); TMD_setCOLOUR(¤tMap->tile[0].col[3], 0,255,255); if(firstStart == 0) { TMD_prepare(FREE_MEM, ¤tMap->tile[0].vert[0], ¤tMap->tile[0].col[0],0); firstStart = 1; } else { TMD_prepare(0, ¤tMap->tile[0].vert[0], ¤tMap->tile[0].col[0],0); } //create face (0,1,3,2,0,1,2,3)2,3 // 1,3,2,1,2,3 TMD_set3_NS_GP(0,1,2,0,1,3); TMD_set3_NS_GP(2,3,0,3,2,0); // finish returnValue = TMD_finish(); return(returnValue); } // Creates a model for a TMD. void CreateTileModels() { long index,x=0,z=0; for(index = 0; index < currentMap->MapArea; index++) { InitialiseModel(¤tMap->tileModel[index],x*(TILE_LENGTH<<1),0, z*(TILE_WIDTH<<1),currentMap->DYNAMIC_TMD[index]); // Use first TMDS co-ordinate system. if(index !=0)currentMap->tileModel[index].Object_Coord.super = ¤tMap->tileModel[0].Object_Coord; if(++x >= currentMap->MapLength){ z++; x=0; } } } // setup map by creating a TMD and a height field entry // for each and every tile/cell. void SetupMap() { long index,x=0,z=0; //create TMDs for(index=0; index < currentMap->MapArea; index++) { currentMap->DYNAMIC_TMD[index] = (u_long*) CreateTileTMD(currentMap->heightFields[x][z+1], currentMap->heightFields[x+1][z+1], currentMap->heightFields[x+1][z], currentMap->heightFields[x][z]); if(++x >= currentMap->MapLength){ z++; x=0; } } // setup models CreateTileModels(); } //Rotate the whole map around cell 0,0. void RotateMap(long x, long y, long z) { RotateModelMatrix(¤tMap->tileModel[0],x,y,z); } // Draw every bit of the height field map. void DrawMap() { long index; // may need to roll out for more speed if possible. for(index=0; index < currentMap->MapArea; index++) { DrawObject(¤tMap->tileModel[index]); } } // Find a height from world co-ordinates by translating them // to cell co-ordinates. long FindHeight(long rx,long rz) { long h1,h2,h3,h4,cellx,cellz; long offsetX,offsetZ; long height1; long height2; long heightTotal; // calculate cell position from actual positon here // so its not calulated more then once. cellx = (rx+TILE_LENGTH) / (TILE_LENGTH<<1); cellz = (rz+TILE_WIDTH) / (TILE_WIDTH<<1); // derefernce heights to be used. h1 = currentMap->heightFields[cellx][cellz]; h2 = currentMap->heightFields[cellx+1][cellz]; h3 = currentMap->heightFields[cellx][cellz+1]; h4 = currentMap->heightFields[cellx+1][cellz+1]; // calculate offset of position (same as cells, done here // to reduce calculations). offsetX = (rx+TILE_LENGTH) % (TILE_LENGTH<<1); offsetZ = (rz+TILE_WIDTH) % (TILE_WIDTH<<1); // calculate X heights height1=(long)((h1*((TILE_LENGTH<<1)-offsetX)) + (h2 * offsetX))/(TILE_LENGTH<<1); height2=(long)((h3*((TILE_LENGTH<<1)-offsetX)) + (h4 * offsetX))/(TILE_LENGTH<<1); // calculate Z height heightTotal=(long)((height1 * ((TILE_WIDTH<<1)-offsetZ)) + (height2 * offsetZ))/(TILE_WIDTH<<1); return (heightTotal); } // Rotation between to heights. // ***** bugs galore here !!!!! ********* long FindRotation(long height1, long height2, long length) { register int delta, delta2; // If heights the same exit as there is no slope if(height1==height2) return(0); // If front higher then the back if(height1 > height2) { // first delta is the difference between the heights. delta= (height1 - height2); //uses advanced atan function which is very fast delta2=rinvtan(length, delta); return ((long)(delta2 & 4095)); } // If the front is lower then the back else { delta= (height2 - height1); delta2=rinvtan(length, delta); return ((long)4096-(delta2 & 4095)); } } // Sets the current Map pointer. void SetCurrentMap(MAP *theMap) { currentMap = theMap; } // Sets dimensions and creates dynamic arrays void SetDimensions(MAP *theMap,u_long NuTx,u_long ML, u_long MW) { u_long index; // Set Dimensions etc. theMap->NuTextures=NuTx; theMap->MapLength =ML; theMap->MapWidth =MW; theMap->MapArea =theMap->MapLength * theMap->MapWidth; // Dynamically allocated memory for Arrays. theMap->DYNAMIC_TMD =(u_long **)malloc (sizeof(u_long)*theMap->MapArea); theMap->tileModel =(ObjectStruct *)malloc (sizeof(ObjectStruct)*theMap->MapArea); theMap->tile =(TileStruct *)malloc (sizeof(TileStruct)*theMap->MapArea); theMap->TEXTURE_MAPS =(u_long **)malloc (sizeof(u_long)*theMap->NuTextures); theMap->heightFields =(long **)malloc(sizeof(long)*(theMap->MapLength+1)); theMap->texturePosition=(long **)malloc(sizeof(long)*theMap->MapLength); // Finish allocation for grid arrays for(index = 0; index < theMap->MapLength+1;index++) { theMap->heightFields[index] =(long *)malloc(sizeof(long)*(theMap->MapWidth+1)); } for(index = 0; index < theMap->MapLength+1;index++) { theMap->texturePosition[index] =(long *)malloc(sizeof(long)*theMap->MapWidth); } } // set up world constraints void SetAttributes(MAP * theMap,long grav,long fric, long wind) { theMap->GRAVITY = grav; theMap->FRICTION = fric; theMap->WIND = wind; } // Accessor functions, Oh er object orientty long getWind() {return currentMap->WIND;} long getFriction() {return currentMap->FRICTION;} long getGravity() {return currentMap->GRAVITY;} void DestroyMap(MAP *theMap) { long index; free(theMap->tileModel); free(theMap->tile); free(theMap->DYNAMIC_TMD); free(theMap->TEXTURE_MAPS); // Just to be on the safe side for(index = 0; index < theMap->MapLength+1; index++) free(theMap->heightFields[index]); free(theMap->heightFields); for(index = 0; index < theMap->MapLength; index++) free(theMap->texturePosition[index]); free(theMap->texturePosition); } // This is used as a demo. Just sets a load of heights up in the heightfield array. // nothing special here. void SetDemoMap() { SetDimensions(&map1,2,10,10); SetAttributes(&map1,40,2,40); //Set Heights map1.heightFields[0][0] = 0; map1.heightFields[0][1] = 0; map1.heightFields[0][2] = 0; map1.heightFields[0][3] = -1000; map1.heightFields[0][4] = 0; map1.heightFields[0][5] = 0; map1.heightFields[0][6] = 0; map1.heightFields[0][7] = 0; map1.heightFields[0][8] = 0; map1.heightFields[0][9] = 0; map1.heightFields[0][10]= 0; map1.heightFields[1][0] = 0; map1.heightFields[1][1] = 0; map1.heightFields[1][2] = -1000; map1.heightFields[1][3] = 0; map1.heightFields[1][4] = 0; map1.heightFields[1][5] = 0; map1.heightFields[1][6] = -1000; map1.heightFields[1][7] = 0; map1.heightFields[1][8] = 0; map1.heightFields[1][9] = 0; map1.heightFields[1][10]= 1000; map1.heightFields[2][0] = 0; map1.heightFields[2][1] = 0; map1.heightFields[2][2] = -1000; map1.heightFields[2][3] = 0; map1.heightFields[2][4] = 0; map1.heightFields[2][5] = 0; map1.heightFields[2][6] = -1000; map1.heightFields[2][7] = -1000; map1.heightFields[2][8] = -1000; map1.heightFields[2][9] = -1000; map1.heightFields[2][10]= -1000; map1.heightFields[3][0] = 0; map1.heightFields[3][1] = 0; map1.heightFields[3][2] = -1000; map1.heightFields[3][3] = 0; map1.heightFields[3][4] = 0; map1.heightFields[3][5] = 0; map1.heightFields[3][6] = -1000; map1.heightFields[3][7] = -2000; map1.heightFields[3][8] = -2000; map1.heightFields[3][9] = -2000; map1.heightFields[3][10]= 0; map1.heightFields[4][0] = 0; map1.heightFields[4][1] = 0; map1.heightFields[4][2] = -1000; map1.heightFields[4][3] = 0; map1.heightFields[4][4] = 0; map1.heightFields[4][5] = 0; map1.heightFields[4][6] = -3000; map1.heightFields[4][7] = -3000; map1.heightFields[4][8] = -3000; map1.heightFields[4][9] = -3000; map1.heightFields[4][10]= 0; map1.heightFields[5][0] = 0; map1.heightFields[5][1] = 0; map1.heightFields[5][2] = -1000; map1.heightFields[5][3] = 0; map1.heightFields[5][4] = 0; map1.heightFields[5][5] = 0; map1.heightFields[5][6] = -2000; map1.heightFields[5][7] = -2000; map1.heightFields[5][8] = -2000; map1.heightFields[5][9] = -2000; map1.heightFields[5][10]= 0; map1.heightFields[6][0] = 0; map1.heightFields[6][1] = 0; map1.heightFields[6][2] = -1000; map1.heightFields[6][3] = 0; map1.heightFields[6][4] = 0; map1.heightFields[6][5] = 0; map1.heightFields[6][6] = -1000; map1.heightFields[6][7] = -1000; map1.heightFields[6][8] = -1000; map1.heightFields[6][9] = -1000; map1.heightFields[6][10]= 0; map1.heightFields[7][0] = 0; map1.heightFields[7][1] = 0; map1.heightFields[7][2] = -1000; map1.heightFields[7][3] = 0; map1.heightFields[7][4] = 0; map1.heightFields[7][5] = 0; map1.heightFields[7][6] = -1000; map1.heightFields[7][7] = 0; map1.heightFields[7][8] = 0; map1.heightFields[7][9] = 0; map1.heightFields[7][10]= 0; map1.heightFields[8][0] = 0; map1.heightFields[8][1] = 0; map1.heightFields[8][2] = -1000; map1.heightFields[8][3] = 0; map1.heightFields[8][4] = 1000; map1.heightFields[8][5] = 1000; map1.heightFields[8][6] = 1000; map1.heightFields[8][7] = 1000; map1.heightFields[8][8] = 0; map1.heightFields[8][9] = 0; map1.heightFields[8][10]= 0; map1.heightFields[9][0] = 0; map1.heightFields[9][1] = 0; map1.heightFields[9][2] = -1000; map1.heightFields[9][3] = 0; map1.heightFields[9][4] = 0; map1.heightFields[9][5] = 0; map1.heightFields[9][6] = -1000; map1.heightFields[9][7] = 0; map1.heightFields[9][8] = 0; map1.heightFields[9][9] = 0; map1.heightFields[9][10]= 0; map1.heightFields[10][0] = 0; map1.heightFields[10][1] = 0; map1.heightFields[10][2] = -1000; map1.heightFields[10][3] = 0; map1.heightFields[10][4] = 0; map1.heightFields[10][5] = 0; map1.heightFields[10][6] = -1000; map1.heightFields[10][7] = 0; map1.heightFields[10][8] = 0; map1.heightFields[10][9] = 0; map1.heightFields[10][10]= 0; // setup Textures map1.TEXTURE_MAPS[0] = (u_long *)GRASS01_TIM; map1.TEXTURE_MAPS[1] = (u_long *)TRACK01_TIM; // set Texture locations map1.texturePosition[0][0]= 0; map1.texturePosition[0][1]= 1; map1.texturePosition[0][2]= 1; map1.texturePosition[0][3]= 1; map1.texturePosition[0][4]= 1; map1.texturePosition[0][5]= 1; map1.texturePosition[0][6]= 1; map1.texturePosition[0][7]= 1; map1.texturePosition[0][8]= 1; map1.texturePosition[0][9]= 1; map1.texturePosition[1][0]= 1; map1.texturePosition[1][1]= 1; map1.texturePosition[1][2]= 1; map1.texturePosition[1][3]= 1; map1.texturePosition[1][4]= 1; map1.texturePosition[1][5]= 1; map1.texturePosition[1][6]= 1; map1.texturePosition[1][7]= 1; map1.texturePosition[1][8]= 1; map1.texturePosition[1][9]= 1; map1.texturePosition[2][0]= 1; map1.texturePosition[2][1]= 1; map1.texturePosition[2][2]= 1; map1.texturePosition[2][3]= 1; map1.texturePosition[2][4]= 1; map1.texturePosition[2][5]= 0; map1.texturePosition[2][6]= 0; map1.texturePosition[2][7]= 0; map1.texturePosition[2][8]= 0; map1.texturePosition[2][9]= 0; map1.texturePosition[3][0]= 0; map1.texturePosition[3][1]= 0; map1.texturePosition[3][2]= 0; map1.texturePosition[3][3]= 0; map1.texturePosition[3][4]= 0; map1.texturePosition[3][5]= 0; map1.texturePosition[3][6]= 0; map1.texturePosition[3][7]= 0; map1.texturePosition[3][8]= 0; map1.texturePosition[3][9]= 0; map1.texturePosition[4][0]= 0; map1.texturePosition[4][1]= 0; map1.texturePosition[4][2]= 0; map1.texturePosition[4][3]= 0; map1.texturePosition[4][4]= 0; map1.texturePosition[4][5]= 0; map1.texturePosition[4][6]= 0; map1.texturePosition[4][7]= 0; map1.texturePosition[4][8]= 0; map1.texturePosition[4][9]= 0; map1.texturePosition[5][0]= 0; map1.texturePosition[5][1]= 0; map1.texturePosition[5][2]= 0; map1.texturePosition[5][3]= 0; map1.texturePosition[5][4]= 0; map1.texturePosition[5][5]= 0; map1.texturePosition[5][6]= 0; map1.texturePosition[5][7]= 0; map1.texturePosition[5][8]= 0; map1.texturePosition[5][9]= 0; map1.texturePosition[6][0]= 0; map1.texturePosition[6][1]= 0; map1.texturePosition[6][2]= 0; map1.texturePosition[6][3]= 0; map1.texturePosition[6][4]= 0; map1.texturePosition[6][5]= 0; map1.texturePosition[6][6]= 0; map1.texturePosition[6][7]= 0; map1.texturePosition[6][8]= 0; map1.texturePosition[6][9]= 0; map1.texturePosition[7][0]= 0; map1.texturePosition[7][1]= 0; map1.texturePosition[7][2]= 0; map1.texturePosition[7][3]= 0; map1.texturePosition[7][4]= 0; map1.texturePosition[7][5]= 0; map1.texturePosition[7][6]= 0; map1.texturePosition[7][7]= 0; map1.texturePosition[7][8]= 0; map1.texturePosition[7][9]= 0; map1.texturePosition[8][0]= 0; map1.texturePosition[8][1]= 0; map1.texturePosition[8][2]= 0; map1.texturePosition[8][3]= 0; map1.texturePosition[8][4]= 0; map1.texturePosition[8][5]= 0; map1.texturePosition[8][6]= 0; map1.texturePosition[8][7]= 0; map1.texturePosition[8][8]= 0; map1.texturePosition[8][9]= 0; map1.texturePosition[9][0]= 0; map1.texturePosition[9][1]= 0; map1.texturePosition[9][2]= 0; map1.texturePosition[9][3]= 0; map1.texturePosition[9][4]= 0; map1.texturePosition[9][5]= 0; map1.texturePosition[9][6]= 0; map1.texturePosition[9][7]= 0; map1.texturePosition[9][8]= 0; map1.texturePosition[9][9]= 0; }