Skip to content

[ZH] Fix compilation using MinGW #547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

zzambers
Copy link

@zzambers zzambers commented Mar 30, 2025

Fixes code to be buildable using MinGW. Contains only fixes to game code. Does add support of MinGW to build system (cmake files) or any CI testing yet.

Partially fixes: #486

@zzambers zzambers marked this pull request as draft March 30, 2025 02:32
@Mauller Mauller added 🚫Do Not Merge Build Anything related to building, compiling ZeroHour Relates to Zero Hour labels Mar 30, 2025
@Mauller
Copy link

Mauller commented Mar 30, 2025

There are VC6 breaking changes in this due to the use of c++11 features.

If those are required then this cannot be used yet.

Marked do not merge for now.

@zzambers
Copy link
Author

zzambers commented Mar 30, 2025

There are VC6 breaking changes in this due to the use of c++11 features.

If those are required then this cannot be used yet.

Marked do not merge for now.

Thanks, this is definitely not yet ready for merge :)

Yes, I was afraid that enum Name : int syntax is probably not supported by VC6, but tried it anyway. So I'll probably need to go for macros and #ifdefs to fix forward enum declarations. :( (untyped forward declarations of enums are VC extension and typed ones are since c++11 and not supported by VC6...)

Maybe macro like IENUM(Name), INT_ENUM(Name) or ENUM_INT(Name) can be crated...

@xezon
Copy link

xezon commented Mar 30, 2025

Maybe macro like IENUM(Name), INT_ENUM(Name) or ENUM_INT(Name) can be crated...

Perhaps create a univeral macro

#if __cplusplus >= 201103L
    #define CPP_11(code) code
#else
    #define CPP_11(code)
#endif

Used as

enum EnumName CPP_11(: int)
{
}

Then this macro can be used for different things concerning c++11 features.

Or make it enum specific with

#if __cplusplus >= 201103L
    #define ENUM_UNDERLYING(type) : type
#else
    #define ENUM_UNDERLYING(type)
#endif

@zzambers
Copy link
Author

zzambers commented Mar 30, 2025

Maybe macro like IENUM(Name), INT_ENUM(Name) or ENUM_INT(Name) can be crated...

Perhaps create a univeral macro

#if __cplusplus >= 201103L
    #define CPP_11(code) code
#else
    #define CPP_11(code)
#endif

Interesting idea with universal CPP_11 macro, I quite like it. :)

@zzambers
Copy link
Author

zzambers commented Mar 30, 2025

@xezon I addapted approch with CPP_11 macro you suggested. thanks

Finally made it compile on VC6, I'll clean it up later for easier review (rebasing, combining related commits together, better commit messages etc..) I expect asm replacements to be merged to main first, I'll then rebase my changes on top.

If you prefer, I can also make fix of enums (forward declarations) separate PR. (as it is quite a big change set)

@xezon xezon added this to the Code foundation build up milestone Mar 31, 2025
@zzambers zzambers mentioned this pull request Mar 31, 2025
17 tasks
@zzambers
Copy link
Author

zzambers commented Apr 2, 2025

Rebased, combined related commits, wrote better commit messages. Commits are done so that they only include one kind of change (no unrelated changes), for easier review.

Ready for review.

@zzambers zzambers marked this pull request as ready for review April 2, 2025 21:03
@zzambers zzambers changed the title [ZH] Fix compilation on MinGW (WIP) [ZH] Fix compilation on MinGW Apr 2, 2025
@zzambers zzambers changed the title [ZH] Fix compilation on MinGW [ZH] Fix compilation using MinGW Apr 2, 2025
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed up until [ZH] Fix of unsigned values in signed arrays so far.

@@ -20,6 +20,7 @@ target_link_libraries(z_generals PRIVATE
safedisc
vfw32
winmm
gz_utility
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alphabetical order. Several times in this change.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed that these are in alphabetical order, I can fix that.

@@ -51,7 +51,7 @@
#include <Common/GameMemory.h>
#include "EABrowserDispatch/BrowserDispatch.h"
#include "FEBDispatch.h"
#include <Utility/CppMacros.h>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps CppMacros.h can be removed at a few more places then (if present).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can take a look.

@@ -58,7 +58,7 @@ class Squad;
* Each of these constants will be associated with an instance of a State class
* in a given StateMachine.
*/
enum AIStateType
enum AIStateType CPP_11(: int)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a small burdon, because MSVC users need to remember putting that thing. What is the error message with MinGW for this? Is there perhaps a way to avoid an error by specifying the default type for unscoped enums to the compiler?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If forward declarations are not typed, GCC (MinGW toolchain) produces error such as:

CnC_Generals_Zero_Hour/GeneralsMD/Code/GameEngine/Include/Common/STLTypedefs.h:67:6: error: use of enum ‘NameKeyType’ without previous declaration
   67 | enum NameKeyType;
      |      ^~~~~~~~~~~

I don't think, you can configure GCC to accept this, as this is not standard c++. Compiler needs to see definition to decide on type or since c++11 enum type can be explicitly specified. (Assumption of int underlying type is MSVC extension.)

When it comes to MSVC users, I think, they should not learn to write forward enum declarations as in original code, because it's non-standard and non-portable. MS itself warns it's not portable and has compiler warning for this. It's another inconvenience, that VC6 is too old to support typed enums. Solution may not be super pretty, but portability comes with a price. :(

Also note that typed enums are kind of all or nothing thing. Mixing typed declarations and untyped definitions of same enum may (and will) result in errors as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for MSVC users, untyped forward enum declarations will get caught by github CI, once build using MinGW is implemented there.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just fix this properly and just have enums like AIStateType fully defined either by including the actual header its defined in, moving it to a header if its defined in the cpp, or moving it to its own header to be included multiple places without including other class declarations.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, Google C++ Style Guide also discourages forward declarations:
https://google.github.io/styleguide/cppguide.html#Forward_Declarations

Copy link

@Mauller Mauller Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCC

https://gcc.gnu.org/onlinedocs/gcc/Enum-Extensions.html#Incomplete-Enums

Forward-declaring an incomplete enum type without an explicit underlying type is supported as an extension in all GNU C dialects, but is not supported at all in GNU C++.

This is interesting because i forward declare enumerations and structs in my embedded work with std=c++17 set and have never had issues with it. The cross compiler is also GCC.

although the enums are enum classes usually, which might be the key difference.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although the enums are enum classes usually, which might be the key difference.

Yes class seems to make difference between so called Unscoped enumerations and Scoped enumerations

Unscoped enumerations:
enum name (optional) { enumerator = constant-expression , enumerator = constant-expression , ... }

Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is an implementation-defined integral type that can represent all enumerator values; this type is not larger than int unless the value of an enumerator cannot fit in an int or unsigned int. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value ​0​. If no integral type can represent all the enumerator values, the enumeration is ill-formed).

Scoped enumerations:
enum struct|class name { enumerator = constant-expression , enumerator = constant-expression , ... }

declares a scoped enumeration type whose underlying type is int (the keywords class and struct are exactly equivalent)

Scoped enums are also c++11 feature. Also there are more differences. Namely, values scoped (as name says :)) also values do not implicitly cast to integer.

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just fix this properly and just have enums like AIStateType fully defined either by including the actual header its defined in, moving it to a header if its defined in the cpp, or moving it to its own header to be included multiple places without including other class declarations.

Interestingly, Google C++ Style Guide also discourages forward declarations: https://google.github.io/styleguide/cppguide.html#Forward_Declarations

I wouldn't always follow Googles C++ style guide, as long as you don't need the implementation in the header, forward declarations are always better as they reduce compilation overhead.

I am afraid we cannot (easily) do without forward declarations in this project. (not only for performance reasons). They are also way to break dependency loops. (e.g. if class A uses class B and class B uses class A).

You would run into similar issue with enums even if defined in headers. (e.g. class A uses enum defined in header of class B and class B uses enum defined in header of class A). So that by itself would not solve the issue.

Maybe use of forward declarations could be limited, but that would be big refactoring effort (which would icrease number of headers, possibly significantly). So, I think, there are various kinds of tradeoffs, that come into play here...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is my point with moving the enums that are shared between a few coupled classes, just move it to a totally new header that is included where that enum or groups of enums are required?

I think we should just fix this properly and just have enums like AIStateType fully defined either by including the actual header its defined in, moving it to a header if its defined in the cpp, or moving it to its own header to be included multiple places without including other class declarations.

Interestingly, Google C++ Style Guide also discourages forward declarations: https://google.github.io/styleguide/cppguide.html#Forward_Declarations

I wouldn't always follow Googles C++ style guide, as long as you don't need the implementation in the header, forward declarations are always better as they reduce compilation overhead.

I am afraid we cannot (easily) do without forward declarations in this project. (not only for performance reasons). They are also way to break dependency loops. (e.g. if class A uses class B and class B uses class A).

You would run into similar issue with enums even if defined in headers. (e.g. class A uses enum defined in header of class B and class B uses enum defined in header of class A). So that by itself would not solve the issue.

Maybe use of forward declarations could be limited, but that would be big refactoring effort (which would icrease number of headers, possibly significantly). So, I think, there are various kinds of tradeoffs, that come into play here...

That is my point with moving the enums that are shared between a few coupled classes, just move it to a totally new header that is included where that enum or groups of enums are required? I guess if forward declarations with storage type are supported by the standard then its a less invasive and standards compliant way to solve the issue, I just don't like it.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding underlying types to enums looks like the least invasive change. It does not look pretty with the macro, but it is technically all correct.

@@ -84,6 +84,8 @@ class DX8PolygonRendererAttachClass;
class DX8SkinFVFCategoryContainer;
class GapFillerClass;

class MeshModelClass;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps put that closer to one of the other Mesh classes above?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I can do that

@@ -78,7 +78,7 @@ class DLDestroyListClass : public DLListClass<T>
public:
virtual ~DLDestroyListClass()
{
while (T* t=Head()) {
while (T* t=this->Head()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this required? There already is a using clause above that should avoid this.

Copy link
Author

@zzambers zzambers Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, seems it is not necessary anymore. I have created this part of change set before, you addressed it by different approach.

Maybe commit [ZH] Fix of accesses to parent class members is no longer necessary.
Nice find!

@@ -69,18 +69,18 @@ template <class T>
__inline bool PriorityVectorClass<T>::Process_Head (T &object)
{
bool retval = false;
if (Vector != NULL) {
if (this->Vector != NULL) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be avoided by adding a using DynamicVectorClass<T>::Vector in the class declaration? This is how we fixed these for VS2022. Same for all the other this-> additions in this commit.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, I'll take a look at this. I'll investigate, if whole commit is necessary at all. If some pieces are, I'll try to use your approach.

@@ -5606,7 +5606,7 @@ static int cellValueProc(PartitionCell* cell, void* userData)
}

// -----------------------------------------------------------------------------
static void hLineAddLooker(Int x1, Int x2, Int y, void *playerIndexVoid)
void hLineAddLooker(Int x1, Int x2, Int y, void *playerIndexVoid)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am surprised that this is a problem. What is the error? static function in cpp should be legal, no?

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem here (and in other cases) was not function being static. But rather function being declared non-static and then defined (or re-declared) as static. In this particular case, problem was inconsistency with friend declarations in PartitionManager.h, if I remember correctly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compiler error:

CnC_Generals_Zero_Hour/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp:340:13: error: ‘void hLineAddLooker(Int, Int, Int, void*)’ was declared ‘extern’ and later ‘static’ [-fpermissive]
  340 | static void hLineAddLooker(Int x1, Int x2, Int y, void *playerIndexVoid);
      |             ^~~~~~~~~~~~~~
In file included from CnC_Generals_Zero_Hour/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp:74:
CnC_Generals_Zero_Hour/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h:1300:21: note: previous declaration of ‘void hLineAddLooker(Int, Int, Int, void*)’
 1300 |         friend void hLineAddLooker(Int x1, Int x2, Int y, void *playerIndex);
      |                     ^~~~~~~~~~~~~~

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make a static friend here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making static fried results in error:

CnC_Generals_Zero_Hour/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h:1300:16: error: storage class specifiers invalid in friend function declarations
 1300 |         friend static void hLineAddLooker(Int x1, Int x2, Int y, void *playerIndex);
      |                ^~~~~~

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit title [ZH] Fix of function pointer catsts to void* has typing mistake.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can fix that :)

@@ -68,7 +68,7 @@ struct AcademyAdviceInfo
UnsignedInt numTips;
};

enum AcademyClassificationType
enum AcademyClassificationType CPP_11(: int)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you specifying the underlying type for enums that are fully defined? Specifying the type is optional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you use type on forward declarations of enum, you then need to use it also for definitions. Inconsistency here can lead to compiler errors as well.

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the scale of the issue, I have not explicitly checked existence of forward declarations of each enum, but simply changed them all (in GameEngine and GameEngineDevice, by script). I think changing all is better anyway, because in other case you would have some enums you can forward declare and some which you cant...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with consistency.

@@ -1102,7 +1102,7 @@ extern HWND ApplicationHWnd;
//TODO: Fix editor so it actually draws the wave segment instead of line while editing
//Could freeze all the water while editing? Or keep setting elapsed time on current segment.
//Have to make it so seamless merge of segments at final position.
static void TestWaterUpdate(void)
void TestWaterUpdate(void)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestWaterUpdate isn't called in any other translation units, correct fix would be to specify static on its forward declaration rather than remove it here.

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I changed definition to match declaration, but in this case declaration could have been static. I can fix that.

@@ -354,25 +354,25 @@ LERPAnimationChannelClass<T>::Evaluate (float time)
//
// Don't interpolate past the last keyframe
//
if (time < m_Data[key_count - 1].Get_Time ()) {
if (time < this->m_Data[key_count - 1].Get_Time ()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the errors relating to this? PrimitiveAnimationChannelClass is a base class and m_Data and m_LastIndex are members of it and shouldn't require this-> to be resolved correctly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of this may not actually be needed anymore, see: #547 (comment)

}

KeyClass *key1 = &m_Data[m_LastIndex];
KeyClass *key2 = &m_Data[key_count - 1];
typename PrimitiveAnimationChannelClass<T>::KeyClass *key1 = &m_Data[m_LastIndex];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again what is the error relating to this? The template should be resolved correctly within the function because the class is a nested member of the class this function belongs to?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error is:

CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h: In member function ‘virtual T LERPAnimationChannelClass<T>::Evaluate(float)’:
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:364:27: error: ‘key1’ was not declared in this scope; did you mean ‘y1’?
  364 |                 KeyClass *key1 = &m_Data[m_LastIndex];
      |                           ^~~~
      |                           y1
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:365:27: error: ‘key2’ was not declared in this scope
  365 |                 KeyClass *key2 = &m_Data[key_count - 1];
      |   

Copy link
Author

@zzambers zzambers Apr 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If just typename is added, error is:

CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h: In member function ‘virtual T LERPAnimationChannelClass<T>::Evaluate(float)’:
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:364:26: error: expected nested-name-specifier before ‘KeyClass’
  364 |                 typename KeyClass *key1 = &m_Data[m_LastIndex];
      |                          ^~~~~~~~
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:364:26: error: expected ‘(’ before ‘KeyClass’
  364 |                 typename KeyClass *key1 = &m_Data[m_LastIndex];
      |                          ^~~~~~~~
      |                          (
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:365:26: error: expected nested-name-specifier before ‘KeyClass’
  365 |                 typename KeyClass *key2 = &m_Data[key_count - 1];
      |                          ^~~~~~~~
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:365:26: error: expected ‘(’ before ‘KeyClass’
  365 |                 typename KeyClass *key2 = &m_Data[key_count - 1];

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When typename is omitted:

CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h: In member function ‘virtual T LERPAnimationChannelClass<T>::Evaluate(float)’:
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:364:62: error: ‘key1’ was not declared in this scope; did you mean ‘y1’?
  364 |                 PrimitiveAnimationChannelClass<T>::KeyClass *key1 = &m_Data[m_LastIndex];
      |                                                              ^~~~
      |                                                              y1
CnC_Generals_Zero_Hour/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/prim_anim.h:365:62: error: ‘key2’ was not declared in this scope
  365 |                 PrimitiveAnimationChannelClass<T>::KeyClass *key2 = &m_Data[key_count - 1];
      |                                                              ^~~~

@@ -139,39 +139,39 @@ class TPoint3D : public TPoint2D<T> {
TPoint3D(BASECLASS const & rvalue) : TPoint2D<T>(rvalue), Z(0) {}

// Equality comparison operators.
bool operator == (TPoint3D<T> const & rvalue) const {return(X==rvalue.X && Y==rvalue.Y && Z==rvalue.Z);}
bool operator != (TPoint3D<T> const & rvalue) const {return(X!=rvalue.X || Y!=rvalue.Y || Z!=rvalue.Z);}
bool operator == (TPoint3D<T> const & rvalue) const {return(this->X==rvalue.X && this->Y==rvalue.Y && Z==rvalue.Z);}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again why is this-> needed here? The using BASECLASS::X; statement should make it unneccessary?

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as: #547 (comment)

@@ -185,7 +185,9 @@ class FastCriticalSectionClass
;
#else
while (cs.Flag.test_and_set(std::memory_order_acquire)) {
#if defined(__cpp_lib_atomic_wait) && __cpp_lib_atomic_wait >= 201907L

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a dangerous change that will increase CPU use as the loop busy waits instead of yielding the CPU as its supposed to do in the original code? Would be better to revert it to ThreadClass::Swich_Thread() as per the original implementation so it yields as intended? Which version of mingw are you using as this is supposed to be implementing in GCC 11 and newer.

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have found out this code actually works with GCC with -std=c++20 flag, I was testing with default settings, which did not work (probably g++ still defaults to older c++ standard). But still I think it would be good to depend on so recent standard.

It would indeed busy wait, if not supported. True, that I could have used original impl or used it in #else. In case of uncontended locks original implementation could even be cheaper (avoiding overhead of notify_one() for each unlock, but I don't know how big that is).

btw. I actually wonder, if busy wait isn't actually cheaper on modern multi-processor machines, if number of threads is low (relatively speaking) and critical sections are small (as OS machinery associated with sleeping waking up thread or switching threads could be more expensive). It would however mean burning rest of time slice on uniprocessor system (where there is not true concurrency), until OS scheduler switches to another thread, which is not very nice indeed...

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whole project should insist on C++20 for none VC6 build and the configure fail if its not available. I did argue for requiring an older standard such as C++17 as the standard but was outvoted so we can rely on C++20 as the base for builds other than VC6.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we do not need to cater to C++17 at this time, because there currently is no practical use case for c++17. We just need c++98 & c++20 :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I can then probably drop this part from the patch, as it turns out it is not required even for MinGW/GCC configured for c++20.

@@ -52,7 +52,7 @@ void __cdecl ThreadClass::Internal_Thread_Function(void* params)
tc->running=true;
tc->ThreadID = GetCurrentThreadId();

#ifdef _WIN32
#if defined(_WIN32) && !defined(__GNUC__)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use #ifdef _MSCVER instead if this section is compiler and not platform dependant?

Copy link
Author

@zzambers zzambers Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure, use of __try and __except could maybe work with clang. (e.g. if clang was used with mingw; not tested)

@@ -2,6 +2,7 @@
//
// typelib filename: <could not determine filename>

import "oaidl.idl";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was already moved to Core folder so you will need to replicate this there.

@@ -2,6 +2,7 @@
//
// typelib filename: <could not determine filename>

import "oaidl.idl";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The IDL file was generated by a tool. Perhaps add a fat comment here that this has been added by hand.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error by widl is:

BrowserEngine.idl:31:44: error: type 'IDispatch' not found in global namespace

    interface IFEBrowserEngine2 : IDispatch {
                                           ^

IDispatch is in oaidl.idl in wine headers.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with MinGW headers. (IDispatch is in oaidl.idl)

@@ -3,6 +3,11 @@

#pragma once

#include <cassert>
#define UNIMPLEMEMTED_ERROR(msg) do { \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UNIMPLEMENTED_ERROR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I had to read it several times to spot the typo :) I'll fix that.

@@ -61,6 +61,7 @@
#include "GameClient/IMEManager.h"
#include "Win32Device/GameClient/Win32Mouse.h"
#include "Win32Device/Common/Win32GameEngine.h"
#include "WWLib/trim.h"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typing error in commit title:

"[ZH] Removal of duplicit strtrim"

"duplicate"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's probably not an English world, sorry. :) However, I think, this has already been addressed by other PR already in meantime...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you plan to replicate these changes if we decide to merge this before we move things to Core?

Right now the amount of single commits is massive. Replicating this equally to Generals would mean 64 commits for this effort.

Perhaps combine some of the smaller commits into new commits, and also add Generals changes to each Zero Hour change commit once we are happy with Zero Hour? This could perhaps get the commit count down to 24 or so.

Each of the commits needs to be able to compile on their own.

Copy link
Author

@zzambers zzambers Apr 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I was just planning to do ZH as whole, followed by backport to GEN. But I see, there is quite a lot of activity in this project, causing code to diverge quickly. Also sometimes other efforts (like fixes of warnings) address same things, as this PR.

So now, I am considering breaking this into multiple smaller PRs, (which would probably be [GEN][ZH]). I have seen others following similar approach for their PRs. I would not like to end up in endless rebase loop. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll probably do bigger change sets as separate PRs (referencing discussions here), hopefully this one will then have more manageable size...

Copy link

@Mauller Mauller Apr 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Enum one should be a PR of its own considering how many fines it hits.

Just taking that one out will cleanup a lot of this.

EDIT: NVm i just saw that you did exactly that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I second this. Let us get the enum fixes in one single Pull Request, without anything else. A lot of things are going into main line right now, so you want to keep the amount of things that happen inside the Pull Request small, so it can get reviewed swiftly.

@xezon xezon added Major Severity: Minor < Major < Critical < Blocker and removed 🚫Do Not Merge labels Apr 10, 2025
@Mauller
Copy link

Mauller commented Apr 12, 2025

At level 4 warnings, the untyped enumerations actually create nearly 10k worth of warnings, a lot of it due to the forward declarations in headers.

@zzambers
Copy link
Author

@xezon @Mauller @OmniBlade @DevGeniusCode Thank you for your reviews.

As I have written higher I'll try to separate parts of this into new PRs, to keep this manageble size. (Possibly using this PR for of smaller changes.) I'll address raised issues there, linking this PR with reviews.

I'll post link to new derived PRs here

@zzambers
Copy link
Author

zzambers commented Apr 12, 2025

Fixes to forward enum declarations: #665

@zzambers
Copy link
Author

Rest of asm made VC only: #670

@zzambers
Copy link
Author

Fixes to intrin_compat.h: #671

@zzambers
Copy link
Author

COM related fixes: #672

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Build Anything related to building, compiling Major Severity: Minor < Major < Critical < Blocker ZeroHour Relates to Zero Hour
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make project buildable using MinGW toolchain
5 participants