Skip to content

Commit 0ee2733

Browse files
authored
[GEN] Backport WW3D2's StaticSortListClass from Zero Hour (#662)
1 parent 4e45e90 commit 0ee2733

File tree

5 files changed

+209
-45
lines changed

5 files changed

+209
-45
lines changed

Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ set(WW3D2_SRC
8686
sortingrenderer.cpp
8787
soundrobj.cpp
8888
sphereobj.cpp
89+
static_sort_list.cpp
8990
statistics.cpp
9091
streak.cpp
9192
streakRender.cpp
@@ -197,6 +198,7 @@ set(WW3D2_SRC
197198
sortingrenderer.h
198199
soundrobj.h
199200
sphereobj.h
201+
static_sort_list.h
200202
statistics.h
201203
streak.h
202204
streakRender.h
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
** Command & Conquer Generals(tm)
3+
** Copyright 2025 Electronic Arts Inc.
4+
**
5+
** This program is free software: you can redistribute it and/or modify
6+
** it under the terms of the GNU General Public License as published by
7+
** the Free Software Foundation, either version 3 of the License, or
8+
** (at your option) any later version.
9+
**
10+
** This program is distributed in the hope that it will be useful,
11+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
** GNU General Public License for more details.
14+
**
15+
** You should have received a copy of the GNU General Public License
16+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
/***************************************************************************************************
20+
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21+
***************************************************************************************************
22+
* *
23+
* Project Name : G *
24+
* *
25+
* $Archive:: $*
26+
* *
27+
* Creator::Scott K. Bowen - 7/15/2002 *
28+
* *
29+
* $Author:: $*
30+
* *
31+
* $Modtime:: $*
32+
* *
33+
* $Revision:: $*
34+
* *
35+
*-------------------------------------------------------------------------------------------------*
36+
* Functions: *
37+
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38+
39+
////////////////////////////////////////////////////////////////////////////////////////////////////
40+
// Include files ///////////////////////////////////////////////////////////////////////////////////
41+
42+
#include "static_sort_list.h"
43+
44+
#include "rendobj.h"
45+
#include "dx8renderer.h"
46+
47+
////////////////////////////////////////////////////////////////////////////////////////////////////
48+
// Initialization Functions ////////////////////////////////////////////////////////////////////////
49+
50+
DefaultStaticSortListClass::DefaultStaticSortListClass(void) :
51+
StaticSortListClass(),
52+
SortLists(),
53+
MinSort(1),
54+
MaxSort(MAX_SORT_LEVEL)
55+
{
56+
}
57+
58+
DefaultStaticSortListClass::~DefaultStaticSortListClass(void)
59+
{
60+
}
61+
62+
////////////////////////////////////////////////////////////////////////////////////////////////////
63+
// Virtual functions ///////////////////////////////////////////////////////////////////////////////
64+
65+
void DefaultStaticSortListClass::Add_To_List(RenderObjClass * robj, unsigned int sort_level)
66+
{
67+
if(sort_level < 1 || sort_level > MAX_SORT_LEVEL) {
68+
WWASSERT(0);
69+
return;
70+
}
71+
SortLists[sort_level].Add_Tail(robj, false);
72+
}
73+
74+
void DefaultStaticSortListClass::Render_And_Clear(RenderInfoClass & rinfo)
75+
{
76+
// We go from higher sort level to lower, since lower sort level means higher priority (in
77+
// front), so lower sort level meshes need to be rendered later.
78+
for(unsigned int sort_level = MaxSort; sort_level >= MinSort; sort_level--) {
79+
bool render=false;
80+
for ( RenderObjClass *robj = SortLists[sort_level].Remove_Head(); robj;
81+
robj->Release_Ref(), robj = SortLists[sort_level].Remove_Head())
82+
{
83+
robj->Render(rinfo);
84+
render = true;
85+
}
86+
if (render) TheDX8MeshRenderer.Flush();
87+
}
88+
}
89+
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
** Command & Conquer Generals(tm)
3+
** Copyright 2025 Electronic Arts Inc.
4+
**
5+
** This program is free software: you can redistribute it and/or modify
6+
** it under the terms of the GNU General Public License as published by
7+
** the Free Software Foundation, either version 3 of the License, or
8+
** (at your option) any later version.
9+
**
10+
** This program is distributed in the hope that it will be useful,
11+
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
** GNU General Public License for more details.
14+
**
15+
** You should have received a copy of the GNU General Public License
16+
** along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
/*****************************************************************************************************************
20+
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21+
*****************************************************************************************************************
22+
* *
23+
* Project Name : G *
24+
* *
25+
* $Archive:: $*
26+
* *
27+
* Creator::Scott K. Bowen - 7/15/2002 *
28+
* *
29+
* $Author:: $*
30+
* *
31+
* $Modtime:: $*
32+
* *
33+
* $Revision:: $*
34+
* *
35+
*---------------------------------------------------------------------------------------------------------------*
36+
* Functions: *
37+
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38+
#if defined(_MSC_VER)
39+
#pragma once
40+
#endif
41+
42+
#ifndef STATIC_SORT_LIST_H
43+
#define STATIC_SORT_LIST_H
44+
45+
#include "robjlist.h"
46+
#include "w3d_file.h"
47+
48+
class RenderInfoClass;
49+
50+
// Just defines the interface for the class as used by WW3D..
51+
class StaticSortListClass
52+
{
53+
public:
54+
///////////////////////////////////////////////////////////////////////////////////
55+
// Construction.
56+
StaticSortListClass(void) {}
57+
virtual ~StaticSortListClass(void) {}
58+
59+
virtual void Add_To_List(RenderObjClass * robj, unsigned int sort_level) = 0;
60+
virtual void Render_And_Clear(RenderInfoClass & rinfo) = 0;
61+
62+
}; // end StaticSortListClass
63+
64+
// The actual implementation for the standard ww3d StaticSortList.
65+
class DefaultStaticSortListClass : public StaticSortListClass
66+
{
67+
public:
68+
///////////////////////////////////////////////////////////////////////////////////
69+
// Construction.
70+
DefaultStaticSortListClass(void);
71+
virtual ~DefaultStaticSortListClass(void);
72+
73+
virtual void Add_To_List(RenderObjClass * robj, unsigned int sort_level);
74+
virtual void Render_And_Clear(RenderInfoClass & rinfo);
75+
76+
77+
unsigned int Get_Min_Sort(void) const {return MinSort;};
78+
unsigned int Get_Max_Sort(void) const {return MaxSort;};
79+
80+
void Set_Min_Sort(unsigned int value) {MinSort = (value > MAX_SORT_LEVEL) ? MAX_SORT_LEVEL : value;}
81+
void Set_Max_Sort(unsigned int value) {MaxSort = (value > MAX_SORT_LEVEL) ? MAX_SORT_LEVEL : value;}
82+
83+
private:
84+
// These are for use by controlling classes to allow control of what levels
85+
// to render when Render_And_Clear() is called. As for this class, the values
86+
// are set to 1..MAX_SORT_LEVEL and then never changed.
87+
unsigned int MinSort;
88+
unsigned int MaxSort;
89+
90+
// An array of lists - each object in a given list has same SortLevel.
91+
RefRenderObjListClass SortLists[MAX_SORT_LEVEL + 1];
92+
93+
}; // end StaticSortListClass
94+
95+
96+
97+
98+
#endif //STATIC_SORT_LIST_H
99+

Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
#include "cpudetect.h"
114114
#include "dx8texman.h"
115115
#include "formconv.h"
116+
#include "static_sort_list.h"
116117

117118

118119
#ifndef _UNIX
@@ -190,10 +191,8 @@ long WW3D::UserStat2 = 0;
190191

191192
float WW3D::DefaultNativeScreenSize = 1.0f;
192193

193-
RefRenderObjListClass * WW3D::DefaultStaticSortLists = NULL;
194-
RefRenderObjListClass * WW3D::CurrentStaticSortLists = NULL;
195-
unsigned int WW3D::MinStaticSortLevel = 1; // The 0 list is not used
196-
unsigned int WW3D::MaxStaticSortLevel = MAX_SORT_LEVEL;
194+
StaticSortListClass * WW3D::DefaultStaticSortLists = NULL;
195+
StaticSortListClass * WW3D::CurrentStaticSortLists = NULL;
197196

198197

199198
VertexMaterialClass * WW3D::DefaultDebugMaterial = NULL;
@@ -301,7 +300,7 @@ WW3DErrorType WW3D::Init(void *hwnd, char *defaultpal)
301300
** Initialize the default static sort lists
302301
** Note that DefaultStaticSortLists[0] is unused.
303302
*/
304-
DefaultStaticSortLists = W3DNEWARRAY RefRenderObjListClass[MAX_SORT_LEVEL + 1];
303+
DefaultStaticSortLists = W3DNEW DefaultStaticSortListClass();
305304
Reset_Current_Static_Sort_Lists_To_Default();
306305

307306
IsInitted = true;
@@ -360,7 +359,7 @@ WW3DErrorType WW3D::Shutdown(void)
360359
/*
361360
** Clear the default static sort lists
362361
*/
363-
delete [] DefaultStaticSortLists;
362+
delete DefaultStaticSortLists;
364363

365364
IsInitted = false;
366365
return WW3D_ERROR_OK;
@@ -1035,6 +1034,7 @@ WW3DErrorType WW3D::End_Render(bool flip_frame)
10351034

10361035
// If sorting renderer flush isn't called from within any of the render functions
10371036
// the sorting arrays will overflow!
1037+
10381038
SortingRendererClass::Flush();
10391039

10401040
IsRendering = false;
@@ -1813,13 +1813,7 @@ int WW3D::Get_Texture_Bitdepth()
18131813

18141814
void WW3D::Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level)
18151815
{
1816-
if(sort_level < 1 || sort_level > MAX_SORT_LEVEL) {
1817-
WWASSERT(0);
1818-
return;
1819-
}
1820-
1821-
CurrentStaticSortLists[sort_level].Add_Tail(robj, false);
1822-
1816+
CurrentStaticSortLists->Add_To_List(robj, sort_level);
18231817
}
18241818

18251819
void WW3D::Render_And_Clear_Static_Sort_Lists(RenderInfoClass & rinfo)
@@ -1828,20 +1822,7 @@ void WW3D::Render_And_Clear_Static_Sort_Lists(RenderInfoClass & rinfo)
18281822
// Render() function will just dump the objects right back on the same lists.
18291823
bool old_enable = AreStaticSortListsEnabled;
18301824
AreStaticSortListsEnabled = false;
1831-
1832-
// We go from higher sort level to lower, since lower sort level means higher priority (in
1833-
// front), so lower sort level meshes need to be rendered later.
1834-
for(unsigned int sort_level = MaxStaticSortLevel; sort_level >= MinStaticSortLevel; sort_level--)
1835-
{
1836-
bool render=false;
1837-
for ( RenderObjClass *robj = CurrentStaticSortLists[sort_level].Remove_Head(); robj;
1838-
robj->Release_Ref(), robj = CurrentStaticSortLists[sort_level].Remove_Head())
1839-
{
1840-
robj->Render(rinfo);
1841-
render=true;
1842-
}
1843-
if (render) TheDX8MeshRenderer.Flush();
1844-
}
1825+
CurrentStaticSortLists->Render_And_Clear(rinfo);
18451826
AreStaticSortListsEnabled = old_enable;
18461827
}
18471828

@@ -1853,22 +1834,17 @@ void WW3D::Enable_Sorting(bool onoff)
18531834
TheDX8MeshRenderer.Invalidate();
18541835
}
18551836

1856-
void WW3D::Override_Current_Static_Sort_Lists(RefRenderObjListClass *sort_list, unsigned int min_sort, unsigned int max_sort)
1837+
void WW3D::Override_Current_Static_Sort_Lists(StaticSortListClass * sort_list)
18571838
{
1858-
CurrentStaticSortLists = sort_list;
1859-
if (min_sort <= max_sort) {
1860-
MinStaticSortLevel = min_sort;
1861-
MaxStaticSortLevel = max_sort;
1839+
if (sort_list) {
1840+
CurrentStaticSortLists = sort_list;
18621841
} else {
1863-
WWASSERT(0);
1864-
MinStaticSortLevel = max_sort;
1865-
MaxStaticSortLevel = min_sort;
1842+
WWASSERT(sort_list);
18661843
}
18671844
}
18681845

1846+
18691847
void WW3D::Reset_Current_Static_Sort_Lists_To_Default(void)
18701848
{
18711849
CurrentStaticSortLists = DefaultStaticSortLists;
1872-
MinStaticSortLevel = 1; // The 0 list is not used
1873-
MaxStaticSortLevel = MAX_SORT_LEVEL;
1874-
}
1850+
}

Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class RenderDeviceDescClass;
6262
class StringClass;
6363
class LightEnvironmentClass;
6464
class MaterialPassClass;
65+
class StaticSortListClass;
6566

6667
#define SNAPSHOT_SAY(x) if (WW3D::Is_Snapshot_Activated()) { WWDEBUG_SAY(x); }
6768
//#define SNAPSHOT_SAY(x)
@@ -278,7 +279,7 @@ class WW3D
278279
static bool Is_Munge_Sort_On_Load_Enabled(void) { return MungeSortOnLoad; }
279280
static void Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level);
280281
static void Render_And_Clear_Static_Sort_Lists(RenderInfoClass & rinfo);
281-
static void Override_Current_Static_Sort_Lists(RefRenderObjListClass *sort_list, unsigned int min_sort, unsigned int max_sort);
282+
static void Override_Current_Static_Sort_Lists(StaticSortListClass * sort_list);
282283
static void Reset_Current_Static_Sort_Lists_To_Default(void);
283284

284285
static bool Is_Snapshot_Activated() { return SnapshotActivated; }
@@ -367,12 +368,9 @@ class WW3D
367368
// For meshes which have a static sorting order. These will get drawn
368369
// after opaque meshes and before normally sorted meshes. The 'current'
369370
// pointer is so the application can temporarily set a different set of
370-
// static sort lists to be used temporarily. This and the min/max sort
371-
// levels are for specialised uses.
372-
static RefRenderObjListClass * DefaultStaticSortLists;
373-
static RefRenderObjListClass * CurrentStaticSortLists;
374-
static unsigned int MinStaticSortLevel;
375-
static unsigned int MaxStaticSortLevel;
371+
// static sort lists to be used temporarily. This is for specialised uses.
372+
static StaticSortListClass * DefaultStaticSortLists;
373+
static StaticSortListClass * CurrentStaticSortLists;
376374

377375
// Memory allocation statistics
378376
static int LastFrameMemoryAllocations;

0 commit comments

Comments
 (0)