Merge remote-tracking branch 'gzdoom/master' into qzdoom
This commit is contained in:
commit
5ef46d1730
208 changed files with 21902 additions and 6688 deletions
463
src/g_level.cpp
463
src/g_level.cpp
|
|
@ -81,10 +81,10 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "a_strifeglobal.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "farchive.h"
|
||||
#include "r_renderer.h"
|
||||
#include "r_utility.h"
|
||||
#include "p_spec.h"
|
||||
#include "serializer.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
void STAT_StartNewGame(const char *lev);
|
||||
void STAT_ChangeLevel(const char *newl);
|
||||
|
||||
|
||||
EXTERN_CVAR(Bool, save_formatted)
|
||||
EXTERN_CVAR (Float, sv_gravity)
|
||||
EXTERN_CVAR (Float, sv_aircontrol)
|
||||
EXTERN_CVAR (Int, disableautosave)
|
||||
|
|
@ -822,7 +822,7 @@ void G_DoCompleted (void)
|
|||
}
|
||||
else
|
||||
{ // Make sure we don't have a snapshot lying around from before.
|
||||
level.info->ClearSnapshot();
|
||||
level.info->Snapshot.Clean();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1477,135 +1477,6 @@ void G_AirControlChanged ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_SerializeGlobals(FArchive &arc);
|
||||
|
||||
void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
||||
{
|
||||
int i = level.totaltime;
|
||||
|
||||
Renderer->StartSerialize(arc);
|
||||
if (arc.IsLoading()) P_DestroyThinkers(hubLoad);
|
||||
gl_SerializeGlobals(arc);
|
||||
|
||||
arc << level.flags
|
||||
<< level.flags2
|
||||
<< level.fadeto
|
||||
<< level.found_secrets
|
||||
<< level.found_items
|
||||
<< level.killed_monsters
|
||||
<< level.gravity
|
||||
<< level.aircontrol
|
||||
<< level.teamdamage
|
||||
<< level.maptime
|
||||
<< i;
|
||||
|
||||
// Hub transitions must keep the current total time
|
||||
if (!hubLoad)
|
||||
level.totaltime = i;
|
||||
|
||||
arc << level.skytexture1 << level.skytexture2;
|
||||
if (arc.IsLoading())
|
||||
{
|
||||
sky1texture = level.skytexture1;
|
||||
sky2texture = level.skytexture2;
|
||||
R_InitSkyMap();
|
||||
}
|
||||
|
||||
G_AirControlChanged ();
|
||||
|
||||
BYTE t;
|
||||
|
||||
// Does this level have scrollers?
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
t = level.Scrolls ? 1 : 0;
|
||||
arc << t;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << t;
|
||||
if (level.Scrolls)
|
||||
{
|
||||
delete[] level.Scrolls;
|
||||
level.Scrolls = NULL;
|
||||
}
|
||||
if (t)
|
||||
{
|
||||
level.Scrolls = new FSectorScrollValues[numsectors];
|
||||
memset (level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
|
||||
}
|
||||
}
|
||||
|
||||
FBehavior::StaticSerializeModuleStates (arc);
|
||||
if (arc.IsLoading()) interpolator.ClearInterpolations();
|
||||
P_SerializeWorld(arc);
|
||||
P_SerializeThinkers (arc, hubLoad);
|
||||
P_SerializeWorldActors(arc); // serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
|
||||
P_SerializePolyobjs (arc);
|
||||
P_SerializeSubsectors(arc);
|
||||
StatusBar->Serialize (arc);
|
||||
|
||||
arc << level.total_monsters << level.total_items << level.total_secrets;
|
||||
|
||||
// Does this level have custom translations?
|
||||
FRemapTable *trans;
|
||||
WORD w;
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
|
||||
{
|
||||
trans = translationtables[TRANSLATION_LevelScripted][i];
|
||||
if (trans != NULL && !trans->IsIdentity())
|
||||
{
|
||||
w = WORD(i);
|
||||
arc << w;
|
||||
trans->Serialize(arc);
|
||||
}
|
||||
}
|
||||
w = 0xffff;
|
||||
arc << w;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (arc << w, w != 0xffff)
|
||||
{
|
||||
trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
|
||||
if (trans == NULL)
|
||||
{
|
||||
trans = new FRemapTable;
|
||||
translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
|
||||
}
|
||||
trans->Serialize(arc);
|
||||
}
|
||||
}
|
||||
|
||||
// This must be saved, too, of course!
|
||||
FCanvasTextureInfo::Serialize (arc);
|
||||
AM_SerializeMarkers(arc);
|
||||
|
||||
P_SerializePlayers (arc, hubLoad);
|
||||
P_SerializeSounds (arc);
|
||||
if (arc.IsLoading())
|
||||
{
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
P_Recalculate3DFloors(§ors[i]);
|
||||
}
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (playeringame[i] && players[i].mo != NULL)
|
||||
{
|
||||
players[i].mo->SetupWeaponSlots();
|
||||
}
|
||||
}
|
||||
}
|
||||
Renderer->EndSerialize(arc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Archives the current level
|
||||
|
|
@ -1614,19 +1485,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
|
|||
|
||||
void G_SnapshotLevel ()
|
||||
{
|
||||
if (level.info->snapshot)
|
||||
delete level.info->snapshot;
|
||||
level.info->Snapshot.Clean();
|
||||
|
||||
if (level.info->isValid())
|
||||
{
|
||||
level.info->snapshotVer = SAVEVER;
|
||||
level.info->snapshot = new FCompressedMemFile;
|
||||
level.info->snapshot->Open ();
|
||||
FSerializer arc;
|
||||
|
||||
FArchive arc (*level.info->snapshot);
|
||||
|
||||
SaveVersion = SAVEVER;
|
||||
G_SerializeLevel (arc, false);
|
||||
if (arc.OpenWriter(save_formatted))
|
||||
{
|
||||
SaveVersion = SAVEVER;
|
||||
G_SerializeLevel(arc, false);
|
||||
level.info->Snapshot = arc.GetCompressedOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1639,18 +1509,15 @@ void G_SnapshotLevel ()
|
|||
|
||||
void G_UnSnapshotLevel (bool hubLoad)
|
||||
{
|
||||
if (level.info->snapshot == NULL)
|
||||
if (level.info->Snapshot.mBuffer == nullptr)
|
||||
return;
|
||||
|
||||
if (level.info->isValid())
|
||||
{
|
||||
SaveVersion = level.info->snapshotVer;
|
||||
level.info->snapshot->Reopen ();
|
||||
FArchive arc (*level.info->snapshot);
|
||||
if (hubLoad)
|
||||
arc.SetHubTravel ();
|
||||
FSerializer arc;
|
||||
if (!arc.OpenReader(&level.info->Snapshot)) return;
|
||||
|
||||
G_SerializeLevel (arc, hubLoad);
|
||||
arc.Close ();
|
||||
level.FromSnapshot = true;
|
||||
|
||||
TThinkerIterator<APlayerPawn> it;
|
||||
|
|
@ -1680,7 +1547,7 @@ void G_UnSnapshotLevel (bool hubLoad)
|
|||
}
|
||||
}
|
||||
// No reason to keep the snapshot around once the level's been entered.
|
||||
level.info->ClearSnapshot();
|
||||
level.info->Snapshot.Clean();
|
||||
if (hubLoad)
|
||||
{
|
||||
// Unlock ACS global strings that were locked when the snapshot was made.
|
||||
|
|
@ -1693,10 +1560,28 @@ void G_UnSnapshotLevel (bool hubLoad)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void writeSnapShot (FArchive &arc, level_info_t *i)
|
||||
void G_WriteSnapshots(TArray<FString> &filenames, TArray<FCompressedBuffer> &buffers)
|
||||
{
|
||||
arc << i->snapshotVer << i->MapName;
|
||||
i->snapshot->Serialize (arc);
|
||||
unsigned int i;
|
||||
FString filename;
|
||||
|
||||
for (i = 0; i < wadlevelinfos.Size(); i++)
|
||||
{
|
||||
if (wadlevelinfos[i].Snapshot.mCompressedSize > 0)
|
||||
{
|
||||
filename.Format("%s.map.json", wadlevelinfos[i].MapName.GetChars());
|
||||
filename.ToLower();
|
||||
filenames.Push(filename);
|
||||
buffers.Push(wadlevelinfos[i].Snapshot);
|
||||
}
|
||||
}
|
||||
if (TheDefaultLevelInfo.Snapshot.mCompressedSize > 0)
|
||||
{
|
||||
filename.Format("%s.mapd.json", TheDefaultLevelInfo.MapName.GetChars());
|
||||
filename.ToLower();
|
||||
filenames.Push(filename);
|
||||
buffers.Push(TheDefaultLevelInfo.Snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -1704,70 +1589,39 @@ static void writeSnapShot (FArchive &arc, level_info_t *i)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void G_WriteSnapshots (FILE *file)
|
||||
void G_WriteVisited(FSerializer &arc)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < wadlevelinfos.Size(); i++)
|
||||
if (arc.BeginArray("visited"))
|
||||
{
|
||||
if (wadlevelinfos[i].snapshot)
|
||||
// Write out which levels have been visited
|
||||
for (auto & wi : wadlevelinfos)
|
||||
{
|
||||
FPNGChunkArchive arc (file, SNAP_ID);
|
||||
writeSnapShot (arc, (level_info_t *)&wadlevelinfos[i]);
|
||||
}
|
||||
}
|
||||
if (TheDefaultLevelInfo.snapshot != NULL)
|
||||
{
|
||||
FPNGChunkArchive arc (file, DSNP_ID);
|
||||
writeSnapShot(arc, &TheDefaultLevelInfo);
|
||||
}
|
||||
|
||||
FPNGChunkArchive *arc = NULL;
|
||||
|
||||
// Write out which levels have been visited
|
||||
for (i = 0; i < wadlevelinfos.Size(); ++i)
|
||||
{
|
||||
if (wadlevelinfos[i].flags & LEVEL_VISITED)
|
||||
{
|
||||
if (arc == NULL)
|
||||
if (wi.flags & LEVEL_VISITED)
|
||||
{
|
||||
arc = new FPNGChunkArchive (file, VIST_ID);
|
||||
arc.AddString(nullptr, wi.MapName);
|
||||
}
|
||||
(*arc) << wadlevelinfos[i].MapName;
|
||||
}
|
||||
}
|
||||
|
||||
if (arc != NULL)
|
||||
{
|
||||
FString empty = "";
|
||||
(*arc) << empty;
|
||||
delete arc;
|
||||
arc.EndArray();
|
||||
}
|
||||
|
||||
// Store player classes to be used when spawning a random class
|
||||
if (multiplayer)
|
||||
{
|
||||
FPNGChunkArchive arc2 (file, RCLS_ID);
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
SBYTE cnum = SinglePlayerClass[i];
|
||||
arc2 << cnum;
|
||||
}
|
||||
arc.Array("randomclasses", SinglePlayerClass, MAXPLAYERS);
|
||||
}
|
||||
|
||||
// Store player classes that are currently in use
|
||||
FPNGChunkArchive arc3 (file, PCLS_ID);
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (arc.BeginObject("playerclasses"))
|
||||
{
|
||||
BYTE pnum;
|
||||
if (playeringame[i])
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
pnum = i;
|
||||
arc3 << pnum;
|
||||
arc3.UserWriteClass (players[i].cls);
|
||||
if (playeringame[i])
|
||||
{
|
||||
FString key;
|
||||
key.Format("%d", i);
|
||||
arc(key, players[i].cls);
|
||||
}
|
||||
}
|
||||
pnum = 255;
|
||||
arc3 << pnum;
|
||||
arc.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1776,95 +1630,89 @@ void G_WriteSnapshots (FILE *file)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void G_ReadSnapshots (PNGHandle *png)
|
||||
void G_ReadSnapshots(FResourceFile *resf)
|
||||
{
|
||||
DWORD chunkLen;
|
||||
FString MapName;
|
||||
level_info_t *i;
|
||||
|
||||
G_ClearSnapshots ();
|
||||
G_ClearSnapshots();
|
||||
|
||||
chunkLen = (DWORD)M_FindPNGChunk (png, SNAP_ID);
|
||||
while (chunkLen != 0)
|
||||
for (unsigned j = 0; j < resf->LumpCount(); j++)
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), SNAP_ID, chunkLen);
|
||||
DWORD snapver;
|
||||
|
||||
arc << snapver;
|
||||
arc << MapName;
|
||||
i = FindLevelInfo (MapName);
|
||||
i->snapshotVer = snapver;
|
||||
i->snapshot = new FCompressedMemFile;
|
||||
i->snapshot->Serialize (arc);
|
||||
chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID);
|
||||
}
|
||||
|
||||
chunkLen = (DWORD)M_FindPNGChunk (png, DSNP_ID);
|
||||
if (chunkLen != 0)
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), DSNP_ID, chunkLen);
|
||||
DWORD snapver;
|
||||
|
||||
arc << snapver;
|
||||
arc << MapName;
|
||||
TheDefaultLevelInfo.snapshotVer = snapver;
|
||||
TheDefaultLevelInfo.snapshot = new FCompressedMemFile;
|
||||
TheDefaultLevelInfo.snapshot->Serialize (arc);
|
||||
}
|
||||
|
||||
chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID);
|
||||
if (chunkLen != 0)
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen);
|
||||
|
||||
while (arc << MapName, MapName.Len() > 0)
|
||||
FResourceLump * resl = resf->GetLump(j);
|
||||
if (resl != nullptr)
|
||||
{
|
||||
i = FindLevelInfo(MapName);
|
||||
i->flags |= LEVEL_VISITED;
|
||||
auto ptr = strstr(resl->FullName, ".map.json");
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptrdiff_t maplen = ptr - resl->FullName.GetChars();
|
||||
FString mapname(resl->FullName.GetChars(), (size_t)maplen);
|
||||
i = FindLevelInfo(mapname);
|
||||
if (i != nullptr)
|
||||
{
|
||||
i->Snapshot = resl->GetRawData();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ptr = strstr(resl->FullName, ".mapd.json");
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptrdiff_t maplen = ptr - resl->FullName.GetChars();
|
||||
FString mapname(resl->FullName.GetChars(), (size_t)maplen);
|
||||
TheDefaultLevelInfo.Snapshot = resl->GetRawData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chunkLen = (DWORD)M_FindPNGChunk (png, RCLS_ID);
|
||||
if (chunkLen != 0)
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), PCLS_ID, chunkLen);
|
||||
SBYTE cnum;
|
||||
|
||||
for (DWORD j = 0; j < chunkLen; ++j)
|
||||
{
|
||||
arc << cnum;
|
||||
SinglePlayerClass[j] = cnum;
|
||||
}
|
||||
}
|
||||
|
||||
chunkLen = (DWORD)M_FindPNGChunk (png, PCLS_ID);
|
||||
if (chunkLen != 0)
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), RCLS_ID, chunkLen);
|
||||
BYTE pnum;
|
||||
|
||||
arc << pnum;
|
||||
while (pnum != 255)
|
||||
{
|
||||
arc.UserReadClass (players[pnum].cls);
|
||||
arc << pnum;
|
||||
}
|
||||
}
|
||||
png->File->ResetFilePtr();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void G_ReadVisited(FSerializer &arc)
|
||||
{
|
||||
if (arc.BeginArray("visited"))
|
||||
{
|
||||
for (int s = arc.ArraySize(); s > 0; s--)
|
||||
{
|
||||
FString str;
|
||||
arc(nullptr, str);
|
||||
auto i = FindLevelInfo(str);
|
||||
if (i != nullptr) i->flags |= LEVEL_VISITED;
|
||||
}
|
||||
arc.EndArray();
|
||||
}
|
||||
|
||||
arc.Array("randomclasses", SinglePlayerClass, MAXPLAYERS);
|
||||
|
||||
if (arc.BeginObject("playerclasses"))
|
||||
{
|
||||
for (int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
FString key;
|
||||
key.Format("%d", i);
|
||||
arc(key, players[i].cls);
|
||||
}
|
||||
arc.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(listsnapshots)
|
||||
{
|
||||
for (unsigned i = 0; i < wadlevelinfos.Size(); ++i)
|
||||
{
|
||||
FCompressedMemFile *snapshot = wadlevelinfos[i].snapshot;
|
||||
if (snapshot != NULL)
|
||||
FCompressedBuffer *snapshot = &wadlevelinfos[i].Snapshot;
|
||||
if (snapshot->mBuffer != nullptr)
|
||||
{
|
||||
unsigned int comp, uncomp;
|
||||
snapshot->GetSizes(comp, uncomp);
|
||||
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), comp, uncomp);
|
||||
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), snapshot->mCompressedSize, snapshot->mSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1874,38 +1722,32 @@ CCMD(listsnapshots)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void writeDefereds (FArchive &arc, level_info_t *i)
|
||||
void P_WriteACSDefereds (FSerializer &arc)
|
||||
{
|
||||
arc << i->MapName << i->defered;
|
||||
}
|
||||
bool found = false;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_WriteACSDefereds (FILE *file)
|
||||
{
|
||||
FPNGChunkArchive *arc = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
|
||||
// only write this stuff if needed
|
||||
for (auto &wi : wadlevelinfos)
|
||||
{
|
||||
if (wadlevelinfos[i].defered)
|
||||
if (wi.deferred.Size() > 0)
|
||||
{
|
||||
if (arc == NULL)
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found && arc.BeginObject("deferred"))
|
||||
{
|
||||
for (auto &wi : wadlevelinfos)
|
||||
{
|
||||
if (wi.deferred.Size() > 0)
|
||||
{
|
||||
arc = new FPNGChunkArchive (file, ACSD_ID);
|
||||
if (wi.deferred.Size() > 0)
|
||||
{
|
||||
arc(wi.MapName, wi.deferred);
|
||||
}
|
||||
}
|
||||
writeDefereds (*arc, (level_info_t *)&wadlevelinfos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (arc != NULL)
|
||||
{
|
||||
// Signal end of defereds
|
||||
FString empty = "";
|
||||
(*arc) << empty;
|
||||
delete arc;
|
||||
arc.EndObject();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1914,28 +1756,27 @@ void P_WriteACSDefereds (FILE *file)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_ReadACSDefereds (PNGHandle *png)
|
||||
void P_ReadACSDefereds (FSerializer &arc)
|
||||
{
|
||||
FString MapName;
|
||||
size_t chunklen;
|
||||
|
||||
|
||||
P_RemoveDefereds ();
|
||||
|
||||
if ((chunklen = M_FindPNGChunk (png, ACSD_ID)) != 0)
|
||||
if (arc.BeginObject("deferred"))
|
||||
{
|
||||
FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen);
|
||||
const char *key;
|
||||
|
||||
while (arc << MapName, MapName.Len() > 0)
|
||||
while ((key = arc.GetKey()))
|
||||
{
|
||||
level_info_t *i = FindLevelInfo(MapName);
|
||||
level_info_t *i = FindLevelInfo(key);
|
||||
if (i == NULL)
|
||||
{
|
||||
I_Error("Unknown map '%s' in savegame", MapName.GetChars());
|
||||
I_Error("Unknown map '%s' in savegame", key);
|
||||
}
|
||||
arc << i->defered;
|
||||
arc(nullptr, i->deferred);
|
||||
}
|
||||
arc.EndObject();
|
||||
}
|
||||
png->File->ResetFilePtr();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1947,9 +1788,9 @@ void P_ReadACSDefereds (PNGHandle *png)
|
|||
void FLevelLocals::Tick ()
|
||||
{
|
||||
// Reset carry sectors
|
||||
if (Scrolls != NULL)
|
||||
if (Scrolls.Size() > 0)
|
||||
{
|
||||
memset (Scrolls, 0, sizeof(*Scrolls)*numsectors);
|
||||
memset (&Scrolls[0], 0, sizeof(Scrolls[0])*Scrolls.Size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1964,10 +1805,10 @@ void FLevelLocals::AddScroller (int secnum)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (Scrolls == NULL)
|
||||
if (Scrolls.Size() == 0)
|
||||
{
|
||||
Scrolls = new FSectorScrollValues[numsectors];
|
||||
memset (Scrolls, 0, sizeof(*Scrolls)*numsectors);
|
||||
Scrolls.Resize(numsectors);
|
||||
memset (&Scrolls[0], 0, sizeof(Scrolls[0])*numsectors);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue