Skip to content

Commit be3c65d

Browse files
committed
- generic CBaseLevelRegion & Map cell object handling'
- unpacking all Driver 2 PCOs
1 parent ee6cb84 commit be3c65d

6 files changed

Lines changed: 114 additions & 65 deletions

File tree

DriverLevelTool/driver_routines/regions.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ void CBaseLevelRegion::FreeAll()
4949

5050
delete[] m_cellPointers;
5151
m_cellPointers = nullptr;
52+
53+
if (m_cellObjects)
54+
free(m_cellObjects);
55+
m_cellObjects = nullptr;
5256

5357
m_pvsData = nullptr;
5458
m_roadmapData = nullptr;
@@ -66,6 +70,19 @@ int CBaseLevelRegion::GetNumber() const
6670
return m_regionNumber;
6771
}
6872

73+
CELL_OBJECT* CBaseLevelRegion::GetCellObject(int num) const
74+
{
75+
int numStraddlers = m_owner->m_numStraddlers;
76+
77+
if (num >= numStraddlers)
78+
{
79+
num -= m_owner->m_cell_objects_add[m_regionBarrelNumber] + numStraddlers;
80+
return &m_cellObjects[num];
81+
}
82+
83+
return &m_owner->m_straddlers[num];
84+
}
85+
6986
//-------------------------------------------------------------
7087
// Region unpacking function
7188
//-------------------------------------------------------------
@@ -190,6 +207,9 @@ void CBaseLevelMap::FreeAll()
190207

191208
delete[] m_areaDataStates;
192209
m_areaDataStates = nullptr;
210+
211+
delete[] m_straddlers;
212+
m_straddlers = nullptr;
193213
}
194214

195215
int CBaseLevelMap::GetAreaDataCount() const

DriverLevelTool/driver_routines/regions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class CBaseLevelRegion
4343
bool IsEmpty() const;
4444
int GetNumber() const;
4545

46+
CELL_OBJECT* GetCellObject(int num) const;
47+
4648
protected:
4749
static int UnpackCellPointers(ushort* dest_ptrs, char* src_data, int cell_slots_add, int targetRegion = 0);
4850

@@ -51,6 +53,7 @@ class CBaseLevelRegion
5153
Spool* m_spoolInfo{ nullptr };
5254

5355
ushort* m_cellPointers{ nullptr }; // cell pointers - pointing to CELL_DATA
56+
CELL_OBJECT* m_cellObjects{ nullptr }; // cell objects that represents objects placed in the world
5457

5558
ushort* m_pvsData{ nullptr }; // potentially visibile set of cells
5659
short* m_roadmapData{ nullptr }; // heightfield with planes and BSP
@@ -147,6 +150,8 @@ class CBaseLevelMap
147150
int m_regions_across{ 0 };
148151
int m_regions_down{ 0 };
149152

153+
CELL_OBJECT* m_straddlers{ nullptr };
154+
150155
OnRegionLoaded_t m_onRegionLoaded{ nullptr };
151156
OnRegionFreed_t m_onRegionFreed{ nullptr };
152157
};

DriverLevelTool/driver_routines/regions_d1.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ void CDriver1LevelRegion::FreeAll()
1717
if (m_cells)
1818
free(m_cells);
1919
m_cells = nullptr;
20-
21-
if (m_cellObjects)
22-
free(m_cellObjects);
23-
m_cellObjects = nullptr;
2420
}
2521

2622
void CDriver1LevelRegion::LoadRegionData(const SPOOL_CONTEXT& ctx)
@@ -89,21 +85,6 @@ void CDriver1LevelRegion::LoadRegionData(const SPOOL_CONTEXT& ctx)
8985
// TODO: PVS and heightmap data
9086
}
9187

92-
CELL_OBJECT* CDriver1LevelRegion::GetCellObject(int num) const
93-
{
94-
CDriver1LevelMap* owner = (CDriver1LevelMap*)m_owner;
95-
96-
int numStraddlers = owner->m_numStraddlers;
97-
98-
if (num >= numStraddlers)
99-
{
100-
num -= owner->m_cell_objects_add[m_regionBarrelNumber] + numStraddlers;
101-
return &m_cellObjects[num];
102-
}
103-
104-
return &owner->m_straddlers[num];
105-
}
106-
10788
//----------------------------------------
10889
// cell iterator
10990
CELL_OBJECT* CDriver1LevelRegion::StartIterator(CELL_ITERATOR_D1* iterator, int cellNumber) const
@@ -139,9 +120,6 @@ void CDriver1LevelMap::FreeAll()
139120
delete[] m_regions;
140121
m_regions = nullptr;
141122

142-
delete[] m_straddlers;
143-
m_straddlers = nullptr;
144-
145123
CBaseLevelMap::FreeAll();
146124
}
147125

DriverLevelTool/driver_routines/regions_d1.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,11 @@ class CDriver1LevelRegion : public CBaseLevelRegion
2626
void FreeAll() override;
2727
void LoadRegionData(const SPOOL_CONTEXT& ctx) override;
2828

29-
CELL_OBJECT* GetCellObject(int num) const;
30-
3129
// cell iterator
3230
CELL_OBJECT* StartIterator(CELL_ITERATOR_D1* iterator, int cellNumber) const;
3331

3432
protected:
3533
CELL_DATA_D1* m_cells{ nullptr }; // cell data that holding information about cell pointers. 3D world seeks cells first here
36-
CELL_OBJECT* m_cellObjects{ nullptr }; // cell objects that represents objects placed in the world
3734
};
3835

3936

@@ -66,7 +63,6 @@ class CDriver1LevelMap : public CBaseLevelMap
6663

6764
// Driver 2 - specific
6865
CDriver1LevelRegion* m_regions{ nullptr }; // map of regions
69-
CELL_OBJECT* m_straddlers{ nullptr }; // cell objects between regions
7066
};
7167

7268

DriverLevelTool/driver_routines/regions_d2.cpp

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,9 @@ void CDriver2LevelRegion::FreeAll()
333333
free(m_cells);
334334
m_cells = nullptr;
335335

336-
if (m_cellObjects)
337-
free(m_cellObjects);
338-
m_cellObjects = nullptr;
336+
if (m_packedCellObjects)
337+
free(m_packedCellObjects);
338+
m_packedCellObjects = nullptr;
339339

340340
if (m_pvsData)
341341
free(m_pvsData);
@@ -405,13 +405,16 @@ void CDriver2LevelRegion::LoadRegionData(const SPOOL_CONTEXT& ctx)
405405
pFile->Read(m_cells, m_spoolInfo->cell_data_size[0] * SPOOL_CD_BLOCK_SIZE, sizeof(char));
406406

407407
// read cell objects
408-
m_cellObjects = (PACKED_CELL_OBJECT*)malloc(m_spoolInfo->cell_data_size[2] * SPOOL_CD_BLOCK_SIZE);
408+
m_packedCellObjects = (PACKED_CELL_OBJECT*)malloc(m_spoolInfo->cell_data_size[2] * SPOOL_CD_BLOCK_SIZE);
409409
pFile->Seek(ctx.lumpInfo->spooled_offset + cellObjectsOffset * SPOOL_CD_BLOCK_SIZE, VS_SEEK_SET);
410-
pFile->Read(m_cellObjects, m_spoolInfo->cell_data_size[2] * SPOOL_CD_BLOCK_SIZE, sizeof(char));
410+
pFile->Read(m_packedCellObjects, m_spoolInfo->cell_data_size[2] * SPOOL_CD_BLOCK_SIZE, sizeof(char));
411411
}
412412
else
413413
MsgError("BAD PACKED CELL POINTER DATA, region = %d\n", m_regionNumber);
414414

415+
// post-process
416+
UnpackAllCellObjects();
417+
415418
delete [] packed_cell_pointers;
416419

417420
pFile->Seek(ctx.lumpInfo->spooled_offset + pvsHeightmapDataOffset * SPOOL_CD_BLOCK_SIZE, VS_SEEK_SET);
@@ -425,6 +428,53 @@ void CDriver2LevelRegion::LoadRegionData(const SPOOL_CONTEXT& ctx)
425428
m_owner->OnRegionLoaded(this);
426429
}
427430

431+
//---------------------------------------------------------------------
432+
// Unpacks all cell objects from PACKED_CELL_OBJECT
433+
//---------------------------------------------------------------------
434+
void CDriver2LevelRegion::UnpackAllCellObjects()
435+
{
436+
CDriver2LevelMap* owner = (CDriver2LevelMap*)m_owner;
437+
int numCellObjects = (m_spoolInfo->cell_data_size[2] * SPOOL_CD_BLOCK_SIZE) / sizeof(PACKED_CELL_OBJECT);
438+
439+
// alloc and convert
440+
m_cellObjects = (CELL_OBJECT*)malloc(numCellObjects * sizeof(CELL_OBJECT));
441+
memset(m_cellObjects, 0, numCellObjects * sizeof(CELL_OBJECT));
442+
443+
const OUT_CELL_FILE_HEADER& mapInfo = owner->GetMapInfo();
444+
const int numStraddlers = owner->m_numStraddlers;
445+
const int cellObjectsAdd = owner->m_cell_objects_add[m_regionBarrelNumber];
446+
447+
// walk through all cell data
448+
for (int i = 0; i < mapInfo.region_size * mapInfo.region_size; i++)
449+
{
450+
CELL_ITERATOR_D2 ci;
451+
PACKED_CELL_OBJECT* pco = StartIterator(&ci, i);
452+
453+
if (!pco)
454+
continue;
455+
456+
while (pco)
457+
{
458+
int num = ci.pcd->num & 0x3fff;
459+
460+
if (num >= numStraddlers)
461+
{
462+
num -= cellObjectsAdd + numStraddlers;
463+
464+
CELL_OBJECT& co = m_cellObjects[num];
465+
CDriver2LevelMap::UnpackCellObject(co, pco, ci.nearCell);
466+
}
467+
else
468+
{
469+
// unpack straddlers
470+
CDriver2LevelMap::UnpackCellObject(owner->m_straddlers[num], pco, ci.nearCell);
471+
}
472+
473+
pco = owner->GetNextPackedCop(&ci);
474+
}
475+
}
476+
}
477+
428478
void CDriver2LevelRegion::ReadHeightmapData(const SPOOL_CONTEXT& ctx)
429479
{
430480
IVirtualStream* pFile = ctx.dataStream;
@@ -453,7 +503,7 @@ void CDriver2LevelRegion::ReadHeightmapData(const SPOOL_CONTEXT& ctx)
453503
}
454504
}
455505

456-
PACKED_CELL_OBJECT* CDriver2LevelRegion::GetCellObject(int num) const
506+
PACKED_CELL_OBJECT* CDriver2LevelRegion::GetPackedCellObject(int num) const
457507
{
458508
CDriver2LevelMap* owner = (CDriver2LevelMap*)m_owner;
459509

@@ -462,10 +512,10 @@ PACKED_CELL_OBJECT* CDriver2LevelRegion::GetCellObject(int num) const
462512
if (num >= numStraddlers)
463513
{
464514
num -= owner->m_cell_objects_add[m_regionBarrelNumber] + numStraddlers;
465-
return &m_cellObjects[num];
515+
return &m_packedCellObjects[num];
466516
}
467517

468-
return &owner->m_straddlers[num];
518+
return &owner->m_packedStraddlers[num];
469519
}
470520

471521
CELL_DATA* CDriver2LevelRegion::GetCellData(int num) const
@@ -481,13 +531,14 @@ PACKED_CELL_OBJECT* CDriver2LevelRegion::StartIterator(CELL_ITERATOR_D2* iterato
481531
if (cell_ptr == 0xFFFF)
482532
return nullptr;
483533

484-
const OUT_CELL_FILE_HEADER& mapInfo = m_owner->m_mapInfo;
534+
CDriver2LevelMap* owner = (CDriver2LevelMap*)m_owner;
535+
const OUT_CELL_FILE_HEADER& mapInfo = owner->m_mapInfo;
485536

486537
iterator->region = (CDriver2LevelRegion*)this;
487538

488539
// IDK if it gonna work correct
489540
XZPAIR cpos;
490-
m_owner->WorldPositionToCellXZ(cpos, {0,0,0});
541+
owner->WorldPositionToCellXZ(cpos, {0,0,0});
491542

492543
// convert cell number to XZ
493544
int cellx = cellNumber % mapInfo.region_size;
@@ -503,19 +554,21 @@ PACKED_CELL_OBJECT* CDriver2LevelRegion::StartIterator(CELL_ITERATOR_D2* iterato
503554
// get the packed cell data start and near cell
504555
CELL_DATA* celld = &m_cells[cell_ptr];
505556

506-
iterator->listType = 0;
557+
iterator->listType = -1;
507558

508559
if (celld->num & 0x4000) // if we immediately got to the typed list
509560
{
510-
iterator->listType = celld->num;
561+
iterator->listType = celld->num & 0x3fff;
511562
celld++; // get to the start
512563
}
513564

514-
PACKED_CELL_OBJECT* ppco = GetCellObject(celld->num & 0x3fff);
565+
PACKED_CELL_OBJECT* ppco = GetPackedCellObject(celld->num & 0x3fff);
515566
iterator->pcd = celld;
516567

568+
iterator->co = GetCellObject(celld->num & 0x3fff);
569+
517570
if (ppco->value == 0xffff && (ppco->pos.vy & 1))
518-
ppco = ((CDriver2LevelMap*)m_owner)->GetNextPackedCop(iterator);
571+
ppco = owner->GetNextPackedCop(iterator);
519572

520573
iterator->ppco = ppco;
521574

@@ -537,8 +590,8 @@ void CDriver2LevelMap::FreeAll()
537590
delete[] m_regions;
538591
m_regions = nullptr;
539592

540-
delete[] m_straddlers;
541-
m_straddlers = nullptr;
593+
delete[] m_packedStraddlers;
594+
m_packedStraddlers = nullptr;
542595

543596
delete[] m_straights;
544597
m_straights = nullptr;
@@ -561,8 +614,11 @@ void CDriver2LevelMap::LoadMapLump(IVirtualStream* pFile)
561614

562615
// read straddlers
563616
// Driver 2 PCO
564-
m_straddlers = new PACKED_CELL_OBJECT[m_numStraddlers];
565-
pFile->Read(m_straddlers, m_numStraddlers, sizeof(PACKED_CELL_OBJECT));
617+
m_packedStraddlers = new PACKED_CELL_OBJECT[m_numStraddlers];
618+
pFile->Read(m_packedStraddlers, m_numStraddlers, sizeof(PACKED_CELL_OBJECT));
619+
620+
m_straddlers = new CELL_OBJECT[m_numStraddlers];
621+
memset(m_straddlers, 0, m_numStraddlers * sizeof(CELL_OBJECT));
566622
}
567623

568624
//-------------------------------------------------------------
@@ -830,15 +886,16 @@ PACKED_CELL_OBJECT* CDriver2LevelMap::GetFirstPackedCop(CELL_ITERATOR_D2* iterat
830886
0x8000 - end of cell objects
831887
*/
832888

833-
iterator->listType = 0;
889+
iterator->listType = -1;
834890

835891
if (celld->num & 0x4000) // if we immediately got to the typed list
836892
{
837-
iterator->listType = celld->num;
893+
iterator->listType = celld->num & 0x3fff;
838894
celld++; // get to the start
839895
}
840896

841-
PACKED_CELL_OBJECT* ppco = region.GetCellObject(celld->num & 0x3fff);
897+
PACKED_CELL_OBJECT* ppco = region.GetPackedCellObject(celld->num & 0x3fff);
898+
iterator->co = region.GetCellObject(celld->num & 0x3fff);
842899

843900
iterator->pcd = celld;
844901

@@ -857,6 +914,7 @@ PACKED_CELL_OBJECT* CDriver2LevelMap::GetNextPackedCop(CELL_ITERATOR_D2* iterato
857914
{
858915
ushort num;
859916
PACKED_CELL_OBJECT* ppco;
917+
CELL_OBJECT* co;
860918

861919
do {
862920
CELL_DATA* celld = iterator->pcd;
@@ -874,24 +932,13 @@ PACKED_CELL_OBJECT* CDriver2LevelMap::GetNextPackedCop(CELL_ITERATOR_D2* iterato
874932

875933
iterator->pcd = celld;
876934

877-
/*
878-
celld++;
879-
num = celld->num;
880-
881-
if (celld->num & 0x4000) // if we immediately got to the typed list
882-
{
883-
iterator->listType = celld->num;
884-
celld++; // get to the start
885-
}
886-
887-
if(num & 0x4000) // start of new sub list?
888-
return nullptr;
889-
*/
890-
ppco = iterator->region->GetCellObject(celld->num & 0x3fff);
935+
ppco = iterator->region->GetPackedCellObject(celld->num & 0x3fff);
936+
co = iterator->region->GetCellObject(celld->num & 0x3fff);
891937

892938
} while (ppco->value == 0xffff && (ppco->pos.vy & 1));
893939

894940
iterator->ppco = ppco;
941+
iterator->co = co;
895942

896943
return ppco;
897944
}

0 commit comments

Comments
 (0)