Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - A C99 Single-Header-File Platform Abstraction Library 10 months, 1 week ago Edited by Finalspace on March 31, 2018, 7:47 a.m. Hi i wanted to present you my recent project i am working on which is a platform abstraction library. This library is designed to be simple, non-bloated, can be included however you want and do not require any thirdparty libraries at all. It will simply abstract away all relevant platform specific things in a simple to use api without hiding any data. The main focus is game/media/simulation development, so you get a window, audio playback and a rendering context. Mindset: - Its written in C99 but is C++ compatible - There is just a single header file you have to include and thats it. - C-Runtime support can be disabled - The code style is simple and clean - Its full open source, so you can use and extend it however you want - Uses just the built-in operating system functions/libraries - Works well with other libraries as well (ImGUI, Box2D, Glew, STL, etc.) - Some features can be compiled out as needed (Window, OpenGL, etc.) - Fixed and small memory footprint - Easy to use api - Can be debugged Why: - Moving away from object orienation to handmade programming - Most platform abstraction libraries are bloated, have a bad api, cannot be debugged, are slow, has bad memory management - I dont want to write platform specific code anymore, just once for each platform with a fixed set of features and thats it. - Learning C99 low level programming Features: - Window creation and handling - OpenGL legacy and modern rendering context creation - Memory allocation and deallocation - Timing operations - Threading and syncronisation - File/Path IO - String conversion functions - Atomic operations - Dynamic library loading - Console out - Gamepad input - Audio playback History: Initially the project was fully written with 100% C/89 compability in mind without needing the c-runtime library, but as i see myself always fighting against C or missing any features like console output, i decided to move to a minimal C++ version. After a while i upgraded to C++/11, but felt there was no need for C++ at all... Now its written in C99 and it was the best choice ever. Current state: - Win32 support is complete - Linux support is almost complete Planned: - More video drivers (Direct2D/3D/Vulcan) - More audio drivers (XAudio, Wasapi) - More platforms (MacOSX, maybe Android not sure) - More docs & tutorials - More tests Source: https://github.com/f1nalspace/final_game_tech Feedback/Comments: I would like to know what you think about, what is missing, how can i improve it, what do you want from it, etc.
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Update v0.4.1 alpha: Cleanup: Internal cleanup Changed: All the settings constructors removed and replaced by a simple inline function. Added: Added native C++ unit test project to demos solution Fixed: FPL_OFFSETOF was not working Fixed: All file size macros like FPL_MEGABYTES was returning invalid results. Removed: FPL_PETABYTES and higher are removed, just because its useless. State: I cleaned up all the internals so i have a single block per platform and fixed some small bugs. Also i decided to continue with the subnamespace style - one nested level is fine. Next big thing will be audio output using directsound or xaudio and of course implementing the linux platform. But as for now it is working great, i use it in all my C++ stuff know.
 mrmixer Simon Anciaux 453 posts FPL - a single header platform abstraction c++ library 10 months ago Edited by Simon Anciaux on Nov. 18, 2017, 2:35 p.m. Reason: Typo Maybe support wasapi for audio as DirectSound and XAudio are built on top of it ? As for the namespace things, have you considered that C doesn't support them ?
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Edited by Finalspace on Nov. 20, 2017, 9:25 a.m. mrmixer Maybe support wasapi for audio as DirectSound and XAudio are built on top of it ? As for the namespace things, have you considered that C doesn't support them ? For audio and win32 i will definitly use directsound + optionally xaudio2. And for regarding C-Support: This library is C++/11 only. In the past it was C, but as i was fighting against C all the time i changed it to C++/11 - without introducing any oop concepts or using the std library. Why: - Automatic typedef for struct and enums - constexpr for seeing the expanded constants automatically in the IDE (Very useful) - Enum class for having proper type checking (Normal C/C++ enums are the worst in < C++/11). I could live without: - Method/Operator overloading (Op overload is required for enum class) - Namespaces (Prevent name conflicts, Categorizing)
FPL - a single header platform abstraction c++ library
10 months ago Edited by Finalspace on Nov. 21, 2017, 8:06 a.m.

I am thinking about doing something like this, but i am not sure:

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 //! Optional C++/11 and namespace support #if defined(FPL_CPP11_SUPPORTED) # define fpl_constant constexpr # define FPL_ENUM_DECL_TYPE(name, type) \ enum class name : type # define FPL_ENUM_DECL_VALUE(type, name, value) \ name = value # define FPL_ENUM_VALUE(type, name) \ name #else # define fpl_constant const static # define FPL_ENUM_DECL_TYPE(name, t) \ enum name # define FPL_ENUM_DECL_VALUE(t, name, value) \ t##_##name = value # define FPL_ENUM_VALUE(t, name) \ t##_##name #endif #if !defined(FPL_NO_NAMESPACE) # define FPL_NS_BEGIN(name) \ namespace name { # define FPL_NS_END(name) \ } #else # define FPL_NS_BEGIN(name) # define FPL_NS_END(name) #endif //! Initialization flags (Window, Video, All, etc.) FPL_ENUM_DECL_TYPE(InitFlags, uint32_t) { //! No init flags FPL_ENUM_DECL_VALUE(InitFlags, None, 0), //! Create a single window FPL_ENUM_DECL_VALUE(InitFlags, Window, 1 << 0), //! Create a video context FPL_ENUM_DECL_VALUE(InitFlags, Video, 1 << 1), //! Default init flags for a window + video FPL_ENUM_DECL_VALUE(InitFlags, All, FPL_ENUM_VALUE(InitFlags, Window) | FPL_ENUM_VALUE(InitFlags, Video)), }; 

  1 2 3 4 5 6 7 8 9 10  enum class InitFlags : uint32_t { //! No init flags None = 0, //! Create a single window Window = 1 << 0, //! Create a video context Video = 1 << 1, //! Default init flags for a window + video All = Window | Video, }; 

What do you think? This would make C++/11 optional and even not require any namespace. But the system code would be pretty ugly when using enums and namespace. This will also break the identitations entirely. :-(

In addition this code (in the enum declaration):

 1 FPL_ENUM_DECL_VALUE(InitFlags, All, FPL_ENUM_VALUE(InitFlags, Window) | FPL_ENUM_VALUE(InitFlags, Video)), 

wont compile at all :-(
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Edited by Finalspace on Nov. 21, 2017, 6:59 p.m. * Crap was written here
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Edited by Finalspace on Nov. 21, 2017, 7 p.m. Update v0.4.2 alpha: Added: [Linux] Started linux implementation Added: [Linux] Memory allocations Added: [Linux] Atomic operations Added: Check for C++/11 compiler and fail if not supported Added: Nasty vstudio 2015+ workaround to detect C++/11 Added: &= operator overloading for enums Changed: AtomicCompareAndExchange argument "comparand" and "exchange" flipped. Changed: constexpr is now fpl_constant to make clear what is a constant Removed: [Win32] CreateDIBSection is not needed for a software backbuffer Fixed: [Win32] Software rendering was not working properly. Fixed: Some AtomicCompareAndExchange signatures was still AtomicAndCompareExchange State/Planned: [Linux] Implement all non-window based functions [Linux] Implement XWindow + GLX [Linux] Implement Wayland + GLX [Win32] Use dynamic library for all the things, so you simple just link to kernel32.lib and thats it [Win32] DirectSound/XAudio2 audio output + api Still unsure/Questions: I dont like callers requiring C++/11 just for constexpr and enum class. Should i go back to C++ 199711? I still dont like the nested namespaces, its just a couple of functions and types right now, so one namespace maybe totally enough and this i could make optional if i want to. But i dont know... Would this project be suitable for handmade network?
 mrmixer Simon Anciaux 453 posts FPL - a single header platform abstraction c++ library 10 months ago I don't think it would be a good idea to change your library to be able to enable/disable those functionalities. It's your choice to use whatever feature and language version you like. Instead of namespaces I prefer to just put "ModuleName_" in front of a function or type name. I don't like enum class either for the reason you love them. The type checking often is in the way when you want to convert to/from int, which happens somewhat often in my case (also don't like the :: syntax). I don't know about constexpr (never used it). Once again, if those feature work for you, use them !
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Edited by Finalspace on Nov. 22, 2017, 6:33 a.m. mrmixer I don't think it would be a good idea to change your library to be able to enable/disable those functionalities. It's your choice to use whatever feature and language version you like. Instead of namespaces I prefer to just put "ModuleName_" in front of a function or type name. I don't like enum class either for the reason you love them. The type checking often is in the way when you want to convert to/from int, which happens somewhat often in my case (also don't like the :: syntax). I don't know about constexpr (never used it). Once again, if those feature work for you, use them ! Yeah i tried the normal enum style, but i really dont like them. Just the fact that enum values are always in global scope when not putting in into classes is just wrong. "enum class" is that feature, c++ should had from the very beginning even though its not perfect. It still cannot handle flags without manually overloading the operators - but you can specify the actual type which will be used which is nice as well. enum class: uint8_t is really a 8-bit enum and reserves no more memory than 1 byte. And you get proper type checking. Typecasting to integer works as well. constexpr is really nice, because formulas in them gets evaluated at compile time and can be immediatly seen in the IDE. But right now, the library does not use constexpr at all, because there are no const-expressions but rather constants. So a const static would totally be sufficient, good IDEs show the value for this as well when you mouse over it.
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 10 months ago Update v0.4.3 alpha (Big one): New: Introduced IsAtomicCompareAndExchange Added: [Linux] Implemented IsAtomicCompareAndExchange for all 32 and 64 bit integer types Added: [Win32] Implemented IsAtomicCompareAndExchange for all 32 and 64 bit integer types Added: [Win32] Loading gdi32.dll dynamically for ChoosePixelFormat, etc. Added: [Win32] Loading opengl32.dll dynamically for wglGetProcAddress, wglMakeCurrent, etc. Fixed: [Win32] Adding memory fence for AtomicReadWriteFence on non-x64 architectures Fixed: [Win32] Adding memory fence for AtomicReadFence on non-x64 architectures Fixed: [Win32] Adding memory fence for AtomicWriteFence on non-x64 architectures Fixed: Solidified descriptions for all Atomic*Fence Changed: Enabled FPL_FORCE_ASSERTIONS will ensure that C asserts are never used, because it may be compiled out. Changed: Removed all FPL_WIN32_ kernel32 macros and replaced it with normal calls. Changed: [Win32] Changed a lof ot the internals State/Planned: [Linux] Implement all non-window based functions [Win32] Use dynamic library for all the things, so you simple just link to kernel32.lib and thats it (Partially done) [Win32] DirectSound/XAudio2 audio output + api
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 9 months, 4 weeks ago Update v0.4.4 alpha: New: [Win32] Implemented argument parsing for WinMain and wWinMain Fixed: Corrected small things for doxygen Changed: Renamed CopyAFile to FileCopy Changed: Renamed DeleteAFile to FileDelete Note: Next update while take a while, because i want to get the linux implementation to the same level as the win32 implementation.
 mmozeiko Mārtiņš Možeiko 1789 posts / 1 project FPL - a single header platform abstraction c++ library 9 months, 4 weeks ago Edited by Mārtiņš Možeiko on Nov. 24, 2017, 1:40 a.m. Finalspace Implemented argument parsing for WinMain and wWinMain Windows has API that will do this for you: CommandLineToArgvW . Your code can be smaller, and less prone to bugs. This function will parse arguments in standard way how windows users expect it (escaping, quotes, whitespaces, ...).
 Finalspace 118 posts / 1 project I am finalspace and do programming since more than 25 years, started on C64 and got serious with borland delphi. Nowadays i use C/C++ only. FPL - a single header platform abstraction c++ library 9 months, 4 weeks ago Edited by Finalspace on Nov. 24, 2017, 9:09 a.m. mmozeiko Finalspace Implemented argument parsing for WinMain and wWinMain Windows has API that will do this for you: CommandLineToArgvW . Your code can be smaller, and less prone to bugs. This function will parse arguments in standard way how windows users expect it (escaping, quotes, whitespaces, ...). Well i have seen that function before, but there was no CommandLineToArgvA equivalent so i decided to write it myself. But when i think about it, i should rather convert the ansi source argument to a wide string and then call this function to safe me writing a full command line parser - which btw. is not that hard but time consuming as always. The only thing i always need to do is to convert the arguments back to UTF8. Anyway, thanks for that hint. In the next version i will use CommandLineToArgvW.
FPL - a single header platform abstraction c++ library
9 months, 4 weeks ago Edited by Finalspace on Nov. 24, 2017, noon

*Edit: I tried "CommandLineToArgvW" and it is just shit, why?

It returns the executable path splitted by spaces - which is just nonsense:

 1 2 3 0x00000000004a3680 L"C:\\Users\\Finalspace\\Documents\\Visual" 0x00000000004a36c4 L"Studio" 0x00000000004a36d2 L"2015\\Projects\\Whatever\\fgt\\demos\\bin\\FPL_OpenGL\\x64-Debug\\FPL_OpenGL.exe" 

How should i know which are the actual arguments and which are the executable path?

With the following arguments:

 1 "argument with space" escaped\"string_in_quotes\" -someoption 42 -o ..\relative path\to something\ 

I get 8 arguments:

 1 2 3 4 5 6 7 8 0x0000000000392148 L"argument with space" 0x0000000000392170 L"escaped\"string_in_quotes\"" 0x00000000003921a4 L"-someoption" 0x00000000003921bc L"42" 0x00000000003921c2 L"-o" 0x00000000003921c8 L"..\\relative" 0x00000000003921e0 L"path\\to" 0x00000000003921f0 L"something\\" 

At least forced quotes and escaping seem to work -.-

*Workaround: Call CommandLineToArgvW twice and the first time you concat the arguments to form the executable and the second time you start with the actual index the actual first argument starts... *sigh*

*Edit: Stupid tree vs forst... I take anything back, the first call gets the executable path only and the second call with arguments returns the actual arguments only.