Final Platform Layer»Blog

I am back - new release 0.9.4

Hi there,

after a very long break, i am finally back - fully well and very motivated to code ;)
For people wo didn´t knew: i had several health & private issues in the last year, so i couldn´t do any private coding at all - resulting in putting FPL to a freezing state. But now everything is fine and i already changed it back to active, so lets get down to some business shall we?

New version 0.9.4

Its here, i have another release of FPL for you all!
This time its a huge update, with tons bugfixes, lots of internal changes, new stuff and improvements in almost every area. Its really a lot, so i had to categorize it for you for a better overview.

https://github.com/f1nalspace/final_game_tech

Multithreading:

I added functions for getting and setting the thread priority and retrieving the current thread/id.
Also i added functions for atomically incrementing integrals, such as u/int64, u/int32 and fplAtomicAddAndFetch* has now a addend argument as well (Was missing somehow). The signature of fplThreadWaitFor() had to be extended by a stride parameter - to support user structs as well. This way you can also have your fplThreadHandle ** in structs ;)

Hardware

I want to get more into SIMD programming, so i added lots of stuff in FPL to prepare for that.
Naming a few, there is now: fplRDTSC(), fplGetProcessorCapabilities(), fplCPUID(), fplGetXCR0() and more.
Some are x86 only, so it will only return useful values when you are on a x86 platform.

Memory:

To support drag & drop for more than one file, i added support for allocating and freeing dynamic memory with the nice ability to be fully controllable by the user. See fplMemorySettings for more details.

Input

I simply added device names for gamepads, to support multiple game controllers. For XInput, its a fixed string for each index of the gamepad and for linux its just the device name.
Not great, but works for now. Maybe in the future, we find a way to actually query the real device name. Oh you can now check if the controller is active or not. To see this in actual use, you are invited to run the demos: FPL_Input and FPL_Crackout. Also i added a function for disabling any input handling in window events -> fplSetWindowInputEvents()

New macros/detections:

As you know or not know, FPL makes heavy use of macros to detect everything - even a toaster. Okay its a joke, toasters are not detected yet - but we now have:

- fplIsBitSet(), fplHasInclude(), fplAlwaysAssert(), fpl_no_inline
- FPL_WARNING, FPL_IS_IDE
- Detecting of 32 and 64-bit PPC
- The CPU size detection is now independent from the CPU architecture detection

IDE intellisense detection

In visual studio, CLion or QT-Creator sometimes while doing debugging in FPL, i dont see the FPL_IMPLEMENTATION block in the editor - resulting in graying out the code and not parsing it at all. This is really bad, so i added support to detect the usage of intellisense or other editor specific macros etc. Therefore we now have FPL_IS_IDE, a boolean to identify if FPL is using some sort code parsing thingy.
Right know, its tested and working for visual studio and CLion only - but it may work on other IDEs, who knows.

Windowing

I removed the fake thread-safe event queue and replaced it with a normal one - because the window management in FPL is executed on the main thread only, so there was no need for it anyway.

Raspberry Pi (arm32):

To learn and test more other platforms, i bought a raspberry pi 4 and after a bit of fiddling in FPL, everything was compiling and running just fine in the ARM32 environment ;) Of course, it was not perfect. The audio system was barely working and some systems, was not working at all - so i still have to do some adjustments and fixes to get in a reasonable state. But for the most part, it was surprisingly working really well - including running all the OpenGL demos and games. I definitly will work on this platform more and add a proper FPL_PLATFORM_RASPBERRYPI in the future ;)

I would really hope, to get more feedback on this - so if you have a raspberry pi, please give it a try and give me some feedback, thanks!

Linux/Unix:

I havent booted linux for a very long time, so most new stuff are implemented for win32 only - but i am planning to implement it for POSIX/Linux/Unix as well, so stay tuned for that.

But if you are an expert in Linux or UNIX programming and want to support this project - please contact me!
I am working on FPL in my spare time only, so i appreciate any help for getting the linux/unix parts finished as well. Thanks!

Improvements:

In previous FPL versions, all enums to string conversions was using either string comparisons or switch statements.
Now most of this conversions use a nametable now, which may improve performance a little bit ;)

Bugfixes:

In addition i fixed several bugs, which i found while testing - especially in the process of getting the raspberry pi running.

Documentations:

I improved the documentations a lot and documented more things, but its still not finished yet. If you want to support this project - i highly appreciate any help in writing documentations.

Demos:

All the demo makefiles are updated to compile demos with GCC as well.

FFMPEG:
- Added text-rendering, so we now have a OSD showing all the relevant infos (Time, Frames, Media, etc.).
- Relative seeking to support jumping back and forth in the video.

Audio:
- Disabled sample rendering, due to wrongness of its output

OpenGL:
- Now we render a rotated triangle in 3D instead of the boring 2D triangle

Software:
- Render less random pixels
- Drawing lines and a moving rectangle

Presentation (New):

I added a experimental demo, which can render custom written presentations in a similar way than powerpoint, but much simpler.
Its not complete yet, because i have no support for saving or loading a presentation - so everything is generated by code only, but i will implement it when i have a good idea how i want these to be stored.

More?

Of course there are many more additions and fixes, but too much to descripe here. See the changelog for details.

Todo/Planned

Even though we have the corona situation, i still have not that much time to work on my private projects - because i work at full time from home, with jumping kids around - so i will not planning much ahead this time.

But there are definitly things i want to implement for the next releases:

- Fixing all the string functions -> Return the number of characters modified instead of returning the useless start pointer
- Changing the audio system to support different buffer sizes -> to support different platforms and/or audio devices (Important for raspberry pi!)
- Making fullscreen windowing much simpler (Removing refresh rate support, No more custom positions, Only desktop or custom monitor)
- Adding functions for getting and setting environment variables
- Better naming for time query functions (fplTimePrecision enum)
- Correct naming style everywhere -> fpl[Get/Set/Add/Init, etc.][ModuleName][Function]
- Correct order of arguments everywhere -> Input first, than output with exceptions for VARG functions
- Change input key translation functions from a switch to a table instead
- Query CPU informations from /proc/cpu on non-x86 platforms
- Finishing up important functions in X11 (Clipboard, Cursor, Query of displays)
- Use ImGUI more to test hardware info querying and windowing stuff

And for future releases:

- Adding TCP/UDP networking support (May come sooner than later)
- Adding Vulkan support (May come sooner than later)
- Adding WASAPI support
- Adding PulseAudio support

Your support!

I cannot improve FPL without any feedback! So if you want to help me making it better - you are welcome to send me in any feedback.
The best thing you can do, is to clone the git repository, compile the demos and run all of it. If you find issues or have questions, dont hesitate - just drop a message in the forum!



As usual, the develop branch was merged into the master branch and is now tagged as "0.9.4".

Thank you,
have a nice day,
stay tuned for the next release ;-)

Cheers!

Here are the full changelog:

## v0.9.4 beta
- New: Added callbacks fpl_memory_allocate_callback & fpl_memory_release_callback
- New: Added enum fplMemoryAllocationMode
- New: Added struct fplMemoryAllocationSettings
- New: Added struct fplMemorySettings for controlling dynamic and temporary memory allocations
- New: Added enum fplThreadPriority
- New: Added function fplGetThreadPriority
- New: Added function fplSetThreadPriority
- New: Added function fplGetCurrentThreadId
- New: Introduced dynamic/temporary allocations wrapping
- New: Added FPL_WARNING macro for pushing on warnings only
- New: Print out function name and line number in all log outputs
- New: Added functions fplAtomicIncrement* used for incrementing a value by one atomically
- New: Added macro fplRDTSC
- New: Added struct fplProcessorCapabilities
- New: Added function fplGetProcessorCapabilities
- New: Added macro fplIsBitSet
- New: Added function fplGetMainThread
- New: Added field isActive to struct fplGamepadState
- New: Added field deviceName to struct fplGamepadState and fplGamepadEvent
- New: Added function fplSetWindowInputEvents
- New: Added struct fplCPUIDLeaf
- New: Added function fplCPUID and implemented it for X86/X64
- New: Added function fplGetXCR0 and implemented it for X86/X64
- New: Added macro fplHasInclude
- New: Added power-pc 32/64 architecture detection
- New: Added storage class identifier fpl_no_inline
- New: Added macro fplAlwaysAssert()
- New: Added function fplIsPlatformInitialized()
- New: Added FPL_IS_IDE macro for checking if any source editor is active.
- New: [MSVC] Always show implementation block when FPL_IS_IDE is set

- Fixed: Corrected opengl example code in the header file
- Fixed: Tons of documentation improvements
- Fixed: fpl__PushError_Formatted was always pushing errors on regardless of the log level
- Fixed: Invalid memory clear with zero bytes, when there was no audio samples to clear
- Fixed: All non inlineable functions changed from fpl_internal_inline to fpl_internal instead (GCC/Clang compatible)
- Fixed: Use actual window size for video initialization always instead of fixed size
- Fixed: fplAtomicAddAndFetch* had no addend parameter
- Fixed: All non-tab spacings replaced with tab spacings
- Fixed: ARM64 was not detected properly
- Fixed: Atomics was not detected for ICC (Intel C/C++ Compiler)

- Changed: Removed fake thread-safe implementation of the internal event queue
- Changed: Changed drop event structure in fplWindowEvent to support multiple dropped files
- Changed: Renamed fplGetPlatformTypeString() to fplGetPlatformName()
- Changed: Added stride to fplThreadWaitForAll() to support custom sized user structs
- Changed: Added stride to fplThreadWaitForAny() to support custom sized user structs
- Changed: Added stride to fplSignalWaitForAll() to support custom sized user structs
- Changed: Added stride to fplSignalWaitForAny() to support custom sized user structs
- Changed: Set audio worker thread to realtime priority
- Changed: Use name table for fplArchType to string conversion
- Changed: Use name table for fplPlatformType to string conversion
- Changed: Use name table for fplPlatformResultType to string conversion
- Changed: Use name table for fplVideoDriverType to string conversion
- Changed: Use name table for fplAudioDriverType to string conversion
- Changed: Use name table for fplAudioFormatType to string conversion
- Changed: Use name table for fplLogLevel to string conversion
- Changed: Values for fplPlatformResultType changed to be ascending
- Changed: Moved fplInitFlags_All constant to fplInitFlags enum
- Changed: CPU size detection is now independent from CPU architecture detection
- Changed: fplGetProcessorName moved to common section with fallback to not supported architectures
- Changed: Removed wrong compiler detection for LLVM (Clang is LLVM)
- Changed: Removed pre-spaces from all code documentation comments
- Changed: Changed from default audio sample rate of 48000 to 44100
- Changed: Moved compiler includes into its own section
- Changed: Moved rdtsc/cpuid, etc. into the implementation block
- Changed: Renamed enum fplAudioResult to fplAudioResultType
- Changed: Use fplLogLevel_Warning as max by default for all log functions
- Renamed function fplGetAudioFormatString to fplGetAudioFormatTypeString

- New: [Win32] Implemented function fplGetCurrentThreadId
- New: [Win32] Support for multiple files in WM_DROPFILES
- New: [Win32] Implemented fplGetThreadPriority
- New: [Win32] Implemented fplSetThreadPriority
- New: [Win32/Linux] Implemented isActive field for fplGamepadState for state querying, indicating any buttons are pressed or triggers have been moved
- New: [Win32/XInput] Fill out the deviceName in fplGamepadState and fplGamepadEvent -> Generic name for now
- New: [POSIX/Win32] Implemented functions fplAtomicIncrement*
- New: [Linux/ALSA] Print compiler warning when alsa include was not found
- New: [X11] Implemented fplSetWindowDecorated
- New: [X11] Implemented fplIsWindowDecorated

- Fixed: [Win32] Fixed missing WINAPI keyword for fpl__Win32MonitorCountEnumProc/fpl__Win32MonitorInfoEnumProc/fpl__Win32PrimaryMonitorEnumProc
- Fixed: [Win32] Software video output was not outputing the image as top-down
- Fixed: [Win32/X11] Mouse wheel delta message is not ignored anymore
- Fixed: [X11] Fixed software video output (was broken)
- Fixed: [POSIX] Moved __sync_synchronize before __sync_lock_test_and_set in fplAtomicStore*
- Fixed: [POSIX/Win32] fplAtomicAddAndFetch* uses now addend parameter
- Fixed: [Linux] Previous gamepad state was not cleared before filling in the new state
- Fixed: [X11] Gamepad controller handling was broken

- Changed: [POSIX] Use __sync_add_and_fetch instead of __sync_fetch_and_or in fplAtomicLoad*
- Changed: [POSIX/Win32] When a dynamic library failed to load, it will push on a warning instead of a error
- Changed: [POSIX/Win32] When a dynamic library procedure address failed to retrieve, it will push on a warning instead of a error
- Changed: [POSIX/Win32] Reflect api changes for fplThreadWaitForAll()
- Changed: [POSIX/Win32] Reflect api changes for fplThreadWaitForAny()
- Changed: [POSIX/Win32] Reflect api changes for fplSignalWaitForAll()
- Changed: [POSIX/Win32] Reflect api changes for fplSignalWaitForAny()
- Changed: [X86/X64] fplGetProcessorName are only enabled on X86 or X64 architecture
- Changed: [X86/X64] fplGetProcessorCapabilities are only enabled on X86 or X64 architecture
- Changed: [MSVC] Implemented fplCPUID/fplGetXCR0 for MSVC
- Changed: [GCC/Clang] Implemented fplCPUID/fplGetXCR0 for GCC/Clang
- Changed: [Win32] Input events are not flushed anymore, when disabled
Simon Anciaux, Edited by Simon Anciaux on
Welcome back. Glad to see you're ok.

There are a few title markup issues in the post ( Linux/Unix:, Improvements:, Bugfixes:, Documentations: ).

I looked a little bit in the code:
- in fplAlwaysAssert() instead of using *( int* ) 0 = 0; you could use __debugbreak(); This will cause a debugger to break but will also let you continue just by using any stepping function.
- FPL_WARNING isn't defined anywhere in final_platform_layer.h
mrmixer
Welcome back. Glad to see you're ok.

There are a few title markup issues in the post ( Linux/Unix:, Improvements:, Bugfixes:, Documentations: ).

I looked a little bit in the code:
- in fplAlwaysAssert() instead of using *( int* ) 0 = 0; you could use __debugbreak(); This will cause a debugger to break but will also let you continue just by using any stepping function.
- FPL_WARNING isn't defined anywhere in final_platform_layer.h


Ah thanks for the hints:

- I fixed the markup types ;)
- There is a reason why fplAlwaysAssert() does just a null pointer assignment -> Debug break does not work anymore, when you are in release mode. Always assert should always assert, regardless if optimized/release mode or not. Therefore i dont use debug break there.
- And yes you are right, there is no FPL_WARNING... but there is FPL__WARNING, which is internal only - not sure why i put it on the changelog O_o
Simon Anciaux,
In a simple test on Windows with Visual Studio 2017 and compiling with /O2, __debugbreak( ); still triggers a breakpoint.
Mārtiņš Možeiko,
- There is a reason why fplAlwaysAssert() does just a null pointer assignment -> Debug break does not work anymore, when you are in release mode. Always assert should always assert, regardless if optimized/release mode or not. Therefore i dont use debug break there.

What is "release mode" in your opinion? Typically by "release mode" people mean enabled optimizations. But __debugbreak() is intrinsic that generates "int3" instruction. Always. Regardless of optimizations. Just like __nop() will generate "nop" instruction, or "_mm_sqrt_ps" will "sqrtps" instruction. And int3 will create fake breakpoint that debuggers will catch it.