From ef6cc7e7702535f744face0cf47125faefefb680 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:11:56 +0200 Subject: [PATCH 1/5] refactor(sortingrenderer): Replace custom doubly linked list with std::list --- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 70 ++++++++----------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index c2c89a07bdf..23afbbdeaac 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -49,6 +49,7 @@ #include "statistics.h" #include #include +#include bool SortingRendererClass::_EnableTriangleDraw=true; @@ -150,7 +151,7 @@ void Sort(TempIndexStruct *begin, TempIndexStruct *end) // ---------------------------------------------------------------------------- -class SortingNodeStruct : public DLNodeClass +class SortingNodeStruct { W3DMPO_CODE(SortingNodeStruct) @@ -166,20 +167,18 @@ class SortingNodeStruct : public DLNodeClass unsigned short vertex_count; // Number of vertices used in vb }; -static DLListClass sorted_list; -static DLListClass clean_list; +static std::list sorted_list; +static std::list clean_list; static unsigned total_sorting_vertices; static SortingNodeStruct* Get_Sorting_Struct() { - - SortingNodeStruct* state=clean_list.Head(); - if (state) { - state->Remove(); + if (!clean_list.empty()) { + SortingNodeStruct* state = clean_list.front(); + clean_list.pop_front(); return state; } - state=W3DNEW SortingNodeStruct(); - return state; + return W3DNEW SortingNodeStruct(); } // ---------------------------------------------------------------------------- @@ -258,18 +257,15 @@ void SortingRendererClass::Insert_Triangles( /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - SortingNodeStruct* node=sorted_list.Head(); - while (node) { - if (state->transformed_center.Z>node->transformed_center.Z) { - if (sorted_list.Head()==sorted_list.Tail()) - sorted_list.Add_Head(state); - else - state->Insert_Before(node); + std::list::iterator node = sorted_list.begin(); + while (node != sorted_list.end()) { + if (state->transformed_center.Z > (*node)->transformed_center.Z) { + sorted_list.insert(node, state); break; } - node=node->Succ(); + ++node; } - if (!node) sorted_list.Add_Tail(state); + if (node == sorted_list.end()) sorted_list.push_back(state); #ifdef WWDEBUG unsigned short* indices=nullptr; @@ -577,7 +573,7 @@ void SortingRendererClass::Flush_Sorting_Pool() for (unsigned node_id=0;node_idRemove(); + while (!sorted_list.empty()) { + SortingNodeStruct* state = sorted_list.front(); + sorted_list.pop_front(); if ((state->sorting_state.index_buffer_type==BUFFER_TYPE_SORTING || state->sorting_state.index_buffer_type==BUFFER_TYPE_DYNAMIC_SORTING) && (state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_SORTING || state->sorting_state.vertex_buffer_types[0]==BUFFER_TYPE_DYNAMIC_SORTING)) { @@ -609,7 +606,7 @@ void SortingRendererClass::Flush() DX8Wrapper::Draw_Triangles(state->start_index,state->polygon_count,state->min_vertex_index,state->vertex_count); DX8Wrapper::Release_Render_State(); Release_Refs(state); - clean_list.Add_Head(state); + clean_list.push_front(state); } } @@ -635,22 +632,20 @@ void SortingRendererClass::Flush() void SortingRendererClass::Deinit() { - SortingNodeStruct *head = nullptr; - // // Flush the sorted list // - while ((head = sorted_list.Head ()) != nullptr) { - sorted_list.Remove_Head (); - delete head; + while (!sorted_list.empty()) { + delete sorted_list.front(); + sorted_list.pop_front(); } // // Flush the clean list // - while ((head = clean_list.Head ()) != nullptr) { - clean_list.Remove_Head (); - delete head; + while (!clean_list.empty()) { + delete clean_list.front(); + clean_list.pop_front(); } delete[] temp_index_array; @@ -717,16 +712,13 @@ void SortingRendererClass::Insert_VolumeParticle( /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - SortingNodeStruct* node=sorted_list.Head(); - while (node) { - if (state->transformed_center.Z>node->transformed_center.Z) { - if (sorted_list.Head()==sorted_list.Tail()) - sorted_list.Add_Head(state); - else - state->Insert_Before(node); + std::list::iterator node = sorted_list.begin(); + while (node != sorted_list.end()) { + if (state->transformed_center.Z > (*node)->transformed_center.Z) { + sorted_list.insert(node, state); break; } - node=node->Succ(); + ++node; } - if (!node) sorted_list.Add_Tail(state); + if (node == sorted_list.end()) sorted_list.push_back(state); } From 424cf0f52d334caaa3795a623e30a9d3966f42c6 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:40:18 +0200 Subject: [PATCH 2/5] Process comments --- .../Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index 23afbbdeaac..2b402fa3222 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -265,7 +265,10 @@ void SortingRendererClass::Insert_Triangles( } ++node; } - if (node == sorted_list.end()) sorted_list.push_back(state); + if (node == sorted_list.end()) + { + sorted_list.push_back(state); + } #ifdef WWDEBUG unsigned short* indices=nullptr; @@ -720,5 +723,8 @@ void SortingRendererClass::Insert_VolumeParticle( } ++node; } - if (node == sorted_list.end()) sorted_list.push_back(state); + if (node == sorted_list.end()) + { + sorted_list.push_back(state); + } } From 2b86deb2931c47546e4f8ef7397847f0a582fab7 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 20 Jun 2026 11:03:43 +0200 Subject: [PATCH 3/5] Use typedef for the list. Clean up loops --- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index 2b402fa3222..14db4cc5e8c 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -167,8 +167,9 @@ class SortingNodeStruct unsigned short vertex_count; // Number of vertices used in vb }; -static std::list sorted_list; -static std::list clean_list; +typedef std::list SortingNodeStructList; +static SortingNodeStructList sorted_list; +static SortingNodeStructList clean_list; static unsigned total_sorting_vertices; static SortingNodeStruct* Get_Sorting_Struct() @@ -245,31 +246,6 @@ void SortingRendererClass::Insert_Triangles( WWASSERT(vertex_buffer); WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); - D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; - D3DXVECTOR4 transformed_vec; - D3DXVec3Transform( - &transformed_vec, - &vec, - &mtx); - state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); - - - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - std::list::iterator node = sorted_list.begin(); - while (node != sorted_list.end()) { - if (state->transformed_center.Z > (*node)->transformed_center.Z) { - sorted_list.insert(node, state); - break; - } - ++node; - } - if (node == sorted_list.end()) - { - sorted_list.push_back(state); - } - #ifdef WWDEBUG unsigned short* indices=nullptr; SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); @@ -288,6 +264,28 @@ void SortingRendererClass::Insert_Triangles( WWASSERT(idx3vertex_count); } #endif // WWDEBUG + + D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; + D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; + D3DXVECTOR4 transformed_vec; + D3DXVec3Transform( + &transformed_vec, + &vec, + &mtx); + state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); + + + /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times + + for (SortingNodeStructList::iterator node = sorted_list.begin(); node != sorted_list.end(); ++node) + { + if (state->transformed_center.Z > (*node)->transformed_center.Z) { + sorted_list.insert(node, state); + return; + } + } + + sorted_list.push_back(state); } // ---------------------------------------------------------------------------- @@ -715,16 +713,13 @@ void SortingRendererClass::Insert_VolumeParticle( /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - std::list::iterator node = sorted_list.begin(); - while (node != sorted_list.end()) { + for (SortingNodeStructList::iterator node = sorted_list.begin(); node != sorted_list.end(); ++node) + { if (state->transformed_center.Z > (*node)->transformed_center.Z) { sorted_list.insert(node, state); - break; + return; } - ++node; - } - if (node == sorted_list.end()) - { - sorted_list.push_back(state); } + + sorted_list.push_back(state); } From e01d68e96d5d32f14d9c57a3d103334f2c126875 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 20 Jun 2026 12:20:45 +0200 Subject: [PATCH 4/5] Restore the break. Move WWDEBUG stuff to the bottom --- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index 14db4cc5e8c..84de49e8a19 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -242,11 +242,37 @@ void SortingRendererClass::Insert_Triangles( state->min_vertex_index=min_vertex_index; state->vertex_count=vertex_count; + D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; + D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; + D3DXVECTOR4 transformed_vec; + D3DXVec3Transform( + &transformed_vec, + &vec, + &mtx); + state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); + + + /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times + + SortingNodeStructList::iterator node; + for (node = sorted_list.begin(); node != sorted_list.end(); ++node) + { + if (state->transformed_center.Z > (*node)->transformed_center.Z) { + sorted_list.insert(node, state); + break; + } + } + + if (node == sorted_list.end()) + { + sorted_list.push_back(state); + } + +#ifdef WWDEBUG SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); WWASSERT(vertex_buffer); WWASSERT(state->vertex_count<=vertex_buffer->Get_Vertex_Count()); -#ifdef WWDEBUG unsigned short* indices=nullptr; SortingIndexBufferClass* index_buffer=static_cast(state->sorting_state.index_buffer); WWASSERT(index_buffer); @@ -264,28 +290,6 @@ void SortingRendererClass::Insert_Triangles( WWASSERT(idx3vertex_count); } #endif // WWDEBUG - - D3DXMATRIX mtx=(D3DXMATRIX&)state->sorting_state.world*(D3DXMATRIX&)state->sorting_state.view; - D3DXVECTOR3 vec=(D3DXVECTOR3&)state->bounding_sphere.Center; - D3DXVECTOR4 transformed_vec; - D3DXVec3Transform( - &transformed_vec, - &vec, - &mtx); - state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); - - - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - for (SortingNodeStructList::iterator node = sorted_list.begin(); node != sorted_list.end(); ++node) - { - if (state->transformed_center.Z > (*node)->transformed_center.Z) { - sorted_list.insert(node, state); - return; - } - } - - sorted_list.push_back(state); } // ---------------------------------------------------------------------------- @@ -713,13 +717,17 @@ void SortingRendererClass::Insert_VolumeParticle( /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - for (SortingNodeStructList::iterator node = sorted_list.begin(); node != sorted_list.end(); ++node) + SortingNodeStructList::iterator node; + for (node = sorted_list.begin(); node != sorted_list.end(); ++node) { if (state->transformed_center.Z > (*node)->transformed_center.Z) { sorted_list.insert(node, state); - return; + break; } } - sorted_list.push_back(state); + if (node == sorted_list.end()) + { + sorted_list.push_back(state); + } } From c4577aa530fada4386632c5ef2a3483c06224111 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sat, 20 Jun 2026 13:46:28 +0200 Subject: [PATCH 5/5] Add insertion to sorted list into new function --- .../Source/WWVegas/WW3D2/sortingrenderer.cpp | 50 +++++++------------ .../Source/WWVegas/WW3D2/sortingrenderer.h | 1 + 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp index 84de49e8a19..288e4bd9429 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.cpp @@ -251,22 +251,7 @@ void SortingRendererClass::Insert_Triangles( &mtx); state->transformed_center=Vector3(transformed_vec[0],transformed_vec[1],transformed_vec[2]); - - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - SortingNodeStructList::iterator node; - for (node = sorted_list.begin(); node != sorted_list.end(); ++node) - { - if (state->transformed_center.Z > (*node)->transformed_center.Z) { - sorted_list.insert(node, state); - break; - } - } - - if (node == sorted_list.end()) - { - sorted_list.push_back(state); - } + Insert_To_Sorted_List(state); #ifdef WWDEBUG SortingVertexBufferClass* vertex_buffer=static_cast(state->sorting_state.vertex_buffers[0]); @@ -336,6 +321,23 @@ static SortingNodeStruct* overlapping_nodes[MAX_OVERLAPPING_NODES]; // ---------------------------------------------------------------------------- +void SortingRendererClass::Insert_To_Sorted_List(SortingNodeStruct *state) +{ + /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times + + for (SortingNodeStructList::iterator node = sorted_list.begin(); node != sorted_list.end(); ++node) + { + if (state->transformed_center.Z > (*node)->transformed_center.Z) { + sorted_list.insert(node, state); + return; + } + } + + sorted_list.push_back(state); +} + +// ---------------------------------------------------------------------------- + void SortingRendererClass::Insert_To_Sorting_Pool(SortingNodeStruct* state) { if (overlapping_node_count>=MAX_OVERLAPPING_NODES) { @@ -715,19 +717,5 @@ void SortingRendererClass::Insert_VolumeParticle( //THE TRANSFORMED CENTER[2] IS THE ZBUFFER DEPTH - /// @todo lorenzen sez use a bucket sort here... and stop copying so much data so many times - - SortingNodeStructList::iterator node; - for (node = sorted_list.begin(); node != sorted_list.end(); ++node) - { - if (state->transformed_center.Z > (*node)->transformed_center.Z) { - sorted_list.insert(node, state); - break; - } - } - - if (node == sorted_list.end()) - { - sorted_list.push_back(state); - } + Insert_To_Sorted_List(state); } diff --git a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h index 06f0b5e826c..4cf874bdeba 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/sortingrenderer.h @@ -28,6 +28,7 @@ class SortingRendererClass static bool _EnableTriangleDraw; static void Flush_Sorting_Pool(); + static void Insert_To_Sorted_List(SortingNodeStruct* state); static void Insert_To_Sorting_Pool(SortingNodeStruct* state); public: