implemented GTA stream read functions
This commit is contained in:
parent
12697a8553
commit
b4afb591a7
|
@ -66,4 +66,8 @@ project "re3"
|
|||
defines { "NDEBUG" }
|
||||
optimize "On"
|
||||
staticruntime "on"
|
||||
filter "configurations:DebugCI"
|
||||
defines { "DEBUG" }
|
||||
staticruntime "on"
|
||||
symbols "On"
|
||||
|
||||
|
|
|
@ -163,8 +163,8 @@ myfseek(int fd, long offset, int whence)
|
|||
static int
|
||||
myfeof(int fd)
|
||||
{
|
||||
// return feof(myfiles[fd].file);
|
||||
return ferror(myfiles[fd].file);
|
||||
return feof(myfiles[fd].file);
|
||||
// return ferror(myfiles[fd].file);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
|
||||
struct rpGeometryList
|
||||
{
|
||||
RpGeometry **geometries;
|
||||
int32 numGeoms;
|
||||
};
|
||||
|
||||
struct rpAtomicBinary
|
||||
{
|
||||
RwInt32 frameIndex;
|
||||
RwInt32 geomIndex;
|
||||
RwInt32 flags;
|
||||
RwInt32 unused;
|
||||
};
|
||||
|
||||
static int32 numberGeometrys;
|
||||
static int32 streamPosition;
|
||||
static rpGeometryList gGeomList;
|
||||
static rwFrameList gFrameList;
|
||||
static RpClumpChunkInfo gClumpInfo;
|
||||
|
||||
rpGeometryList*
|
||||
GeometryListStreamRead1(RwStream *stream, rpGeometryList *geomlist)
|
||||
{
|
||||
int i;
|
||||
RwUInt32 size, version;
|
||||
RwInt32 numGeoms;
|
||||
|
||||
numberGeometrys = 0;
|
||||
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
|
||||
return nil;
|
||||
assert(size == 4);
|
||||
if(RwStreamRead(stream, &numGeoms, 4) != 4)
|
||||
return nil;
|
||||
|
||||
numberGeometrys = numGeoms/2;
|
||||
geomlist->numGeoms = numGeoms;
|
||||
if(geomlist->numGeoms > 0){
|
||||
geomlist->geometries = (RpGeometry**)RwMalloc(geomlist->numGeoms * sizeof(RpGeometry*));
|
||||
if(geomlist->geometries == nil)
|
||||
return nil;
|
||||
memset(geomlist->geometries, 0, geomlist->numGeoms * sizeof(RpGeometry*));
|
||||
}else
|
||||
geomlist->geometries = nil;
|
||||
|
||||
for(i = 0; i < numberGeometrys; i++){
|
||||
if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version))
|
||||
return nil;
|
||||
geomlist->geometries[i] = RpGeometryStreamRead(stream);
|
||||
if(geomlist->geometries[i] == nil)
|
||||
return nil;
|
||||
}
|
||||
|
||||
return geomlist;
|
||||
}
|
||||
|
||||
rpGeometryList*
|
||||
GeometryListStreamRead2(RwStream *stream, rpGeometryList *geomlist)
|
||||
{
|
||||
int i;
|
||||
RwUInt32 version;
|
||||
|
||||
for(i = numberGeometrys; i < geomlist->numGeoms; i++){
|
||||
if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version))
|
||||
return nil;
|
||||
geomlist->geometries[i] = RpGeometryStreamRead(stream);
|
||||
if(geomlist->geometries[i] == nil)
|
||||
return nil;
|
||||
}
|
||||
|
||||
return geomlist;
|
||||
}
|
||||
|
||||
void
|
||||
GeometryListDeinitialize(rpGeometryList *geomlist)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < geomlist->numGeoms; i++)
|
||||
if(geomlist->geometries[i])
|
||||
RpGeometryDestroy(geomlist->geometries[i]);
|
||||
|
||||
if(geomlist->numGeoms){
|
||||
RwFree(geomlist->geometries);
|
||||
geomlist->numGeoms = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RpAtomic*
|
||||
ClumpAtomicStreamRead(RwStream *stream, rwFrameList *frmList, rpGeometryList *geomList)
|
||||
{
|
||||
RwUInt32 size, version;
|
||||
rpAtomicBinary a;
|
||||
RpAtomic *atomic;
|
||||
|
||||
numberGeometrys = 0;
|
||||
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
|
||||
return nil;
|
||||
assert(size <= sizeof(rpAtomicBinary));
|
||||
if(RwStreamRead(stream, &a, size) != size)
|
||||
return nil;
|
||||
|
||||
atomic = RpAtomicCreate();
|
||||
if(atomic == nil)
|
||||
return nil;
|
||||
|
||||
RpAtomicSetFlags(atomic, a.flags);
|
||||
|
||||
if(frmList->numFrames){
|
||||
assert(a.frameIndex < frmList->numFrames);
|
||||
RpAtomicSetFrame(atomic, frmList->frames[a.frameIndex]);
|
||||
}
|
||||
|
||||
if(geomList->numGeoms){
|
||||
assert(a.geomIndex < geomList->numGeoms);
|
||||
RpAtomicSetGeometry(atomic, geomList->geometries[a.geomIndex], 0);
|
||||
}else{
|
||||
RpGeometry *geom;
|
||||
if(!RwStreamFindChunk(stream, rwID_GEOMETRY, nil, &version)){
|
||||
RpAtomicDestroy(atomic);
|
||||
return nil;
|
||||
}
|
||||
geom = RpGeometryStreamRead(stream);
|
||||
if(geom == nil){
|
||||
RpAtomicDestroy(atomic);
|
||||
return nil;
|
||||
}
|
||||
RpAtomicSetGeometry(atomic, geom, 0);
|
||||
RpGeometryDestroy(geom);
|
||||
}
|
||||
|
||||
return atomic;
|
||||
}
|
||||
|
||||
bool
|
||||
RpClumpGtaStreamRead1(RwStream *stream)
|
||||
{
|
||||
RwUInt32 size, version;
|
||||
|
||||
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
|
||||
return false;
|
||||
if(version >= 0x33000){
|
||||
assert(size == 12);
|
||||
if(RwStreamRead(stream, &gClumpInfo, 12) != 12)
|
||||
return false;
|
||||
}else{
|
||||
assert(size == 4);
|
||||
if(RwStreamRead(stream, &gClumpInfo, 4) != 4)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!RwStreamFindChunk(stream, rwID_FRAMELIST, nil, &version))
|
||||
return false;
|
||||
if(_rwFrameListStreamRead(stream, &gFrameList) == nil)
|
||||
return false;
|
||||
|
||||
if(!RwStreamFindChunk(stream, rwID_GEOMETRYLIST, nil, &version)){
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
return false;
|
||||
}
|
||||
if(GeometryListStreamRead1(stream, &gGeomList) == nil){
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
return false;
|
||||
}
|
||||
streamPosition = stream->Type.memory.position;
|
||||
return true;
|
||||
}
|
||||
|
||||
RpClump*
|
||||
RpClumpGtaStreamRead2(RwStream *stream)
|
||||
{
|
||||
int i;
|
||||
RwUInt32 version;
|
||||
RpAtomic *atomic;
|
||||
RpClump *clump;
|
||||
|
||||
clump = RpClumpCreate();
|
||||
if(clump == nil)
|
||||
return nil;
|
||||
|
||||
RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
|
||||
|
||||
if(GeometryListStreamRead2(stream, &gGeomList) == nil){
|
||||
GeometryListDeinitialize(&gGeomList);
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
RpClumpDestroy(clump);
|
||||
return nil;
|
||||
}
|
||||
|
||||
RpClumpSetFrame(clump, gFrameList.frames[0]);
|
||||
|
||||
for(i = 0; i < gClumpInfo.numAtomics; i++){
|
||||
if(!RwStreamFindChunk(stream, rwID_ATOMIC, nil, &version)){
|
||||
GeometryListDeinitialize(&gGeomList);
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
RpClumpDestroy(clump);
|
||||
return nil;
|
||||
}
|
||||
|
||||
atomic = ClumpAtomicStreamRead(stream, &gFrameList, &gGeomList);
|
||||
if(atomic == nil){
|
||||
GeometryListDeinitialize(&gGeomList);
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
RpClumpDestroy(clump);
|
||||
return nil;
|
||||
}
|
||||
|
||||
RpClumpAddAtomic(clump, atomic);
|
||||
}
|
||||
|
||||
GeometryListDeinitialize(&gGeomList);
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
return clump;
|
||||
}
|
||||
|
||||
void
|
||||
RpClumpGtaCancelStream(void)
|
||||
{
|
||||
GeometryListDeinitialize(&gGeomList);
|
||||
rwFrameListDeinitialize(&gFrameList);
|
||||
gFrameList.numFrames = 0;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x526060, RpClumpGtaStreamRead1, PATCH_JUMP);
|
||||
InjectHook(0x526180, RpClumpGtaStreamRead2, PATCH_JUMP);
|
||||
InjectHook(0x5262D0, RpClumpGtaCancelStream, PATCH_JUMP);
|
||||
ENDPATCHES
|
|
@ -88,7 +88,7 @@ CameraSize(RwCamera * camera, RwRect * rect,
|
|||
{
|
||||
RwVideoMode videoMode;
|
||||
RwRect r;
|
||||
RwRect origSize;
|
||||
RwRect origSize = { 0, 0, 0, 0 }; // FIX just to make the compier happy
|
||||
RwV2d vw;
|
||||
|
||||
RwEngineGetVideoModeInfo(&videoMode,
|
||||
|
|
|
@ -5,6 +5,11 @@ RwFrame *GetFirstChild(RwFrame *frame);
|
|||
RwObject *GetFirstObject(RwFrame *frame);
|
||||
RpAtomic *GetFirstAtomic(RpClump *clump);
|
||||
|
||||
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
|
||||
bool RpClumpGtaStreamRead1(RwStream *stream);
|
||||
RpClump *RpClumpGtaStreamRead2(RwStream *stream);
|
||||
void RpClumpGtaCancelStream(void);
|
||||
|
||||
void CameraSize(RwCamera *camera,
|
||||
RwRect *rect,
|
||||
RwReal viewWindow,
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
|
||||
RwTexture*
|
||||
RwTextureGtaStreamRead(RwStream *stream)
|
||||
{
|
||||
RwUInt32 size, version;
|
||||
RwTexture *tex;
|
||||
|
||||
if(!RwStreamFindChunk(stream, rwID_TEXTURENATIVE, &size, &version))
|
||||
return nil;
|
||||
|
||||
// TODO: unused timing
|
||||
|
||||
if(!RWSRCGLOBAL(stdFunc[rwSTANDARDNATIVETEXTUREREAD](stream, &tex, size)))
|
||||
return nil;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
RwTexture*
|
||||
destroyTexture(RwTexture *texture, void *data)
|
||||
{
|
||||
RwTextureDestroy(texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
RwTexDictionary*
|
||||
RwTexDictionaryGtaStreamRead(RwStream *stream)
|
||||
{
|
||||
RwUInt32 size, version;
|
||||
RwInt32 numTextures;
|
||||
RwTexDictionary *texDict;
|
||||
RwTexture *tex;
|
||||
|
||||
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
|
||||
return nil;
|
||||
assert(size == 4);
|
||||
if(RwStreamRead(stream, &numTextures, size) != size)
|
||||
return nil;
|
||||
|
||||
texDict = RwTexDictionaryCreate();
|
||||
if(texDict == nil)
|
||||
return nil;
|
||||
|
||||
while(numTextures--){
|
||||
tex = RwTextureGtaStreamRead(stream);
|
||||
if(tex == nil){
|
||||
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
|
||||
RwTexDictionaryDestroy(texDict);
|
||||
return nil;
|
||||
}
|
||||
RwTexDictionaryAddTexture(texDict, tex);
|
||||
}
|
||||
|
||||
return texDict;
|
||||
}
|
||||
|
||||
static int32 numberTextures = -1;
|
||||
static int32 streamPosition;
|
||||
|
||||
RwTexDictionary*
|
||||
RwTexDictionaryGtaStreamRead1(RwStream *stream)
|
||||
{
|
||||
RwUInt32 size, version;
|
||||
RwInt32 numTextures;
|
||||
RwTexDictionary *texDict;
|
||||
RwTexture *tex;
|
||||
|
||||
numberTextures = 0;
|
||||
if(!RwStreamFindChunk(stream, rwID_STRUCT, &size, &version))
|
||||
return nil;
|
||||
assert(size == 4);
|
||||
if(RwStreamRead(stream, &numTextures, size) != size)
|
||||
return nil;
|
||||
|
||||
texDict = RwTexDictionaryCreate();
|
||||
if(texDict == nil)
|
||||
return nil;
|
||||
|
||||
numberTextures = numTextures/2;
|
||||
|
||||
while(numTextures > numberTextures){
|
||||
numTextures--;
|
||||
|
||||
tex = RwTextureGtaStreamRead(stream);
|
||||
if(tex == nil){
|
||||
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
|
||||
RwTexDictionaryDestroy(texDict);
|
||||
return nil;
|
||||
}
|
||||
RwTexDictionaryAddTexture(texDict, tex);
|
||||
}
|
||||
|
||||
numberTextures = numTextures;
|
||||
streamPosition = stream->Type.memory.position;
|
||||
|
||||
return texDict;
|
||||
}
|
||||
|
||||
RwTexDictionary*
|
||||
RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
|
||||
{
|
||||
RwTexture *tex;
|
||||
|
||||
RwStreamSkip(stream, streamPosition - stream->Type.memory.position);
|
||||
|
||||
while(numberTextures--){
|
||||
tex = RwTextureGtaStreamRead(stream);
|
||||
if(tex == nil){
|
||||
RwTexDictionaryForAllTextures(texDict, destroyTexture, nil);
|
||||
RwTexDictionaryDestroy(texDict);
|
||||
return nil;
|
||||
}
|
||||
RwTexDictionaryAddTexture(texDict, tex);
|
||||
}
|
||||
|
||||
return texDict;
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x592380, RwTextureGtaStreamRead, PATCH_JUMP);
|
||||
InjectHook(0x5924A0, RwTexDictionaryGtaStreamRead, PATCH_JUMP);
|
||||
InjectHook(0x592550, RwTexDictionaryGtaStreamRead1, PATCH_JUMP);
|
||||
InjectHook(0x592650, RwTexDictionaryGtaStreamRead2, PATCH_JUMP);
|
||||
ENDPATCHES
|
|
@ -2,11 +2,9 @@
|
|||
#include "patcher.h"
|
||||
#include "templates.h"
|
||||
#include "Streaming.h"
|
||||
#include "RwHelper.h"
|
||||
#include "TxdStore.h"
|
||||
|
||||
WRAPPER RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream) { EAXJMP(0x5924A0); }
|
||||
|
||||
|
||||
CPool<TxdDef,TxdDef> *&CTxdStore::ms_pTxdPool = *(CPool<TxdDef,TxdDef>**)0x8F5FB8;
|
||||
RwTexDictionary *&CTxdStore::ms_pStoredTxd = *(RwTexDictionary**)0x9405BC;
|
||||
|
||||
|
|
Loading…
Reference in New Issue