Skip to content

Commit

Permalink
Fix IO; you can now place actors when running the x64 build
Browse files Browse the repository at this point in the history
  • Loading branch information
beholdnec committed Jun 22, 2022
1 parent c19c7e9 commit ef29e41
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 42 deletions.
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ endif()
add_compile_definitions(
$<$<PLATFORM_ID:Windows>:WIN>
$<$<CONFIG:Debug>:DEBUG>
LITTLE_ENDIAN
)

if (CMAKE_SIZEOF_VOID_P EQUAL 4)
add_compile_definitions(
$<$<PLATFORM_ID:Windows>:IN_80386>
# IN_80386 implies LITTLE_ENDIAN
)
else()
add_compile_definitions(
LITTLE_ENDIAN
)
endif()

Expand Down
7 changes: 6 additions & 1 deletion inc/tagman.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ const long ksidInvalid = -1; // negative SIDs imply an invalid TAG
const long sidNil = 0;
const long ksidUseCrf = 0; // chunk is in ptag->pcrf

PCRF RefToPcrf(ulong ref);
ulong PcrfToRef(PCRF pcrf);
void ReleasePpoPcrfRef(ulong* ref);

typedef struct TAG *PTAG;
struct TAG
{
Expand All @@ -54,7 +58,8 @@ struct TAG
#endif // DEBUG

long sid; // Source ID (or ksidUseCrf)
PCRF pcrf; // File to look in for this chunk if sid is ksidUseCrf
//PCRF pcrf; // File to look in for this chunk if sid is ksidUseCrf
ulong pcrfRef; // An 8-byte pointer cannot be stored here, so use a ulong reference instead.
CTG ctg; // CTG of chunk
CNO cno; // CNO of chunk
};
Expand Down
4 changes: 2 additions & 2 deletions src/engine/actredit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ bool ACTR::FPaste(long nfrm, SCEN *pscen)
{
return fFalse;
}
if (pcrf != _tagTmpl.pcrf)
if (pcrf != RefToPcrf(_tagTmpl.pcrfRef))
{
// Need to save this actor's tagTmpl in this movie because it came from another movie

Expand Down Expand Up @@ -839,7 +839,7 @@ bool ACTR::FPaste(long nfrm, SCEN *pscen)
if (aevsnd.tag.sid != ksidUseCrf)
continue;
// Save tag (this may be a new movie)
if (!aevsnd.tag.pcrf->Pcfl()->FFind(aevsnd.tag.ctg, aevsnd.tag.cno))
if (!RefToPcrf(aevsnd.tag.pcrfRef)->Pcfl()->FFind(aevsnd.tag.ctg, aevsnd.tag.cno))
{
PushErc(ercSocNoSndOnPaste);
_RemoveAev(iaev);
Expand Down
62 changes: 58 additions & 4 deletions src/engine/modl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Review Status: REVIEWED - any changes to this file must be reviewed!
***************************************************************************/
#include <stdio.h>
#include "soc.h"
ASSERTNAME

Expand Down Expand Up @@ -80,6 +81,40 @@ bool MODL::FReadModl(PCRF pcrf, CTG ctg, CNO cno, PBLCK pblck, PBACO *ppbaco, lo
return fTrue;
}

// Portable version of br_face for reading from files.
// Original comes from BRender model.h.
// br_material* material has been replaced with a ulong.
#pragma pack(4)
typedef struct BRF_IO
{
br_uint_16 vertices[3]; /* Vertices around face */
br_uint_16 edges[3]; /* Edges around face */
ulong material; /* Face material (or NULL) */
br_uint_16 smoothing; /* Controls if shared edges are smooth */
br_uint_8 flags; /* Bits 0,1 and 2 denote internal edges */
br_uint_8 _pad0;
br_fvector3 n; /* Plane equation of face */
br_scalar d;
} BRF_IO;
#pragma pack()

void BRF_IoToNative(BRF* dst, const BRF_IO* src, size_t count)
{
for (size_t f = 0; f < count; f++)
{
for (int i = 0; i < 3; i++)
dst[f].vertices[i] = src[f].vertices[i];
for (int i = 0; i < 3; i++)
dst[f].edges[i] = src[f].edges[i];
dst[f].material = pvNil;
dst[f].smoothing = src[f].smoothing;
dst[f].flags = src[f].flags;
dst[f]._pad0 = src[f]._pad0;
dst[f].n = src[f].n;
dst[f].d = src[f].d;
}
}

/***************************************************************************
Reads a MODL from a BLCK
***************************************************************************/
Expand Down Expand Up @@ -109,9 +144,13 @@ bool MODL::_FInit(PBLCK pblck)
SwapBytesBom(&modlf, kbomModlf);
Assert(kboCur == modlf.bo, "bad MODL!");

printf("size of MODLF == %d\n", (int)size(MODLF));
printf("size of BRV == %d\n", (int)size(BRV));
printf("size of BRF == %d\n", (int)size(BRF_IO));

// Allocate space for the BMDL, array of vertices, and array of faces
cbrgbrv = LwMul(modlf.cver, size(BRV));
cbrgbrf = LwMul(modlf.cfac, size(BRF));
cbrgbrf = LwMul(modlf.cfac, size(BRF_IO));

if (modlf.rRadius == rZero)
{
Expand All @@ -123,8 +162,16 @@ bool MODL::_FInit(PBLCK pblck)
CopyPb(&pmodlThis, _pbmdl->identifier, size(PMODL));
if (!pblck->FReadRgb(_pbmdl->vertices, cbrgbrv, size(MODLF)))
return fFalse;
if (!pblck->FReadRgb(_pbmdl->faces, cbrgbrf, size(MODLF) + cbrgbrv))
BRF_IO* faces_io = new BRF_IO[modlf.cfac];
if (!pblck->FReadRgb(faces_io, cbrgbrf, size(MODLF) + cbrgbrv))
{
delete[] faces_io;
return fFalse;
}

BRF_IoToNative(_pbmdl->faces, faces_io, modlf.cfac);

delete[] faces_io;

BrModelAdd(_pbmdl);

Expand Down Expand Up @@ -160,18 +207,25 @@ bool MODL::_FInit(PBLCK pblck)
SwapBytesBom(pbrv, kbomBrv);
}
}
if (!pblck->FReadRgb(_pbmdl->prepared_faces, cbrgbrf, size(MODLF) + cbrgbrv))
BRF_IO* prepared_faces_io = new BRF_IO[modlf.cfac];
if (!pblck->FReadRgb(prepared_faces_io, cbrgbrf, size(MODLF) + cbrgbrv))
{
delete[] prepared_faces_io;
return fFalse;
}
if (kboOther == modlf.bo)
{
for (ibrf = 0, pbrf = _pbmdl->prepared_faces; ibrf < modlf.cfac; ibrf++, pbrf++)
BRF_IO* pbrf;
for (ibrf = 0, pbrf = prepared_faces_io; ibrf < modlf.cfac; ibrf++, pbrf++)
{
SwapBytesBom(pbrf, kbomBrf);
}
}

BRF_IoToNative(_pbmdl->prepared_faces, prepared_faces_io, modlf.cfac);

delete[] prepared_faces_io;

_pbmdl->flags = BR_MODF_PREPREPARED;
_pbmdl->nprepared_vertices = (ushort)modlf.cver;
_pbmdl->nprepared_faces = (ushort)modlf.cfac;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/movie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6135,7 +6135,7 @@ void MVU::SetTagTool(PTAG ptag)
// Make sure the new tag has been opened, if it's a "ksidUseCrf" tag
if (ptag->sid == ksidUseCrf)
{
AssertPo(ptag->pcrf, 0);
AssertPo(RefToPcrf(ptag->pcrfRef), 0);
}
#endif

Expand Down
6 changes: 3 additions & 3 deletions src/engine/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7201,7 +7201,7 @@ void ReleasePpsse(PSSE *ppsse)

for (itagc = 0; itagc < psse->ctagc; itagc++)
{
if (psse->Ptag(itagc)->pcrf != pvNil)
if (psse->Ptag(itagc)->pcrfRef != pvNil)
TAGM::CloseTag(psse->Ptag(itagc));
}

Expand Down Expand Up @@ -7234,14 +7234,14 @@ PSSE SSE::PsseDupFromGg(PGG pgg, long iv, bool fDupTags)
{
if (psse->Ptag(itagc)->sid == ksidUseCrf)
{
AssertPo(psse->Ptag(itagc)->pcrf, 0);
AssertPo(RefToPcrf(psse->Ptag(itagc)->pcrfRef), 0);
TAGM::DupTag(psse->Ptag(itagc));
}
}
else
{
// Clear the crf on read, since the caller isn't having us dupe the tag
psse->Ptag(itagc)->pcrf = pvNil;
psse->Ptag(itagc)->pcrfRef = pvNil;
}
}

Expand Down
82 changes: 62 additions & 20 deletions src/engine/tagman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,51 @@
short names.
***************************************************************************/
#include <map>
#include "soc.h"
ASSERTNAME

ulong g_nextPcrfRef = 1; // FIXME: handle/prevent overflow and generally make this more robust
// These two maps form a bidirectional map of refs and their corresponding PCRF's.
static std::map<ulong, PCRF> g_refToPcrfMap;
static std::map<PCRF, ulong> g_pcrfToRefMap;

PCRF RefToPcrf(ulong ref)
{
if (ref == 0)
return pvNil;
return g_refToPcrfMap[ref];
}

ulong PcrfToRef(PCRF pcrf)
{
if (pcrf == pvNil)
return 0;
if (g_pcrfToRefMap.find(pcrf) == g_pcrfToRefMap.end())
{
g_pcrfToRefMap[pcrf] = g_nextPcrfRef;
++g_nextPcrfRef;
}

return g_pcrfToRefMap[pcrf];
}

void ReleasePpoPcrfRef(ulong* ref)
{
if (*ref != 0)
{
PCRF pcrf = g_refToPcrfMap[*ref];
if (pcrf->CactRef() <= 1)
{
// PCRF will be deleted, remove it from the bimap.
g_pcrfToRefMap.erase(pcrf);
g_refToPcrfMap.erase(*ref);
}
ReleasePpo(&pcrf);
*ref = 0;
}
}

RTCLASS(TAGM)

const BOM kbomSid = 0xc0000000;
Expand Down Expand Up @@ -779,14 +821,14 @@ bool TAGM::FBuildChildTag(PTAG ptagPar, CHID chid, CTG ctgChild, PTAG ptagChild)

if (ksidUseCrf == ptagPar->sid)
{
AssertPo(ptagPar->pcrf, 0);
if (!ptagPar->pcrf->Pcfl()->FGetKidChidCtg(ptagPar->ctg, ptagPar->cno, chid, ctgChild, &kid))
AssertPo(RefToPcrf(ptagPar->pcrfRef), 0);
if (!RefToPcrf(ptagPar->pcrfRef)->Pcfl()->FGetKidChidCtg(ptagPar->ctg, ptagPar->cno, chid, ctgChild, &kid))
{
return fFalse; // child chunk not found
}
ptagChild->sid = ksidUseCrf;
ptagChild->pcrf = ptagPar->pcrf;
ptagPar->pcrf->AddRef();
ptagChild->pcrfRef = ptagPar->pcrfRef;
RefToPcrf(ptagPar->pcrfRef)->AddRef();
ptagChild->ctg = kid.cki.ctg;
ptagChild->cno = kid.cki.cno;
return fTrue;
Expand Down Expand Up @@ -890,8 +932,8 @@ PBACO TAGM::PbacoFetch(PTAG ptag, PFNRPO pfnrpo, bool fUseCD)
{
// Tag knows pcrf, so just read from there. Nothing we can do if
// it's not there.
AssertPo(ptag->pcrf, 0);
return ptag->pcrf->PbacoFetch(ptag->ctg, ptag->cno, pfnrpo);
AssertPo(RefToPcrf(ptag->pcrfRef), 0);
return RefToPcrf(ptag->pcrfRef)->PbacoFetch(ptag->ctg, ptag->cno, pfnrpo);
}

// fTrue parameter ensures that _PcrmSourceGet won't hit the CD
Expand Down Expand Up @@ -990,12 +1032,12 @@ bool TAGM::FOpenTag(PTAG ptag, PCRF pcrfDest, PCFL pcflSrc)
{
if (!pcflSrc->FCopy(ptag->ctg, ptag->cno, pcrfDest->Pcfl(), &cnoDest))
{
ptag->pcrf = pvNil;
ptag->pcrfRef = pvNil;
return fFalse; // copy failed
}
ptag->cno = cnoDest;
}
ptag->pcrf = pcrfDest;
ptag->pcrfRef = PcrfToRef(pcrfDest);
pcrfDest->AddRef();
return fTrue;
}
Expand All @@ -1015,18 +1057,18 @@ bool TAGM::FSaveTag(PTAG ptag, PCRF pcrf, bool fRedirect)
if (ptag->sid != ksidUseCrf)
return fTrue;

AssertPo(ptag->pcrf, 0);
AssertPo(RefToPcrf(ptag->pcrfRef), 0);

if (!ptag->pcrf->Pcfl()->FCopy(ptag->ctg, ptag->cno, pcrf->Pcfl(), &cnoDest))
if (!RefToPcrf(ptag->pcrfRef)->Pcfl()->FCopy(ptag->ctg, ptag->cno, pcrf->Pcfl(), &cnoDest))
{
return fFalse; // copy failed
}

if (fRedirect)
{
pcrf->AddRef();
ReleasePpo(&ptag->pcrf);
ptag->pcrf = pcrf;
ReleasePpoPcrfRef(&ptag->pcrfRef);
ptag->pcrfRef = PcrfToRef(pcrf);
ptag->cno = cnoDest;
}

Expand All @@ -1044,8 +1086,8 @@ void TAGM::DupTag(PTAG ptag)

if (ptag->sid == ksidUseCrf)
{
AssertPo(ptag->pcrf, 0);
ptag->pcrf->AddRef();
AssertPo(RefToPcrf(ptag->pcrfRef), 0);
RefToPcrf(ptag->pcrfRef)->AddRef();
}
}

Expand All @@ -1061,8 +1103,8 @@ void TAGM::CloseTag(PTAG ptag)

if (ptag->sid == ksidUseCrf)
{
AssertPo(ptag->pcrf, 0);
ReleasePpo(&ptag->pcrf);
AssertPo(RefToPcrf(ptag->pcrfRef), 0);
ReleasePpoPcrfRef(&ptag->pcrfRef);
}
}

Expand Down Expand Up @@ -1091,9 +1133,9 @@ ulong TAGM::FcmpCompareTags(PTAG ptag1, PTAG ptag2)
// If both sids are ksidUseCrf, compare CRFs
if (ptag1->sid == ksidUseCrf) // implies ptag2->sid == ksidUseCrf
{
if (ptag1->pcrf < ptag2->pcrf)
if (ptag1->pcrfRef < ptag2->pcrfRef)
return fcmpLt;
if (ptag1->pcrf > ptag2->pcrf)
if (ptag1->pcrfRef > ptag2->pcrfRef)
return fcmpGt;
}
return fcmpEq;
Expand Down Expand Up @@ -1151,8 +1193,8 @@ void TAG::MarkMem(void)
{
if (sid == ksidUseCrf)
{
AssertPo(pcrf, 0);
MarkMemObj(pcrf);
AssertPo(RefToPcrf(pcrfRef), 0);
MarkMemObj(RefToPcrf(pcrfRef));
}
}
#endif // DEBUG
Loading

0 comments on commit ef29e41

Please sign in to comment.