Uint64 SDL_ReadLE64 (SDL_RWops *src) { Uint64 value; SDL_RWread(src, &value, (sizeof value), 1); return(SDL_SwapLE64(value)); }
// endian-swapping fwrite size_t efwrite( void *buffer, size_t size, size_t num, FILE *stream ) { void *swap_buffer; switch (size) { case 2: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint16 *)swap_buffer)[i] = SDL_SwapLE16(((Uint16 *)buffer)[i]); break; case 4: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint32 *)swap_buffer)[i] = SDL_SwapLE32(((Uint32 *)buffer)[i]); break; case 8: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint64 *)swap_buffer)[i] = SDL_SwapLE64(((Uint64 *)buffer)[i]); break; default: swap_buffer = buffer; break; } size_t f = fwrite(swap_buffer, size, num, stream); if (swap_buffer != buffer) free(swap_buffer); return f; }
Uint64 SDL_ReadLE64(SDL_RWops * src) { Uint64 value = 0; SDL_RWread(src, &value, sizeof (value), 1); return SDL_SwapLE64(value); }
Uint64 IFileStream::readUint64() { Uint64 tmp; if(fread(&tmp,sizeof(Uint64),1,fp) != 1) { if(feof(fp) != 0) { throw InputStream::eof("IFileStream::readUint64(): End-of-File reached!"); } else { throw InputStream::error("IFileStream::readUint64(): An I/O-Error occurred!"); } } return SDL_SwapLE64(tmp); }
/** * Optimized 8 bit zoomer for resizing by a factor of 4. Doesn't flip. * Used internally by _zoomSurfaceY() below. * source and dest. widths must be multiples of 8 bytes for 64-bit access */ static int zoomSurface4X_64bit(SDL_Surface *src, SDL_Surface *dst) { Uint64 dataSrc; Uint64 dataDst; Uint8 *pixelSrc = (Uint8*)src->pixels; Uint8 *pixelDstRow = (Uint8*)dst->pixels; int sx, sy; static bool proclaimed = false; if (!proclaimed) { proclaimed = true; Log(LOG_INFO) << "Using modestly fast 4X zoom routine."; } for (sy = 0; sy < src->h; ++sy, pixelDstRow += dst->pitch*4) { Uint8 *pixelDst = pixelDstRow; for (sx = 0; sx < src->w; sx += 8, pixelSrc += 8) { dataSrc = *((Uint64*) pixelSrc); // boo (void)SDL_SwapLE64(dataSrc); /* expanded form of of data shift: dataDst = (dataSrc & 0xFF) | ((dataSrc & 0xFF) << 8) | ((dataSrc & 0xFF) << 16 | ((datasrc & 0xFF) << 24) | ((dataSrc & 0xFF00 ) << 24) | ((dataSrc & 0xFF00) << 32) | ((dataSrc & 0xFF00 ) << 40) | ((dataSrc & 0xFF00) << 48) ; */ for (int i = 0; i < 4; ++i) { // compact form, combining terms with equal multipliers (shifts) dataDst = (dataSrc & 0xFF) | ((dataSrc & 0xFF) << 8) | ((dataSrc & 0xFF) << 16) | ((dataSrc & 0xFFFF ) << 24) | ((dataSrc & 0xFF00) << 32) | ((dataSrc & 0xFF00 ) << 40) | ((dataSrc & 0xFF00) << 48) ; *((Uint64*)pixelDst) = dataDst; *((Uint64*)(pixelDst + dst->pitch)) = dataDst; *((Uint64*)(pixelDst + dst->pitch*2)) = dataDst; *((Uint64*)(pixelDst + dst->pitch*3)) = dataDst; pixelDst+=8; // forward 8 bytes! dataSrc >>= 16; } } } return 0; }
// endian-swapping fwrite that dies if the expected amount cannot be written size_t efwrite( const void *buffer, size_t size, size_t num, FILE *stream ) { void *swap_buffer = NULL; switch (size) { #if SDL_BYTEORDER == SDL_BIG_ENDIAN case 2: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint16 *)swap_buffer)[i] = SDL_SwapLE16(((Uint16 *)buffer)[i]); buffer = swap_buffer; break; case 4: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint32 *)swap_buffer)[i] = SDL_SwapLE32(((Uint32 *)buffer)[i]); buffer = swap_buffer; break; case 8: swap_buffer = malloc(size * num); for (size_t i = 0; i < num; i++) ((Uint64 *)swap_buffer)[i] = SDL_SwapLE64(((Uint64 *)buffer)[i]); buffer = swap_buffer; break; #endif default: break; } size_t num_written = fwrite(buffer, size, num, stream); if (swap_buffer != NULL) free(swap_buffer); if (num_written != num) { fprintf(stderr, "error: An unexpected problem occurred while writing to a file.\n"); JE_tyrianHalt(1); } return num_written; }
int SDL_WriteLE64 (SDL_RWops *dst, Uint64 value) { value = SDL_SwapLE64(value); return(SDL_RWwrite(dst, &value, (sizeof value), 1)); }
/*----------------------------------------------------------------------------- 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 }
size_t SDL_WriteLE64(SDL_RWops * dst, Uint64 value) { const Uint64 swapped = SDL_SwapLE64(value); return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); }