@@ -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+
428478void 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
471521CELL_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