Sign in to follow this  

FPL - a single header file platform abstraction library

Recommended Posts

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.
The main focus is game or simulation development, so you get a window and a rendering context plus Memory/IO/Threading and more.

 

Why a single header platform abstract library these days?

- There is not a single one out there, which do not require a ton of DLL´s or Libs just for the library itself.
- I dont want C-Runtime linking madness anymore
- Most are bloated and are far beyond abstracting the platform
- Bad or no control how memory is being handled
- There is no good single header platform abstraction library out there
- I dont want to write platform specific code anymore, just once for each platform with a fixed set of features and thats it.

- Debugging when you have issues with platform specific things is near impossible

 

Mindset:

- Its written in C++/98, so its much easier to get it compile and running on other platforms as well
- There is just a single header file you have to include and thats it
- Its full open source, so you can use and extend it however you want
- No data hiding in the code, you have control over everything
- Easy to use api
- Does not directly allocate any memory at all
- Uses just the built-in operating system functions/libraries and the C-Runtime library
- Works well with non platform-specific libraries as well (ImGUI, Box2D, etc.)
- Features can be compiled out as needed (Window, OpenGL, etc.)

- I want to debug everything if i want to without any hassle

- [Learning about low level operating system programming besides win32]

 

Features:

- Create/Handling a optional window
- Create a optional opengl rendering context on the window
- Memory allocation and deallocation
- Timing operations
- Threading
- File/Path IO
- Atomic operations
- Dynamic library loading (.dll / .so)
- Console out/in

- Gamepad input

 

Current state / Planned:

- Its not complete at all, buts its usable and works - so feedback is very appreciated
- Some API calls are weird, require more thinking or need to be simpler (fpl_ListFilesBegin, fpl_ListFilesNext, etc.)
- Only x86/x64 win32 platform for now

- Support for Direct2D/3D/Vulcan (Only to get it up and running)
- Audio output (XAudio, ALSA)
- Good useful automated testing
- More Guides and Samples
- More Platforms (Linux/Unix, maybe Android not sure)
- More compiling out options (Some prefer the C++ standard template library or other libraries)
- Moving utility functions into its own library which have nothing todo with the platform (fpl_ExtractFileName, fpl_RemoveEmptyDirectory)
- Let the user allocate memory for storing platform input events as well

 

Issues:

- Will not work with any other platform abstraction libraries, because they all do magic stuff with entry points and such - so they gets in the way

 

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, etc. All constructive non hating comments are welcome!

 

Greetings,
Final

Edited by Finalspace

Share this post


Link to post
Share on other sites

I skimmed your code and there are two (maybe three) things that stuck out to me.

#define FPL_NULL 0

This is not how you should be defining NULL. Either use (void*)0 or nullptr if C++11 is available.

#if !FPL_ENABLE_C_RUNTIME_LIBRARY
void __stdcall WinMainCRTStartup() {
    int result = wWinMain(GetModuleHandleW(0), 0, 0, 0);
    ExitProcess(result);
}
#endif // !FPL_ENABLE_C_RUNTIME_LIBRARY

I read your comment further up the file about how you hate the CRT, but this is clearly taking it too far. I'll quote a section of ExitProcess()'s documentation:

Quote

Calling ExitProcess in a DLL can lead to unexpected application or system errors. Be sure to call ExitProcess from a DLL only if you know which applications or system components will load the DLL and that it is safe to call ExitProcess in this context.

And that's pretty much the point at which I stopped reading your code. Parts of it looked good, other parts looked really, really bad. A more important question to me is: Who needs this? Why does this exist? All of this stuff is already available in other libraries or game frameworks.

As a side note, why are people writing more and more of these "header only" libraries? The preprocessor seems like a flimsy way to configure how your code should compile. A more solid solution is to use a proper build system.

Share this post


Link to post
Share on other sites
51 minutes ago, TheComet said:

I skimmed your code and there are two (maybe three) things that stuck out to me.


#define FPL_NULL 0

This is not how you should be defining NULL. Either use (void*)0 or nullptr if C++11 is available.


#if !FPL_ENABLE_C_RUNTIME_LIBRARY
void __stdcall WinMainCRTStartup() {
    int result = wWinMain(GetModuleHandleW(0), 0, 0, 0);
    ExitProcess(result);
}
#endif // !FPL_ENABLE_C_RUNTIME_LIBRARY

I read your comment further up the file about how you hate the CRT, but this is clearly taking it too far. I'll quote a section of ExitProcess()'s documentation:

And that's pretty much the point at which I stopped reading your code. Parts of it looked good, other parts looked really, really bad. A more important question to me is: Who needs this? Why does this exist? All of this stuff is already available in other libraries or game frameworks.

As a side note, why are people writing more and more of these "header only" libraries? The preprocessor seems like a flimsy way to configure how your code should compile. A more solid solution is to use a proper build system.

I tried FPL_NULL (void *)0 - but i had trouble with it, so i simply set it to zero. But yes i agree, using nullptr on C++/11 would be better, but how do i detect if C++/11 is available - through preprocessor directives? Btw. FPL_NULL is internal only, so its not meant to be used outside.

 

That entire no CRT thing - i am not sure about this. Its a experiment to see if it works, because some people dont want to include even the C-Runtime Library at all. Also regards DLL´s and ExitProcess and need to think it more, as a matter of fact i havent created a library project yet - but this will come soon. When i see that no-CRT is support is too complicated, i will drop it. Right know i dont see any benefit disabling CRT, except for smalling out the executable size.

 

Why header library only? Because its simple and works all the time. No linking madness, no dll´s needed - besides from the standard system operating stuff which is included anyway.

 

Regards build-systems: I dont like build-systems at all, all i ever used was just awful: Slow, hard to configure, not working -> On any programming language the same bad experience.

But what i will do for sure, is making several simple build scripts (Batch, Shell) which just builds the samples in the simplest possible way for a set of compilers/platforms.

Edited by Finalspace

Share this post


Link to post
Share on other sites
Quote

That entire no CRT thing - i am not sure about this. Its a experiment to see if it works, because some people dont want to include even the C-Runtime Library at all. 

I do not know a person or a product that does not link with CRT. Starting form small games, 3D DCCs, even some "serious software" uses it.
 

Quote

Why header library only? Because its simple and works all the time. No linking madness, no dll´s needed - besides from the standard system operating stuff which is included anyway.

A header and a *.cpp is equally simple to me.
 

#define fpl_globalvar static
#define fpl_inline inline
#define fpl_internal static
#if FPL_API_AS_PRIVATE
#    define fpl_api static
#else
#    define fpl_api extern

This is unnecessary code to me, it doesn't tell much to the reader and these have no functional benefit, actually it is wrong:
if I "fpl_globalvar int x;" in a *.cpp this will actually make the variable "private" to that *.cpp, making it inaccessible to other files.

Share this post


Link to post
Share on other sites
40 minutes ago, ongamex92 said:

I do not know a person or a product that does not link with CRT. Starting form small games, 3D DCCs, even some "serious software" uses it.
 

A header and a *.cpp is equally simple to me.
 


#define fpl_globalvar static
#define fpl_inline inline
#define fpl_internal static
#if FPL_API_AS_PRIVATE
#    define fpl_api static
#else
#    define fpl_api extern

This is unnecessary code to me, it doesn't tell much to the reader and these have no functional benefit, actually it is wrong:
if I "fpl_globalvar int x;" in a *.cpp this will actually make the variable "private" to that *.cpp, making it inaccessible to other files.

Insomniac Games and EA for example do not use the C standard library, they even dont use the STL.

Also there are others people in the industry who do not use the C standard library as well.

For myself, i dont care but its great when you have the option to not need to ship the C Runtime with your game (VC++ redist for example).

 

Static has more than one meaning, private scope for this file only, local persisting state, global variable, class field in c++, etc. Even though it just mean: Private in this file only. Techniqually there are no differences between all of them, but this way you see right away which scope its meant to be in.

 

Right, there are no difference between header and source files. C++ has no definition of a file, you just have translation units which gets compiled to object files - thats it. I dont want to force users to have a separate translation unit, just for the library - if they want, they can have one but its not required.

Edited by Finalspace

Share this post


Link to post
Share on other sites

I will definitely have a look at it but as most other people might, I have those platform specific stuff already build into my game engine from the beginning. Platform detection for PC and propably Console, Threads, Locking, Atomics, Extensions (via LoadLibrary and similar) and even a Window class as same as some graphics API dependent startup code

Share this post


Link to post
Share on other sites

New version:

 

- Dropped C support

- Dropped No-C-Runtime support

- Removed all FPL prefixes from functions and types

- Moved to a more c++ ish api (Namespaces, const reference, enum class, constexpr, nullptr)

- Nested namespaces to categorize certain things (window, memory, strings, atomics, threading, etc.)

Edited by Finalspace

Share this post


Link to post
Share on other sites
On 6.10.2017 at 9:04 PM, ferreiradaselva said:

You need a reference doc

If you add something like this https://github.com/ferreiradaselva/cgdfw/blob/master/REFERENCE.md  it will make things much easier.

Thanks i will do that - good idea!

Is there a way to export all my api structs and functions into that automatically?

Never mind, i will write a command line tool which does that.

Edited by Finalspace

Share this post


Link to post
Share on other sites

Monster Update:

  • Added memory::CopyMemory
  • Added fpl::GetLastError and fpl::GetLastErrorCount for proper error handling
  • Added files::CreateBinaryFile and files::OpenBinaryFile for wide file paths
  • Added basic support for creating a modern opengl rendering context, see VideoCompabilityProfile in VideoSettings
  • Added support for enabling opengl vsync through WGL
  • Returns char * for all paths:: get like functions
  • Returns char/wchar_t * for all strings:: functions
  • Fixed files::CreateBinaryFile was never able to overwrite the file.
  • Fixed #include was in some namespaces defined
  • Fixed files::ClearMemory was wrong
  • Replaced all const constants with constexpr
  • Removed template code / Replaced it with macros
     

Share this post


Link to post
Share on other sites

Update:

  • All types/structs/fields/functions documented
  • [Win32] Fixed legacy opengl (GL_INVALID_OPERATION)
  • [Win32] Support for WGL opengl profile selection

 

Todo:

  • Create full reference.md documentation / upload doxygen documentation.
  • Win32 audio output + api
  • Win32 threading + api
  • Win32 clipboard get/set

Share this post


Link to post
Share on other sites

Update:

  • Renamed: All memory/library/threading functions
  • Renamed: CopyFile/DeleteFile renamed (Stupid win32!)
  • Renamed: All internal opengl defines renamed, so that it wont conflict with other libraries
  • Fixed: [Win32] strings::All Wide conversions was not working properly
  • Removed: [Win32] All undefs removed
  • Changed: [Win32/OpenGL] Check for already included gl.h
  • Added: Basic threading creation and handling

Todo:

  • Create full reference.md documentation / upload doxygen documentation.
  • Win32 audio output + api
  • Win32 mutex / condition + api
  • Win32 clipboard get/set
  • Linux platform support
Edited by Finalspace

Share this post


Link to post
Share on other sites

Update v0.4.0 alpha:

  • Changed: All FPL_ENABLE_ defines are internal now, the caller must use FPL_NO_ or FPL_YES_ respectivily.
  • Changed: AtomicCompareExchange is now AtomicCompareAndExchange
  • Changed: InitFlags::VideoOpenGL is now InitFlags::Video
  • Added: Software rendering support
  • Added: VideoDriverType enumeration for selecting the active video driver
  • Added: video::GetVideoBackBuffer with [Win32] implementation
  • Added: video::ResizeVideoBackBuffer with [Win32] implementation
  • Added: FPL_PETABYTES macro
  • Added: FPL_EXABYTES macro
  • Added: FPL_ZETTABYTES macro
  • Added: FPL_YOTTABYTES macro
  • Added: FPL_MIN macro
  • Added: FPL_MAX macro
  • Added: MutexCreate with [Win32] implementation
  • Added: MutexDestroy with [Win32] implementation
  • Added: MutexLock with [Win32] implementation
  • Added: MutexUnlock with [Win32] implementation
  • Added: SignalCreate with [Win32] implementation
  • Added: SignalDestroy with [Win32] implementation
  • Added: SignalWait with [Win32] implementation
  • Added: SignalWakeUp with [Win32] implementation
  • Added: GetClipboardAnsiText with [Win32] implementation
  • Added: GetClipboardWideText with [Win32] implementation
  • Added: SetClipboardText with [Win32] implementation for ansi and wide strings
  • Added [MSVC]: AtomicExchangeS32 (Signed integer)
  • Added [MSVC]: AtomicExchangeS64 (Signed integer)
  • Added [MSVC]: AtomicAddS32 (Signed integer)
  • Added [MSVC]: AtomicAddS64 (Signed integer)
  • Added [MSVC]: AtomicCompareExchangeS32 (Signed integer)
  • Added [MSVC]: AtomicCompareExchangeS64 (Signed integer)
  • Fixed [MSVC]: AtomicExchangeU32 was not using unsigned intrinsic
  • Fixed [MSVC]: AtomicExchangeU64 was not using unsigned intrinsic
  • Fixed [MSVC]: AtomicAddU32 was not using unsigned intrinsic
  • Fixed [MSVC]: AtomicAddU64 was not using unsigned intrinsic
  • Fixed [MSVC]: AtomicCompareExchangeU32 was not using unsigned intrinsic
  • Fixed [MSVC]: AtomicCompareExchangeU64 was not using unsigned intrinsic
  • Implemented [Win32]: GetProcessorCoreCount
  • Implemented [Win32]: Main thread infos
  • Performance [Win32]: GetProcessorName (3 loop iterations at max)

State:

Its almost feature complete for Win32, only audio output is missing.

Next i will clean up all the ifdef madness to get a more clean code structure - so i have a single ifdef block for each platform/backend. Also i am thinking about removing the sub namespaces, just because its so much useless typing for no reason.

Edited by Finalspace

Share this post


Link to post
Share on other sites

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 implementing the linux platform.

Share this post


Link to post
Share on other sites

Is this a discussion about this repo of yours? https://github.com/f1nalspace/final_game_tech

Some small remarks:

  • You can create releases via Github (e.g. v0.4.1) which are just Git tags.
  • Why warning level W3 instead of W4?
Edited by matt77hias

Share this post


Link to post
Share on other sites
7 minutes ago, matt77hias said:

Is this a discussion about this repo of yours? https://github.com/f1nalspace/final_game_tech

Some small remarks:

  • You can create releases via Github (e.g. v0.4.1) which are just Git tags.
  • Why warning level W3 instead of W4?

This thread is for annoncing new releases only, so its appreciated to create a seperate thread for discussions.

But thanks for the tip with the releases, i will try to do that. Seems i have forget about that entirely, since i am using another version control system at work...

What do you mean with warning level 3 instead of 4? (Visual Studio Project configuration?)

Edited by Finalspace

Share this post


Link to post
Share on other sites
15 minutes ago, Finalspace said:

What do you mean with warning level 3 instead of 4? (Visual Studio Project configuration?)

Yes. (This is of course not an issue for your users, just noticed it in the Visual Studio files.)

16 minutes ago, Finalspace said:

This thread is for annoncing new releases only, so its appreciated to create a seperate thread for discussions.

My apologies. Didn't know.

Share this post


Link to post
Share on other sites

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
  • [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:

  • I dont like callers requiring C++/11 just for constexpr and enums, should i go back to C++ 1997/11?
  • I still dont like the nested namespaces, its just a couple of functions and types, one namespace is enough and this i could make optional if i want to. But i dont know...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Forum Statistics

    • Total Topics
      628633
    • Total Posts
      2983957
  • Similar Content

    • By _Engine_
      Atum engine is a newcomer in a row of game engines. Most game engines focus on render
      techniques in features list. The main task of Atum is to deliver the best toolset; that’s why,
      as I hope, Atum will be a good light weighted alternative to Unity for indie games. Atum already
      has fully workable editor that has an ability to play test edited scene. All system code has
      simple ideas behind them and focuses on easy to use functionality. That’s why code is minimized
      as much as possible.
      Currently the engine consists from:
      - Scene Editor with ability to play test edited scene;
      - Powerful system for binding properties into the editor;
      - Render system based on DX11 but created as multi API; so, adding support of another GAPI
        is planned;
      - Controls system based on aliases;
      - Font system based on stb_truetype.h;
      - Support of PhysX 3.0, there are samples in repo that use physics;
      - Network code which allows to create server/clinet; there is some code in repo which allows
        to create a simple network game
      I plan to use this engine in multiplayer game - so, I definitely will evolve the engine. Also
      I plan to add support for mobile devices. And of course, the main focus is to create a toolset
      that will ease games creation.
      Link to repo on source code is - https://github.com/ENgineE777/Atum

    • By Giannis Marinakis
      Hello everyone!
      I have a GitHub repository on which I'm developing a Open Network Library for Java Developers and I'd like to share it so more people come in and contribute. Till now the repo is being developed only by me so the library is not 100% bug free. I'd really like this repo to be famous and got people working on it!
      [You will find more information in the repo]
      Here's the link for the repo: https://github.com/giannismarinakis/java-open-nl
      Thanks!
    • By swiftcoder
      Pictured are outputs of the Marching Cubes algorithm (left), and surface reconstruction via 'Deferred Rasterisation' (right).
      These are examples from a little library I wrote for Rust, that provides various implementations of isosurface extraction from volume data. You can find the Apache-2.0 licensed source code on github, or the Rust package on crates.io.
    • By Effekseer
      Effekseer Project develops "Effekseer," which is visual software for creating open source games; on November 1, I released "Effekseer 1.3," which is the latest major version release. With Effekseer, you can easily create various visual effects simply by specifying different parameters.
       
      Effekseer is a tool to create various visual effects used in games and others. You can create various visual effects such as explosion, light emission, and particles. Effekseer's effect creation tool works only on Windows. However, the created visual effects can be viewed on Mac OS X, Linux, iOS, Android, and other environments using plugins runtime / plugins such as DirectX, OpenGL, and Unity.
      Effekseer 1.3 is an updated version of Effekseer 1.2 released in June 2016.
      This update contains the following changes:
      -Addition of a file viewer that makes it easy to manage effect files;
      -Improvements in UI such as adding icons for easy understanding of editing status;
      -Addition of a function to read FBX as a 3D model file;
      -Addition of parameters for easier control of the effects.
      In addition to Unity, I have added plugins / libraries to UnrealEngine 4 and Cocos2d-x.
      This makes it possible to play effects in most major development environments.Besides that, more than 70 new sample effects have been added and many bugs have been fixed.
      Effekseer 1.3 is available on the project website.
      The license for the software is the MIT license.

      Effekseer 
      http://effekseer.github.io/

      Github
      https://github.com/effekseer/Effekseer
       
       

      View full story
    • By Effekseer
      Effekseer Project develops "Effekseer," which is visual software for creating open source games; on November 1, I released "Effekseer 1.3," which is the latest major version release. With Effekseer, you can easily create various visual effects simply by specifying different parameters.
       
      Effekseer is a tool to create various visual effects used in games and others. You can create various visual effects such as explosion, light emission, and particles. Effekseer's effect creation tool works only on Windows. However, the created visual effects can be viewed on Mac OS X, Linux, iOS, Android, and other environments using plugins runtime / plugins such as DirectX, OpenGL, and Unity.
      Effekseer 1.3 is an updated version of Effekseer 1.2 released in June 2016.
      This update contains the following changes:
      -Addition of a file viewer that makes it easy to manage effect files;
      -Improvements in UI such as adding icons for easy understanding of editing status;
      -Addition of a function to read FBX as a 3D model file;
      -Addition of parameters for easier control of the effects.
      In addition to Unity, I have added plugins / libraries to UnrealEngine 4 and Cocos2d-x.
      This makes it possible to play effects in most major development environments.Besides that, more than 70 new sample effects have been added and many bugs have been fixed.
      Effekseer 1.3 is available on the project website.
      The license for the software is the MIT license.

      Effekseer 
      http://effekseer.github.io/

      Github
      https://github.com/effekseer/Effekseer
       
       
  • Popular Now