2019-05-30 11:35:13 +00:00
|
|
|
#define WITHD3D
|
2019-05-15 14:52:37 +00:00
|
|
|
#include "common.h"
|
2019-06-12 17:05:06 +00:00
|
|
|
#include "patcher.h"
|
2019-06-30 10:53:39 +00:00
|
|
|
#include "Timecycle.h"
|
2019-06-12 17:05:06 +00:00
|
|
|
#include "skeleton.h"
|
2020-04-14 07:31:00 +00:00
|
|
|
#if defined(RWLIBS) && !defined(FINAL)
|
|
|
|
#include "rtcharse.h"
|
|
|
|
#pragma comment( lib, "rtcharse.lib" )
|
|
|
|
|
|
|
|
RtCharset *debugCharset;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void CreateDebugFont()
|
|
|
|
{
|
|
|
|
#if defined(RWLIBS) && !defined(FINAL)
|
|
|
|
RwRGBA color = { 255, 255, 128, 255 };
|
|
|
|
RwRGBA colorbg = { 0, 0, 0, 0 };
|
|
|
|
RtCharsetOpen();
|
|
|
|
debugCharset = RtCharsetCreate(&color, &colorbg);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void DestroyDebugFont()
|
|
|
|
{
|
|
|
|
#if defined(RWLIBS) && !defined(FINAL)
|
|
|
|
RtCharsetDestroy(debugCharset);
|
|
|
|
RtCharsetClose();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void ObrsPrintfString(const char *str, short x, short y)
|
|
|
|
{
|
|
|
|
#if defined(RWLIBS) && !defined(FINAL)
|
|
|
|
RtCharsetPrintBuffered(debugCharset, str, x, y, true);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void FlushObrsPrintfs()
|
|
|
|
{
|
|
|
|
#if defined(RWLIBS) && !defined(FINAL)
|
|
|
|
RtCharsetBufferFlush();
|
|
|
|
#endif
|
|
|
|
}
|
2019-05-15 14:52:37 +00:00
|
|
|
|
2019-06-17 13:32:38 +00:00
|
|
|
void *
|
|
|
|
RwMallocAlign(RwUInt32 size, RwUInt32 align)
|
|
|
|
{
|
|
|
|
void *mem = (void *)malloc(size + align);
|
|
|
|
|
2019-06-30 10:53:39 +00:00
|
|
|
ASSERT(mem != nil);
|
2019-06-17 13:32:38 +00:00
|
|
|
|
|
|
|
void *addr = (void *)((((RwUInt32)mem) + align) & ~(align - 1));
|
|
|
|
|
2019-06-30 10:53:39 +00:00
|
|
|
ASSERT(addr != nil);
|
2019-06-17 13:32:38 +00:00
|
|
|
|
|
|
|
*(((void **)addr) - 1) = mem;
|
|
|
|
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
RwFreeAlign(void *mem)
|
|
|
|
{
|
2019-06-30 10:53:39 +00:00
|
|
|
ASSERT(mem != nil);
|
2019-06-17 13:32:38 +00:00
|
|
|
|
|
|
|
void *addr = *(((void **)mem) - 1);
|
|
|
|
|
2019-06-30 10:53:39 +00:00
|
|
|
ASSERT(addr != nil);
|
2019-06-17 13:32:38 +00:00
|
|
|
|
|
|
|
free(addr);
|
|
|
|
}
|
|
|
|
|
2019-05-30 11:35:13 +00:00
|
|
|
void
|
|
|
|
DefinedState(void)
|
|
|
|
{
|
|
|
|
RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSWRAP);
|
|
|
|
RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)TRUE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEGOURAUD);
|
|
|
|
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEALPHAPRIMITIVEBUFFER, (void*)FALSE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEBORDERCOLOR, (void*)RWRGBALONG(0, 0, 0, 255));
|
|
|
|
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
|
|
|
|
RwRenderStateSet(rwRENDERSTATEFOGCOLOR,
|
|
|
|
(void*)RWRGBALONG(CTimeCycle::GetFogRed(), CTimeCycle::GetFogGreen(), CTimeCycle::GetFogBlue(), 255));
|
|
|
|
RwRenderStateSet(rwRENDERSTATEFOGTYPE, (void*)rwFOGTYPELINEAR);
|
|
|
|
RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
|
|
|
|
|
2020-04-15 12:05:24 +00:00
|
|
|
#ifdef LIBRW
|
|
|
|
#pragma message (" TODO: alphatest func")
|
|
|
|
#else
|
2019-05-30 11:35:13 +00:00
|
|
|
// D3D stuff
|
|
|
|
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
|
|
|
|
RwD3D8SetRenderState(D3DRS_ALPHAREF, 2);
|
2020-04-15 12:05:24 +00:00
|
|
|
#endif
|
2019-05-30 11:35:13 +00:00
|
|
|
}
|
2019-05-15 14:52:37 +00:00
|
|
|
|
2019-06-12 18:07:37 +00:00
|
|
|
RwFrame*
|
|
|
|
GetFirstFrameCallback(RwFrame *child, void *data)
|
|
|
|
{
|
|
|
|
*(RwFrame**)data = child;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwFrame*
|
|
|
|
GetFirstChild(RwFrame *frame)
|
|
|
|
{
|
|
|
|
RwFrame *child;
|
|
|
|
|
|
|
|
child = nil;
|
|
|
|
RwFrameForAllChildren(frame, GetFirstFrameCallback, &child);
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
2019-05-15 14:52:37 +00:00
|
|
|
RwObject*
|
|
|
|
GetFirstObjectCallback(RwObject *object, void *data)
|
|
|
|
{
|
|
|
|
*(RwObject**)data = object;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwObject*
|
|
|
|
GetFirstObject(RwFrame *frame)
|
|
|
|
{
|
|
|
|
RwObject *obj;
|
|
|
|
|
|
|
|
obj = nil;
|
|
|
|
RwFrameForAllObjects(frame, GetFirstObjectCallback, &obj);
|
|
|
|
return obj;
|
|
|
|
}
|
2019-06-12 17:05:06 +00:00
|
|
|
|
2019-06-12 18:07:37 +00:00
|
|
|
RpAtomic*
|
|
|
|
GetFirstAtomicCallback(RpAtomic *atm, void *data)
|
|
|
|
{
|
|
|
|
*(RpAtomic**)data = atm;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
RpAtomic*
|
|
|
|
GetFirstAtomic(RpClump *clump)
|
|
|
|
{
|
|
|
|
RpAtomic *atm;
|
|
|
|
|
|
|
|
atm = nil;
|
|
|
|
RpClumpForAllAtomics(clump, GetFirstAtomicCallback, &atm);
|
|
|
|
return atm;
|
|
|
|
}
|
|
|
|
|
2019-06-23 17:59:58 +00:00
|
|
|
RwTexture*
|
|
|
|
GetFirstTextureCallback(RwTexture *tex, void *data)
|
|
|
|
{
|
|
|
|
*(RwTexture**)data = tex;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwTexture*
|
|
|
|
GetFirstTexture(RwTexDictionary *txd)
|
|
|
|
{
|
|
|
|
RwTexture *tex;
|
|
|
|
|
|
|
|
tex = nil;
|
|
|
|
RwTexDictionaryForAllTextures(txd, GetFirstTextureCallback, &tex);
|
|
|
|
return tex;
|
|
|
|
}
|
|
|
|
|
2019-06-12 17:05:06 +00:00
|
|
|
void
|
|
|
|
CameraSize(RwCamera * camera, RwRect * rect,
|
|
|
|
RwReal viewWindow, RwReal aspectRatio)
|
|
|
|
{
|
|
|
|
if (camera)
|
|
|
|
{
|
|
|
|
RwVideoMode videoMode;
|
|
|
|
RwRect r;
|
2019-06-13 09:57:43 +00:00
|
|
|
RwRect origSize = { 0, 0, 0, 0 }; // FIX just to make the compier happy
|
2019-06-12 17:05:06 +00:00
|
|
|
RwV2d vw;
|
|
|
|
|
|
|
|
RwEngineGetVideoModeInfo(&videoMode,
|
|
|
|
RwEngineGetCurrentVideoMode());
|
|
|
|
|
|
|
|
origSize.w = RwRasterGetWidth(RwCameraGetRaster(camera));
|
|
|
|
origSize.h = RwRasterGetHeight(RwCameraGetRaster(camera));
|
|
|
|
|
|
|
|
if (!rect)
|
|
|
|
{
|
|
|
|
if (videoMode.flags & rwVIDEOMODEEXCLUSIVE)
|
|
|
|
{
|
|
|
|
/* For full screen applications, resizing the camera just doesn't
|
|
|
|
* make sense, use the video mode size.
|
|
|
|
*/
|
|
|
|
|
|
|
|
r.x = r.y = 0;
|
|
|
|
r.w = videoMode.width;
|
|
|
|
r.h = videoMode.height;
|
|
|
|
rect = &r;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
rect not specified - reuse current values
|
|
|
|
*/
|
|
|
|
r.w = RwRasterGetWidth(RwCameraGetRaster(camera));
|
|
|
|
r.h = RwRasterGetHeight(RwCameraGetRaster(camera));
|
|
|
|
r.x = r.y = 0;
|
|
|
|
rect = &r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (( origSize.w != rect->w ) && ( origSize.h != rect->h ))
|
|
|
|
{
|
|
|
|
RwRaster *raster;
|
|
|
|
RwRaster *zRaster;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroy rasters...
|
|
|
|
*/
|
|
|
|
|
|
|
|
raster = RwCameraGetRaster(camera);
|
|
|
|
if( raster )
|
|
|
|
{
|
|
|
|
RwRasterDestroy(raster);
|
|
|
|
}
|
|
|
|
|
|
|
|
zRaster = RwCameraGetZRaster(camera);
|
|
|
|
if( zRaster )
|
|
|
|
{
|
|
|
|
RwRasterDestroy(zRaster);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create new rasters...
|
|
|
|
*/
|
|
|
|
|
|
|
|
raster = RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPECAMERA);
|
|
|
|
zRaster = RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPEZBUFFER);
|
|
|
|
|
|
|
|
if( raster && zRaster )
|
2019-06-12 17:08:04 +00:00
|
|
|
{
|
|
|
|
RwCameraSetRaster(camera, raster);
|
|
|
|
RwCameraSetZRaster(camera, zRaster);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( raster )
|
|
|
|
{
|
|
|
|
RwRasterDestroy(raster);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( zRaster )
|
|
|
|
{
|
|
|
|
RwRasterDestroy(zRaster);
|
|
|
|
}
|
|
|
|
|
|
|
|
rect->x = origSize.x;
|
|
|
|
rect->y = origSize.y;
|
2019-06-12 18:07:37 +00:00
|
|
|
rect->w = origSize.w;
|
2019-06-12 17:08:04 +00:00
|
|
|
rect->h = origSize.h;
|
2019-06-12 17:05:06 +00:00
|
|
|
|
2019-06-12 17:08:04 +00:00
|
|
|
/*
|
|
|
|
* Use default values...
|
|
|
|
*/
|
|
|
|
raster =
|
|
|
|
RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPECAMERA);
|
2019-06-12 17:05:06 +00:00
|
|
|
|
2019-06-12 17:08:04 +00:00
|
|
|
zRaster =
|
|
|
|
RwRasterCreate(rect->w, rect->h, 0, rwRASTERTYPEZBUFFER);
|
2019-06-12 17:05:06 +00:00
|
|
|
|
2019-06-12 17:08:04 +00:00
|
|
|
RwCameraSetRaster(camera, raster);
|
|
|
|
RwCameraSetZRaster(camera, zRaster);
|
|
|
|
}
|
2019-06-12 17:05:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Figure out the view window */
|
|
|
|
if (videoMode.flags & rwVIDEOMODEEXCLUSIVE)
|
|
|
|
{
|
|
|
|
/* derive ratio from aspect ratio */
|
|
|
|
vw.x = viewWindow;
|
|
|
|
vw.y = viewWindow / aspectRatio;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* derive from pixel ratios */
|
|
|
|
if (rect->w > rect->h)
|
|
|
|
{
|
|
|
|
vw.x = viewWindow;
|
|
|
|
vw.y = (rect->h * viewWindow) / rect->w;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vw.x = (rect->w * viewWindow) / rect->h;
|
|
|
|
vw.y = viewWindow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RwCameraSetViewWindow(camera, &vw);
|
|
|
|
|
|
|
|
RsGlobal.width = rect->w;
|
|
|
|
RsGlobal.height = rect->h;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CameraDestroy(RwCamera *camera)
|
|
|
|
{
|
|
|
|
RwRaster *raster, *tmpRaster;
|
|
|
|
RwFrame *frame;
|
|
|
|
|
|
|
|
if (camera)
|
|
|
|
{
|
|
|
|
frame = RwCameraGetFrame(camera);
|
|
|
|
if (frame)
|
|
|
|
{
|
|
|
|
RwFrameDestroy(frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
raster = RwCameraGetRaster(camera);
|
|
|
|
if (raster)
|
|
|
|
{
|
|
|
|
tmpRaster = RwRasterGetParent(raster);
|
|
|
|
|
|
|
|
RwRasterDestroy(raster);
|
|
|
|
|
2019-06-30 10:53:39 +00:00
|
|
|
if ((tmpRaster != nil) && (tmpRaster != raster))
|
2019-06-12 17:05:06 +00:00
|
|
|
{
|
|
|
|
RwRasterDestroy(tmpRaster);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
raster = RwCameraGetZRaster(camera);
|
|
|
|
if (raster)
|
|
|
|
{
|
|
|
|
tmpRaster = RwRasterGetParent(raster);
|
|
|
|
|
|
|
|
RwRasterDestroy(raster);
|
|
|
|
|
2019-06-30 10:53:39 +00:00
|
|
|
if ((tmpRaster != nil) && (tmpRaster != raster))
|
2019-06-12 17:05:06 +00:00
|
|
|
{
|
|
|
|
RwRasterDestroy(tmpRaster);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RwCameraDestroy(camera);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwCamera *
|
|
|
|
CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
|
|
|
|
{
|
|
|
|
RwCamera *camera;
|
|
|
|
|
|
|
|
camera = RwCameraCreate();
|
|
|
|
|
|
|
|
if (camera)
|
|
|
|
{
|
|
|
|
RwCameraSetFrame(camera, RwFrameCreate());
|
|
|
|
RwCameraSetRaster(camera,
|
|
|
|
RwRasterCreate(0, 0, 0, rwRASTERTYPECAMERA));
|
|
|
|
|
|
|
|
if (zBuffer)
|
|
|
|
{
|
|
|
|
RwCameraSetZRaster(camera,
|
|
|
|
RwRasterCreate(0, 0, 0,
|
|
|
|
rwRASTERTYPEZBUFFER));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* now check that everything is valid */
|
|
|
|
if (RwCameraGetFrame(camera) &&
|
|
|
|
RwCameraGetRaster(camera) &&
|
|
|
|
RwRasterGetParent(RwCameraGetRaster(camera)) &&
|
|
|
|
(!zBuffer || (RwCameraGetZRaster(camera) &&
|
|
|
|
RwRasterGetParent(RwCameraGetZRaster
|
|
|
|
(camera)))))
|
|
|
|
{
|
|
|
|
/* everything OK */
|
|
|
|
return (camera);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we're here then an error must have occurred so clean up */
|
|
|
|
|
|
|
|
CameraDestroy(camera);
|
2019-06-30 10:53:39 +00:00
|
|
|
return (nil);
|
2019-06-12 17:05:06 +00:00
|
|
|
}
|
|
|
|
|
2020-04-17 05:54:14 +00:00
|
|
|
#ifdef USE_TEXTURE_POOL
|
2020-03-28 20:55:23 +00:00
|
|
|
WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); }
|
|
|
|
WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); }
|
2020-04-17 05:54:14 +00:00
|
|
|
#endif
|
2020-03-22 14:23:40 +00:00
|
|
|
|
2019-06-12 17:05:06 +00:00
|
|
|
STARTPATCHES
|
2019-06-12 17:08:04 +00:00
|
|
|
//InjectHook(0x526450, GetFirstObjectCallback, PATCH_JUMP);
|
2019-06-12 17:05:06 +00:00
|
|
|
InjectHook(0x526460, GetFirstObject, PATCH_JUMP);
|
|
|
|
InjectHook(0x527170, CameraSize, PATCH_JUMP);
|
|
|
|
InjectHook(0x527340, CameraDestroy, PATCH_JUMP);
|
|
|
|
InjectHook(0x5273B0, CameraCreate, PATCH_JUMP);
|
2019-06-12 18:07:37 +00:00
|
|
|
ENDPATCHES
|