- cache QAVs outside the file system as well.

- delete some voxel code that's software rendering only.
- apply Big Endian byte swapping for SFXs, as well, now that this no longer involves hacking the file system cache.
This commit is contained in:
Christoph Oelckers 2020-07-25 23:35:39 +02:00
parent b804589f81
commit b2f794bde5
22 changed files with 92 additions and 168 deletions

View file

@ -57,7 +57,6 @@ set( PCH_SOURCES
src/player.cpp src/player.cpp
src/qav.cpp src/qav.cpp
src/replace.cpp src/replace.cpp
src/resource.cpp
src/screen.cpp src/screen.cpp
src/sectorfx.cpp src/sectorfx.cpp
src/seq.cpp src/seq.cpp

View file

@ -1061,9 +1061,6 @@ int GameInterface::app_main()
gGameOptions.nMonsterSettings = !userConfig.nomonsters; gGameOptions.nMonsterSettings = !userConfig.nomonsters;
bQuickStart = userConfig.nologo; bQuickStart = userConfig.nologo;
ReadAllRFS(); ReadAllRFS();
#ifdef USE_QHEAP
Resource::heap = new QHeap(nMaxAlloc);
#endif
HookReplaceFunctions(); HookReplaceFunctions();

View file

@ -39,12 +39,11 @@ void CChoke::sub_83ff0(int a1, void(*a2)(PLAYER*))
{ {
at0 = NULL; at0 = NULL;
at1c = a2; at1c = a2;
if (!at4 && a1 != -1) if (!at8 && a1 != -1)
{ {
at4 = gSysRes.Lookup(a1, "QAV"); at8 = getQAV(a1);
if (!at4) if (!at8)
ThrowError("Could not load QAV %d\n", a1); ThrowError("Could not load QAV %d\n", a1);
at8 = (QAV*)gSysRes.Lock(at4);
at8->nSprite = -1; at8->nSprite = -1;
at8->x = at14; at8->x = at14;
at8->y = at18; at8->y = at18;
@ -55,7 +54,7 @@ void CChoke::sub_83ff0(int a1, void(*a2)(PLAYER*))
void CChoke::sub_84110(int x, int y) void CChoke::sub_84110(int x, int y)
{ {
if (!at4) if (!at8)
return; return;
ClockTicks v4 = gFrameClock; ClockTicks v4 = gFrameClock;
gFrameClock = totalclock; gFrameClock = totalclock;

View file

@ -34,7 +34,6 @@ public:
CChoke() CChoke()
{ {
at0 = NULL; at0 = NULL;
at4 = NULL;
at8 = NULL; at8 = NULL;
atc = 0; atc = 0;
at10 = 0; at10 = 0;
@ -46,7 +45,6 @@ public:
void sub_84110(int x, int y); void sub_84110(int x, int y);
void sub_84218(); void sub_84218();
char *at0; char *at0;
DICTNODE *at4;
QAV *at8; QAV *at8;
int atc; int atc;
int at10; int at10;

View file

@ -44,7 +44,7 @@ void CellularFrame(char *pFrame, int sizeX, int sizeY);
char FrameBuffer[17280]; char FrameBuffer[17280];
char SeedBuffer[16][128]; char SeedBuffer[16][128];
char *gCLU; static TArray<uint8_t> gCLU;
void InitSeedBuffers(void) void InitSeedBuffers(void)
{ {
@ -89,10 +89,10 @@ void FireInit(void)
memset(FrameBuffer, 0, sizeof(FrameBuffer)); memset(FrameBuffer, 0, sizeof(FrameBuffer));
BuildCoolTable(); BuildCoolTable();
InitSeedBuffers(); InitSeedBuffers();
DICTNODE *pNode = gSysRes.Lookup("RFIRE", "CLU"); auto fr = fileSystem.OpenFileReader("rfire.clu");
if (!pNode) if (!fr.isOpen())
ThrowError("RFIRE.CLU not found"); ThrowError("RFIRE.CLU not found");
gCLU = (char*)gSysRes.Lock(pNode); gCLU = fr.Read();
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
DoFireFrame(); DoFireFrame();
} }

View file

@ -39,8 +39,6 @@ int gFrame;
//int volatile gGameClock; //int volatile gGameClock;
int gFrameRate; int gFrameRate;
Resource& gSysRes = fileSystem;
static const char *_module; static const char *_module;
static int _line; static int _line;

View file

@ -35,6 +35,4 @@ extern int gFrame;
extern int gFrameRate; extern int gFrameRate;
extern bool bVanilla; extern bool bVanilla;
extern FileSystem &gSysRes;
END_BLD_NS END_BLD_NS

View file

@ -4741,11 +4741,9 @@ void usePictureChanger(XSPRITE* pXSource, int objType, int objIndex) {
// player related // player related
QAV* playerQavSceneLoad(int qavId) { QAV* playerQavSceneLoad(int qavId) {
QAV* pQav = NULL; DICTNODE* hQav = gSysRes.Lookup(qavId, "QAV"); QAV* pQav = getQAV(qavId);
if (hQav) pQav = (QAV*)gSysRes.Lock(hQav);
else viewSetSystemMessage("Failed to load QAV animation #%d", qavId);
if (!pQav) viewSetSystemMessage("Failed to load QAV animation #%d", qavId);
return pQav; return pQav;
} }

View file

@ -155,4 +155,61 @@ void QAV::Precache(void)
} }
} }
} }
void ByteSwapQAV(void* p)
{
#if B_BIG_ENDIAN == 1
QAV* qav = (QAV*)p;
qav->nFrames = B_LITTLE32(qav->nFrames);
qav->ticksPerFrame = B_LITTLE32(qav->ticksPerFrame);
qav->at10 = B_LITTLE32(qav->at10);
qav->x = B_LITTLE32(qav->x);
qav->y = B_LITTLE32(qav->y);
qav->nSprite = B_LITTLE32(qav->nSprite);
for (int i = 0; i < qav->nFrames; i++)
{
FRAMEINFO* pFrame = &qav->frames[i];
SOUNDINFO* pSound = &pFrame->sound;
pFrame->nCallbackId = B_LITTLE32(pFrame->nCallbackId);
pSound->sound = B_LITTLE32(pSound->sound);
for (int j = 0; j < 8; j++)
{
TILE_FRAME* pTile = &pFrame->tiles[j];
pTile->picnum = B_LITTLE32(pTile->picnum);
pTile->x = B_LITTLE32(pTile->x);
pTile->y = B_LITTLE32(pTile->y);
pTile->z = B_LITTLE32(pTile->z);
pTile->stat = B_LITTLE32(pTile->stat);
pTile->angle = B_LITTLE16(pTile->angle);
}
}
#endif
}
// 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.
extern FMemArena seqcache; // Use the same storage as the SEQs.
static TMap<int, QAV*> sequences;
QAV* getQAV(int res_id)
{
auto p = sequences.CheckKey(res_id);
if (p != nullptr) return *p;
int index = fileSystem.FindResource(res_id, "QAV");
if (index < 0)
{
return nullptr;
}
auto fr = fileSystem.OpenFileReader(index);
auto qavdata = (QAV*)seqcache.Alloc(fr.GetLength());
fr.Read(qavdata, fr.GetLength());
sequences.Insert(res_id, qavdata);
ByteSwapQAV(qavdata);
return qavdata;
}
END_BLD_NS END_BLD_NS

View file

@ -91,5 +91,6 @@ struct QAV
#pragma pack(pop) #pragma pack(pop)
int qavRegisterClient(void(*pClient)(int, void *)); int qavRegisterClient(void(*pClient)(int, void *));
QAV* getQAV(int res_id);
END_BLD_NS END_BLD_NS

View file

@ -95,7 +95,6 @@ void HookReplaceFunctions(void)
deletesprite_replace = qdeletesprite; deletesprite_replace = qdeletesprite;
changespritesect_replace = qchangespritesect; changespritesect_replace = qchangespritesect;
changespritestat_replace = qchangespritestat; changespritestat_replace = qchangespritestat;
loadvoxel_replace = qloadvoxel;
loadboard_replace = qloadboard; loadboard_replace = qloadboard;
} }

View file

@ -1,89 +0,0 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
This file is part of NBlood.
NBlood is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "compat.h"
#include "common_game.h"
#include "misc.h"
#if B_BIG_ENDIAN == 1
#include "qav.h"
#include "seq.h"
#include "sound.h"
#endif
BEGIN_BLD_NS
// Code left here for documentation.
// It's unlikely to be needed by today's systems so unless needed I rather leave such hacks out of the file system.
#if B_BIG_ENDIAN == 1
void ByteSwapQAV(void *p)
{
QAV *qav = (QAV*)p;
qav->nFrames = B_LITTLE32(qav->nFrames);
qav->ticksPerFrame = B_LITTLE32(qav->ticksPerFrame);
qav->at10 = B_LITTLE32(qav->at10);
qav->x = B_LITTLE32(qav->x);
qav->y = B_LITTLE32(qav->y);
qav->nSprite = B_LITTLE32(qav->nSprite);
for (int i = 0; i < qav->nFrames; i++)
{
FRAMEINFO *pFrame = &qav->frames[i];
SOUNDINFO *pSound = &pFrame->sound;
pFrame->nCallbackId = B_LITTLE32(pFrame->nCallbackId);
pSound->sound = B_LITTLE32(pSound->sound);
for (int j = 0; j < 8; j++)
{
TILE_FRAME *pTile = &pFrame->tiles[j];
pTile->picnum = B_LITTLE32(pTile->picnum);
pTile->x = B_LITTLE32(pTile->x);
pTile->y = B_LITTLE32(pTile->y);
pTile->z = B_LITTLE32(pTile->z);
pTile->stat = B_LITTLE32(pTile->stat);
pTile->angle = B_LITTLE16(pTile->angle);
}
}
}
void ByteSwapSFX(void *p)
{
SFX *pSFX = (SFX*)p;
pSFX->relVol = B_LITTLE32(pSFX->relVol);
pSFX->pitch = B_LITTLE32(pSFX->pitch);
pSFX->pitchRange = B_LITTLE32(pSFX->pitchRange);
pSFX->format = B_LITTLE32(pSFX->format);
pSFX->loopStart = B_LITTLE32(pSFX->loopStart);
}
#endif
END_BLD_NS

View file

@ -603,6 +603,7 @@ void SeqLoadSaveConstruct(void)
static void ByteSwapSEQ(Seq* pSeq) static void ByteSwapSEQ(Seq* pSeq)
{ {
#if B_BIG_ENDIAN == 1
pSeq->version = B_LITTLE16(pSeq->version); pSeq->version = B_LITTLE16(pSeq->version);
pSeq->nFrames = B_LITTLE16(pSeq->nFrames); pSeq->nFrames = B_LITTLE16(pSeq->nFrames);
pSeq->at8 = B_LITTLE16(pSeq->at8); pSeq->at8 = B_LITTLE16(pSeq->at8);
@ -636,6 +637,7 @@ static void ByteSwapSEQ(Seq* pSeq)
swapFrame.reserved = bitReader.readUnsigned(2); swapFrame.reserved = bitReader.readUnsigned(2);
*pFrame = swapFrame; *pFrame = swapFrame;
} }
#endif
} }

View file

@ -52,6 +52,17 @@ int soundRates[13] = {
#define kChannelMax 32 #define kChannelMax 32
void ByteSwapSFX(SFX* pSFX)
{
#if B_BIG_ENDIAN == 1
pSFX->relVol = B_LITTLE32(pSFX->relVol);
pSFX->pitch = B_LITTLE32(pSFX->pitch);
pSFX->pitchRange = B_LITTLE32(pSFX->pitchRange);
pSFX->format = B_LITTLE32(pSFX->format);
pSFX->loopStart = B_LITTLE32(pSFX->loopStart);
#endif
}
//========================================================================== //==========================================================================
// //
// S_AddBloodSFX // S_AddBloodSFX
@ -64,7 +75,8 @@ int soundRates[13] = {
static void S_AddBloodSFX(int lumpnum) static void S_AddBloodSFX(int lumpnum)
{ {
auto sfxlump = fileSystem.ReadFile(lumpnum); auto sfxlump = fileSystem.ReadFile(lumpnum);
const SFX* sfx = (SFX*)sfxlump.GetMem(); SFX* sfx = (SFX*)sfxlump.GetMem();
ByteSwapSFX(sfx);
FStringf rawname("%s.raw", sfx->rawName); FStringf rawname("%s.raw", sfx->rawName);
auto rawlump = fileSystem.FindFile(rawname); auto rawlump = fileSystem.FindFile(rawname);
int sfxnum; int sfxnum;

View file

@ -38,30 +38,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS BEGIN_BLD_NS
void qloadvoxel(int32_t nVoxel)
{
static int nLastVoxel = 0;
DICTNODE *hVox = gSysRes.Lookup(nVoxel, "KVX");
if (!hVox) {
Printf("Missing voxel #%d (max voxels: %d)", nVoxel, kMaxVoxels);
return;
}
if (!hVox->LockCount())
voxoff[nLastVoxel][0] = 0;
nLastVoxel = nVoxel;
char *pVox = (char*)gSysRes.Lock(hVox);
for (int i = 0; i < MAXVOXMIPS; i++)
{
int nSize = *((int*)pVox);
#if B_BIG_ENDIAN == 1
nSize = B_LITTLE32(nSize);
#endif
pVox += 4;
voxoff[nVoxel][i] = (intptr_t)pVox;
pVox += nSize;
}
}
bool artLoaded = false; bool artLoaded = false;
int nTileFiles = 0; int nTileFiles = 0;
@ -128,11 +104,12 @@ void tileProcessGLVoxels(void)
voxInit = true; voxInit = true;
for (int i = 0; i < kMaxVoxels; i++) for (int i = 0; i < kMaxVoxels; i++)
{ {
DICTNODE *hVox = gSysRes.Lookup(i, "KVX"); auto index = fileSystem.FindResource(i, "KVX");
if (!hVox) if (index >= 0)
continue; {
char *pVox = (char*)gSysRes.Load(hVox); auto data = fileSystem.ReadFile(index);
voxmodels[i] = loadkvxfrombuf(pVox, hVox->Size()); voxmodels[i] = loadkvxfrombuf((const char*)data.GetMem(), data.GetSize());
}
} }
} }
#endif #endif
@ -175,8 +152,6 @@ void tilePreloadTile(int nTile)
voxelIndex[nTile] = -1; voxelIndex[nTile] = -1;
picanm[nTile].extra &= ~7; picanm[nTile].extra &= ~7;
} }
else
qloadvoxel(voxelIndex[nTile]);
break; break;
} }
while(n--) while(n--)

View file

@ -53,7 +53,6 @@ extern short voxelIndex[kMaxTiles];
extern int nPrecacheCount; extern int nPrecacheCount;
extern char precachehightile[2][(MAXTILES+7)>>3]; extern char precachehightile[2][(MAXTILES+7)>>3];
void qloadvoxel(int32_t nVoxel);
int tileInit(char a1, const char *a2); int tileInit(char a1, const char *a2);
#ifdef USE_OPENGL #ifdef USE_OPENGL
void tileProcessGLVoxels(void); void tileProcessGLVoxels(void);

View file

@ -2398,8 +2398,6 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
pTSprite->cstat &= ~(4|8); pTSprite->cstat &= ~(4|8);
pTSprite->yoffset += tileTopOffset(pTSprite->picnum); pTSprite->yoffset += tileTopOffset(pTSprite->picnum);
pTSprite->picnum = voxelIndex[pTSprite->picnum]; pTSprite->picnum = voxelIndex[pTSprite->picnum];
if (!voxoff[pTSprite->picnum])
qloadvoxel(pTSprite->picnum);
if ((picanm[nTile].extra&7) == 7) if ((picanm[nTile].extra&7) == 7)
{ {
pTSprite->ang = ((int)totalclock<<3)&2047; pTSprite->ang = ((int)totalclock<<3)&2047;

View file

@ -218,10 +218,9 @@ void WeaponInit(void)
{ {
for (int i = 0; i < kQAVEnd; i++) for (int i = 0; i < kQAVEnd; i++)
{ {
DICTNODE *hRes = gSysRes.Lookup(i, "QAV"); weaponQAV[i] = getQAV(i);
if (!hRes) if (!weaponQAV[i])
ThrowError("Could not load QAV %d\n", i); ThrowError("Could not load QAV %d\n", i);
weaponQAV[i] = (QAV*)gSysRes.Lock(hRes);
weaponQAV[i]->nSprite = -1; weaponQAV[i]->nSprite = -1;
} }
} }

View file

@ -992,7 +992,6 @@ int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, f
extern TArray<FString> g_clipMapFiles; extern TArray<FString> g_clipMapFiles;
EXTERN int32_t nextvoxid; EXTERN int32_t nextvoxid;
EXTERN intptr_t voxoff[MAXVOXELS][MAXVOXMIPS]; // used in KenBuild
EXTERN int8_t voxreserve[(MAXVOXELS+7)>>3]; EXTERN int8_t voxreserve[(MAXVOXELS+7)>>3];
EXTERN int8_t voxrotate[(MAXVOXELS+7)>>3]; EXTERN int8_t voxrotate[(MAXVOXELS+7)>>3];
@ -1139,7 +1138,6 @@ extern int32_t(*insertsprite_replace)(int16_t sectnum, int16_t statnum);
extern int32_t(*deletesprite_replace)(int16_t spritenum); extern int32_t(*deletesprite_replace)(int16_t spritenum);
extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum); extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum);
extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum); extern int32_t(*changespritestat_replace)(int16_t spritenum, int16_t newstatnum);
extern void(*loadvoxel_replace)(int32_t voxel);
extern int32_t(*loadboard_replace)(const char *filename, char flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum); extern int32_t(*loadboard_replace)(const char *filename, char flags, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum);
#ifdef USE_OPENGL #ifdef USE_OPENGL
extern void(*PolymostProcessVoxels_Callback)(void); extern void(*PolymostProcessVoxels_Callback)(void);

View file

@ -58,7 +58,6 @@ int16_t pskybits_override = -1;
// This was on the cache but is permanently allocated, so put it into something static. This needs some rethinking anyway // This was on the cache but is permanently allocated, so put it into something static. This needs some rethinking anyway
static TArray<TArray<uint8_t>> voxelmemory; static TArray<TArray<uint8_t>> voxelmemory;
void (*loadvoxel_replace)(int32_t voxindex) = NULL;
int16_t tiletovox[MAXTILES]; int16_t tiletovox[MAXTILES];
#ifdef USE_OPENGL #ifdef USE_OPENGL
char *voxfilenames[MAXVOXELS]; char *voxfilenames[MAXVOXELS];
@ -3030,7 +3029,6 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
voxelmemory.Reserve(1); voxelmemory.Reserve(1);
voxelmemory.Last() = fil.Read(dasiz); voxelmemory.Last() = fil.Read(dasiz);
voxoff[voxindex][i] = (intptr_t)voxelmemory.Last().Data();
lengcnt += dasiz+4; lengcnt += dasiz+4;
if (lengcnt >= lengtot-768) if (lengcnt >= lengtot-768)
@ -3069,11 +3067,6 @@ void vox_undefine(int32_t const tile)
DO_FREE_AND_NULL(voxfilenames[voxindex]); DO_FREE_AND_NULL(voxfilenames[voxindex]);
#endif #endif
for (ssize_t j = 0; j < MAXVOXMIPS; ++j)
{
// CACHE1D_FREE
voxoff[voxindex][j] = 0;
}
voxscale[voxindex] = 65536; voxscale[voxindex] = 65536;
voxrotate[voxindex>>3] &= ~pow2char[voxindex&7]; voxrotate[voxindex>>3] &= ~pow2char[voxindex&7];
tiletovox[tile] = -1; tiletovox[tile] = -1;

View file

@ -1637,12 +1637,6 @@ FResourceLump *FileSystem::Lookup(const char *name, const char *type)
else return nullptr; else return nullptr;
} }
FResourceLump *FileSystem::Lookup(unsigned int id, const char *type)
{
auto lump = FindResource(id, type);
if (lump >= 0) return FileInfo[lump].lump;
else return nullptr;
}
FResourceLump* FileSystem::GetFileAt(int no) FResourceLump* FileSystem::GetFileAt(int no)
{ {
return FileInfo[no].lump; return FileInfo[no].lump;

View file

@ -190,8 +190,7 @@ public:
// Blood stuff // Blood stuff
FResourceLump* Lookup(const char* name, const char* type); FResourceLump* Lookup(const char* name, const char* type);
FResourceLump* Lookup(unsigned int id, const char* type);
FResourceLump* GetFileAt(int no); FResourceLump* GetFileAt(int no);
const void* Lock(int lump); const void* Lock(int lump);