Port XboxHandsVC
Based on https://github.com/gennariarmando/gtavc-xbox-hands
This commit is contained in:
@@ -18,7 +18,7 @@ CXX = $(PREFIX)-g++
|
||||
ARCH := -mtune=cortex-a9 -march=armv7-a -mfpu=neon
|
||||
CFLAGS := -g -Wl,-q,--no-enum-size-warning -fno-short-enums -fno-optimize-sibling-calls -O2 -ftree-vectorize -mfloat-abi=hard -fno-builtin-memcpy $(ARCH) $(DEFINES)
|
||||
CFLAGS += $(INCLUDE) -DPSP2 -DMASTER -DLIBRW -DRW_GL3 -DAUDIO_OAL -DLIBRW_GLAD
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
LIBS := -lrw -lopenal -lSDL2 -lvita2d -lvitaGL -lSceAppMgr_stub -lSceDisplay_stub -lSceCommonDialog_stub -lSceLibKernel_stub \
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ColStore.h"
|
||||
#include "Radar.h"
|
||||
#include "Pools.h"
|
||||
#include "CutsceneHands.h"
|
||||
|
||||
const struct {
|
||||
const char *szTrackName;
|
||||
@@ -204,6 +205,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
|
||||
|
||||
strcpy(ms_cutsceneName, szCutsceneName);
|
||||
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::InitXML();
|
||||
#endif
|
||||
|
||||
RwStream *stream;
|
||||
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG");
|
||||
assert(stream);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Cranes.h"
|
||||
#include "Credits.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "CutsceneHands.h"
|
||||
#include "DMAudio.h"
|
||||
#include "Darkel.h"
|
||||
#include "Debug.h"
|
||||
@@ -585,6 +586,10 @@ bool CGame::Initialise(const char* datFile)
|
||||
|
||||
DMAudio.SetStartingTrackPositions(TRUE);
|
||||
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
|
||||
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::Initialise();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -25,6 +25,7 @@
|
||||
#include "Population.h"
|
||||
#include "Gangs.h"
|
||||
#include "CutsceneMgr.h"
|
||||
#include "CutsceneHands.h"
|
||||
#include "CdStream.h"
|
||||
#include "Streaming.h"
|
||||
#include "Replay.h"
|
||||
@@ -1055,17 +1056,28 @@ void
|
||||
CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags)
|
||||
{
|
||||
RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags);
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::RequestSpecialChar(charId, modelName);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
CStreaming::HasSpecialCharLoaded(int32 id)
|
||||
{
|
||||
return HasModelLoaded(id + MI_SPECIAL01);
|
||||
bool loaded = HasModelLoaded(id + MI_SPECIAL01);
|
||||
#ifdef CUTSCENE_HANDS
|
||||
if(loaded)
|
||||
CutsceneHands::SpecialCharLoaded(id);
|
||||
#endif
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void
|
||||
CStreaming::SetMissionDoesntRequireSpecialChar(int32 id)
|
||||
{
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::UnloadSpecialChar(id);
|
||||
#endif
|
||||
return SetMissionDoesntRequireModel(id + MI_SPECIAL01);
|
||||
}
|
||||
|
||||
|
||||
@@ -355,6 +355,9 @@ enum Config {
|
||||
#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
||||
#define SCREEN_DROPLETS // neo water droplets
|
||||
#define NEW_RENDERER // leeds-like world rendering, needs librw
|
||||
#ifdef RT
|
||||
#define CUTSCENE_HANDS // Xbox HD cutscene hands (ported from XboxHandsVC.asi); RT-only (10thAE/Vanilla mod builds), needs assets, self-disables if absent
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FIX_SPRITES // fix sprites aspect ratio(moon, coronas, particle etc)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef CUTSCENE_HANDS
|
||||
|
||||
// HD cutscene hands, backported from the Xbox version of GTA:VC.
|
||||
// Ported from the "XboxHandsVC" plugin-sdk mod (XboxHandsVC.asi) into native
|
||||
// re3/reVC source: the plugin's address hooks become direct calls from
|
||||
// CCutsceneObject / CCutsceneMgr / CStreaming, and its RenderWare skin/HAnim
|
||||
// calls are mapped onto librw.
|
||||
//
|
||||
// SAFETY: the feature is fully opt-in on the assets. Initialise() only flips
|
||||
// ms_enabled to true when EVERY required asset loads (anim/CSHands.txd,
|
||||
// anim/CSHands.dff, the four anim/*.anm files, data/CutsceneHands.xml). If any
|
||||
// is missing or fails to parse, ms_enabled stays false, a note is logged, and
|
||||
// every entry point below becomes a no-op. The game then runs exactly as stock
|
||||
// -- the original mod called exit(1) on a missing model; we never do that.
|
||||
|
||||
class CObject;
|
||||
|
||||
class CutsceneHands
|
||||
{
|
||||
public:
|
||||
static bool ms_enabled; // true only after all assets loaded successfully
|
||||
|
||||
// Lifecycle (call once RenderWare + streaming/TxdStore are up, and at shutdown)
|
||||
static void Initialise(void); // loads txd/dff/anm/xml; sets ms_enabled
|
||||
static void Shutdown(void);
|
||||
|
||||
// CCutsceneMgr::LoadCutsceneData -> (re)parse the per-cutscene config
|
||||
static void InitXML(void);
|
||||
|
||||
// Special-character streaming (CStreaming request/loaded/remove for cutscene actors)
|
||||
static void RequestSpecialChar(int slot, const char *name);
|
||||
static void SpecialCharLoaded(int id);
|
||||
static void UnloadSpecialChar(int id);
|
||||
|
||||
// CCutsceneObject render hooks
|
||||
static void PreRender(CObject *obj); // attach + pose the HD hands, atrophy stock hand bones
|
||||
static void Render(CObject *obj); // draw the HD hand atomics for this actor
|
||||
};
|
||||
|
||||
#endif // CUTSCENE_HANDS
|
||||
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#ifdef CUTSCENE_HANDS
|
||||
|
||||
// Small RenderWare helpers for the cutscene-hands port. The original mod's Utils.h
|
||||
// reimplemented these with hardcoded retail-VC addresses and RW-SDK struct field
|
||||
// names; none of that exists here, so everything is redone on top of librw (via the
|
||||
// fakerw layer, which already provides the native RpHAnim*/RpClump*/RwStream* API).
|
||||
|
||||
#include "rwcore.h"
|
||||
#include "rpworld.h"
|
||||
#include "rphanim.h"
|
||||
#include "rpskin.h"
|
||||
|
||||
// Load a .dff clump from a loose file. Returns nil on any failure (caller decides).
|
||||
static RpClump *CutsceneHands_LoadClump(const char *name)
|
||||
{
|
||||
RwStream *stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, name);
|
||||
if(stream == nil)
|
||||
return nil;
|
||||
RpClump *out = nil;
|
||||
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
|
||||
out = RpClumpStreamRead(stream);
|
||||
RwStreamClose(stream, nil);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Load a RenderWare .anm (HAnim animation) from a loose file. nil on failure.
|
||||
static RpHAnimAnimation *CutsceneHands_LoadAnm(const char *name)
|
||||
{
|
||||
RwStream *stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, name);
|
||||
if(stream == nil)
|
||||
return nil;
|
||||
RpHAnimAnimation *out = nil;
|
||||
if(RwStreamFindChunk(stream, rwID_HANIMANIMATION, nil, nil))
|
||||
out = RpHAnimAnimationStreamRead(stream);
|
||||
RwStreamClose(stream, nil);
|
||||
return out;
|
||||
}
|
||||
|
||||
static RpAtomic *CutsceneHands_GetHierCB(RpAtomic *atomic, void *data)
|
||||
{
|
||||
*(RpHAnimHierarchy**)data = RpSkinAtomicGetHAnimHierarchy(atomic);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// First skinned atomic's HAnim hierarchy in a clump.
|
||||
static RpHAnimHierarchy *CutsceneHands_GetHierarchy(RpClump *clump)
|
||||
{
|
||||
RpHAnimHierarchy *hier = nil;
|
||||
RpClumpForAllAtomics(clump, CutsceneHands_GetHierCB, &hier);
|
||||
return hier;
|
||||
}
|
||||
|
||||
#endif // CUTSCENE_HANDS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,230 @@
|
||||
//base code from unknown
|
||||
//psksvp@ccs.neu.edu has added/modified this code.
|
||||
#ifndef __XML_LIBRARY__
|
||||
#define __XML_LIBRARY__
|
||||
|
||||
#include "config.h"
|
||||
#ifdef CUTSCENE_HANDS // only built for the Xbox cutscene-hands feature (handhelds)
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <istream>
|
||||
|
||||
|
||||
|
||||
namespace XmlLibrary
|
||||
{
|
||||
class Attribute;
|
||||
class Element;
|
||||
class Null;
|
||||
|
||||
typedef std::vector<Attribute*> AttributeVector;
|
||||
typedef std::vector<Element*> ElementVector;
|
||||
|
||||
class Attribute
|
||||
{
|
||||
std::string m_strName;
|
||||
std::string m_strValue;
|
||||
|
||||
public:
|
||||
Attribute(const std::string& strName, const std::string& strValue);
|
||||
|
||||
const std::string& Name(void) const;
|
||||
const std::string& Value(void) const;
|
||||
};
|
||||
|
||||
class Value
|
||||
{
|
||||
std::string m_strValue;
|
||||
public:
|
||||
Value(void);
|
||||
void Add(const std::string& strText);
|
||||
void Add(char c);
|
||||
|
||||
operator const std::string&(void) const;
|
||||
operator const char*(void) const;
|
||||
operator bool(void) const;
|
||||
operator char(void) const;
|
||||
operator unsigned char(void) const;
|
||||
operator short(void) const;
|
||||
operator unsigned short(void) const;
|
||||
operator int(void) const;
|
||||
operator unsigned int(void) const;
|
||||
operator long(void) const;
|
||||
operator unsigned long(void) const;
|
||||
operator float(void) const;
|
||||
operator double(void) const;
|
||||
};
|
||||
|
||||
class Element
|
||||
{
|
||||
private:
|
||||
const std::string m_strName;
|
||||
Value m_value;
|
||||
|
||||
public:
|
||||
static Null& null;
|
||||
|
||||
public:
|
||||
Element(void);
|
||||
Element(const std::string& strName);
|
||||
virtual ~Element(void);
|
||||
|
||||
void AddValue(const std::string& strText);
|
||||
void AddValue(char c);
|
||||
|
||||
const std::string& GetName(void) const;
|
||||
const Value& GetValue(void) const;
|
||||
|
||||
const Element& operator()(const char* szName, int nIndex = 0) const;
|
||||
|
||||
public:
|
||||
virtual bool IsNull(void) const;
|
||||
virtual bool Add(Element* pChild) = 0;
|
||||
virtual const ElementVector* GetChilds(void) const = 0;
|
||||
virtual const Element& GetChild(const char* szName, int nIndex = 0) const = 0;
|
||||
virtual const AttributeVector* GetAttributes(void) const = 0;
|
||||
};
|
||||
|
||||
class Tag :public Element
|
||||
{
|
||||
private:
|
||||
AttributeVector m_attributes;
|
||||
ElementVector m_childs;
|
||||
|
||||
public:
|
||||
Tag(const std::string& strName);
|
||||
~Tag(void);
|
||||
|
||||
void Add(Attribute* pAttribute);
|
||||
|
||||
virtual bool Add(Element* pChild);
|
||||
virtual const ElementVector* GetChilds(void) const;
|
||||
virtual const Element& GetChild(const char* szName, int nIndex = 0) const;
|
||||
virtual const AttributeVector* GetAttributes(void) const;
|
||||
|
||||
private:
|
||||
bool FindChild(const char* szName, ElementVector::const_iterator& it) const;
|
||||
};
|
||||
|
||||
class Simple :public Element
|
||||
{
|
||||
public:
|
||||
Simple(const std::string& strName);
|
||||
virtual bool Add(Element* pChild);
|
||||
virtual const ElementVector* GetChilds(void) const;
|
||||
virtual const Element& GetChild(const char* szName, int nIndex = 0) const;
|
||||
virtual const AttributeVector* GetAttributes(void) const;
|
||||
};
|
||||
|
||||
class Comment :public Simple
|
||||
{
|
||||
public:
|
||||
Comment(const std::string& strComment);
|
||||
};
|
||||
|
||||
class Null :public Simple
|
||||
{
|
||||
public:
|
||||
Null(void);
|
||||
|
||||
private:
|
||||
virtual bool IsNull(void) const;
|
||||
};
|
||||
|
||||
class SyntaxError
|
||||
{
|
||||
private:
|
||||
int m_nLine;
|
||||
int m_nColumn;
|
||||
|
||||
public:
|
||||
SyntaxError(int nLine, int nColumn);
|
||||
|
||||
int GetLine(void) const;
|
||||
int GetColumn(void) const;
|
||||
};
|
||||
|
||||
class Parser;
|
||||
class Bookmark
|
||||
{
|
||||
private:
|
||||
Parser& m_reader;
|
||||
const char* m_szSourceCurrent;
|
||||
//std::istream::pos_type m_CurPos;
|
||||
int m_nLine;
|
||||
int m_nColumn;
|
||||
|
||||
public:
|
||||
Bookmark(Parser& reader);
|
||||
void Restore(void);
|
||||
void GetSubString(std::string& strString, int nNumEndSkip = 0);
|
||||
void Reset(void);
|
||||
};
|
||||
|
||||
class Parser
|
||||
{
|
||||
friend class Bookmark;
|
||||
private:
|
||||
const char* m_szSource;
|
||||
const char* m_szSourceCurrent;
|
||||
const char* m_szSourceEnd;
|
||||
//std::istream* m_pInputStream;
|
||||
int m_nLine;
|
||||
int m_nColumn;
|
||||
|
||||
std::string m_strXmlVersion;
|
||||
std::unique_ptr<Element> m_pRootElem;
|
||||
bool m_hasError; // set instead of throwing under -fno-exceptions
|
||||
|
||||
public:
|
||||
bool HadError(void) const { return m_hasError; }
|
||||
Parser(void);
|
||||
virtual ~Parser(void);
|
||||
|
||||
//Element& Parse(std::istream* pInputStream);
|
||||
Element& Parse(const char* szXmlSource, unsigned int nSourceSize);
|
||||
private:
|
||||
char NextChar(void);
|
||||
void PreviousChar(void);
|
||||
|
||||
|
||||
bool ParseSpaces(void);
|
||||
bool ParseString(const char* pString);
|
||||
bool ParseStringNoCase(const char* pString);
|
||||
bool ParseNumber(int& nNum);
|
||||
bool ParseHexNumber(int& nNum);
|
||||
bool ParseChar(char c);
|
||||
bool ParseName(std::string& strName);
|
||||
|
||||
bool ParseDeclBegining(const char* szString);
|
||||
bool ParseXMLDecl(void);
|
||||
bool ParseEq(void);
|
||||
bool ParseVersionInfo(std::string& strVersion);
|
||||
bool ParseVersionNum(std::string& strVersion);
|
||||
bool ParseEncodingDecl(void);
|
||||
bool ParseEncName(void);
|
||||
void ParseMiscs(void);
|
||||
bool ParseReference(char& c);
|
||||
bool ParseAttValue(std::string& strValue);
|
||||
bool ParseAttribute(Tag* pElem);
|
||||
bool ParseETag(Element& element);
|
||||
void ParseContentETag(Tag& element);
|
||||
bool ParseMarkup(Element& element);
|
||||
bool ParseCDATA(Element& element);
|
||||
|
||||
Comment* ParseComment(void);
|
||||
Tag* ParseTagBegining(void);
|
||||
Tag* ParseElement(void);
|
||||
Element* ParseDocument(void);
|
||||
|
||||
bool MapReferenceName(const std::string& strName, char& c);
|
||||
|
||||
void RaiseSyntaxError(void);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CUTSCENE_HANDS
|
||||
#endif
|
||||
|
||||
+9
-2
@@ -47,7 +47,8 @@ RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb) { return dot(*ina,
|
||||
//void RwV3dCrossProduct(RwV3d * out, const RwV3d * ina, const RwV3d * inb);
|
||||
RwV3d *RwV3dTransformPoints(RwV3d * pointsOut, const RwV3d * pointsIn, RwInt32 numPoints, const RwMatrix * matrix)
|
||||
{ V3d::transformPoints(pointsOut, pointsIn, numPoints, matrix); return pointsOut; }
|
||||
//RwV3d *RwV3dTransformVectors(RwV3d * vectorsOut, const RwV3d * vectorsIn, RwInt32 numPoints, const RwMatrix * matrix);
|
||||
RwV3d *RwV3dTransformVectors(RwV3d * vectorsOut, const RwV3d * vectorsIn, RwInt32 numPoints, const RwMatrix * matrix)
|
||||
{ V3d::transformVectors(vectorsOut, vectorsIn, numPoints, matrix); return vectorsOut; }
|
||||
|
||||
|
||||
|
||||
@@ -92,7 +93,7 @@ RwFrame *RwFrameTransform(RwFrame * frame, const RwMatrix * m, RwOpCombineType c
|
||||
RwFrame *RwFrameOrthoNormalize(RwFrame * frame) { return frame; }
|
||||
RwFrame *RwFrameSetIdentity(RwFrame * frame) { frame->matrix.setIdentity(); frame->updateObjects(); return frame; }
|
||||
//RwFrame *RwFrameCloneHierarchy(RwFrame * root);
|
||||
//RwBool RwFrameDestroyHierarchy(RwFrame * frame);
|
||||
RwBool RwFrameDestroyHierarchy(RwFrame * frame) { frame->destroyHierarchy(); return true; }
|
||||
RwFrame *RwFrameForAllChildren(RwFrame * frame, RwFrameCallBack callBack, void *data)
|
||||
{ return frame->forAllChildren(callBack, data); }
|
||||
RwFrame *RwFrameRemoveChild(RwFrame * child) { child->removeChild(); return child; }
|
||||
@@ -897,6 +898,12 @@ RpHAnimHierarchy *RpHAnimHierarchySetFlags(RpHAnimHierarchy *hierarchy, RpHAnimH
|
||||
|
||||
RwBool RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy *hierarchy, RpHAnimAnimation *anim) { hierarchy->interpolator->setCurrentAnim(anim); return true; }
|
||||
RwBool RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy *hierarchy, RwReal time) { hierarchy->interpolator->addTime(time); return true; }
|
||||
RwBool RpHAnimHierarchySetCurrentAnimTime(RpHAnimHierarchy *hierarchy, RwReal time) {
|
||||
// librw has no absolute-time setter; reset to t=0 then advance.
|
||||
rw::AnimInterpolator *interp = hierarchy->interpolator;
|
||||
if(interp->currentAnim){ interp->setCurrentAnim(interp->currentAnim); interp->addTime(time); }
|
||||
return true;
|
||||
}
|
||||
|
||||
RwMatrix *RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy *hierarchy) { return hierarchy->matrices; }
|
||||
RwBool RpHAnimHierarchyUpdateMatrices(RpHAnimHierarchy *hierarchy) { hierarchy->updateMatrices(); return true; }
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Shadows.h"
|
||||
#include "Timecycle.h"
|
||||
#include "CutsceneShadow.h"
|
||||
#include "CutsceneHands.h"
|
||||
#include "CutsceneObject.h"
|
||||
#include "ModelIndices.h"
|
||||
#include "RpAnimBlend.h"
|
||||
@@ -145,6 +146,10 @@ CCutsceneObject::PreRender(void)
|
||||
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
|
||||
RpGeometryForAllMaterials(geometry, MaterialSetAlpha, (void*)255);
|
||||
}
|
||||
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::PreRender(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -152,6 +157,9 @@ CCutsceneObject::Render(void)
|
||||
{
|
||||
SetCullMode(rwCULLMODECULLNONE);
|
||||
CObject::Render();
|
||||
#ifdef CUTSCENE_HANDS
|
||||
CutsceneHands::Render(this);
|
||||
#endif
|
||||
SetCullMode(rwCULLMODECULLBACK);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user