mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
- implemented a proper cache for Blood's SEQs.
Messing around in the file system cache should be a no-go, so now it's no longer done. This also allows reenabling the byte swapping needed for Big Endian.
This commit is contained in:
parent
bbbd7fadbb
commit
b804589f81
11 changed files with 126 additions and 107 deletions
|
@ -2498,8 +2498,8 @@ void actInit(bool bSaveLoad) {
|
|||
case kThingBloodChunks: {
|
||||
SEQINST *pInst = GetInstance(3, pSprite->extra);
|
||||
if (pInst && pInst->at13) {
|
||||
DICTNODE *hSeq = gSysRes.Lookup(pInst->at8, "SEQ");
|
||||
if (!hSeq) break;
|
||||
auto seq = getSequence(pInst->at8);
|
||||
if (!seq) break;
|
||||
seqSpawn(pInst->at8, 3, pSprite->extra);
|
||||
}
|
||||
break;
|
||||
|
@ -2577,7 +2577,7 @@ void actInit(bool bSaveLoad) {
|
|||
|
||||
}
|
||||
|
||||
if (gSysRes.Lookup(seqStartId, "SEQ")) seqSpawn(seqStartId, 3, pSprite->extra);
|
||||
if (getSequence(seqStartId)) seqSpawn(seqStartId, 3, pSprite->extra);
|
||||
}
|
||||
aiInit();
|
||||
}
|
||||
|
@ -2966,7 +2966,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
|
||||
playGenDudeSound(pSprite, kGenDudeSndTransforming);
|
||||
int seqId = pXSprite->data2 + kGenDudeSeqTransform;
|
||||
if (gSysRes.Lookup(seqId, "SEQ")) seqSpawn(seqId, 3, nXSprite, -1);
|
||||
if (getSequence(seqId)) seqSpawn(seqId, 3, nXSprite, -1);
|
||||
else {
|
||||
seqKill(3, nXSprite);
|
||||
spritetype* pEffect = gFX.fxSpawn((FX_ID)52, pSprite->sectnum, pSprite->x, pSprite->y, pSprite->z, pSprite->ang);
|
||||
|
@ -3152,7 +3152,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!gSysRes.Lookup(getDudeInfo(nType+kDudeBase)->seqStartID + nSeq, "SEQ"))
|
||||
if (!getSequence(getDudeInfo(nType+kDudeBase)->seqStartID + nSeq))
|
||||
{
|
||||
seqKill(3, nXSprite);
|
||||
gKillMgr.AddKill(pSprite);
|
||||
|
@ -3227,7 +3227,7 @@ void actKillDude(int nKillerSprite, spritetype *pSprite, DAMAGE_TYPE damageType,
|
|||
if (pExtra->availDeaths[kDmgBurn] == 3) seqSpawn((15 + Random(2)) + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 2) seqSpawn(16 + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
else if (pExtra->availDeaths[kDmgBurn] == 1) seqSpawn(15 + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
else if (gSysRes.Lookup(pXSprite->data2 + nSeq, "SEQ"))seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
else if (getSequence(pXSprite->data2 + nSeq))seqSpawn(nSeq + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
else seqSpawn(1 + pXSprite->data2, 3, nXSprite, dudeToGib);
|
||||
|
||||
} else {
|
||||
|
@ -5344,7 +5344,7 @@ void actExplodeSprite(spritetype *pSprite)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (gSysRes.Lookup(nSeq, "SEQ"))
|
||||
if (getSequence(nSeq))
|
||||
seqSpawn(nSeq, 3, nXSprite, -1);
|
||||
|
||||
sfxPlay3DSound(pSprite, nSnd, -1, 0);
|
||||
|
@ -6110,7 +6110,7 @@ spritetype *actSpawnDude(spritetype *pSource, short nType, int a3, int a4)
|
|||
pSprite2->clipdist = getDudeInfo(nDude+kDudeBase)->clipdist;
|
||||
pXSprite2->health = getDudeInfo(nDude+kDudeBase)->startHealth<<4;
|
||||
pXSprite2->respawn = 1;
|
||||
if (gSysRes.Lookup(getDudeInfo(nDude+kDudeBase)->seqStartID, "SEQ"))
|
||||
if (getSequence(getDudeInfo(nDude+kDudeBase)->seqStartID))
|
||||
seqSpawn(getDudeInfo(nDude+kDudeBase)->seqStartID, 3, pSprite2->extra, -1);
|
||||
|
||||
#ifdef NOONE_EXTENSIONS
|
||||
|
|
|
@ -94,7 +94,7 @@ void aiNewState(spritetype *pSprite, XSPRITE *pXSprite, AISTATE *pAIState)
|
|||
|
||||
if (pAIState->seqId >= 0) {
|
||||
seqStartId += pAIState->seqId;
|
||||
if (gSysRes.Lookup(seqStartId, "SEQ"))
|
||||
if (getSequence(seqStartId))
|
||||
seqSpawn(seqStartId, 3, pSprite->extra, pAIState->funcId);
|
||||
}
|
||||
|
||||
|
|
|
@ -1110,7 +1110,7 @@ void aiGenDudeNewState(spritetype* pSprite, AISTATE* pAIState) {
|
|||
pXSprite->stateTimer = pAIState->stateTicks; pXSprite->aiState = pAIState;
|
||||
|
||||
int stateSeq = pXSprite->data2 + pAIState->seqId;
|
||||
if (pAIState->seqId >= 0 && gSysRes.Lookup(stateSeq, "SEQ")) {
|
||||
if (pAIState->seqId >= 0 && getSequence(stateSeq)) {
|
||||
seqSpawn(stateSeq, 3, pSprite->extra, pAIState->funcId);
|
||||
}
|
||||
|
||||
|
@ -1460,10 +1460,13 @@ void scaleDamage(XSPRITE* pXSprite) {
|
|||
//viewSetSystemMessage("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d, 6: %d", dc[0], dc[1], dc[2], dc[3], dc[4], dc[5], dc[6]);
|
||||
}
|
||||
|
||||
int getDispersionModifier(spritetype* pSprite, int minDisp, int maxDisp) {
|
||||
int getDispersionModifier(spritetype* pSprite, int minDisp, int maxDisp)
|
||||
{
|
||||
// the faster fire rate, the less frames = more dispersion
|
||||
Seq* pSeq = NULL; DICTNODE* hSeq = gSysRes.Lookup(xsprite[pSprite->extra].data2 + 6, "SEQ"); int disp = 1;
|
||||
if (hSeq != NULL && (pSeq = (Seq*)gSysRes.Load(hSeq)) != NULL) {
|
||||
Seq* pSeq = getSequence(xsprite[pSprite->extra].data2 + 6);
|
||||
int disp = 1;
|
||||
if (pSeq != nullptr)
|
||||
{
|
||||
int nFrames = pSeq->nFrames; int ticks = pSeq->at8; int shots = 0;
|
||||
for (int i = 0; i <= pSeq->nFrames; i++) {
|
||||
if (pSeq->frames[i].at5_5) shots++;
|
||||
|
@ -1487,9 +1490,8 @@ int getRangeAttackDist(spritetype* pSprite, int minDist, int maxDist) {
|
|||
|
||||
if (yrepeat > 0) {
|
||||
if (seqId >= 0) {
|
||||
Seq* pSeq = NULL; DICTNODE* hSeq = gSysRes.Lookup(seqId, "SEQ");
|
||||
if (hSeq) {
|
||||
pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
Seq* pSeq = getSequence(seqId);
|
||||
if (pSeq) {
|
||||
picnum = seqGetTile(&pSeq->frames[0]);
|
||||
}
|
||||
}
|
||||
|
@ -1974,7 +1976,7 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
|||
}
|
||||
|
||||
pExtra->canAttack = false;
|
||||
if (pExtra->curWeapon > 0 && gSysRes.Lookup(pXSprite->data2 + kGenDudeSeqAttackNormalL, "SEQ"))
|
||||
if (pExtra->curWeapon > 0 && getSequence(pXSprite->data2 + kGenDudeSeqAttackNormalL))
|
||||
pExtra->canAttack = true;
|
||||
|
||||
pExtra->weaponType = kGenDudeWeaponNone;
|
||||
|
@ -2033,14 +2035,17 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
|||
case kGenDudeSeqAttackNormalL:
|
||||
case kGenDudeSeqAttackThrow:
|
||||
case kGenDudeSeqAttackPunch:
|
||||
if (!gSysRes.Lookup(i, "SEQ")) {
|
||||
{
|
||||
Seq* pSeq = getSequence(i);
|
||||
if (!pSeq)
|
||||
{
|
||||
pXSprite->data2 = getDudeInfo(pSprite->type)->seqStartID;
|
||||
viewSetSystemMessage("No SEQ animation id %d found for custom dude #%d!", i, pSprite->index);
|
||||
viewSetSystemMessage("SEQ base id: %d", seqStartId);
|
||||
} else if ((i - seqStartId) == kGenDudeSeqAttackPunch) {
|
||||
}
|
||||
else if ((i - seqStartId) == kGenDudeSeqAttackPunch)
|
||||
{
|
||||
pExtra->forcePunch = true; // required for those who don't have fire trigger in punch seq and for default animation
|
||||
Seq* pSeq = NULL; DICTNODE* hSeq = gSysRes.Lookup(i, "SEQ");
|
||||
pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
for (int i = 0; i < pSeq->nFrames; i++) {
|
||||
if (!pSeq->frames[i].at5_5) continue;
|
||||
pExtra->forcePunch = false;
|
||||
|
@ -2048,30 +2053,36 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kGenDudeSeqDeathExplode:
|
||||
pExtra->availDeaths[kDmgExplode] = (bool)gSysRes.Lookup(i, "SEQ");
|
||||
pExtra->availDeaths[kDmgExplode] = !!getSequence(i);
|
||||
break;
|
||||
case kGenDudeSeqBurning:
|
||||
pExtra->canBurn = gSysRes.Lookup(i, "SEQ");
|
||||
pExtra->canBurn = !!getSequence(i);
|
||||
break;
|
||||
case kGenDudeSeqElectocuted:
|
||||
pExtra->canElectrocute = gSysRes.Lookup(i, "SEQ");
|
||||
pExtra->canElectrocute = !!getSequence(i);
|
||||
break;
|
||||
case kGenDudeSeqRecoil:
|
||||
pExtra->canRecoil = gSysRes.Lookup(i, "SEQ");
|
||||
pExtra->canRecoil = !!getSequence(i);
|
||||
break;
|
||||
case kGenDudeSeqMoveL: {
|
||||
bool oldStatus = pExtra->canWalk;
|
||||
pExtra->canWalk = gSysRes.Lookup(i, "SEQ");
|
||||
pExtra->canWalk = !!getSequence(i);
|
||||
if (oldStatus != pExtra->canWalk) {
|
||||
if (!spriRangeIsFine(pXSprite->target)) {
|
||||
if (!spriRangeIsFine(pXSprite->target))
|
||||
{
|
||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeIdleW);
|
||||
else aiGenDudeNewState(pSprite, &genDudeIdleL);
|
||||
} else if (pExtra->canWalk) {
|
||||
}
|
||||
else if (pExtra->canWalk)
|
||||
{
|
||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeChaseW);
|
||||
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pSprite, &genDudeChaseD);
|
||||
else aiGenDudeNewState(pSprite, &genDudeChaseL);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (spriteIsUnderwater(pSprite, false)) aiGenDudeNewState(pSprite, &genDudeChaseNoWalkW);
|
||||
else if (inDuck(pXSprite->aiState)) aiGenDudeNewState(pSprite, &genDudeChaseNoWalkD);
|
||||
else aiGenDudeNewState(pSprite, &genDudeChaseNoWalkL);
|
||||
|
@ -2080,12 +2091,13 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
|||
break;
|
||||
}
|
||||
case kGenDudeSeqAttackNormalDW:
|
||||
pExtra->canDuck = (gSysRes.Lookup(i, "SEQ") && gSysRes.Lookup(seqStartId + 14, "SEQ"));
|
||||
pExtra->canSwim = (gSysRes.Lookup(i, "SEQ") && gSysRes.Lookup(seqStartId + 13, "SEQ")
|
||||
&& gSysRes.Lookup(seqStartId + 17, "SEQ"));
|
||||
pExtra->canDuck = (getSequence(i) && getSequence(seqStartId + 14));
|
||||
pExtra->canSwim = (getSequence(i) && getSequence(seqStartId + 13)
|
||||
&& getSequence(seqStartId + 17));
|
||||
break;
|
||||
case kGenDudeSeqDeathBurn1: {
|
||||
bool seq15 = gSysRes.Lookup(i, "SEQ"); bool seq16 = gSysRes.Lookup(seqStartId + 16, "SEQ");
|
||||
bool seq15 = getSequence(i);
|
||||
bool seq16 = getSequence(seqStartId + 16);
|
||||
if (seq15 && seq16) pExtra->availDeaths[kDmgBurn] = 3;
|
||||
else if (seq16) pExtra->availDeaths[kDmgBurn] = 2;
|
||||
else if (seq15) pExtra->availDeaths[kDmgBurn] = 1;
|
||||
|
@ -2103,7 +2115,7 @@ bool genDudePrepare(spritetype* pSprite, int propId) {
|
|||
case kGenDudeSeqReserved6:
|
||||
case kGenDudeSeqReserved7:
|
||||
case kGenDudeSeqReserved8:
|
||||
/*if (gSysRes.Lookup(i, "SEQ")) {
|
||||
/*if (getSequence(i)) {
|
||||
viewSetSystemMessage("Found reserved SEQ animation (%d) for custom dude #%d!", i, pSprite->index);
|
||||
viewSetSystemMessage("Using reserved animation is not recommended.");
|
||||
viewSetSystemMessage("SEQ base id: %d", seqStartId);
|
||||
|
|
|
@ -1782,10 +1782,6 @@ bool VanillaMode() {
|
|||
return gDemo.m_bLegacy && gDemo.at1;
|
||||
}
|
||||
|
||||
bool fileExistsRFF(int id, const char *ext) {
|
||||
return gSysRes.Lookup(id, ext);
|
||||
}
|
||||
|
||||
int sndTryPlaySpecialMusic(int nMusic)
|
||||
{
|
||||
if (Mus_Play(nullptr, quoteMgr.GetQuote(nMusic), true))
|
||||
|
|
|
@ -132,7 +132,6 @@ void ProcessFrame(void);
|
|||
void ScanINIFiles(void);
|
||||
bool DemoRecordStatus(void);
|
||||
bool VanillaMode(void);
|
||||
bool fileExistsRFF(int id, const char* ext);
|
||||
int sndTryPlaySpecialMusic(int nMusic);
|
||||
void sndPlaySpecialMusicOrNothing(int nMusic);
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ void Respawn(int nSprite) // 9
|
|||
switch (pSprite->type) {
|
||||
default:
|
||||
pSprite->clipdist = getDudeInfo(nType + kDudeBase)->clipdist;
|
||||
if (gSysRes.Lookup(getDudeInfo(nType + kDudeBase)->seqStartID, "SEQ"))
|
||||
if (getSequence(getDudeInfo(nType + kDudeBase)->seqStartID))
|
||||
seqSpawn(getDudeInfo(nType + kDudeBase)->seqStartID, 3, pSprite->extra, -1);
|
||||
break;
|
||||
case kDudeModernCustom:
|
||||
|
@ -285,7 +285,7 @@ void Respawn(int nSprite) // 9
|
|||
#else
|
||||
pSprite->clipdist = getDudeInfo(nType + kDudeBase)->clipdist;
|
||||
pXSprite->health = getDudeInfo(nType + kDudeBase)->startHealth << 4;
|
||||
if (gSysRes.Lookup(getDudeInfo(nType + kDudeBase)->seqStartID, "SEQ"))
|
||||
if (getSequence(getDudeInfo(nType + kDudeBase)->seqStartID))
|
||||
seqSpawn(getDudeInfo(nType + kDudeBase)->seqStartID, 3, pSprite->extra, -1);
|
||||
#endif
|
||||
aiInitSprite(pSprite);
|
||||
|
|
|
@ -948,10 +948,9 @@ int getSpriteMassBySize(spritetype* pSprite) {
|
|||
short massDiv = 30; short addMul = 2; short subMul = 2;
|
||||
|
||||
if (seqId >= 0) {
|
||||
DICTNODE* hSeq = gSysRes.Lookup(seqId, "SEQ");
|
||||
if (hSeq)
|
||||
auto pSeq = getSequence(seqId);
|
||||
if (pSeq)
|
||||
{
|
||||
pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
picnum = seqGetTile(&pSeq->frames[0]);
|
||||
} else
|
||||
picnum = pSprite->picnum;
|
||||
|
@ -2326,7 +2325,7 @@ void useSpriteDamager(XSPRITE* pXSource, spritetype* pSprite) {
|
|||
|
||||
void useSeqSpawnerGen(XSPRITE* pXSource, int objType, int index) {
|
||||
|
||||
if (pXSource->data2 > 0 && !gSysRes.Lookup(pXSource->data2, "SEQ")) {
|
||||
if (pXSource->data2 > 0 && !getSequence(pXSource->data2)) {
|
||||
consoleSysMsg("Missing sequence #%d", pXSource->data2);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2121,7 +2121,7 @@ int playerDamageSprite(int nSource, PLAYER *pPlayer, DAMAGE_TYPE nDamageType, in
|
|||
FragPlayer(pPlayer, nSource);
|
||||
trTriggerSprite(nSprite, pXSprite, kCmdOff);
|
||||
}
|
||||
dassert(gSysRes.Lookup(pDudeInfo->seqStartID + nDeathSeqID, "SEQ") != NULL);
|
||||
dassert(getSequence(pDudeInfo->seqStartID + nDeathSeqID) != NULL);
|
||||
seqSpawn(pDudeInfo->seqStartID+nDeathSeqID, 3, nXSprite, nKneelingPlayer);
|
||||
return nDamage;
|
||||
}
|
||||
|
|
|
@ -73,44 +73,6 @@ void ByteSwapQAV(void *p)
|
|||
}
|
||||
}
|
||||
|
||||
void ByteSwapSEQ(void *p)
|
||||
{
|
||||
Seq *pSeq = (Seq*)p;
|
||||
pSeq->version = B_LITTLE16(pSeq->version);
|
||||
pSeq->nFrames = B_LITTLE16(pSeq->nFrames);
|
||||
pSeq->at8 = B_LITTLE16(pSeq->at8);
|
||||
pSeq->ata = B_LITTLE16(pSeq->ata);
|
||||
pSeq->atc = B_LITTLE32(pSeq->atc);
|
||||
for (int i = 0; i < pSeq->nFrames; i++)
|
||||
{
|
||||
SEQFRAME *pFrame = &pSeq->frames[i];
|
||||
BitReader bitReader((char *)pFrame, sizeof(SEQFRAME));
|
||||
SEQFRAME swapFrame;
|
||||
swapFrame.tile = bitReader.readUnsigned(12);
|
||||
swapFrame.at1_4 = bitReader.readBit();
|
||||
swapFrame.at1_5 = bitReader.readBit();
|
||||
swapFrame.at1_6 = bitReader.readBit();
|
||||
swapFrame.at1_7 = bitReader.readBit();
|
||||
swapFrame.at2_0 = bitReader.readUnsigned(8);
|
||||
swapFrame.at3_0 = bitReader.readUnsigned(8);
|
||||
swapFrame.at4_0 = bitReader.readSigned(8);
|
||||
swapFrame.at5_0 = bitReader.readUnsigned(5);
|
||||
swapFrame.at5_5 = bitReader.readBit();
|
||||
swapFrame.at5_6 = bitReader.readBit();
|
||||
swapFrame.at5_7 = bitReader.readBit();
|
||||
swapFrame.at6_0 = bitReader.readBit();
|
||||
swapFrame.at6_1 = bitReader.readBit();
|
||||
swapFrame.at6_2 = bitReader.readBit();
|
||||
swapFrame.at6_3 = bitReader.readBit();
|
||||
swapFrame.at6_4 = bitReader.readBit();
|
||||
swapFrame.tile2 = bitReader.readUnsigned(4);
|
||||
swapFrame.soundRange = bitReader.readUnsigned(4);
|
||||
swapFrame.surfaceSound = bitReader.readBit();
|
||||
swapFrame.reserved = bitReader.readUnsigned(2);
|
||||
*pFrame = swapFrame;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteSwapSFX(void *p)
|
||||
{
|
||||
SFX *pSFX = (SFX*)p;
|
||||
|
|
|
@ -79,11 +79,8 @@ void Seq::Precache(void)
|
|||
|
||||
void seqPrecacheId(int id)
|
||||
{
|
||||
DICTNODE *hSeq = gSysRes.Lookup(id, "SEQ");
|
||||
if (!hSeq)
|
||||
return;
|
||||
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
pSeq->Precache();
|
||||
auto pSeq = getSequence(id);
|
||||
if (pSeq) pSeq->Precache();
|
||||
}
|
||||
|
||||
SEQINST siWall[kMaxXWalls];
|
||||
|
@ -371,9 +368,7 @@ SEQINST * GetInstance(int a1, int a2)
|
|||
void UnlockInstance(SEQINST *pInst)
|
||||
{
|
||||
dassert(pInst != NULL);
|
||||
dassert(pInst->hSeq != NULL);
|
||||
dassert(pInst->pSequence != NULL);
|
||||
pInst->hSeq = NULL;
|
||||
pInst->pSequence = NULL;
|
||||
pInst->at13 = 0;
|
||||
}
|
||||
|
@ -383,14 +378,14 @@ void seqSpawn(int a1, int a2, int a3, int a4)
|
|||
SEQINST *pInst = GetInstance(a2, a3);
|
||||
if (!pInst) return;
|
||||
|
||||
DICTNODE *hSeq = gSysRes.Lookup(a1, "SEQ");
|
||||
if (!hSeq)
|
||||
auto pSeq = getSequence(a1);
|
||||
if (!pSeq)
|
||||
ThrowError("Missing sequence #%d", a1);
|
||||
|
||||
int i = activeCount;
|
||||
if (pInst->at13)
|
||||
{
|
||||
if (hSeq == pInst->hSeq)
|
||||
if (pSeq == pInst->pSequence)
|
||||
return;
|
||||
UnlockInstance(pInst);
|
||||
for (i = 0; i < activeCount; i++)
|
||||
|
@ -400,7 +395,6 @@ void seqSpawn(int a1, int a2, int a3, int a4)
|
|||
}
|
||||
dassert(i < activeCount);
|
||||
}
|
||||
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
||||
ThrowError("Invalid sequence %d", a1);
|
||||
if ((pSeq->version & 0xff00) != 0x300)
|
||||
|
@ -411,7 +405,6 @@ void seqSpawn(int a1, int a2, int a3, int a4)
|
|||
pSeq->frames[i].tile2 = 0;
|
||||
}
|
||||
pInst->at13 = 1;
|
||||
pInst->hSeq = hSeq;
|
||||
pInst->pSequence = pSeq;
|
||||
pInst->at8 = a1;
|
||||
pInst->atc = a4;
|
||||
|
@ -557,21 +550,16 @@ void SeqLoadSave::Load(void)
|
|||
Read(&activeCount, sizeof(activeCount));
|
||||
for (int i = 0; i < kMaxXWalls; i++)
|
||||
{
|
||||
siWall[i].hSeq = NULL;
|
||||
siMasked[i].hSeq = NULL;
|
||||
siWall[i].pSequence = NULL;
|
||||
siMasked[i].pSequence = NULL;
|
||||
}
|
||||
for (int i = 0; i < kMaxXSectors; i++)
|
||||
{
|
||||
siCeiling[i].hSeq = NULL;
|
||||
siFloor[i].hSeq = NULL;
|
||||
siCeiling[i].pSequence = NULL;
|
||||
siFloor[i].pSequence = NULL;
|
||||
}
|
||||
for (int i = 0; i < kMaxXSprites; i++)
|
||||
{
|
||||
siSprite[i].hSeq = NULL;
|
||||
siSprite[i].pSequence = NULL;
|
||||
}
|
||||
for (int i = 0; i < activeCount; i++)
|
||||
|
@ -580,17 +568,15 @@ void SeqLoadSave::Load(void)
|
|||
if (pInst->at13)
|
||||
{
|
||||
int nSeq = pInst->at8;
|
||||
DICTNODE *hSeq = gSysRes.Lookup(nSeq, "SEQ");
|
||||
if (!hSeq) {
|
||||
auto pSeq = getSequence(nSeq);
|
||||
if (!pSeq) {
|
||||
ThrowError("Missing sequence #%d", nSeq);
|
||||
continue;
|
||||
}
|
||||
Seq *pSeq = (Seq*)gSysRes.Load(hSeq);
|
||||
if (memcmp(pSeq->signature, "SEQ\x1a", 4) != 0)
|
||||
ThrowError("Invalid sequence %d", nSeq);
|
||||
if ((pSeq->version & 0xff00) != 0x300)
|
||||
ThrowError("Sequence %d is obsolete version", nSeq);
|
||||
pInst->hSeq = hSeq;
|
||||
pInst->pSequence = pSeq;
|
||||
}
|
||||
}
|
||||
|
@ -614,4 +600,66 @@ void SeqLoadSaveConstruct(void)
|
|||
myLoadSave = new SeqLoadSave();
|
||||
}
|
||||
|
||||
|
||||
static void ByteSwapSEQ(Seq* pSeq)
|
||||
{
|
||||
pSeq->version = B_LITTLE16(pSeq->version);
|
||||
pSeq->nFrames = B_LITTLE16(pSeq->nFrames);
|
||||
pSeq->at8 = B_LITTLE16(pSeq->at8);
|
||||
pSeq->ata = B_LITTLE16(pSeq->ata);
|
||||
pSeq->atc = B_LITTLE32(pSeq->atc);
|
||||
for (int i = 0; i < pSeq->nFrames; i++)
|
||||
{
|
||||
SEQFRAME* pFrame = &pSeq->frames[i];
|
||||
BitReader bitReader((char*)pFrame, sizeof(SEQFRAME));
|
||||
SEQFRAME swapFrame;
|
||||
swapFrame.tile = bitReader.readUnsigned(12);
|
||||
swapFrame.at1_4 = bitReader.readBit();
|
||||
swapFrame.at1_5 = bitReader.readBit();
|
||||
swapFrame.at1_6 = bitReader.readBit();
|
||||
swapFrame.at1_7 = bitReader.readBit();
|
||||
swapFrame.at2_0 = bitReader.readUnsigned(8);
|
||||
swapFrame.at3_0 = bitReader.readUnsigned(8);
|
||||
swapFrame.at4_0 = bitReader.readSigned(8);
|
||||
swapFrame.at5_0 = bitReader.readUnsigned(5);
|
||||
swapFrame.at5_5 = bitReader.readBit();
|
||||
swapFrame.at5_6 = bitReader.readBit();
|
||||
swapFrame.at5_7 = bitReader.readBit();
|
||||
swapFrame.at6_0 = bitReader.readBit();
|
||||
swapFrame.at6_1 = bitReader.readBit();
|
||||
swapFrame.at6_2 = bitReader.readBit();
|
||||
swapFrame.at6_3 = bitReader.readBit();
|
||||
swapFrame.at6_4 = bitReader.readBit();
|
||||
swapFrame.tile2 = bitReader.readUnsigned(4);
|
||||
swapFrame.soundRange = bitReader.readUnsigned(4);
|
||||
swapFrame.surfaceSound = bitReader.readBit();
|
||||
swapFrame.reserved = bitReader.readUnsigned(2);
|
||||
*pFrame = swapFrame;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is to eliminate a huge design issue in NBlood that was apparently copied verbatim from the DOS-Version.
|
||||
// Sequences were cached in the resource and directly returned from there in writable form, with byte swapping directly performed in the cache on Big Endian systems.
|
||||
// To avoid such unsafe operations this caches the read data separately in static memory that's guaranteed not to be touched by the file system.
|
||||
FMemArena seqcache;
|
||||
static TMap<int, Seq*> sequences;
|
||||
Seq* getSequence(int res_id)
|
||||
{
|
||||
auto p = sequences.CheckKey(res_id);
|
||||
if (p != nullptr) return *p;
|
||||
|
||||
int index = fileSystem.FindResource(res_id, "SEQ");
|
||||
if (index < 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto fr = fileSystem.OpenFileReader(index);
|
||||
auto seqdata = (Seq*)seqcache.Alloc(fr.GetLength());
|
||||
fr.Read(seqdata, fr.GetLength());
|
||||
sequences.Insert(res_id, seqdata);
|
||||
ByteSwapSEQ(seqdata);
|
||||
return seqdata;
|
||||
}
|
||||
|
||||
END_BLD_NS
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
BEGIN_BLD_NS
|
||||
|
||||
|
||||
struct SEQFRAME {
|
||||
unsigned int tile : 12;
|
||||
unsigned int at1_4 : 1; // transparent
|
||||
|
@ -68,7 +69,6 @@ struct ACTIVE
|
|||
|
||||
struct SEQINST
|
||||
{
|
||||
DICTNODE *hSeq;
|
||||
Seq *pSequence;
|
||||
int at8;
|
||||
int atc;
|
||||
|
@ -94,4 +94,7 @@ int seqGetStatus(int a1, int a2);
|
|||
int seqGetID(int a1, int a2);
|
||||
void seqProcess(int a1);
|
||||
|
||||
Seq* getSequence(int res_id);
|
||||
|
||||
|
||||
END_BLD_NS
|
||||
|
|
Loading…
Reference in a new issue