/*----------------------------------------------------------------------------- Name : btgLoad Description : load a btg scene into our structures Inputs : filename - the name of the btg file to load Outputs : Return : ----------------------------------------------------------------------------*/ void BtgBackground::btgLoad(const std::string filename) { ubyte* btgData; udword headSize; udword vertSize; udword starSize, fileStarSize; udword polySize; real32 thetaSave, phiSave; //fileLoadAlloc(filename, (void**)&btgData, 0); base::fs::read( filename, (char**)&btgData ); //reset / free any previous structures thetaSave = btgThetaOffset; phiSave = btgPhiOffset; btgReset(); btgThetaOffset = thetaSave; btgPhiOffset = phiSave; //header. trivial copy headSize = sizeof(btgHeader); btgHead = (btgHeader*)malloc(headSize); memcpy(btgHead, btgData, headSize); //vertices. trivial copy vertSize = btgHead->numVerts * sizeof(btgVertex); if (vertSize) { btgVerts = (btgVertex*)malloc(vertSize); memcpy(btgVerts, btgData + headSize, vertSize); } //stars. non-trivial munging around starSize = btgHead->numStars * sizeof(btgStar); fileStarSize = 0; if (starSize != 0) { btgStar* outstarp; ubyte* instarp; udword* udp; sdword i, j, tempSize, count, length; char filename[48]; btgStars = (btgStar*)malloc(starSize); instarp = btgData + headSize + vertSize; outstarp = btgStars; for (i = 0; i < btgHead->numStars; i++, outstarp++) { //extract constant-sized header tempSize = sizeof(udword) + 2*sizeof(real64) + 4*sizeof(sdword); memcpy(outstarp, instarp, tempSize); instarp += tempSize; fileStarSize += tempSize; //extract variable-sized filename count = 0; memset(filename, 0, 48); udp = (udword*)instarp; length = (sdword)*udp; instarp += 4; fileStarSize += 4; for (j = 0; j < length; j++) { filename[count++] = *instarp++; fileStarSize++; } memcpy(outstarp->filename, filename, 48); //create a GL texture object if (!btgTexInList(filename)) { btgGetTexture(filename, &outstarp->glhandle, &outstarp->width, &outstarp->height); btgAddTexToList(filename, outstarp->glhandle, outstarp->width, outstarp->height); } else { btgFindTexture(filename, outstarp); } } } //reset the game's current texture, which now differs from the GL's //trClearCurrent(); //polys. trivial copy polySize = btgHead->numPolys * sizeof(btgPolygon); if (polySize != 0) { btgPolys = (btgPolygon*)malloc(polySize); memcpy(btgPolys, btgData + headSize + vertSize + fileStarSize, polySize); } free(btgData); btgIndices = (udword*)malloc(3 * btgHead->numPolys * sizeof(udword)); //spherically project things, blend colours, &c btgConvertVerts(); }
/*----------------------------------------------------------------------------- Name : btgLoad Description : load a btg scene into our structures Inputs : filename - the name of the btg file to load Outputs : Return : ----------------------------------------------------------------------------*/ void btgLoad(char* filename) { ubyte* btgData = NULL; ubyte* btgDataOffset = NULL; ubyte* instarp = NULL; udword headSize; udword vertSize; udword vertSizeFile; udword starSize, fileStarSize; udword polySize; real32 thetaSave, phiSave; udword i; #if FIX_ENDIAN Uint64 *swap; #endif #if BTG_VERBOSE_LEVEL >= 2 dbgMessagef("filename= %s", filename); #endif fileLoadAlloc(filename, (void**)&btgData, 0); btgDataOffset=btgData; memStrncpy(btgLastBackground, filename, 127); //reset / free any previous structures thetaSave = btgThetaOffset; phiSave = btgPhiOffset; btgReset(); btgThetaOffset = thetaSave; btgPhiOffset = phiSave; //header. trivial copy headSize = sizeof(btgHeader); btgHead = (btgHeader*)memAlloc(headSize, "btg header", 0); #if BTG_VERBOSE_LEVEL >=3 dbgMessagef("btgData= %x", btgData); dbgMessagef("btgHead= %x", btgHead); #endif // Hard coding sizeof values. // This is because they may change later on in the world but static in the file. // This allows us to align variables. It replaces // memcpy(btgHead, btgData, headSize); memset(btgHead,0,sizeof(btgHead)); memcpy( (ubyte*)btgHead+offsetof(btgHeader,btgFileVersion), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,numVerts ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,numStars ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,numPolys ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,xScroll ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,yScroll ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,zoomVal ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,pageWidth ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,pageHeight ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mRed ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mGreen ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mBlue ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mBGRed ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mBGGreen ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,mBGBlue ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,bVerts ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,bPolys ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,bStars ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,bOutlines ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,bBlends ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgHead+offsetof(btgHeader,renderMode ), btgDataOffset, 4 ); btgDataOffset += 4; // memcpy(btgHead, btgData, headSize); //See above. #if FIX_ENDIAN btgHead->btgFileVersion = FIX_ENDIAN_INT_32( btgHead->btgFileVersion ); btgHead->numVerts = FIX_ENDIAN_INT_32( btgHead->numVerts ); btgHead->numStars = FIX_ENDIAN_INT_32( btgHead->numStars ); btgHead->numPolys = FIX_ENDIAN_INT_32( btgHead->numPolys ); btgHead->xScroll = FIX_ENDIAN_INT_32( btgHead->xScroll ); btgHead->yScroll = FIX_ENDIAN_INT_32( btgHead->yScroll ); btgHead->zoomVal = FIX_ENDIAN_INT_32( btgHead->zoomVal ); btgHead->pageWidth = FIX_ENDIAN_INT_32( btgHead->pageWidth ); btgHead->pageHeight = FIX_ENDIAN_INT_32( btgHead->pageHeight ); btgHead->mRed = FIX_ENDIAN_INT_32( btgHead->mRed ); btgHead->mGreen = FIX_ENDIAN_INT_32( btgHead->mGreen ); btgHead->mBlue = FIX_ENDIAN_INT_32( btgHead->mBlue ); btgHead->mBGRed = FIX_ENDIAN_INT_32( btgHead->mBGRed ); btgHead->mBGGreen = FIX_ENDIAN_INT_32( btgHead->mBGGreen ); btgHead->mBGBlue = FIX_ENDIAN_INT_32( btgHead->mBGBlue ); btgHead->bVerts = FIX_ENDIAN_INT_32( btgHead->bVerts ); btgHead->bPolys = FIX_ENDIAN_INT_32( btgHead->bPolys ); btgHead->bStars = FIX_ENDIAN_INT_32( btgHead->bStars ); btgHead->bOutlines = FIX_ENDIAN_INT_32( btgHead->bOutlines ); btgHead->bBlends = FIX_ENDIAN_INT_32( btgHead->bBlends ); btgHead->renderMode = FIX_ENDIAN_INT_32( btgHead->renderMode ); #endif //set background colour universe.backgroundColor = colRGB(btgHead->mBGRed, btgHead->mBGGreen, btgHead->mBGBlue); //version check dbgAssertOrIgnore(btgHead->btgFileVersion == BTG_FILE_VERSION); vertSize = btgHead->numVerts * sizeof(btgVertex); //Machine Specific size vertSizeFile = btgHead->numVerts * (4 + (2* 8) + (5*4)); //Actual size from file. (No Alignment) if (vertSize) { btgVerts = (btgVertex*)memAlloc(vertSize, "btg verts", 0); for( i=0; i<btgHead->numVerts; i++ ) { memcpy( (ubyte*)btgVerts+ ( i * sizeof(btgVertex)) +offsetof(btgVertex,flags ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,x ), btgDataOffset, 8 ); btgDataOffset += 8; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,y ), btgDataOffset, 8 ); btgDataOffset += 8; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,red ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,green ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,blue ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,alpha ), btgDataOffset, 4 ); btgDataOffset += 4; memcpy( (ubyte*)btgVerts+( i * sizeof(btgVertex)) +offsetof(btgVertex,brightness ), btgDataOffset, 4 ); btgDataOffset += 4; } // memcpy(btgVerts, btgData + headSize, vertSize); //Replaced by above. #if FIX_ENDIAN for( i=0; i<btgHead->numVerts; i++ ) { btgVerts[i].flags = FIX_ENDIAN_INT_32( btgVerts[i].flags ); swap = ( Uint64 *)&btgVerts[i].x; *swap = SDL_SwapLE64( *swap ); swap = ( Uint64 *)&btgVerts[i].y; *swap = SDL_SwapLE64( *swap ); btgVerts[i].red = FIX_ENDIAN_INT_32( btgVerts[i].red ); btgVerts[i].green = FIX_ENDIAN_INT_32( btgVerts[i].green ); btgVerts[i].blue = FIX_ENDIAN_INT_32( btgVerts[i].blue ); btgVerts[i].alpha = FIX_ENDIAN_INT_32( btgVerts[i].alpha ); btgVerts[i].brightness = FIX_ENDIAN_INT_32( btgVerts[i].brightness ); } #endif } #if BTG_VERBOSE_LEVEL >= 2 dbgMessagef("numStars= %d", btgHead->numStars); #endif //stars. non-trivial munging around starSize = btgHead->numStars * sizeof(btgStar); fileStarSize = 0; if (starSize != 0) { btgStar* outstarp; btgStar* inp; udword* udp; sdword j, tempSize, count, length; char filename[48]; btgStars = (btgStar*)memAlloc(starSize, "btg stars", 0); instarp = btgDataOffset; #if BTG_VERBOSE_LEVEL >= 3 dbgMessagef("instarp= %x",instarp); dbgMessagef("Offset= %x",instarp - btgData); #endif outstarp = btgStars; inp = ( btgStar *)instarp; for (i = 0; i < btgHead->numStars; i++, outstarp++) { //extract constant-sized header // tempSize = sizeof(udword) + 2*sizeof(real64) + 4*sizeof(sdword); tempSize = 4 + 2*8 + 4*4; memcpy( (ubyte*)outstarp+offsetof(btgStar,flags), instarp, 4); instarp += 4; memcpy( (ubyte*)outstarp+offsetof(btgStar,x), instarp, 8); instarp += 8; memcpy( (ubyte*)outstarp+offsetof(btgStar,y), instarp, 8); instarp += 8; memcpy( (ubyte*)outstarp+offsetof(btgStar,red), instarp, 4); instarp += 4; memcpy( (ubyte*)outstarp+offsetof(btgStar,green), instarp, 4); instarp += 4; memcpy( (ubyte*)outstarp+offsetof(btgStar,blue), instarp, 4); instarp += 4; memcpy( (ubyte*)outstarp+offsetof(btgStar,alpha), instarp, 4); instarp += 4; // memcpy(outstarp, instarp, tempSize); //Replaced by Above. #if BTG_VERBOSE_LEVEL >= 3 dbgMessagef("tempSize= %x", tempSize); dbgMessagef("instarp= %x", instarp); #endif fileStarSize += tempSize; #if FIX_ENDIAN swap = ( Uint64 *)&outstarp->x; *swap = SDL_SwapLE64( *swap ); swap = ( Uint64 *)&outstarp->y; *swap = SDL_SwapLE64( *swap ); outstarp->flags = FIX_ENDIAN_INT_32( outstarp->flags ); outstarp->red = FIX_ENDIAN_INT_32( outstarp->red ); outstarp->green = FIX_ENDIAN_INT_32( outstarp->green ); outstarp->blue = FIX_ENDIAN_INT_32( outstarp->blue ); outstarp->alpha = FIX_ENDIAN_INT_32( outstarp->alpha ); #endif //extract variable-sized filename count = 0; memset(filename, 0, 48); udp = (udword*)instarp; #if FIX_ENDIAN length = FIX_ENDIAN_INT_32( (sdword)*udp ); #else length = (sdword)*udp; #endif #if BTG_VERBOSE_LEVEL >=4 dbgMessagef("instarp= %x", instarp); dbgMessagef("udp= %x", udp); dbgMessagef("length= %d", length); dbgMessagef("filename= %s", filename); #endif instarp += 4; fileStarSize += 4; for (j = 0; j < length; j++) { filename[count++] = *instarp++; fileStarSize++; } memcpy(outstarp->filename, filename, 48); //create a GL texture object if (!btgTexInList(filename)) { btgGetTexture(filename, &outstarp->glhandle, &outstarp->width, &outstarp->height); btgAddTexToList(filename, outstarp->glhandle, outstarp->width, outstarp->height); } else { btgFindTexture(filename, outstarp); } } } //reset the game's current texture, which now differs from the GL's trClearCurrent(); btgPolygon* polyOut; //polys. trivial copy polySize = btgHead->numPolys * sizeof(btgPolygon); if (polySize != 0) { btgPolys = (btgPolygon*)memAlloc(polySize, "btg polys", 0); polyOut= btgPolys; // HERE FIX IT HERE // memcpy(btgPolys, btgData + headSize + vertSize + fileStarSize, polySize); for( i=0; i<btgHead->numPolys; i++, polyOut++ ) { memcpy((ubyte*)polyOut+offsetof(btgPolygon,flags), instarp, 4); instarp += 4; memcpy((ubyte*)polyOut+offsetof(btgPolygon,v0), instarp, 4); instarp += 4; memcpy((ubyte*)polyOut+offsetof(btgPolygon,v1), instarp, 4); instarp += 4; memcpy((ubyte*)polyOut+offsetof(btgPolygon,v2), instarp, 4); instarp += 4; } #if FIX_ENDIAN for( i=0; i<btgHead->numPolys; i++ ) { btgPolys[i].flags = FIX_ENDIAN_INT_32( btgPolys[i].flags ); btgPolys[i].v0 = FIX_ENDIAN_INT_32( btgPolys[i].v0 ); btgPolys[i].v1 = FIX_ENDIAN_INT_32( btgPolys[i].v1 ); btgPolys[i].v2 = FIX_ENDIAN_INT_32( btgPolys[i].v2 ); } #endif } memFree(btgData); btgIndices = (uword*)memAlloc(3 * btgHead->numPolys * sizeof(uword), "btg indices", NonVolatile); if (useVBO) glGenBuffers(1, &vboIndices); #ifndef _WIN32_FIXME //spherically project things, blend colours, &c btgConvertVerts(); #endif }