- got rid of klzw and the legacy demo code along with it.

This commit is contained in:
Christoph Oelckers 2019-09-25 23:12:29 +02:00
parent 0261fef4a8
commit d12563f644
6 changed files with 114 additions and 712 deletions

View File

@ -1,22 +0,0 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
//
// This file has been modified from Ken Silverman's original release
// by Jonathon Fowler (jf@jonof.id.au)
// by the EDuke32 team (development@voidpoint.com)
#ifndef klzw_h_
#define klzw_h_
#include "compat.h"
// These two follow the argument order of the C functions "read" and "write":
// handle, buffer, length.
typedef int32_t (*klzw_readfunc)(intptr_t, void *, int32_t);
typedef void (*klzw_writefunc)(intptr_t, void const *, int32_t);
int32_t klzw_read_compressed(void *buffer, int dasizeof, int count, intptr_t const f, klzw_readfunc readfunc);
void klzw_write_compressed(const void * const buffer, int dasizeof, int count, intptr_t const f, klzw_writefunc writefunc);
#endif // klzw_h_

View File

@ -17,7 +17,6 @@
#include "pragmas.h"
#include "baselayer.h"
#include "lz4.h"
#include "klzw.h"
#include "vfs.h"
@ -1674,11 +1673,6 @@ static void dfwrite_func(intptr_t fp, const void *inbuf, int32_t length)
}
int32_t kdfread(void *buffer, int dasizeof, int count, buildvfs_kfd fil)
{
return klzw_read_compressed(buffer, dasizeof, count, (intptr_t)fil, kdfread_func);
}
// LZ4_COMPRESSION_ACCELERATION_VALUE can be tuned for performance/space trade-off
// (lower number = higher compression ratio, higher number = faster compression speed)
#define LZ4_COMPRESSION_ACCELERATION_VALUE 5
@ -1713,11 +1707,6 @@ int32_t kdfread_LZ4(void *buffer, int dasizeof, int count, buildvfs_kfd fil)
}
void dfwrite(const void *buffer, int dasizeof, int count, buildvfs_FILE fil)
{
klzw_write_compressed(buffer, dasizeof, count, (intptr_t)fil, dfwrite_func);
}
void dfwrite_LZ4(const void *buffer, int dasizeof, int count, buildvfs_FILE fil)
{
char * pCompressedData = compressedDataStackBuf;

View File

@ -1,359 +0,0 @@
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
//
// This file has been modified from Ken Silverman's original release
// by Jonathon Fowler (jf@jonof.id.au)
// by the EDuke32 team (development@voidpoint.com)
#include "compat.h"
#include "klzw.h"
//Internal LZW variables
#define LZWSIZE 16384 //Watch out for shorts!
#define LZWSIZEPAD (LZWSIZE+(LZWSIZE>>4))
// lzwrawbuf LZWSIZE+1 (formerly): see (*) below
// XXX: lzwrawbuf size increased again :-/
static char lzwtmpbuf[LZWSIZEPAD], lzwrawbuf[LZWSIZEPAD], lzwcompbuf[LZWSIZEPAD];
static int16_t lzwbuf2[LZWSIZEPAD], lzwbuf3[LZWSIZEPAD];
////////// CORE COMPRESSION FUNCTIONS //////////
static int32_t lzwcompress(const char *lzwinbuf, int32_t uncompleng, char *lzwoutbuf)
{
int32_t i, addr, addrcnt, *intptr;
int32_t bytecnt1, bitcnt, numbits, oneupnumbits;
int16_t *shortptr;
int16_t *const lzwcodehead = lzwbuf2;
int16_t *const lzwcodenext = lzwbuf3;
for (i=255; i>=4; i-=4)
{
lzwtmpbuf[i] = i, lzwcodenext[i] = (i+1)&255;
lzwtmpbuf[i-1] = i-1, lzwcodenext[i-1] = (i) &255;
lzwtmpbuf[i-2] = i-2, lzwcodenext[i-2] = (i-1)&255;
lzwtmpbuf[i-3] = i-3, lzwcodenext[i-3] = (i-2)&255;
lzwcodehead[i] = lzwcodehead[i-1] = lzwcodehead[i-2] = lzwcodehead[i-3] = -1;
}
for (; i>=0; i--)
{
lzwtmpbuf[i] = i;
lzwcodenext[i] = (i+1)&255;
lzwcodehead[i] = -1;
}
Bmemset(lzwoutbuf, 0, 4+uncompleng+1);
// clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L);
addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3);
numbits = 8; oneupnumbits = (1<<8);
do
{
addr = lzwinbuf[bytecnt1];
do
{
int32_t newaddr;
if (++bytecnt1 == uncompleng)
break; // (*) see XXX below
if (lzwcodehead[addr] < 0)
{
lzwcodehead[addr] = addrcnt;
break;
}
newaddr = lzwcodehead[addr];
while (lzwtmpbuf[newaddr] != lzwinbuf[bytecnt1])
{
if (lzwcodenext[newaddr] < 0)
{
lzwcodenext[newaddr] = addrcnt;
break;
}
newaddr = lzwcodenext[newaddr];
}
if (lzwcodenext[newaddr] == addrcnt)
break;
addr = newaddr;
}
while (addr >= 0);
lzwtmpbuf[addrcnt] = lzwinbuf[bytecnt1]; // XXX: potential oob access of lzwinbuf via (*) above
lzwcodehead[addrcnt] = -1;
lzwcodenext[addrcnt] = -1;
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
bitcnt += numbits;
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
bitcnt--;
addrcnt++;
if (addrcnt > oneupnumbits)
{ numbits++; oneupnumbits <<= 1; }
}
while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3)));
intptr = (int32_t *)&lzwoutbuf[bitcnt>>3];
intptr[0] |= B_LITTLE32(addr<<(bitcnt&7));
bitcnt += numbits;
if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1)))
bitcnt--;
shortptr = (int16_t *)lzwoutbuf;
shortptr[0] = B_LITTLE16((int16_t)uncompleng);
if (((bitcnt+7)>>3) < uncompleng)
{
shortptr[1] = B_LITTLE16((int16_t)addrcnt);
return (bitcnt+7)>>3;
}
// Failed compressing, mark this in the stream.
shortptr[1] = 0;
for (i=0; i<uncompleng-4; i+=4)
{
lzwoutbuf[i+4] = lzwinbuf[i];
lzwoutbuf[i+5] = lzwinbuf[i+1];
lzwoutbuf[i+6] = lzwinbuf[i+2];
lzwoutbuf[i+7] = lzwinbuf[i+3];
}
for (; i<uncompleng; i++)
lzwoutbuf[i+4] = lzwinbuf[i];
return uncompleng+4;
}
static int32_t lzwuncompress(const char *lzwinbuf, int32_t compleng, char *lzwoutbuf)
{
int32_t currstr, numbits, oneupnumbits;
int32_t i, bitcnt, outbytecnt;
const int16_t *const shortptr = (const int16_t *)lzwinbuf;
const int32_t strtot = B_LITTLE16(shortptr[1]);
const int32_t uncompleng = B_LITTLE16(shortptr[0]);
if (strtot == 0)
{
if (lzwoutbuf==lzwrawbuf && lzwinbuf==lzwcompbuf)
{
Bassert((compleng-4)+3+0u < sizeof(lzwrawbuf));
Bassert((compleng-4)+3+0u < sizeof(lzwcompbuf)-4);
}
Bmemcpy(lzwoutbuf, lzwinbuf+4, (compleng-4)+3);
return uncompleng;
}
for (i=255; i>=4; i-=4)
{
lzwbuf2[i] = lzwbuf3[i] = i;
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
lzwbuf2[i-3] = lzwbuf3[i-3] = i-3;
}
lzwbuf2[i] = lzwbuf3[i] = i;
lzwbuf2[i-1] = lzwbuf3[i-1] = i-1;
lzwbuf2[i-2] = lzwbuf3[i-2] = i-2;
currstr = 256; bitcnt = (4<<3); outbytecnt = 0;
numbits = 8; oneupnumbits = (1<<8);
do
{
const int32_t *const intptr = (const int32_t *)&lzwinbuf[bitcnt>>3];
int32_t dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1));
int32_t leng;
bitcnt += numbits;
if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1)))
{ dat &= ((oneupnumbits>>1)-1); bitcnt--; }
lzwbuf3[currstr] = dat;
for (leng=0; dat>=256; leng++,dat=lzwbuf3[dat])
lzwtmpbuf[leng] = lzwbuf2[dat];
lzwoutbuf[outbytecnt++] = dat;
for (i=leng-1; i>=4; i-=4, outbytecnt+=4)
{
lzwoutbuf[outbytecnt] = lzwtmpbuf[i];
lzwoutbuf[outbytecnt+1] = lzwtmpbuf[i-1];
lzwoutbuf[outbytecnt+2] = lzwtmpbuf[i-2];
lzwoutbuf[outbytecnt+3] = lzwtmpbuf[i-3];
}
for (; i>=0; i--)
lzwoutbuf[outbytecnt++] = lzwtmpbuf[i];
lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat;
currstr++;
if (currstr > oneupnumbits)
{ numbits++; oneupnumbits <<= 1; }
}
while (currstr < strtot);
return uncompleng;
}
////////// COMPRESSED READ //////////
struct decompress_info
{
klzw_readfunc readfunc;
intptr_t f;
int32_t kgoal;
};
static int decompress_part(struct decompress_info * x)
{
intptr_t const f = x->f;
auto readfunc = x->readfunc;
// Read compressed length first.
int16_t leng;
if (readfunc(f, &leng, sizeof(leng)) != sizeof(leng))
return 1;
leng = B_LITTLE16(leng);
if (readfunc(f, lzwcompbuf, leng) != leng)
return 1;
x->kgoal = lzwuncompress(lzwcompbuf, leng, lzwrawbuf);
return 0;
}
// Read from 'f' into 'buffer'.
int32_t klzw_read_compressed(void *buffer, int dasizeof, int count, intptr_t const f, klzw_readfunc readfunc)
{
char *ptr = (char *)buffer;
if (dasizeof > LZWSIZE)
{
count *= dasizeof;
dasizeof = 1;
}
struct decompress_info x;
x.readfunc = readfunc;
x.f = f;
if (decompress_part(&x))
return -1;
Bmemcpy(ptr, lzwrawbuf, (int32_t)dasizeof);
for (int i=1, k=dasizeof; i<count; i++)
{
if (k >= x.kgoal)
{
k = decompress_part(&x);
if (k) return -1;
}
int j = 0;
if (dasizeof >= 4)
{
for (; j<dasizeof-4; j+=4)
{
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
ptr[j+1+dasizeof] = ((ptr[j+1]+lzwrawbuf[j+1+k])&255);
ptr[j+2+dasizeof] = ((ptr[j+2]+lzwrawbuf[j+2+k])&255);
ptr[j+3+dasizeof] = ((ptr[j+3]+lzwrawbuf[j+3+k])&255);
}
}
for (; j<dasizeof; j++)
ptr[j+dasizeof] = ((ptr[j]+lzwrawbuf[j+k])&255);
k += dasizeof;
ptr += dasizeof;
}
return count;
}
////////// COMPRESSED WRITE //////////
struct compress_info
{
klzw_writefunc writefunc;
intptr_t f;
int32_t k;
};
static void compress_part(struct compress_info * x)
{
const int16_t leng = (int16_t)lzwcompress(lzwrawbuf, x->k, lzwcompbuf);
const int16_t swleng = B_LITTLE16(leng);
intptr_t const f = x->f;
auto writefunc = x->writefunc;
x->k = 0;
writefunc(f, &swleng, sizeof(swleng));
writefunc(f, lzwcompbuf, leng);
}
// Write from 'buffer' to 'f'.
void klzw_write_compressed(const void * const buffer, int dasizeof, int count, intptr_t const f, klzw_writefunc writefunc)
{
char const *ptr = (char const *)buffer;
if (dasizeof > LZWSIZE)
{
count *= dasizeof;
dasizeof = 1;
}
Bmemcpy(lzwrawbuf, ptr, (int32_t)dasizeof);
struct compress_info x;
x.writefunc = writefunc;
x.f = f;
if ((x.k = dasizeof) > LZWSIZE-dasizeof)
compress_part(&x);
for (int i=1; i<count; i++)
{
int j = 0;
if (dasizeof >= 4)
{
for (; j<dasizeof-4; j+=4)
{
lzwrawbuf[j+x.k] = ((ptr[j+dasizeof]-ptr[j])&255);
lzwrawbuf[j+1+x.k] = ((ptr[j+1+dasizeof]-ptr[j+1])&255);
lzwrawbuf[j+2+x.k] = ((ptr[j+2+dasizeof]-ptr[j+2])&255);
lzwrawbuf[j+3+x.k] = ((ptr[j+3+dasizeof]-ptr[j+3])&255);
}
}
for (; j<dasizeof; j++)
lzwrawbuf[j+x.k] = ((ptr[j+dasizeof]-ptr[j])&255);
if ((x.k += dasizeof) > LZWSIZE-dasizeof)
compress_part(&x);
ptr += dasizeof;
}
if (x.k > 0)
compress_part(&x);
}

View File

@ -142,13 +142,6 @@ extern int32_t krd_print(const char *filename);
void G_OpenDemoWrite(void)
{
#ifdef LUNATIC
// TODO: Currently, we can't diff gamevars in Lunatic...
Bstrcpy(apStrings[QUOTE_RESERVED4], "DEMOS UNSUPPORTED IN LUNATIC BUILD");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
#else
char demofn[BMAX_PATH];
int32_t i, demonum=1;
@ -165,26 +158,6 @@ void G_OpenDemoWrite(void)
ud.recstat = ud.m_recstat = 0;
return;
}
# if !defined LUNATIC
if (demorec_diffs_cvar && !demorec_force_cvar)
for (i=1; i<g_scriptSize-2; i++)
{
intptr_t w=apScript[i];
if (VM_DECODE_INST(w)==CON_RESIZEARRAY && VM_DECODE_LINE_NUMBER(w) && apScript[i+1]>=0 && apScript[i+1]<g_gameArrayCount)
{
OSD_Printf("\nThe CON code possibly contains a RESIZEARRAY command.\n");
OSD_Printf("Gamearrays that change their size during the game are unsupported by\n");
OSD_Printf("the demo recording system. If you are sure that the code doesn't\n");
OSD_Printf("contain a RESIZEARRAY command, you can force recording with the\n");
OSD_Printf("`demorec_force' cvar. Alternatively, you can disable diff recording\n");
OSD_Printf("with the `demorec_diffs' cvar.\n\n");
Bstrcpy(apStrings[QUOTE_RESERVED4], "FAILED STARTING DEMO RECORDING. SEE OSD.");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
ud.recstat = ud.m_recstat = 0;
return;
}
}
# endif
do
{
if (demonum == MAXDEMOS)
@ -237,7 +210,6 @@ error_wopen_demo:
krd_enable(1);
# endif
g_demo_cnt = 1;
#endif
}
// demo_profile: < 0: prepare
@ -521,8 +493,10 @@ RECHECK:
renderFlushPerms();
if (!g_netServer && ud.multimode < 2)
foundemo = G_OpenDemoRead(g_whichDemo);
#ifdef PLAYDEMOLOOP // Todo: Make a CVar.
if (!g_netServer && ud.multimode < 2)
foundemo = G_OpenDemoRead(g_whichDemo);
#endif
if (foundemo == 0)
{
@ -799,9 +773,6 @@ nextdemo_nomenu:
if (foundemo == 0)
{
G_DrawBackground();
#ifdef LUNATIC
El_DisplayErrors();
#endif
}
else
{

View File

@ -6085,12 +6085,6 @@ DETONATEB:
}
}
if (deleteAfterExecute && ud.recstat == 2 && g_demo_legacy)
{
A_DeleteSprite(spriteNum);
deleteAfterExecute = 0;
}
if (G_HaveActor(sprite[spriteNum].picnum))
{
int32_t playerDist;

View File

@ -22,27 +22,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "demo.h"
//#include "premap.h" // G_UpdateScreenArea()
#include "duke3d.h"
#include "input.h"
#include "menus.h"
#include "savegame.h"
#include "input.h"
#include "screens.h"
#include "vfs.h"
BEGIN_RR_NS
char g_firstDemoFile[BMAX_PATH];
FILE *g_demo_filePtr = (FILE *)NULL; // write
int32_t g_demo_recFilePtr = -1; // read
buildvfs_FILE g_demo_filePtr{}; // write
buildvfs_kfd g_demo_recFilePtr = buildvfs_kfd_invalid; // read
int32_t g_demo_cnt;
int32_t g_demo_goalCnt=0;
int32_t g_demo_totalCnt;
int32_t g_demo_paused=0;
int32_t g_demo_rewind=0;
int32_t g_demo_showStats=0;
int32_t g_demo_showStats=1;
static int32_t g_demo_soundToggle;
static int32_t demo_hasdiffs, demorec_diffs=1, demorec_difftics = 2*REALGAMETICSPERSEC;
@ -57,26 +59,6 @@ int32_t demoplay_showsync=1;
static int32_t demo_synccompress=1, demorec_seeds=1, demo_hasseeds;
char g_demo_legacy = 0;
int32_t demo_reccnt_init = 0;
#pragma pack(push,1)
typedef struct {
int32_t reccnt;
int8_t version; // 117 for Duke 3d v1.5, 108 for RR(RA)
int8_t volume_number, level_number, player_skill, m_coop, m_ffire;
int16_t multimode, m_monsters_off;
int32_t m_respawn_monsters, m_respawn_items, m_respawn_inventory, playerai;
char user_name[16][32];
} legacydemo_t;
typedef struct {
int8_t avel, horz;
int16_t fvel, svel;
int32_t bits;
} legacyinput_t;
#pragma pack(pop)
static void Demo_RestoreModes(int32_t menu)
{
if (menu)
@ -112,119 +94,23 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
if (g_whichDemo == 1 && g_firstDemoFile[0])
{
demofnptr = g_firstDemoFile;
const int fileNameLen = Bstrlen(g_firstDemoFile);
if (fileNameLen >= 4 && !Bstrncasecmp(&g_firstDemoFile[fileNameLen - 4], ".dmo", 4))
g_demo_legacy = 1;
else
g_demo_legacy = 0;
}
else
{
Bsprintf(demofn, DEMOFN_FMT, g_whichDemo);
demofnptr = demofn;
g_demo_legacy = 0;
}
g_demo_recFilePtr = kopen4loadfrommod(demofnptr, g_loadFromGroupOnly);
if (g_demo_recFilePtr == -1)
{
// Check for legacy demo
Bsprintf(demofn, LDEMOFN_FMT, g_whichDemo);
demofnptr = demofn;
g_demo_legacy = 1;
g_demo_recFilePtr = kopen4loadfrommod(demofnptr, g_loadFromGroupOnly);
if (g_demo_recFilePtr == -1)
return 0;
}
if (g_demo_legacy)
{
ud.reccnt = 0;
legacydemo_t demoHeader;
if (kread(g_demo_recFilePtr, &demoHeader, sizeof(legacydemo_t)) != sizeof(legacydemo_t))
{
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
return 0;
}
demoHeader.reccnt = B_LITTLE32(demoHeader.reccnt);
demoHeader.multimode = B_LITTLE16(demoHeader.multimode);
demoHeader.m_monsters_off = B_LITTLE16(demoHeader.m_monsters_off);
demoHeader.m_respawn_monsters = B_LITTLE32(demoHeader.m_respawn_monsters);
demoHeader.m_respawn_items = B_LITTLE32(demoHeader.m_respawn_items);
demoHeader.m_respawn_inventory = B_LITTLE32(demoHeader.m_respawn_inventory);
demoHeader.playerai = B_LITTLE32(demoHeader.playerai);
ud.volume_number = demoHeader.volume_number;
ud.level_number = demoHeader.level_number;
ud.player_skill = demoHeader.player_skill;
ud.m_coop = demoHeader.m_coop;
ud.m_ffire = demoHeader.m_ffire;
ud.multimode = demoHeader.multimode;
ud.m_monsters_off = demoHeader.m_monsters_off;
ud.m_respawn_monsters = demoHeader.m_respawn_monsters;
ud.m_respawn_items = demoHeader.m_respawn_items;
ud.m_respawn_inventory = demoHeader.m_respawn_inventory;
for (bssize_t i = 0; i < demoHeader.multimode; i++)
{
Bstrncpy(g_player[i].user_name, demoHeader.user_name[i], 32);
}
if (!RR && demoHeader.version == 117)
{
int32_t autoRun;
kread(g_demo_recFilePtr, &autoRun, sizeof(int32_t));
//ud.auto_run = autoRun;
kread(g_demo_recFilePtr, boardfilename, 128);
if (boardfilename[0] != 0)
{
ud.m_level_number = 7;
ud.m_volume_number = 0;
}
}
else if (RR && demoHeader.version == 108)
{
// no op
}
else
{
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
return 0;
}
for (bssize_t i = 0; i < ud.multimode; i++)
{
kread(g_demo_recFilePtr, &g_player[i].ps->aim_mode, 1);
g_player[i].ps->auto_aim = 1;
}
g_demo_totalCnt = demoHeader.reccnt/ud.multimode;
i = g_demo_totalCnt/REALGAMETICSPERSEC;
OSD_Printf("demo %d duration: %d min %d sec\n", g_whichDemo, i/60, i%60);
g_demo_cnt = 1;
ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
ud.noclip = ud.scrollmode = ud.overhead_on = 0; //= ud.pause_on = 0;
totalclock = ototalclock = lockclock = 0;
G_NewGame(ud.volume_number, ud.level_number, ud.player_skill);
demo_reccnt_init = ud.reccnt = demoHeader.reccnt;
return 1;
}
if (g_demo_recFilePtr == buildvfs_kfd_invalid)
return 0;
Bassert(g_whichDemo >= 1);
i = sv_loadsnapshot(g_demo_recFilePtr, -g_whichDemo, &saveh);
if (i)
{
OSD_Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
kclose(g_demo_recFilePtr); g_demo_recFilePtr = buildvfs_kfd_invalid;
return 0;
}
@ -262,7 +148,7 @@ void G_OpenDemoWrite(void)
if (ud.recstat == 2)
{
kclose(g_demo_recFilePtr);
g_demo_recFilePtr = -1;
g_demo_recFilePtr = buildvfs_kfd_invalid;
}
if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag)
@ -285,7 +171,7 @@ void G_OpenDemoWrite(void)
demonum++;
g_demo_filePtr = Bfopen(demofn, "rb");
g_demo_filePtr = buildvfs_fopen_read(demofn);
if (g_demo_filePtr == NULL)
break;
@ -293,7 +179,7 @@ void G_OpenDemoWrite(void)
}
while (1);
g_demo_filePtr = Bfopen(demofn,"wb");
g_demo_filePtr = buildvfs_fopen_write(demofn);
if (g_demo_filePtr == NULL)
return;
@ -345,13 +231,7 @@ void Demo_SetFirst(const char *demostr)
if (tailptr==demostr+Bstrlen(demostr) && (unsigned)i < MAXDEMOS) // demo number passed
Bsprintf(g_firstDemoFile, DEMOFN_FMT, i);
else // demo file name passed
{
int l = Bstrlen(demostr);
if (l >= 4 && !Bstrcasecmp(&demostr[l-4], ".dmo"))
Bstrcpy(g_firstDemoFile, demostr);
else
maybe_append_ext(g_firstDemoFile, sizeof(g_firstDemoFile), demostr, ".edm");
}
maybe_append_ext(g_firstDemoFile, sizeof(g_firstDemoFile), demostr, ".edm");
}
@ -361,16 +241,16 @@ static void Demo_WriteSync()
{
int16_t tmpreccnt;
fwrite("sYnC", 4, 1, g_demo_filePtr);
buildvfs_fwrite("sYnC", 4, 1, g_demo_filePtr);
tmpreccnt = (int16_t)ud.reccnt;
fwrite(&tmpreccnt, sizeof(int16_t), 1, g_demo_filePtr);
buildvfs_fwrite(&tmpreccnt, sizeof(int16_t), 1, g_demo_filePtr);
if (demorec_seeds)
fwrite(g_demo_seedbuf, 1, ud.reccnt, g_demo_filePtr);
buildvfs_fwrite(g_demo_seedbuf, 1, ud.reccnt, g_demo_filePtr);
if (demo_synccompress)
dfwrite_LZ4(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
else //if (demo_synccompress==0)
fwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
buildvfs_fwrite(recsync, sizeof(input_t), ud.reccnt, g_demo_filePtr);
ud.reccnt = 0;
}
@ -407,13 +287,13 @@ void G_CloseDemoWrite(void)
if (ud.reccnt > 0)
Demo_WriteSync();
fwrite("EnD!", 4, 1, g_demo_filePtr);
buildvfs_fwrite("EnD!", 4, 1, g_demo_filePtr);
// lastly, we need to write the number of written recsyncs to the demo file
if (fseek(g_demo_filePtr, offsetof(savehead_t, reccnt), SEEK_SET))
if (buildvfs_fseek_abs(g_demo_filePtr, offsetof(savehead_t, reccnt)))
perror("G_CloseDemoWrite: final fseek");
else
fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr);
buildvfs_fwrite(&g_demo_cnt, sizeof(g_demo_cnt), 1, g_demo_filePtr);
ud.recstat = ud.m_recstat = 0;
MAYBE_FCLOSE_AND_NULL(g_demo_filePtr);
@ -476,28 +356,6 @@ static int32_t Demo_ReadSync(int32_t errcode)
return 0;
}
legacyinput_t recsynclegacy[RECSYNCBUFSIZ];
static void Demo_ReadSyncLegacy(void)
{
int32_t l = min(ud.reccnt, RECSYNCBUFSIZ) / ud.multimode;
kdfread(recsynclegacy, sizeof(legacyinput_t)*ud.multimode, l, g_demo_recFilePtr);
for (bssize_t i = 0; i < l; i ++) {
for (int j = 0; j < ud.multimode; j++)
{
int32_t index = i * ud.multimode + j;
recsync[index].q16avel = F16(recsynclegacy[index].avel<<1);
recsync[index].q16horz = F16(recsynclegacy[index].horz>>1);
recsync[index].fvel = B_LITTLE16(recsynclegacy[index].fvel);
recsync[index].svel = B_LITTLE16(recsynclegacy[index].svel);
recsync[index].bits = B_LITTLE32(recsynclegacy[index].bits);
recsync[index].extbits = 0;
}
}
}
////////// DEMO PROFILING (TIMEDEMO MODE) //////////
static struct {
int32_t numtics, numframes;
@ -669,9 +527,6 @@ RECHECK:
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
if (g_demo_legacy)
G_EnterLevel(MODE_DEMO);
lastsyncofs = ktell(g_demo_recFilePtr);
initsyncofs = lastsyncofs;
lastsynctic = g_demo_cnt;
@ -722,52 +577,36 @@ RECHECK:
int32_t menu = g_player[myconnectindex].ps->gm&MODE_MENU;
if (g_demo_legacy)
if (g_demo_goalCnt > lastsynctic)
{
klseek(g_demo_recFilePtr, initsyncofs, SEEK_SET);
g_levelTextTime = 0;
// we can use a previous diff
if (Demo_UpdateState(0)==0)
{
g_demo_cnt = lastsynctic;
klseek(g_demo_recFilePtr, lastsyncofs, SEEK_SET);
ud.reccnt = 0;
g_demo_cnt = 1;
ud.reccnt = demo_reccnt_init;
bigi = 0;
totalclock = ototalclock = lockclock = 0;
G_EnterLevel(MODE_DEMO);
totalclock = ototalclock = lockclock = lastsyncclock;
}
else CORRUPT(-1);
}
else
{
if (g_demo_goalCnt > lastsynctic)
// update to initial state
if (Demo_UpdateState(1) == 0)
{
// we can use a previous diff
if (Demo_UpdateState(0)==0)
{
g_demo_cnt = lastsynctic;
klseek(g_demo_recFilePtr, lastsyncofs, SEEK_SET);
ud.reccnt = 0;
klseek(g_demo_recFilePtr, initsyncofs, SEEK_SET);
g_levelTextTime = 0;
totalclock = ototalclock = lockclock = lastsyncclock;
}
else CORRUPT(-1);
}
else
{
// update to initial state
if (Demo_UpdateState(1) == 0)
{
klseek(g_demo_recFilePtr, initsyncofs, SEEK_SET);
g_levelTextTime = 0;
g_demo_cnt = 1;
ud.reccnt = 0;
// ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
// ud.noclip = ud.scrollmode = ud.overhead_on = ud.pause_on = 0;
totalclock = ototalclock = lockclock = 0;
}
else CORRUPT(0);
g_demo_cnt = 1;
ud.reccnt = 0;
// ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
// ud.noclip = ud.scrollmode = ud.overhead_on = ud.pause_on = 0;
totalclock = ototalclock = lockclock = 0;
}
else CORRUPT(0);
}
Demo_RestoreModes(menu);
@ -780,105 +619,94 @@ RECHECK:
// || (ud.reccnt > REALGAMETICSPERSEC*2 && ud.pause_on)
|| (g_demo_goalCnt>0 && g_demo_cnt<g_demo_goalCnt))
{
if (g_demo_legacy)
if (ud.reccnt<=0)
{
if (bigi == 0 || bigi >= RECSYNCBUFSIZ)
// Record count reached zero (or <0, corrupted), need
// reading another chunk.
char tmpbuf[4];
if (ud.reccnt<0)
{
bigi = 0;
Demo_ReadSyncLegacy();
OSD_Printf("G_PlaybackDemo: ud.reccnt<0!\n");
CORRUPT(1);
}
}
else
{
if (ud.reccnt<=0)
bigi = 0;
//reread:
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4)
CORRUPT(2);
if (Bmemcmp(tmpbuf, "sYnC", 4)==0)
{
// Record count reached zero (or <0, corrupted), need
// reading another chunk.
int32_t err = Demo_ReadSync(3);
if (err)
CORRUPT(err);
}
char tmpbuf[4];
else if (demo_hasdiffs && Bmemcmp(tmpbuf, "dIfF", 4)==0)
{
int32_t k = sv_readdiff(g_demo_recFilePtr);
if (ud.reccnt<0)
if (k)
{
OSD_Printf("G_PlaybackDemo: ud.reccnt<0!\n");
CORRUPT(1);
OSD_Printf("sv_readdiff() returned %d.\n", k);
CORRUPT(6);
}
bigi = 0;
//reread:
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4)
CORRUPT(2);
if (Bmemcmp(tmpbuf, "sYnC", 4)==0)
else
{
int32_t err = Demo_ReadSync(3);
if (err)
CORRUPT(err);
}
lastsyncofs = ktell(g_demo_recFilePtr);
lastsynctic = g_demo_cnt;
lastsyncclock = (int32_t) totalclock;
else if (demo_hasdiffs && Bmemcmp(tmpbuf, "dIfF", 4)==0)
{
int32_t k = sv_readdiff(g_demo_recFilePtr);
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4)
CORRUPT(7);
if (Bmemcmp(tmpbuf, "sYnC", 4))
CORRUPT(8);
if (k)
{
OSD_Printf("sv_readdiff() returned %d.\n", k);
CORRUPT(6);
int32_t err = Demo_ReadSync(9);
if (err)
CORRUPT(err);
}
else
if ((g_demo_goalCnt==0 && demoplay_diffs) ||
(g_demo_goalCnt>0 && ud.reccnt/ud.multimode >= g_demo_goalCnt-g_demo_cnt))
{
lastsyncofs = ktell(g_demo_recFilePtr);
lastsynctic = g_demo_cnt;
lastsyncclock = (int32_t) totalclock;
if (kread(g_demo_recFilePtr, tmpbuf, 4) != 4)
CORRUPT(7);
if (Bmemcmp(tmpbuf, "sYnC", 4))
CORRUPT(8);
{
int32_t err = Demo_ReadSync(9);
if (err)
CORRUPT(err);
}
if ((g_demo_goalCnt==0 && demoplay_diffs) ||
(g_demo_goalCnt>0 && ud.reccnt/ud.multimode >= g_demo_goalCnt-g_demo_cnt))
{
Demo_UpdateState(0);
}
Demo_UpdateState(0);
}
}
else if (Bmemcmp(tmpbuf, "EnD!", 4)==0)
goto nextdemo;
else CORRUPT(12);
}
else if (Bmemcmp(tmpbuf, "EnD!", 4)==0)
goto nextdemo;
else CORRUPT(12);
if (0)
{
if (0)
{
corrupt:
OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
OSD_Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
Menu_Open(myconnectindex);
Menu_Open(myconnectindex);
nextdemo_nomenu:
foundemo = 0;
ud.reccnt = 0;
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
foundemo = 0;
ud.reccnt = 0;
kclose(g_demo_recFilePtr); g_demo_recFilePtr = buildvfs_kfd_invalid;
if (g_demo_goalCnt>0)
{
g_demo_goalCnt=0;
ud.config.SoundToggle = g_demo_soundToggle;
}
if (Demo_IsProfiling()) // don't reset g_demo_profile if it's < 0
Demo_FinishProfile();
goto RECHECK;
if (g_demo_goalCnt>0)
{
g_demo_goalCnt=0;
ud.config.SoundToggle = g_demo_soundToggle;
}
}
if (demo_hasseeds)
outofsync = ((uint8_t)(randomseed>>24) != g_demo_seedbuf[bigi]);
if (Demo_IsProfiling()) // don't reset g_demo_profile if it's < 0
Demo_FinishProfile();
goto RECHECK;
}
}
if (demo_hasseeds)
outofsync = ((uint8_t)(randomseed>>24) != g_demo_seedbuf[bigi]);
for (TRAVERSE_CONNECT(j))
{
Bmemcpy(&inputfifo[movefifoplc&(MOVEFIFOSIZ-1)][j], &recsync[bigi], sizeof(input_t));
@ -1111,6 +939,7 @@ nextdemo_nomenu:
if (ud.show_help == 0 && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
rotatesprite_fs((320-50)<<16, 9<<16, 65536L, 0, BETAVERSION, 0, 0, 2+8+16+128);
}
videoNextPage();
}
@ -1128,7 +957,7 @@ nextdemo_nomenu:
#if KRANDDEBUG
krd_print("krandplay.log");
#endif
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
kclose(g_demo_recFilePtr); g_demo_recFilePtr = buildvfs_kfd_invalid;
}
return 0;
@ -1136,7 +965,7 @@ nextdemo_nomenu:
}
ud.multimode = numplayers; // fixes 2 infinite loops after watching demo
kclose(g_demo_recFilePtr); g_demo_recFilePtr = -1;
kclose(g_demo_recFilePtr); g_demo_recFilePtr = buildvfs_kfd_invalid;
Demo_FinishProfile();