Permalink
79f7164 Oct 14, 2018
2 contributors

Users who have contributed to this file

@f1nalspace @Manuzor
18538 lines (16908 sloc) 707 KB
/*
final_platform_layer.h
-------------------------------------------------------------------------------
About
-------------------------------------------------------------------------------
Final Platform Layer is a Single-Header-File cross-platform C development library designed to abstract the underlying platform to a simple and easy to use api - providing low level access to (Window, Video, Audio, Input, File/Path IO, Threads, Memory, Hardware, etc.).
The main focus is game/media/simulation development, so the default settings will create a window, setup a OpenGL rendering context and initialize audio playback on any platform.
It is written in C99 for simplicity and best portability, but is C++ compatible as well.
FPL supports the platforms Windows/Linux/Unix for the architectures x86/x64.
The only dependencies are built-in operating system libraries and a C99 complaint compiler.
It is licensed under the MIT-License. This license allows you to use FPL freely in any software.
-------------------------------------------------------------------------------
Getting started
-------------------------------------------------------------------------------
- Drop this file into any C/C++ projects you want and include it in any place you want
- In your main translation unit provide the typical main() entry point
- Define FPL_IMPLEMENTATION in at least one translation unit before including this header file
- Init the platform using fplPlatformInit()
- Use the features you want
- Release the platform when you are done using fplPlatformRelease()
-------------------------------------------------------------------------------
Usage: Hello world console application
-------------------------------------------------------------------------------
#define FPL_IMPLEMENTATION
#include <final_platform_layer.h>
int main(int argc, char **args){
if (fplPlatformInit(fplInitFlags_None, fpl_null)) {
fplConsoleOut("Hello World!");
fplPlatformRelease();
return 0;
} else {
return -1;
}
}
-------------------------------------------------------------------------------
Usage: OpenGL legacy or modern application
-------------------------------------------------------------------------------
#define FPL_IMPLEMENTATION
#include <final_platform_layer.h>
int main(int argc, char **args){
fplSettings settings;
fplSetDefaultSettings(&settings);
fplVideoSettings videoSettings = settings.video;
videoSettings.driver = fplVideoDriverType_OpenGL;
// Legacy OpenGL
videoSettings.opengl.compabilityFlags = fplOpenGLCompabilityFlags_Legacy;
// or
// Modern OpenGL
videoSettings.opengl.compabilityFlags = fplOpenGLCompabilityFlags_Core;
videoSettings.opengl.majorVersion = 3;
videoSettings.opengl.minorVersion = 3;
if (fplPlatformInit(fplInitFlags_Video, &settings)) {
// Event/Main loop
while (fplWindowUpdate()) {
// Poll events
fplEvent ev;
while (fplPollEvent(ev)) {
/// ...
}
// your code goes here
fplVideoFlip();
}
fplPlatformRelease();
return 0;
} else {
return -1;
}
}
-------------------------------------------------------------------------------
License
-------------------------------------------------------------------------------
Final Platform Layer is released under the following license:
MIT License
Copyright (c) 2017-2018 Torsten Spaete
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*!
@file final_platform_layer.h
@version v0.9.2.0 beta
@author Torsten Spaete
@brief Final Platform Layer (FPL) - A C99 Single-Header-File Platform Abstraction Library
*/
// ----------------------------------------------------------------------------
// > CHANGELOG
// ----------------------------------------------------------------------------
/*!
@page page_changelog Changelog
@tableofcontents
## v0.9.2.0 beta
- Changed: Removed "Ansi" part from all ansi functions
- Changed: Debug/Release user define is always prefered
- Changed: Properly define posix defines like _XOPEN_SOURCE
- Changed: Renamed FPL_STACKALLOCATE to fplStackAllocate
- Changed: Renamed FPL_OFFSETOF to fplOffsetOf
- Changed: Renamed FPL_ARRAYCOUNT to fplArrayCount
- Changed: Renamed FPL_ASSERT to fplAssert
- Changed: Renamed FPL_STATICASSERT to fplStaticAssert
- Changed: Renamed FPL_CLEAR_STRUCT to fplClearStruct
- Changed: Renamed FPL_MIN to fplMin
- Changed: Renamed FPL_MAX to fplMax
- Changed: Renamed FPL_ZERO_INIT to fplZeroInit
- Changed: Renamed FPL_STRUCT_SET to fplStructSet
- Changed: Renamed FPL_STRUCT_INIT to fplStructInit
- Changed: Renamed FPL_KILOBYTES to fplKiloBytes
- Changed: Renamed FPL_MEGABYTES to fplMegaBytes
- Changed: Renamed FPL_GIGABYTES to fplGigaBytes
- Changed: Renamed FPL_TERABYTES to fplTeraBytes
- Changed: Renamed FPL_ALIGNMENT_OFFSET to fplGetAlignmentOffset
- Changed: Renamed FPL_ALIGNED_SIZE to fplGetAlignedSize
- Changed: Renamed FPL_IS_ALIGNED to fplIsAligned
- Changed: Renamed FPL_IS_POWEROFTWO to fplIsPowerOfTwo
- Changed: Renamed fplFormatAnsiStringArgs() to fplFormatStringArgs()
- Changed: Renamed fplFormatAnsiString() to fplFormatString()
- Changed: Renamed fplCopyAnsiString() to fplCopyString()
- Changed: Renamed fplCopyAnsiStringLen() to fplCopyStringLen()
- Changed: Renamed fplGetAnsiStringLength() to fplGetStringLength()
- Changed: Renamed fplOpenAnsiBinaryFile() to fplOpenBinaryFile()
- Changed: Renamed fplCreateAnsiBinaryFile() to fplCreateBinaryFile()
- Changed: Renamed fplSetWindowAnsiTitle() to fplSetWindowTitle()
- Changed: Renamed fplGetClipboardAnsiText() to fplGetClipboardText()
- Changed: Renamed fplSetClipboardAnsiText() to fplSetClipboardText()
- Changed: Renamed all fplAtomicCompareAndExchange*() to fplAtomicCompareAndSwap*()
- Changed: Renamed all fplAtomicAdd*() to fplAtomicFetchAndAdd*()
- Changed: Renamed all fplAtomicInc*() to fplAtomicAddAndFetch*()
- Changed: Renamed fplGetRunningArchitecture() to fplGetProcessorArchitecture()
- Changed: Renamed fplAudioSettings.deviceFormat to fplAudioSettings.targetFormat
- Changed: Renamed fplAudioSettings.deviceInfo to fplAudioSettings.targetDevice
- Changed: All buffers or fixed char/byte arrays uses now either FPL_MAX_BUFFER_LENGTH or FPL_MAX_NAME_LENGTH except for device-id
- Changed: All callback typedefs are now properly named as such
- Changed: Auto-play/stop of audio samples when enabled in configuration
- Changed: fplPlayAudio() will return fplAudioResult_Success when playback is already started
- Changed: fplStopAudio() will return fplAudioResult_Success when playback is already stopped
- Changed: Use nullptr for fpl_null when C++/11 is detected
- Changed: Separated audio target format and device format
- Removed: Removed obsolete to fplGetWideStringLength()
- Removed: Removed obsolete to fplCopyWideString()
- Removed: Removed obsolete to fplCopyWideStringLen()
- Removed: Removed obsolete fplOpenWideBinaryFile()
- Removed: Removed obsolete fplCreateWideBinaryFile()
- Removed: Removed obsolete fplSetWindowWideTitle()
- Removed: Removed obsolete fplGetClipboardWideText()
- Removed: Removed obsolete fplSetClipboardWideText()
- Removed: Removed obsolete fplWideStringToAnsiString()
- Removed: Removed obsolete fplAnsiStringToWideString()
- Removed: fplUpdateGameControllers()
- Removed: fplPushEvent()
- Removed: fplClearEvents()
- Fixed: fplStaticAssert was not compiling on gcc/clang C99 mode
- Fixed: Corrected a ton of misspellings in the documentation
- Fixed: Define for FPL_DEBUG was missing a raute symbol
- Fixed: Use va_copy for all va_list function arguments
- New: Added fplFlushFile()
- New: Added fplAtomicAddAndFetchPtr()
- New: Added fplAtomicFetchAndAddPtr()
- New: Added startAuto field to fplAudioSettings structure
- New: Added stopAuto field to fplAudioSettings structure
- New: Added fplInitFlags_GameController to fplInitFlags enumeration
- New: Added fplPollEvents()
- New: Added typedef fpl_window_event_callback
- New: Added typedef fpl_window_exposed_callback
- New: Added structure fplWindowCallbacks as a field in fplWindowSettings
- New: Added support for disabling runtime linking -> FPL_NO_RUNTIME_LINKING
- New: Added structure fplAudioTargetFormat
- New: Added macro fplCopyStruct()
- New: Added macro fplIsBigEndian()
- New: Added macro fplIsLittleEndian()
- New: Added fplGetWindowState()
- New: Added fplSetWindowState()
- Changed: [Win32] GetTickCount() replaced with GetTickCount64()
- Changed: [Win32] Use unicode (*W) win32 api functions for everything now
- Changed: [Win32] fplGetOperatingSystemInfos uses additional RtlGetVersion
- Changed: [DirectSound] fplGetAudioDevices() uses DirectSoundEnumerateW instead of DirectSoundEnumerateA
- Changed: [Win32/X11] Changed event handling from indirect to direct
- Changed[*]: Optional runtime linking for OS library calls
- Fixed: [Win32] fplGetProcessorArchitecture was not handling the WOW64-case
- Fixed: [Win32] fplGetClipboardAnsiText() was broken
- Fixed: [Win32] Forced compile error when compiling on < vista (FPL uses several features which requires vista or higher)
- Fixed: [Win32] fplGetOperatingSystemInfos had no WINAPI call defined for GetVersion prototype
- Fixed: [Win32] fplSetWindowFloating was not working
- Fixed: [Win32] fplSetWindowDecorated was not working
- Fixed: [Win32] fplSetWindowResizeable was not working
- Fixed: [Alsa] fpl__AudioWaitForFramesAlsa was not compiling (commonAudio missing)
- Fixed: [Alsa] Alsa output was not working anymore for certain playback devices
- Fixed: [X11] fplButtonState_Repeat was not handled in keyboard events
- New: [Win32/POSIX] Implemented fplFlushFile()
- New: [Win32/X11] Handle fplInitFlags_GameController to enable/disable game controllers
- New: [Win32/X11] Support for handling the OS event directly -> fpl_window_event_callback
- New: [Win32/X11] Support for handling the exposed (Repaint) event directly -> fpl_window_exposed_callback
- New: [Win32] Implemented fplSetWindowState / fplGetWindowState
## v0.9.1.0 beta
- Changed: Updated all the lists
- Changed: Added known issues section
- Changed: Renamed fplPlatformResultType to fplPlatformResultType
- Changed: fplPlatformInit returns now bool instead fplPlatformResultType
- Changed: Changed all comment prefix from \ to @, so it matches java-doc style
- Changed: Disable compile error when unix or bsd is detected
- Changed: Renamed fplGetKeyboardState to fplPollKeyboardState
- Changed: Renamed fplGetGamepadStates to fplPollGamepadStates
- Changed: fplDebugOut prints out to the console on non-MSVC
- Changed: Added enum value fplLogWriterFlags_StandardConsole
- Changed: Added enum value fplLogWriterFlags_ErrorConsole
- Changed: Removed field logToError from fplLogWriterConsole
- Changed: Internal audio system uses condition variables instead of signals now
- Removed: Removed obsolete field skipRepeatKeys in fplInputSettings
- Fixed: Clang compiler detection was not working because LLVM was detected first
- Fixed: UINT32_MAX was missing on android POSIX
- Fixed: fplFormatAnsiStringArgs was checking for argList as pointer which is wrong
- Fixed: leftTrigger/rightTrigger field in fplGamepadState had incorrect documentation
- New: Added function fplGetPlatformResult()
- New: Added struct fplMouseState
- New: Added function fplPollMouseState()
- New: Added field disabledEvents to fplInputSettings
- New: Added android platform detection
- New: Added enum fplGamepadButtonType
- Changed: [POSIX] Proper detection of all architecturess (x86, x86_64, x64, arm32, arm64)
- Changed: [POSIX] Moved fplGetCurrentUsername from the linux-section into the posix-section
- Changed: [POSIX] Moved fplGetProcessorCoreCount from Linux into the POSIX section
- Changed: [POSIX] Moved fplGetOperatingSystemInfos from Linux into the POSIX section
- Changed: [POSIX] Moved fplGetHomePath from Linux into the POSIX section
- Changed: [POSIX] Made fplGetExecutableFilePath Unix/Linux complaint and moved it into the POSIX section
- Changed: [POSIX] Added Clang/LLVM to atomics detection
- Fixed: [POSIX]: Removed alloca.h include when nor win32 or linux is detected
- Fixed: [POSIX]: Fixed typo in fplGetRunningArchitecture
- Fixed: [POSIX]: fplSemaphoreInit() was testing INT32_MAX instead of UINT32_MAX
- Fixed: [Win32] PeekMessage was not using our windowHandle at all
- Fixed: [Win32] fplReadFileBlock64/fplWriteFileBlock64 was not working at all
- Fixed: [Win32/XInput] Left/Right gamepad thumb buttons was not mapped
- Fixed: [POSIX] fplReadFileBlock64/fplWriteFileBlock64 was not working at all
- Fixed: [POSIX] Removed initialization (PTHREAD_MUTEX_INITIALIZER) of pthread_mutex_t in fpl__PosixMutexCreate
- Fixed: [X11] Fixed broken fplPollKeyboardState
- Fixed: [MSVC] Removed duplicated warning override in header
- New: [Win32]: Use SetCapture/ReleaseCapture for mouse down/up events
- New: [Win32]: Implemented fplPollMouseState()
- New: [Win32] Disable keyboard/mouse/gamepad events when fplInputSettings.disabledEvents is enabled
- New: [POSIX] Added __USE_LARGEFILE64 before including sys/types.h
- New: [X11] Implemented fplPollMouseState
- New: [X11] Implemented modifier keys in fplPollKeyboardState
- New: [Linux] Implemented fplPollGamepadStates
## v0.9.0.1 beta
- Changed: Renamed fields "kernel*" to "os*" in fplOSInfos
- Changed: Renamed fields "system*" to "distribution*" in fplOSInfos
- Fixed: [X11] Fixed icon loading was not working at all
- Fixed: [POSIX] fplWriteFileBlock64 was not properly implemented
- Fixed: [POSIX] fplReadFileBlock64 was not properly implemented
## v0.9.0.0 beta:
- Changed: fplKey_Enter renamed to fplKey_Return
- Changed: fplKey_LeftWin renamed to fplKey_LeftSuper
- Changed: fplKey_RightWin renamed to fplKey_RightSuper
- Changed: fplKey_Plus renamed to fplKey_OemPlus
- Changed: fplKey_Minus renamed to fplKey_OemMinus
- Changed: fplKey_Comma renamed to fplKey_OemComma
- Changed: fplKey_Period renamed to fplKey_OemPeriod
- Changed: fplKeyboardModifierFlags_Alt are split into left/right part respectively
- Changed: fplKeyboardModifierFlags_Shift are split into left/right part respectively
- Changed: fplKeyboardModifierFlags_Super are split into left/right part respectively
- Changed: fplKeyboardModifierFlags_Ctrl are split into left/right part respectively
- Changed: All bool fields in structs are replaced with fpl_b32
- Changed: Added COUNTER macro to non-CRT FPL_STATICASSERT
- Changed: Renamed fields in fplMemoryInfos to match correct meaning
- Changed: String copy functions uses fplMemoryCopy instead of iterating and copy each char
- Changed: fplSetFilePosition32 returns now uint32_t instead of void
- Changed: Added field timeStamps to fplFileEntry
- Changed: [X11] Window title uses XChangeProperty now instead of XStoreName
- Changed: [Win32] Detection of left/right keyboard modifier flags
- Changed: [Win32] Mapping OEM 1-8 keys
- Changed: [Win32] Use MapVirtualKeyA to map key code to virtual key
- Fixed: Corrected a ton of comments
- Fixed: fpl__HandleKeyboardButtonEvent had incorrect previous state mapping
- Fixed: [X11] fplMouseEventType_Move event was never created anymore
- New: Added typedef fpl_b32 (32-bit boolean type)
- New: Added struct fplKeyboardState
- New: Added struct fplGamepadStates
- New: Added function fplGetKeyboardState()
- New: Added function fplGetSystemLocale()
- New: Added function fplGetUserLocale()
- New: Added function fplGetInputLocale()
- New: Added function fplGetGamepadStates()
- New: Added function fplKey_Oem1-fplKey_Oem8
- New: Added function fplGetFileTimestampsFromPath
- New: Added function fplGetFileTimestampsFromHandle
- New: Added internal function fpl__ParseTextFile used for parsing /proc/cpuinfo or other device files
- New: Added function fplGetFileSizeFromHandle
- New: Added function fplGetFileSizeFromHandle64
- New: Added function fplGetFileSizeFromPath
- New: Added function fplGetFileSizeFromPath64
- New: Added function fplGetFilePosition
- New: Added function fplGetFilePosition64
- New: Added function fplSetFilePosition
- New: Added function fplSetFilePosition64
- New: Added function fplWriteFileBlock
- New: Added function fplWriteFileBlock64
- New: Added function fplReadFileBlock
- New: Added function fplReadFileBlock64
- New: [Win32] Implemented fplGetKeyboardState
- New: [Win32] Implemented fplGetGamepadStates
- New: [Win32] Implemented fplGetSystemLocale
- New: [Win32] Implemented fplGetUserLocale
- New: [Win32] Implemented fplGetInputLocale
- New: [Win32] Implemented fplGetFileTimestampsFromPath
- New: [Win32] Implemented fplGetFileTimestampsFromHandle
- New: [Win32] Implemented fplReadFileBlock64
- New: [Win32] Implemented fplWriteFileBlock64
- New: [Win32] Implemented fplSetFilePosition64
- New: [Win32] Implemented fplGetFilePosition64
- New: [Win32] Implemented fplGetFileSizeFromPath64
- New: [Win32] Implemented fplGetFileSizeFromHandle64
- New: [X11] Implemented fplGetKeyboardState
- New: [X11] Set window icon title using XChangeProperty
- New: [X11] Give window our process id
- New: [X11] Load window icons on startup
- New: [X11] Added ping support for letting the WM wakeup the window
- New: [Linux] Implemented fplGetSystemLocale
- New: [Linux] Implemented fplGetUserLocale
- New: [Linux] Implemented fplGetInputLocale
- New: [Linux] Reading first joystick as game controller in linux
- New: [POSIX] Implemented fplGetFileTimestampsFromPath
- New: [POSIX] Implemented fplGetFileTimestampsFromHandle
- New: [POSIX] Implemented fplReadFileBlock64
- New: [POSIX] Implemented fplWriteFileBlock64
- New: [POSIX] Implemented fplSetFilePosition64
- New: [POSIX] Implemented fplGetFilePosition64
- New: [POSIX] Implemented fplGetFileSizeFromPath64
- New: [POSIX] Implemented fplGetFileSizeFromHandle64
## v0.8.4.0 beta:
- New: Added macro function FPL_STRUCT_INIT
- New: Added enum value fplWindowEventType_DropSingleFile
- New: Added structure fplWindowDropFiles
- New: Added enum value fplInitFlags_Console
- New: [Win32] Support for WM_DROPFILES -> fplWindowEventType_DropSingleFile event
- Changed: Move fplInitFlags_All out and made it a static constant
- Changed: Use fplInitFlags_Console to activate console or not
- Fixed: fplExtractFileExtension was returning wrong result for files with multiple separators
- Fixed: [Win32] Fullscreen toggling was broken in maximize/minimize mode
- Fixed: [Win32] ClientToScreen prototype was missing WINAPI call
- Fixed: [POSIX] fplListDirNext() was broken
- Fixed: [X11] Key up event was never fired (KeyRelease + KeyPress = Key-Repeat)
## v0.8.3.0 beta:
- Changed: fplVersionInfo is now parsed as char[4] instead of uint32_t
- Changed: fplMouseEvent / fplKeyboardEvent uses fplButtonState instead of a bool for the state
- Changed: Replaced fplMouseEventType_ButtonDown / fplMouseEventType_ButtonUp with fplMouseEventType_Button
- Changed: Replaced fplKeyboardEventType_KeyDown / fplKeyboardEventType_KeyUp with fplKeyboardEventType_Button
- Fixed: Fixed incompabilties with MingW compiler
- New: Added function fplStringToS32
- New: Added function fplStringToS32Len
- New: Added function fplS32ToString
- New: Added function fplAtomicLoadSize
- New: Added function fplAtomicStoreSize
- New: Added function fplAtomicExchangeSize
- New: Added function fplAtomicCompareAndExchangeSize
- New: Added function fplIsAtomicCompareAndSwapSize
- New: Added function fplAtomicAddSize
- New: Added function fplAtomicIncU32
- New: Added function fplAtomicIncU64
- New: Added function fplAtomicIncS32
- New: Added function fplAtomicIncS64
- New: Added function fplAtomicIncSize
- New: Added macro FPL_IS_POWEROFTWO
- New: Introduced FPL_CPU_32BIT and FPL_CPU_64BIT
- New: fplAtomic*Ptr uses FPL_CPU_ instead of FPL_ARCH_ now
- New: Added enumeration fplButtonState
- New: Added field multiSamplingCount to fplOpenGLVideoSettings
- Changed: [Win32] Changed keyboard and mouse handling to use fplButtonState now
- Changed: [Win32] Changed fplListDirBegin/fplListDirNext to ignore . and ..
- Changed: [Win32] Console activation is done when _CONSOLE is set as well
- Changed: [X11] Changed keyboard and mouse handling to use fplButtonState now
- Fixed: [Win32] fplGetTimeInMillisecondsHP was not returning a proper double value
- Fixed: [Win32] Fixed crash when using fplThreadTerminate while threads are already exiting
- Fixed: [Win32] fplThreadWaitForAll/fplThreadWaitForAny was not working properly when threads was already in the process of exiting naturally
- Fixed: [Win32] Fixed incompabilties with MingW compiler
- Fixed: [POSIX] Fixed crash when using fplThreadTerminate while threads are already exiting
- New: [Win32] Support for OpenGL multi sampling context creation
- New: [GLX] Support for OpenGL multi sampling context creation
## v0.8.2.0 beta:
- Changed: Ensures const correctness on all functions
- Changed: Signature of fplDynamicLibraryLoad changed (Returns bool + Target handle parameter)
- Fixed: Corrected code documentation for all categories
- Fixed: FPL_ENUM_AS_FLAGS_OPERATORS had invalid signature for operator overloadings and missed some operators
- Fixed: Fixed fplMemorySet was not working for values > 0
- New: Forward declare thread handle for thread callback
- New: Added fplKey for OEM keys (Plus, Comma, Minus, Period)
- New: Added fplKey for Media & Audio keys
- New: Added fplWindowEventType_Maximized / fplWindowEventType_Minimized / fplWindowEventType_Restored
- New: Added documentation category: Assertions & Debug
- New: Added documentation category: Storage class identifiers
- New: Added documentation category: Constants
- New: Added documentation category: Function macros
- New: Undef annoying defined constants such as None, Success, etc.
- New: Added fplImageType enumeration
- New: Added fplImageSource structure
- New: Added icons as fplImageSource array to fplWindowSettings
- Changed: [Win32] Correct fplDynamicLibraryLoad to match signature change
- Changed: [Win32] Corrected function prototype macro names
- Fixed: [Win32] ClientToScreen prototype was defined twice
- New: [Win32] OEM keys mapping
- New: [Win32] Media & Audio key mapping
- New: [Win32] Handle window maximized/minimized and restored events
- New: [Win32] Load small/big icon from the fplWindowSettings icon imagesources
- Changed: [X11] Corrected function prototype macro names
- New: [X11] OEM keys mapping
- Changed: [X11] Corrected function prototype macro names
- Changed: [POSIX] Correct fplDynamicLibraryLoad to match signature change
- Changed: [POSIX] Use of pthread_timedjoin_np to support timeout in fplThreadWaitForOne when available (GNU extension)
## v0.8.1.0 beta:
- Changed: Locked error states to multiple and removed FPL_NO_MULTIPLE_ERRORSTATES
- Changed: Renamed fplClearPlatformErrors() to fplClearErrors()
- Changed: Renamed fplGetPlatformErrorCount() to fplGetErrorCount()
- Changed: Renamed fplGetPlatformErrorFromIndex() to fplGetErrorByIndex()
- Changed: Renamed fplGetPlatformError() to fplGetLastError()
- Changed: Refactored logging system
- Changed: Updated comments
- Fixed: fplAnsiString<->WideString conversion enforces ANSI locale (Non Win32)
- New: Added enum fplLogLevel
- New: Added enum fplLogWriterFlags
- New: Added struct fplLogWriter
- New: Added struct fplLogSettings
- New: Added struct fplSemaphoreHandle
- New: Added fplSetLogSettings()
- New: Added fplGetLogSettings()
- New: Added fplSetMaxLogLevel()
- New: Added fplGetMaxLogLevel()
- New: Added fplSemaphoreInit()
- New: Added fplSemaphoreDestroy()
- New: Added fplSemaphoreWait()
- New: Added fplSemaphoreTryWait()
- New: Added fplSemaphoreValue()
- New: Added fplSemaphoreRelease()
- New: Added fplIsStringMatchWildcard()
- Changed: [ALSA] Allow user selection of audio device id
- Fixed: [Win32] WaitForMultipleObjects >= WAIT_OBJECT_0 bugfix
- New: [ALSA] Implemented fplGetAudioDevices
- New: [Win32] Implemented Semaphores
- New: [POSIX] Implemented Semaphores
## v0.8.0.0 beta:
- Changed: Changed from inline to api call for fplGetAudioBufferSizeInFrames/fplGetAudioFrameSizeInBytes/fplGetAudioBufferSizeInBytes
- Changed: Changed from inline to api call for fplGetArchTypeString / fplGetPlatformResultTypeString / fplGetPlatformTypeString
- Changed: Moved FPL_CLEAR_STRUCT to public api
- New: Added fplThreadYield()
- Changed: [GLX] Added types such as XVisualInfo directly without relying on glx.h
- Fixed: [Win32] Console window was not working anymore the second time fplPlatformInit was called
- Fixed: [GLX] XVisualInfo was manually defined, now we use Xutil.h
- New: [Win32] Implemented fplThreadYield()
- New: [POSIX] Implemented fplThreadYield()
- New: [Linux] Implemented fplGetRunningArchitecture()
- New: [Linux] Implemented fplGetOperatingSystemInfos()
- New: [X11] Implemented Video Software output for X11
## v0.7.8.0 beta:
- Changed: Collapsed down all argument checking using macros
- Changed: Use FPL_CLEAR_STRUCT only when it is appropriate
- Changed: All public checks for fpl__global__AppState returns proper error now
- Changed: fplGetAudioHardwareFormat returns bool and requires a outFormat argument now
- Changed: fplSetAudioClientReadCallback returns bool now
- Changed: fplListFiles* is renamed to fplListDir*
- Changed: fplListDir* argument for fplFileEntry is renamed to entry for all 3 functions
- Changed. fplFileEntry stores the fullPath instead of the name + internal root infos - Changed: Introduced fplFilePermissions in fplFileEntry
- Changed: Removed flag fplFileAttributeFlags_ReadOnly from fplFileAttributeFlags
- Fixed: Fixed a ton of wrong inline definitions
- Fixed: Fixed GCC warning -Wwrite-strings
- Fixed: fplDebugBreak() was missing function braces for __debugbreak
- New: Added fplEnforcePathSeparatorLen()
- New: Added fplEnforcePathSeparator()
- New: Added fileSize field to fplFileEntry
- New: Added struct fplFilePermissions
- New: Added enum fplFilePermissionMasks
- New: Added fplDebugOut()
- New: Added fplDebugFormatOut()
- New: Added fplWindowShutdown()
- New: Added macro FPL_STRUCT_SET
- Changed: [POSIX] Removed all pthread checks, because there is a check for platform initialization now
- Changed: [Win32] Changed fplListDir* to support fplFilePermissions
- Changed: [Win32] Showing cursor does not clip cursor anymore
- Fixed: [POSIX] Fixed a ton of C99 compile errors
- New: [POSIX] Implemented fplListDirBegin
- New: [POSIX] Implemented fplListDirNext
- New: [POSIX] Implemented fplListDirEnd
- New: [X11] Implemented fplWindowShutdown()
- New: [Win32] Fill out fileSize for fplFileEntry in fplListDir*
- New: [Win32] Implemented fplWindowShutdown()
## v0.7.7.0 beta:
- New: Added fplMutexTryLock()
- New: Added fplMakeDefaultSettings()
- New: Added fplStringAppend() / fplStringAppendLen()
- New: Added fplDebugBreak()
- Changed: Any string buffer writing functions returns the last written character now
- Changed: Changed fplGetClipboardAnsiText() to return bool instead of char *
- Changed: Changed fplGetClipboardWideText() to return bool instead of wchar_t *
- Changed: Entry point definition implementation is now a separated block and controlled by FPL_ENTRYPOINT
- Changed: MSVC compiler warnings are only disabled inside the implementation block
- Fixed: Never detected Win32 Path separator (Wrong define check)
- Fixed: MSVC compiler warnings was overwritten always, now uses push/pop
- Fixed: MSVC _Interlocked* functions has no signature for unsigned, so we use either LONG or LONG64
- New: [X11] Implemented fplIsWindowFullscreen
- New: [X11] Implemented basic fplSetWindowFullscreen
- Fixed: [POSIX] Create/Open*BinaryFile was wrong named
- Fixed: [Win32] fplMemoryFree actually never freed any memory
## v0.7.6.0 beta:
- Changed: Renamed fplGetRunningArchitectureType to fplGetRunningArchitecture
- Changed: Renamed fplThreadDestroy() to fplThreadTerminate() + signature changed (Returns bool)
- Changed: fplSignalInit() + new parameter "initialValue"
- Changed: All functions which uses timeout uses fplTimeoutValue instead of uint32_t
- Changed: All string buffer writing functions returns the last written character instead
- Changed: Removed timeout parameter from fplMutexLock()
- New: Added struct fplConditionVariable
- New: Added enum fplSignalValue
- New: Added fplConditionInit()
- New: Added fplConditionDestroy()
- New: Added fplConditionWait()
- New: Added fplConditionSignal()
- New: Added fplConditionBroadcast()
- New: Added typedef fplTimeoutValue
- New: Added constant FPL_TIMEOUT_INFINITE
- Changed: [Win32] Thread resources are automatically cleaned up when a thread is done running
- Changed: [POSIX] Thread resources are automatically cleaned up when a thread is done running
- Changed: [Win32] fplSignalInit updated to support isSetInitially
- Changed: [Linux] fplSignalInit updated to support isSetInitially
- Fixed: [GLX] Fallback to glXCreateContext was not working properly
- New: [Linux] Implemented fplGetCurrentUsername
- New: [Win32] Implemented all fplCondition*
- New: [POSIX] Implemented all fplCondition*
## v0.7.5.0 beta:
- Changed: Updated documentations
- Changed: Small refactoring of the internal audio system
- Changed: Renamed fplMutexCreate to fplMutexInit + signature change (Returns bool, Mutex pointer argument)
- Changed: Renamed fplSignalCreate to fplSignalInit + signature change (Returns bool, Signal pointer argument)
- Changed: Removed mutex parameter from SignalWaitFor*
- Changed: [GLX] Use glXCreateContext with visual info caching for GLX < 1.3 and glXCreateNewContext for GLX >= 1.3
- Changed: [POSIX] All FPL__POSIX_GET_FUNCTION_ADDRESS_BREAK are wrapped around a do-while loop so it can "break" properly.
- Removed: [POSIX] All signal functions removed
- New: [ALSA] Added rudimentary ALSA playback support
- New: [Linux] Implemented signal functions using eventfd
## v0.7.4.0 beta:
- Fixed: [Win32] Removed x64 detection for fplAtomicStoreS64 and fplAtomicExchangeS64 and use _InterlockedExchange*64 directly
- Changed: [GLX] Implemented modern opengl context creation
## v0.7.3.0 beta:
- Changed: fplConsoleWaitForCharInput returns char instead of const char
- Changed: Added isDecorated field to fplWindowSettings
- Changed: Added isFloating field to fplWindowSettings
- Changed: Renamed fplSetWindowTitle() -> fplSetWindowAnsiTitle()
- Changed: Copy Ansi/Wide String pushes error for buffer range error
- Fixed: Fixed api name mismatch CloseFile() -> fplCloseFile()
- Fixed: Corrected wrong doxygen defines
- Fixed: Corrected most clang compile warnings
- New: Added fplIsWindowDecorated() / fplSetWindowDecorated()
- New: Added fplIsWindowFloating() / fplSetWindowFloating()
- New: Added fplSetWindowWideTitle()
- New: Added fplGetTimeInMillisecondsHP()
- New: Added fplGetTimeInMillisecondsLP()
- New: Added fplGetTimeInSecondsLP()
- New: Added fplGetTimeInSecondsHP()
- New: Added FPL_NO_ENTRYPOINT
- Changed: [Win32] fplAtomicExchangeS64() / fplAtomicAddS64() / fplAtomicStoreS64() uses _Interlocked* operatings directly for x86
- Fixed: [Win32] Corrected wrong case-sensitivity in includes
- Fixed: [Win32] Fixed Cursor visibility was not properly changeable
- Fixed: [Win32] Function prototype macros was not properly named
- New: [Win32] Implemented fplIsWindowDecorated() / fplSetWindowDecorated()
- New: [Win32] Implemented fplIsWindowFloating() / fplSetWindowFloating()
- New: [Win32] Implemented fplSetWindowWideTitle()
- New: [Win32] Implemented fplGetTimeInMillisecondsLP()
- New: [Win32] Implemented fplGetTimeInMillisecondsHP()
- New: [Win32] Implemented fplGetTimeInSecondsLP()
- New: [Win32] Implemented fplGetTimeInSecondsHP()
- New: [POSIX] Implemented fplGetTimeInMillisecondsLP()
- New: [POSIX] Implemented fplGetTimeInMillisecondsHP()
- New: [POSIX] Implemented fplGetTimeInSecondsLP()
- New: [POSIX] Implemented fplGetTimeInSecondsHP()
## v0.7.2.0 beta:
- Changed: Signature of fplGetRunningMemoryInfos() changed
- Changed: Renamed fplGetSystemMemoryInfos to fplGetRunningMemoryInfos
- Changed: Added "p" prefix to linux and unix app state
- New: Added enum fplArchType
- New: Added fplGetRunningArchitectureType()
- New: Added fplGetArchTypeString()
- New: Added enum fplPlatformType
- New: Added fplGetPlatformType()
- New: Added fplGetPlatformTypeString()
- New: Added struct fplVersionInfo
- New: Added struct fplOSInfos
- New: Added fplGetOperatingSystemInfos()
- New: Added fplGetCurrentUsername()
- Changed: [Docs] Updated all documentations to match the current state
- Fixed: [Docs] Missing brief for fpl_extern
- Changed: [MSVC] Removed the compiler specific No-CRT block such as _fltused, etc. -> The caller is responsible for this!
- New: [Win32] Implemented fplGetCurrentUsername()
- New: [Win32] Implemented fplGetOperatingSystemInfos()
- New: [Win32] Implemented fplGetRunningArchitectureType()
## v0.7.1.0 beta:
- Changed: fplConsoleFormatOut/fplConsoleFormatError is now common_api instead of platform_api
- Changed: FPL uses a keyMap for mapping OS key codes to fplKey for every platform
- Changed: [Win32] Console does not cache the output/input/error handles
- Changed: [Win32] fplConsole* uses ReadFile/WriteFile instead of ReadConsole/WriteConsole
- Changed: BSD Platform is detected as a Unix Platform, but has its own subplatform as well
- Fixed: [Win32] Console was always allocated
- Fixed: No CRT stub defintions such as memset and RTC was added for all compilers which is wrong
- Fixed: Several bugfixes
- New: Added stubs for Unix Platform
## v0.7.0.0 beta:
- Changed: Switched to C99
- Changed: Changed Init/app state structs a lot
- Changed: Removed most anonymous unions and structs
- Changed: Renamed a lot of the internal handles
- Changed: Renamed ThreadContext to ThreadHandle
- Changed: Renamed ThreadSignal to SignalHandle
- Changed: Renamed ThreadMutex to MutexHandle
- Changed: All structs, functions with name *API renamed to *Api
- Changed: Moved internal functions around and restructured things
- Changed: Moved platforms and subplatforms into its own namespace
- Changed: Updated documentation a bit
- Changed: Introduced common::Argument*Error functions
- Changed: Removed MemoryStackAllocate()
- Changed: App state memory size is aligned by 16-bytes as well
- Changed: Video/Audio state memory block is included in app state memory as well
- Changed: PlatformInit uses InitResultType
- Changed: fpl*DefaultSettings is now fplSet*DefaultSettings and does not return a struct anymore
- Fixed: Get rid of const char* to char* warnings for Get*DriverString() functions
- Fixed: [Win32] Icon was not default application icon
- Fixed: ExtractFileName and ExtractFileExtension was not returning const char*
- New: [X11][Window] Implemented X11 Subplatform
- New: [X11][OpenGL] Implemented X11/GLX video driver
- New: [X11][Software] Implemented Software video driver
- New: [POSIX] Implemented all remaining posix functions
- New: Introduced debug logging -> FPL_LOGGING
- New: Added FPL_ALIGNMENT_OFFSET macro
- New: Added FPL_ALIGNED_SIZE macro
- New: Added InitResultType
- New: CRT (C-Runtime) is not required anymore
## v0.6.0.0 beta:
- Changed: Documentation changed a bit
- Changed: Renamed SignalWakeUp() to SignalSet()
- Changed: [Win32] Start thread always immediatly
- Changed: Included "Windows" prefix for output path in visual studio projects
- Changed: Moved opengl settings into graphics union
- Changed: All global functions use :: as a prefix
- Deleted: Removed ThreadSuspend() -> Not complaint with pthread
- Deleted: Removed ThreadResume() -> Not complaint with pthread
- Deleted: Removed SignalReset() -> Not complaint with pthread
- Fixed: Resize video backbuffer was not working anymore
- Fixed: [Win32] Some _Interlocked* functions was not existing on x86
- New: Introduced PrepareWindowForVideoAfter() so we can setup a video context after the window has been created
- New: Introduced PrepareWindowForVideoBefore() so we can setup any window before initializing the video context
- New: Added timings::GetTimeInMilliseconds() with [Win32] and [POSIX] implementation
- New: [POSIX] Implemented all threading functions
- New: [Linux] Added a makefile for each demo project
- New: Added files::FileMove
## v0.5.9.1 beta:
- Changed: MemoryInfos uses uint64_t instead of size_t
- Changed: Added BSD to platform detecton
- Changed: Architecture detection does not use _WIN64 or _WIN32 anymore
- Changed: fpl_api is now either fpl_platform_api or fpl_common_api
- Changed: Internal code refactoring
- Changed: Renamed VideoSettings driverType to driver
- Changed: Video initialization is now platform independent
- Changed: Window initialization is now platform independent
- Changed: Moved window::WindowFlip to video::VideoFlip
- Changed: [POSIX] Replaced file-io with POSIX open, read, write
- Changed: [Win32] Removed fpl_api from main entry point forward declararation
- Changed: [Win32] Moved main entry point inside the implementation block
- Fixed: Arm64 was misdetected as X64, this is now its own arch
- Fixed: GNUC and ICC are pure C-compilers, it makes no sense to detect such in a C++ library
- Fixed: [Linux][POSIX] Refactor init and release to match PlatformInitState and PlatformAppState
- Updated: Documentations updated
- New: [POSIX][X11][Linux] Added missing functions as not-implemented
## v0.5.9.0 beta:
- Changed: Moved documentation inside its own file "final_platform_layer.documentation"
- Changed: [Win32] Window creation uses CS_OWNDC always
- Changed: Refactoring of platform and non-platform code
- Changed: InitPlatform() and ReleasePlatform() is now platform independent
## v0.5.8.1 beta:
- Changed: KeyboardEventType::Char renamed to KeyboardEventType::CharInput
- Changed: Completed basic documentation
- Changed: Renamed VideoBackBuffer.stride to VideoBackBuffer.lineWidth
- Changed: Moved a few internal inline audio functions to the global audio namespace
- Fixed: [Win32] WM_CHAR was allowing unicode characters as well, which is wrong because it must be properly converted first.
- Fixed: Audio driver selection was buggy
- Added: pixelStride to fpl::video::VideoBackBuffer
- Added: fpl::window::ClearWindowEvents()
- Added: fpl::window::PushWindowEvent()
- Added: fpl::window::UpdateGameControllers()
- Added: fpl::audio::GetAudioBufferSizeInFrames()
- Added: fpl::audio::GetAudioDriverString()
- Added: fpl::audio::GetAudioFormatString()
- Added: fpl::audio::GetAudioSampleSizeInBytes()
- Added: fpl::audio::GetAudioFrameSizeInBytes()
- Added: fpl::audio::GetAudioBufferSizeInBytes()
## v0.5.8.0 beta:
- Changed: SignalWaitFor* requires additional parameter for passing in the ThreadMutex reference (pthread compability)
- Changed: Signal* does not use const reference anymore (pthread compability)
- Changed: Updated documentation a ton
- Changed: Decreased MAX_ERRORSTATE_COUNT from 1024 to 256
- Changed: global__LastErrorState is a non-pointer global now
- Changed: Renamed GetPlatformLastError() to GetPlatformError()
- Changed: All array of objects parameters uses C++ array style -> int *arr[] instead of int **arr
- Fixed: MemoryAlignedFree() had wrong signature (void **) instead of (void *)
- Fixed: GetPlatformErrorCount() was not increasing when an empty error was pushed on for single error states
- Fixed: [Win32] InitPlatform() was not cleaning up the Win32State when the initialization failed
- Replaced: VideoCompabilityProfile is replaced by OpenGLCompabilityFlags (Only available with OpenGL)
- New: Added ClearPlatformErrors()
## v0.5.7.4 beta:
- Changed: Updated code documentation for all functions and types to doxygen/javadoc style
- Changed: SetFilePosition32 position is now int32_t instead of uint32_t to support negative positions as well
- Changed: Renamed desiredFormat to deviceFormat in AudioSettings
- Changed: [DirectSound] Use deviceID as GUID for the audio device
- New: Introduced AudioDeviceID
- New: Added deviceID field in AudioSettings
- New: Added audio::GetAudioDevices()
- New: Added strings::FormatString()
## v0.5.7.3 beta:
- Fixed: [Win32] Fixed SetWindowFullscreen was not working properly
- New: Introduced outputRect in VideoBackBuffer + Win32 implementation
- Changed: SetWindowFullscreen returns bool
## v0.5.7.2 beta:
- Added: Added new audio formats (AudioFormatType::F64, AudioFormatType::S64)
## v0.5.7.1 beta:
- Fixed: xInputSetState renamed to xInputGetState internally
- Added: Introduced InputSettings
- Added: [Win32] XInput controller detection is now limited to a fixed frequency, for improving performance (InputSettings.controllerDetectionFrequency)
## v0.5.7.0 beta:
- Changed: Total change of documentation style
- Changed: [Win32] ThreadMutex uses a critical section instead of a event
- Changed: [Win32] Include windows.h in the header, so we can define HANDLE, CRITICAL_SECTION in the api
- Changed: [Win32] Changed lots of functions to use conditions instead of asserts
- Changed: [Win32] Changed format specifiers to use either %d or %zu for integer types
- Changed: All Thread*Wait functions returns if the wait was successful or not in the same way Signal*Wait
- Changed: All ListFiles* functions uses reference instead of pointer
## v0.5.6.0 beta:
- Changed: We are back to C++/11 and we will never going back to C++/98
## v0.5.5.1 beta:
- New[POSIX]: Implemented fpl::timings
- New[POSIX]: Implemented fpl::library
- New[POSIX]: Implemented fpl::threading::ThreadSleep
- Changed[POSIX]: Moved Linux fpl::console functions to Posix
## v0.5.5.0 beta:
- Changed: All internal handles are now unions now, so can have different sizes of handles
- Changed: Introduced POSIX platform and moved linux atomics into it
## v0.5.4.0 beta:
- Fixed: Some enum types was not using the namespace version
## v0.5.3.0 beta:
- Changed: Use custom int types because C++/98 has no default types unfortunatly
- Fixed: Changed compiler detection order, because some non-MSVC compilers define _MSVC
- Changed: Better C++/11 feature detection for optional nullptr and constexpr
## v0.5.2.1 beta:
- Fixed: Corrected all doxygen statements to match new enum style or added missing exlamation marks.
## v0.5.2 beta:
- Changed: Library is now C++/98 complaint
- Changed: The actual enum type for "flags" has no "s" at the end anymore.
- Opimization: Changed some internal functions to "static inline"
- Changed: Renamed audio::GetAudioNativeFormat to audio::GetAudioHardwareFormat
- New: Added "periods", "bufferSizeInBytes", "bufferSizeInFrames" to AudioDeviceFormat
## v0.5.1 beta:
- New: audio::GetAudioNativeFormat()
- New: audio::SetAudioClientReadCallback()
- Fixed: InitFlags::Audio was never tested before InitAudio() was being called.
- Changed: Renamed ThreadStop to ThreadDestroy
## v0.5.0 beta:
- Added: [Win32] DirectSound playback support
- Added: Asyncronous audio playback
## v0.4.11 alpha:
- Fixed: [Win32] For now, load all user32 functions always, even when window is not used (This is to prepare for audio playback)
- Fixed: [Win32] ThreadStop was not releasing the thread handle
- Added: [Win32] ThreadWaitForAny
- Added: [Win32] SignalWaitForAll
- Added: [Win32] SignalWaitForAny
- Added: [Win32] SignalReset
- Added: FPL_NO_VIDEO
- Changed: ThreadWaitForSingle renamed to ThreadWaitForOne
- Changed: ThreadWaitForMultiple renamed to ThreadWaitForAll
- Changed: SignalWait renamed to SignalWaitForOne
## v0.4.10 alpha:
- Removed: Removed all _internal _INTERNAL postfixes from types, functions and macros
- Changed: Proper identitation for compiler directives based on context
- Added: [Win32] Dynamically loading ole32 functions (CoCreateInstance, CoInitializeEx, etc.)
- Fixed: [Win32] GetCursor was not using the dynamic loaded function
- Fixed: [Win32] Missing *Clipboard* dynamic functions
## v0.4.9 alpha:
- Removed: Removed all audio code for now
- Changed: A total cleanup of all internal stuff, so its much easier to add in new features
## v0.4.8 alpha:
- New: AtomicLoadU32, AtomicLoadU64, AtomicLoadS32, AtomicLoadS64, AtomicLoadPtr
- New: AtomicStoreU32, AtomicStoreU64, AtomicStoreS32, AtomicStoreS64, AtomicStorePtr
- New: AtomicExchangePtr, AtomicCompareAndExchangePtr, IsAtomicCompareAndExchangePtr
- New: [Win32] Implementation for AtomicLoadU32, AtomicLoadU64, AtomicLoadS32, AtomicLoadS64, AtomicLoadPtr
- New: [Win32] Implementation for AtomicStoreU32, AtomicStoreU64, AtomicStoreS32, AtomicStoreS64, AtomicStorePtr
- New: [Linux] Implementation for AtomicLoadU32, AtomicLoadU64, AtomicLoadS32, AtomicLoadS64, AtomicLoadPtr
- New: [Linux] Implementation for AtomicStoreU32, AtomicStoreU64, AtomicStoreS32, AtomicStoreS64, AtomicStorePtr
- New: [Win32] Loading of DirectSound (Prepare for audio output support)
- Draft: Added first audio output api
- Fixed: Threading context determination
- Fixed: [Win32] Fixed all thread implementations
- Fixed: [Win32] SetWindowLongPtrA does not exists on X86
- Fixed: [Win32] Missing call convention in SHGetFolderPathA and SHGetFolderPathW
- Changed: Improved header documentation (More examples, better descriptions, proper markdown syntax, etc.)
- Changed: All threading functions uses pointer instead of reference
- Changed: [Linux] Atomic* uses __sync instead of __atomic
- Changed: A bit of internal cleanup
## v0.4.7 alpha:
- Changed: [Win32] Load all user32 and shell32 functions dynamically
- Changed: FPL_ENUM_AS_FLAGS_OPERATORS_INTERNAL requires a int type as well
- Fixed: MemoryAlignedAllocate and MemoryAlignedFree was broken
- Added: FPL_IS_ALIGNED macro
## v0.4.6 alpha:
- Fixed: [Win32] Crash when window is not set in the InitFlags but FPL_USE_WINDOW is set.
## v0.4.5 alpha:
- Changed: [Win32] Use CommandLineToArgvW for command line parsing
## 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
## v0.4.3 alpha:
- 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
## 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
## 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.
## 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)
## v0.3.6 alpha:
- Cleanup: All win32 functions are macro calls now (prepare for dynamic function loading)
- Fixed: FPL_ENABLE_WINDOW was enabling window features even when it was deactivated by the caller
## v0.3.5 alpha:
- Renamed: All memory/library/threading functions
- Removed: FPL_ENABLE_PUSHMEMORY removed entirely
## v0.3.4 alpha:
- Renamed: CopyFile/DeleteFile/All memory functions 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] Undefs for CopyFile
- Changed: [Win32/OpenGL] Test for already included gl.h
## v0.3.3 alpha:
- Basic threading creation and handling
- Fixed strings::All Wide convertions was not working properly
## v0.3.2 alpha:
- Introduced: Automatic namespace inclusion (FPL_AUTO_NAMESPACE)
- Introduced: Push memory (FPL_ENABLE_PUSHMEMORY)
- Signature changed for: ExtractFilePath/ChangeFileExtension (source first, destination second)
- Window features not not compiled out anymore when FPL_ENABLE_WINDOW is 0
- New overloaded CombinePath without any destination arguments
- New: AllocateStackMemory function
- Optional destination arguments for: GetExecutableFilePath/GetHomePath/ChangeFileExtension/CombinePath
- Fixed strings::CopyAnsiString/CopyWideString was not returning the correct value
## v0.3.1 alpha:
- All types/structs/fields/functions documented
- [Win32] Fixed legacy opengl (GL_INVALID_OPERATION)
## v0.3.0 alpha:
- Updated documentation a lot
- [Win32] Support for WGL opengl profile selection
## v0.2.6 alpha:
- 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 fpl_constant
- Removed template code / Replaced it with macros
## v0.2.5 alpha:
- Added CreateDirectories
- Returns char * for all path get like functions
- Fixed CreateBinaryFile was never able to overwrite the file.
## v.2.4 alpha:
- Changed to a doxygen + vc complaint documentation style
- CopyFile2, DeleteFile2 and CloseFile2 are now CopyFile, DeleteFile, CloseFile
## v0.2.3 alpha:
- Support for doxygen in documentations
## v0.2.2 alpha:
- Added XInput support
## v0.2.1 alpha:
- Changed a lot of pointer arguments to reference
- Added gamepad event structures
## v0.2 alpha:
- Dropped C support and moved to a more C++ ish api
- Dropped no C-Runtime support
## v0.1 alpha:
- Initial version
*/
/*!
@page page_platform_status Platform Status
@tableofcontents
@section section_platform_status_supported_archs Supported Architectures
- x86
- x86_64
- x64
@section section_platform_status_planned_archs Planned Architectures
- Arm32
- Arm64
@section section_platform_status_supported_platforms Supported Platforms
- Windows
- Linux
- Unix (Partially)
@section section_platform_status_planned_platforms Planned Platforms
- Raspberry Pi
- Android
*/
/*!
@page page_knownissues Known Issues / Limitations
@tableofcontents
This is the list of known limitations and issues which hopefully gets solved sometime:
@section section_knownissues_limitations Limitations
- [Linux] Gamepad detection is locked to /dev/input/js0 for now, so only one controller at a time is supported
@section section_knownissues_issues Issues
- [X11] Icon and Title on gnome 3 window-manager does not show up at all, only KDE/XFCE works
- [Win32] There may be some flickering issues when using software rendering (FPL_FFMpeg demo has this flickering issues)
*/
// ----------------------------------------------------------------------------
// > TODO
// ----------------------------------------------------------------------------
/*!
@page page_todo ToDo / Planned (Top priority order)
@tableofcontents
@section section_todo_inprogress In progress
- Input
- Keyboard state polling (X11, Caps detection)
- Window
- Toggle Resizable (X11)
- Toggle Decorated (X11)
- Toggle Floating (X11)
- Show/Hide Cursor (X11)
- Clipboard Get/Set (X11)
- Change/Get State Minimize/Maximize/Restore (X11)
@section section_todo_planned Planned
- Core
- Introduce a callback system for audio/video drivers
- Application
- Support icon image in gnome (X11)
- Support icon title in gnome (X11)
- Input
- Mapping OEM 1-8 Keys (X11)
- Networking (UDP, TCP)
- [Win32] WinSock
- [POSIX] Socket
- Date/Time functions
- Audio:
- XAudio2 driver
- PulseAudio driver
- OSS driver
- Support for more than two channels
- Support for channel mapping
- Threading
- Signals (POSIX, Non-Linux)
- Documentation
- Window
- Threading
- Syncronisation
- File-IO
- Operations (Copy, Delete, etc)
- Path
- Traversal
- Strings
- Locales
@section section_todo_optional Optional
- DLL-Export support
- Multimonitor-Support
- Window:
- Realtime resize (Win32 using fiber)
- Custom cursor from image (File/Memory)
- Video:
- [Win32] Direct3D
- [Win32] Vulkan
- [POSIX] Vulkan
*/
// ****************************************************************************
//
// HEADER
//
// ****************************************************************************
#ifndef FPL_INCLUDE_H
#define FPL_INCLUDE_H
//
// C99 detection
//
// https://en.wikipedia.org/wiki/C99#Version_detection
// Visual Studio 2015+
#if !defined(__cplusplus) && ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(_MSC_VER) && (_MSC_VER >= 1900)))
//! Detected C99 compiler
# define FPL_IS_C99
#elif defined(__cplusplus)
//! Detected C++ compiler
# define FPL_IS_CPP
#else
# error "This C/C++ compiler is not supported!"
#endif
//
// Platform detection
//
// https://sourceforge.net/p/predef/wiki/OperatingSystems/
#if defined(_WIN32) || defined(_WIN64)
# define FPL_PLATFORM_WIN32
# define FPL_PLATFORM_NAME "Windows"
#elif defined(__ANDROID__)
# define FPL_PLATFORM_ANDROID
# define FPL_PLATFORM_NAME "Android"
# define FPL_SUBPLATFORM_POSIX
# define FPL_SUBPLATFORM_STD_STRINGS
# define FPL_SUBPLATFORM_STD_CONSOLE
#elif defined(__linux__) || defined(__gnu_linux__)
# define FPL_PLATFORM_LINUX
# define FPL_PLATFORM_NAME "Linux"
# define FPL_SUBPLATFORM_POSIX
# define FPL_SUBPLATFORM_X11
# define FPL_SUBPLATFORM_STD_STRINGS
# define FPL_SUBPLATFORM_STD_CONSOLE
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__bsdi__)
// @NOTE(final): BSD is treated as a subplatform for now
# define FPL_PLATFORM_UNIX
# define FPL_PLATFORM_NAME "BSD"
# define FPL_SUBPLATFORM_BSD
# define FPL_SUBPLATFORM_POSIX
# define FPL_SUBPLATFORM_X11
# define FPL_SUBPLATFORM_STD_STRINGS
# define FPL_SUBPLATFORM_STD_CONSOLE
#elif defined(unix) || defined(__unix) || defined(__unix__)
# define FPL_PLATFORM_UNIX
# define FPL_PLATFORM_NAME "Unix"
# define FPL_SUBPLATFORM_POSIX
# define FPL_SUBPLATFORM_X11
# define FPL_SUBPLATFORM_STD_STRINGS
# define FPL_SUBPLATFORM_STD_CONSOLE
#else
# error "This platform is not supported!"
#endif // FPL_PLATFORM
//
// Architecture detection (x86, x64)
// See: https://sourceforge.net/p/predef/wiki/Architectures/
//
#if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__)
# define FPL_ARCH_X64
# define FPL_CPU_64BIT
#elif defined(_M_IX86) || defined(__i386__) || defined(__X86__) || defined(_X86_)
# define FPL_ARCH_X86
# define FPL_CPU_32BIT
#elif defined(__arm__) || defined(_M_ARM)
# if defined(__aarch64__)
# define FPL_ARCH_ARM64
# define FPL_CPU_64BIT
# else
# define FPL_ARCH_ARM32
# define FPL_CPU_32BIT
# endif
#else
# error "This architecture is not supported!"
#endif // FPL_ARCH
//
// Compilers detection
// See: http://beefchunk.com/documentation/lang/c/pre-defined-c/precomp.html
// See: http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros
//
#if defined(__clang__)
//! CLANG compiler detected
# define FPL_COMPILER_CLANG
#elif defined(__llvm__)
//! LLVM compiler detected
# define FPL_COMPILER_LLVM
#elif defined(__INTEL_COMPILER)
//! Intel compiler detected
# define FPL_COMPILER_INTEL
#elif defined(__MINGW32__)
//! MingW compiler detected
# define FPL_COMPILER_MINGW
#elif defined(__GNUC__) && !defined(__clang__)
//! GCC compiler detected
# define FPL_COMPILER_GCC
#elif defined(__CC_ARM)
//! ARM compiler detected
# define FPL_COMPILER_ARM
#elif defined(_MSC_VER)
//! Visual studio compiler detected
# define FPL_COMPILER_MSVC
#else
//! No compiler detected
# define FPL_COMPILER_UNKNOWN
#endif // FPL_COMPILER
//
// Defines required on certain compiler/platform configurations
// Required for: mmap
//
#if defined(FPL_IS_C99) && defined(FPL_SUBPLATFORM_POSIX)
# if !defined(_XOPEN_SOURCE)
# define _XOPEN_SOURCE 600
# endif
# if !defined(_DEFAULT_SOURCE)
# define _DEFAULT_SOURCE 1
# endif
# if !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS
# endif
# if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS
# endif
# if !defined(_LARGEFILE_SOURCE)
# define _LARGEFILE_SOURCE
# endif
# if !defined(_LARGEFILE64_SOURCE)
# define _LARGEFILE64_SOURCE
# endif
# if !defined(_FILE_OFFSET_BITS)
# define _FILE_OFFSET_BITS 64
# endif
#endif
//
// Storage class identifiers
//
/**
* @defgroup StorageClassIdents Storage class identifiers
* @brief This category contains storage class identifiers, such as static, extern, inline, etc.
* @{
*/
//! Global persistent variable
#define fpl_globalvar static
//! Local persistent variable
#define fpl_localvar static
//! Private/Internal function
#define fpl_internal static
//! Inline function
#define fpl_inline inline
//! Internal inlined function
#define fpl_internal_inline inline
#if defined(FPL_IS_CPP)
//! External call
# define fpl_extern
#else
//! External call
# define fpl_extern extern
#endif
#if defined(FPL_API_AS_PRIVATE)
//! Api call
# define fpl_api static
#else
//! Api call
# define fpl_api fpl_extern
#endif // FPL_API_AS_PRIVATE
//! Platform api definition
#define fpl_platform_api fpl_api
//! Common api definition
#define fpl_common_api fpl_api
//! Main entry point api definition
#define fpl_main
//
// Force inline
//
#if defined(FPL_COMPILER_GCC) && (__GNUC__ >= 4)
//! Force inline
# define fpl_force_inline __attribute__((__always_inline__)) inline
#elif defined(FPL_COMPILER_MSVC) && (_MSC_VER >= 1200)
//! Force inline
# define fpl_force_inline __forceinline
#else
//! Force inline
# define fpl_force_inline inline
#endif
/** @}*/
//
// When C-Runtime is disabled we cannot use any function from the C-Standard Library <stdio.h> or <stdlib.h>
//
#if defined(FPL_NO_CRT)
# if defined(FPL_SUBPLATFORM_STD_CONSOLE)
# undef FPL_SUBPLATFORM_STD_CONSOLE
# endif
# if defined(FPL_SUBPLATFORM_STD_STRINGS)
# undef FPL_SUBPLATFORM_STD_STRINGS
# endif
# if !defined(FPL_USERFUNC_vsnprintf)
# error "You need to provide a replacement for vsnprintf() by defining FPL_USERFUNC_vsnprintf!"
# endif
#endif
//
// Application type detection
// - Can be disabled by FPL_NO_APPTYPE
// - Must be explicitly set for No-CRT on Win32
//
#if defined(FPL_APPTYPE_CONSOLE) && defined(FPL_APPTYPE_WINDOW)
# error "Its now allowed to define both FPL_APPTYPE_CONSOLE and FPL_APPTYPE_WINDOW!"
#endif
#if defined(FPL_NO_CRT)
# if !defined(FPL_APPTYPE_CONSOLE) && !defined(FPL_APPTYPE_WINDOW)
# error "In 'No-CRT' mode you need to define either FPL_APPTYPE_CONSOLE or FPL_APPTYPE_WINDOW manually!"
# endif
#elif !defined(FPL_NO_APPTYPE) && !(defined(FPL_APPTYPE_CONSOLE) || defined(FPL_APPTYPE_WINDOW))
# if !defined(FPL_NO_WINDOW)
//! Detected window application type
# define FPL_APPTYPE_WINDOW
# else
//! Detected console application type
# define FPL_APPTYPE_CONSOLE
# endif
#endif
//
// Include entry points always when its not disabled and implementation block is compiled in
//
#if defined(FPL_IMPLEMENTATION) && !defined(FPL_NO_ENTRYPOINT)
# define FPL_ENTRYPOINT
#endif
//
// Debug/Release detection
//
#if defined(FPL_DEBUG)
//! Debug mode detected
# define FPL_ENABLE_DEBUG
#elif defined(FPL_RELEASE)
//! Release mode detected
# define FPL_ENABLE_RELEASE
#endif
//
// Compiler settings
//
#if defined(FPL_COMPILER_MSVC)
//! Debug/Release detection
# if !defined(FPL_ENABLE_DEBUG) && !defined(FPL_ENABLE_RELEASE)
# if defined(_DEBUG) || (!defined(NDEBUG))
//! Debug mode detected
# define FPL_ENABLE_DEBUG
# else
//! Non-debug (Release) mode detected
# define FPL_ENABLE_RELEASE
# endif
# endif
//! Function name macro (Win32)
# define FPL_FUNCTION_NAME __FUNCTION__
//! Setup MSVC subsystem hints
# if defined(FPL_APPTYPE_WINDOW)
# pragma comment(linker, "/SUBSYSTEM:WINDOWS")
# elif defined(FPL_APPTYPE_CONSOLE)
# pragma comment(linker, "/SUBSYSTEM:CONSOLE")
# endif
// Setup MSVC linker hints
# pragma comment(lib, "kernel32.lib")
#else
//! Function name macro (Other compilers)
# define FPL_FUNCTION_NAME __FUNCTION__
#endif // FPL_COMPILER
//
// Debug/Release fallback
//
#if !defined(FPL_ENABLE_DEBUG) && !defined(FPL_ENABLE_RELEASE)
//! Debug mode fallback
# define FPL_ENABLE_DEBUG
#endif
// MingW compiler hack
#if defined(FPL_COMPILER_MINGW)
# if !defined(_WIN32_WINNT)
# define _WIN32_WINNT 0x0600
# endif //!_WIN32_WINNT
#endif // FPL_COMPILER_MINGW
//
// Options & Feature detection
//
// Assertions
#if !defined(FPL_NO_ASSERTIONS)
# if !defined(FPL_FORCE_ASSERTIONS)
# if defined(FPL_ENABLE_DEBUG)
//! Enable Assertions in Debug Mode by default
# define FPL_ENABLE_ASSERTIONS
# endif
# else
//! Enable Assertions always
# define FPL_ENABLE_ASSERTIONS
# endif
#endif // !FPL_NO_ASSERTIONS
#if defined(FPL_ENABLE_ASSERTIONS)
# if !defined(FPL_NO_C_ASSERT) && !defined(FPL_NO_CRT)
//! Enable C-Runtime Assertions by default
# define FPL_ENABLE_C_ASSERT
# endif
#endif // FPL_ENABLE_ASSERTIONS
// Window
#if !defined(FPL_NO_WINDOW) && !defined(FPL_APPTYPE_CONSOLE)
//! Window support enabled by default
# define FPL_SUPPORT_WINDOW
#endif
// Video
#if !defined(FPL_NO_VIDEO)
//! Video support
# define FPL_SUPPORT_VIDEO
#endif
#if defined(FPL_SUPPORT_VIDEO)
# if !defined(FPL_NO_VIDEO_OPENGL)
//! OpenGL support enabled by default
# define FPL_SUPPORT_VIDEO_OPENGL
# endif
# if !defined(FPL_NO_VIDEO_SOFTWARE)
//! Software rendering support enabled by default
# define FPL_SUPPORT_VIDEO_SOFTWARE
# endif
#endif // FPL_SUPPORT_VIDEO
// Audio
#if !defined(FPL_NO_AUDIO)
//! Audio support
# define FPL_SUPPORT_AUDIO
#endif
#if defined(FPL_SUPPORT_AUDIO)
# if !defined(FPL_NO_AUDIO_DIRECTSOUND) && defined(FPL_PLATFORM_WIN32)
//! DirectSound support is only available on Win32
# define FPL_SUPPORT_AUDIO_DIRECTSOUND
# endif
# if !defined(FPL_NO_AUDIO_ALSA) && defined(FPL_PLATFORM_LINUX)
//! ALSA support is only available on POSIX
# define FPL_SUPPORT_AUDIO_ALSA
# endif
#endif // FPL_SUPPORT_AUDIO
// Remove video support when window is disabled
#if !defined(FPL_SUPPORT_WINDOW)
# if defined(FPL_SUBPLATFORM_X11)
# undef FPL_SUBPLATFORM_X11
# endif
# if defined(FPL_SUPPORT_VIDEO)
# undef FPL_SUPPORT_VIDEO
# endif
# if defined(FPL_SUPPORT_VIDEO_OPENGL)
# undef FPL_SUPPORT_VIDEO_OPENGL
# endif
# if defined(FPL_SUPPORT_VIDEO_SOFTWARE)
# undef FPL_SUPPORT_VIDEO_SOFTWARE
# endif
#endif // !FPL_SUPPORT_WINDOW
//
// Enable supports (FPL uses _ENABLE_ internally only)
//
#if defined(FPL_SUPPORT_WINDOW)
//! Enable Window
# define FPL_ENABLE_WINDOW
#endif
#if defined(FPL_SUPPORT_VIDEO)
//! Enable Video
# define FPL_ENABLE_VIDEO
# if defined(FPL_SUPPORT_VIDEO_OPENGL)
//! Enable OpenGL Video
# define FPL_ENABLE_VIDEO_OPENGL
# endif
# if defined(FPL_SUPPORT_VIDEO_SOFTWARE)
//! Enable Software Rendering Video
# define FPL_ENABLE_VIDEO_SOFTWARE
# endif
#endif // FPL_SUPPORT_VIDEO
#if defined(FPL_SUPPORT_AUDIO)
//! Enable Audio
# define FPL_ENABLE_AUDIO
# if defined(FPL_SUPPORT_AUDIO_DIRECTSOUND)
//! Enable DirectSound Audio
# define FPL_ENABLE_AUDIO_DIRECTSOUND
# endif
# if defined(FPL_SUPPORT_AUDIO_ALSA)
//! Enable ALSA Audio
# define FPL_ENABLE_AUDIO_ALSA
# endif
#endif // FPL_SUPPORT_AUDIO
#if defined(FPL_LOGGING)
//! Enable logging
# define FPL_ENABLE_LOGGING
# if defined(FPL_LOG_MULTIPLE_WRITERS)
//! Enable multiple writers
# define FPL_ENABLE_LOG_MULTIPLE_WRITERS
# endif
#endif
//
// Assertions & Debug
//
/**
* @defgroup Debug Assertion & Debug
* @brief This category contains assertion & debug macro functions
* @{
*/
#if defined(FPL_ENABLE_ASSERTIONS)
# if defined(FPL_ENABLE_C_ASSERT) && !defined(FPL_FORCE_ASSERTIONS)
//! Include assert.h
# define FPL__INCLUDE_ASSERT
//! Runtime assert (C Runtime)
# define fplAssert(exp) assert(exp)
# if defined(__cplusplus)
# define fplStaticAssert(exp) static_assert(exp, "fpl_static_assert")
# endif
# else
//! Runtime assert
# define fplAssert(exp) if(!(exp)) {*(int *)0 = 0;}
# endif // FPL_ENABLE_C_ASSERT
# if !defined(fplStaticAssert)
//! Internal static assert wrapper
# define FPL__STATICASSERT_0(exp, line, counter) \
int fpl__ct_assert_##line_##counter(int ct_assert_failed[(exp)?1:-1])
//! Compile time assert
# define fplStaticAssert(exp) \
FPL__STATICASSERT_0(exp, __LINE__, __COUNTER__)
# endif
#else
//! Runtime assertions disabled
# define fplAssert(exp)
//! Compile time assertions disabled
# define fplStaticAssert(exp)
#endif // FPL_ENABLE_ASSERTIONS
//
// Debug-Break
// Based on: https://stackoverflow.com/questions/173618/is-there-a-portable-equivalent-to-debugbreak-debugbreak
//
#if defined(__has_builtin)
# if __has_builtin(__builtin_debugtrap)
//! Stop on a line in the debugger (Trap)
# define fplDebugBreak() __builtin_debugtrap()
# elif __has_builtin(__debugbreak)
//! Stop on a line in the debugger (Break)
# define fplDebugBreak() __debugbreak()
# endif
#endif
#if !defined(fplDebugBreak)
# if defined(FPL_COMPILER_MSVC) || defined(FPL_COMPILER_INTEL)
//! Stop on a line in the debugger (MSVC/Intel)
# define fplDebugBreak() __debugbreak()
# elif defined(FPL_COMPILER_ARM)
//! Stop on a line in the debugger (Arm)
# define fplDebugBreak() __breakpoint(42)
# elif defined(FPL_ARCH_X86) || defined(FPL_ARCH_X64)
//! Stop on a line in the debugger (X86/64)
static fpl_force_inline void fplDebugBreak() { __asm__ __volatile__("int $03"); }
# elif defined(__thumb__)
//! Stop on a line in the debugger (ARM Thumb mode)
static fpl_force_inline void fplDebugBreak() { __asm__ __volatile__(".inst 0xde01"); }
# elif defined(FPL_ARCH_ARM64)
//! Stop on a line in the debugger (ARM64)
static fpl_force_inline void fplDebugBreak() { __asm__ __volatile__(".inst 0xd4200000"); }
# elif defined(FPL_ARCH_ARM32)
//! Stop on a line in the debugger (ARM32)
static fpl_force_inline void fplDebugBreak() { __asm__ __volatile__(".inst 0xe7f001f0"); }
# elif defined(FPL_COMPILER_GCC)
//! Stop on a line in the debugger (GCC)
# define fplDebugBreak() __builtin_trap()
# else
//! Include signal.h
# define FPL__INCLUDE_SIGNAL
# if defined(SIGTRAP)
//! Stop on a line in the debugger (Sigtrap)
# define fplDebugBreak() raise(SIGTRAP)
# else
//! Stop on a line in the debugger (Sigabort)
# define fplDebugBreak() raise(SIGABRT)
# endif
# endif
#endif
/** @}*/
//
// Types & Limits
//
//! @cond FPL_INTERNAL
#include <stdint.h> // uint32_t, ...
#include <stddef.h> // size_t
#include <stdbool.h> // bool
#include <stdarg.h> // va_start, va_end, va_list, va_arg
#include <limits.h> // UINT32_MAX, ...
#if defined(FPL__INCLUDE_ASSERT)
# include <assert.h>
#endif
#if defined(FPL__INCLUDE_SIGNAL)
# include <signal.h>
#endif
//! @endcond
// On android or older posix versions there is no UINT32_MAX
#if !defined(UINT32_MAX)
//! Define max for uint32_t
# define UINT32_MAX ((uint32_t)-1)
#endif
#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (_MSC_VER >= 1900))
//! Null
# define fpl_null nullptr
#elif defined(NULL)
//! Null
# define fpl_null NULL
#else
//! Null
# define fpl_null 0
#endif
//! 32-bit boolean
typedef int32_t fpl_b32;
//
// Test sizes
//
// @WARNING(final): At the moment this is sufficient, but as soon as there are special CPUs detected this may break!
#if defined(FPL_CPU_64BIT)
fplStaticAssert(sizeof(uintptr_t) == sizeof(uint64_t));
fplStaticAssert(sizeof(size_t) == sizeof(uint64_t));
#elif defined(FPL_CPU_32BIT)
fplStaticAssert(sizeof(uintptr_t) == sizeof(uint32_t));
fplStaticAssert(sizeof(size_t) == sizeof(uint32_t));
#endif
//
// Macro functions
//
/**
* @defgroup Macros Function macros
* @brief This category contains several useful macro functions
* @{
*/
//! This will full-on crash when something is not implemented always.
#define FPL_NOT_IMPLEMENTED {*(int *)0 = 0xBAD;}
#if defined(FPL_IS_C99)
//! Initialize a struct to zero (C99)
# define fplZeroInit {0}
//! Sets a struct pointer to the given value (C99)
# define fplStructSet(ptr, type, value) *(ptr) = (type)value
//! Inits a struct by the given type (C99)
# define fplStructInit(type, ...) (type){## __VA_ARGS__}
#else
//! Initialize a struct to zero (C++)
# define fplZeroInit {}
//! Sets a struct pointer to the given value (C++)
# define fplStructSet(ptr, type, value) *(ptr) = value
//! Inits a struct by the given type (C++)
# define fplStructInit(type, ...) {__VA_ARGS__}
#endif
//! Returns the offset for the value to satisfy the given alignment boundary
#define fplGetAlignmentOffset(value, alignment) ( (((alignment) > 1) && (((value) & ((alignment) - 1)) != 0)) ? ((alignment) - ((value) & (alignment - 1))) : 0)
//! Returns the given size extended to satisfy the given alignment boundary
#define fplGetAlignedSize(size, alignment) (((size) > 0 && (alignment) > 0) ? ((size) + fplGetAlignmentOffset(size, alignment)) : (size))
//! Returns true when the given pointer address is aligned to the given alignment
#define fplIsAligned(ptr, alignment) (((uintptr_t)(const void *)(ptr)) % (alignment) == 0)
//! Returns true when the given value is a power of two value
#define fplIsPowerOfTwo(value) (((value) != 0) && (((value) & (~(value) + 1)) == (value)))
//! Returns true when the given platform is big-endian
#define fplIsBigEndian() (*(uint16_t *)"\0\xff" < 0x100)
//! Returns true when the given platform is big-endian
#define fplIsLittleEndian() (!fplIsBigEndian())
//! Returns the number of bytes for the given kilobytes
#define fplKiloBytes(value) (((value) * 1024ull))
//! Returns the number of bytes for the given megabytes
#define fplMegaBytes(value) ((fplKiloBytes(value) * 1024ull))
//! Returns the number of bytes for the given gigabytes
#define fplGigaBytes(value) ((fplMegaBytes(value) * 1024ull))
//! Returns the number of bytes for the given terabytes
#define fplTeraBytes(value) ((fplGigaBytes(value) * 1024ull))
//! Clears the given struct pointer to zero
#define fplClearStruct(ptr) fplMemoryClear((void *)(ptr), sizeof(*(ptr)))
//! Copies the given source struct into the destination struct
#define fplCopyStruct(src, dst) fplMemoryCopy(src, sizeof(*(src)), dst);
//! Returns the element count from a static array,
#define fplArrayCount(arr) (sizeof(arr) / sizeof((arr)[0]))
//! Returns the offset in bytes to a field in a structure
#define fplOffsetOf(type, field) ((size_t)(&(((type*)(0))->field)))
//! Returns the smallest value
#define fplMin(a, b) ((a) < (b) ? (a) : (b))
//! Returns the biggest value
#define fplMax(a, b) ((a) > (b) ? (a) : (b))
#if defined(FPL_PLATFORM_WIN32)
//! Manually allocate memory on the stack (Win32)
# include <malloc.h>
# define fplStackAllocate(size) _alloca(size)
#else
# if defined(FPL_PLATFORM_LINUX)
# include <alloca.h>
# endif
//! Manually allocate memory on the stack (Non-Win32)
# define fplStackAllocate(size) alloca(size)
#endif
/** @}*/
#if defined(FPL_IS_CPP)
//! Macro for overloading enum operators in C++
# define FPL_ENUM_AS_FLAGS_OPERATORS(etype) \
inline etype operator | (etype a, etype b) { \
return static_cast<etype>(static_cast<int>(a) | static_cast<int>(b)); \
} \
inline etype& operator |= (etype &a, etype b) { \
return a = a | b; \
} \
inline etype operator & (etype a, etype b) { \
return static_cast<etype>(static_cast<int>(a) & static_cast<int>(b)); \
} \
inline etype& operator &= (etype &a, etype b) { \
return a = a & b; \
} \
inline etype operator ~ (etype a) { \
return static_cast<etype>(~static_cast<int>(a)); \
} \
inline etype operator ^ (etype a, etype b) { \
return static_cast<etype>(static_cast<int>(a) ^ static_cast<int>(b)); \
} \
inline etype& operator ^= (etype &a, etype b) { \
return a = a ^ b; \
}
#else
//! No need to overload operators for enums in C99
# define FPL_ENUM_AS_FLAGS_OPERATORS(etype)
#endif
// ****************************************************************************
//
// Platform Includes
//
// ****************************************************************************
#if defined(FPL_PLATFORM_WIN32)
// @NOTE(final): windef.h defines min/max macros defined in lowerspace, this will break for example std::min/max so we have to tell the header we dont want this!
# if !defined(NOMINMAX)
# define NOMINMAX
# endif
// @NOTE(final): For now we dont want any network, com or gdi stuff at all, maybe later who knows.
# if !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN 1
# endif
# include <Windows.h> // Win32 api
# if _WIN32_WINNT < 0x0600
# error "Windows Vista or higher required!"
# endif
#endif // FPL_PLATFORM_WIN32
#if defined(FPL_SUBPLATFORM_POSIX)
# include <pthread.h> // pthread_t, pthread_mutex_, pthread_cond_, pthread_barrier_
# include <semaphore.h> // sem_t
# include <dirent.h> // DIR, dirent
#endif // FPL_SUBPLATFORM_POSIX
#if defined(FPL_SUBPLATFORM_X11)
# include <X11/X.h> // Window
# include <X11/Xlib.h> // Display
# include <X11/Xutil.h> // XVisualInfo
# include <X11/Xatom.h> // XA_CARDINAL
#endif // FPL_SUBPLATFORM_X11
//
// Constants
//
/**
* @defgroup Constants Constants
* @brief This category contains constants
* @{
*/
#if defined(FPL_PLATFORM_WIN32)
//! Maximum length of a filename (Win32)
# define FPL_MAX_FILENAME_LENGTH (MAX_PATH + 1)
//! Maximum length of a path (Win32)
# define FPL_MAX_PATH_LENGTH (MAX_PATH * 2 + 1)
//! Path separator character (Win32)
# define FPL_PATH_SEPARATOR '\\'
//! File extension character (Win32)
# define FPL_FILE_EXT_SEPARATOR '.'
#else
//! Maximum length of a filename (Non win32)
# define FPL_MAX_FILENAME_LENGTH (512 + 1)
//! Maximum length of a path (Non win32)
# define FPL_MAX_PATH_LENGTH (2048 + 1)
//! Path separator character (Non win32)
# define FPL_PATH_SEPARATOR '/'
//! File extension character (Non win32)
# define FPL_FILE_EXT_SEPARATOR '.'
#endif
//! Maximum length of a name (in characters)
#define FPL_MAX_NAME_LENGTH (256 + 1)
//! Maximum length of a internal buffer (in bytes)
#define FPL_MAX_BUFFER_LENGTH (2048 + 1)
/** @}*/
// ****************************************************************************
//
// API
//
// ****************************************************************************
// ----------------------------------------------------------------------------
/**
* @defgroup Atomics Atomic operations
* @brief This category contains functions for handling atomic operations, such as Add, Compare And/Or Exchange, Fences, Loads/Stores, etc.
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Inserts a memory read fence/barrier.
* @note This will complete previous reads before future reads and prevents the compiler from reordering memory reads across this fence.
*/
fpl_platform_api void fplAtomicReadFence();
/**
* @brief Inserts a memory write fence/barrier.
* @note This will complete previous writes before future writes and prevents the compiler from reordering memory writes across this fence.
*/
fpl_platform_api void fplAtomicWriteFence();
/**
* @brief Inserts a memory read/write fence/barrier.
* @note This will complete previous reads/writes before future reads/writes and prevents the compiler from reordering memory access across this fence.
*/
fpl_platform_api void fplAtomicReadWriteFence();
/**
* @brief Replaces a 32-bit unsigned integer with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint32_t fplAtomicExchangeU32(volatile uint32_t *target, const uint32_t value);
/**
* @brief Replaces a 64-bit unsigned integer with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint64_t fplAtomicExchangeU64(volatile uint64_t *target, const uint64_t value);
/**
* @brief Replaces a 32-bit signed integer with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int32_t fplAtomicExchangeS32(volatile int32_t *target, const int32_t value);
/**
* @brief Replaces a 64-bit signed integer with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int64_t fplAtomicExchangeS64(volatile int64_t *target, const int64_t value);
/**
* @brief Replaces a pointer with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api void *fplAtomicExchangePtr(volatile void **target, const void *value);
/**
* @brief Replaces a size with the given value atomically.
* @param target The target value to write into
* @param value The source value used for exchange
* @return Returns the initial value before the replacement.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api size_t fplAtomicExchangeSize(volatile size_t *target, const size_t value);
/**
* @brief Adds a 32-bit unsigned integer to the value by the given addend atomically.
* @param value The target value to append to
* @param addend The value used for adding
* @return Returns the initial value before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint32_t fplAtomicFetchAndAddU32(volatile uint32_t *value, const uint32_t addend);
/**
* @brief Adds a 64-bit unsigned integer to the value by the given addend atomically.
* @param value The target value to append to
* @param addend The value used for adding
* @return Returns the initial value before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint64_t fplAtomicFetchAndAddU64(volatile uint64_t *value, const uint64_t addend);
/**
* @brief Adds a 32-bit signed integer to the value by the given addend atomically.
* @param value The target value to append to
* @param addend The value used for adding
* @return Returns the initial value before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int32_t fplAtomicFetchAndAddS32(volatile int32_t *value, const int32_t addend);
/**
* @brief Adds a 64-bit signed integer to the value by the given addend atomically.
* @param value The target value to append to
* @param addend The value used for adding
* @return Returns the initial value before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int64_t fplAtomicFetchAndAddS64(volatile int64_t *value, const int64_t addend);
/**
* @brief Adds a size to the value by the given addend atomically.
* @param dest The target value to append to
* @param addend The value used for adding
* @return Returns the initial value before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api size_t fplAtomicFetchAndAddSize(volatile size_t *dest, const size_t addend);
/**
* @brief Adds a value to the pointer by the given addend atomically.
* @param dest The target pointer to append to
* @param addend The value used for adding
* @return Returns the initial pointer before the append.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api void *fplAtomicFetchAndAddPtr(volatile void **dest, const intptr_t addend);
/**
* @brief Increments the given 32-bit unsigned integer by one atomically.
* @param value The target value to increment
* @return Returns the value after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint32_t fplAtomicAddAndFetchU32(volatile uint32_t *value);
/**
* @brief Increments the given 64-bit unsigned integer by one atomically.
* @param value The target value to increment
* @return Returns the value after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api uint64_t fplAtomicAddAndFetchU64(volatile uint64_t *value);
/**
* @brief Increments the given 32-bit signed integer by one atomically.
* @param value The target value to increment
* @return Returns the value after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int32_t fplAtomicAddAndFetchS32(volatile int32_t *value);
/**
* @brief Increments the given 64-bit signed integer by one atomically.
* @param value The target value to increment
* @return Returns the value after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api int64_t fplAtomicAddAndFetchS64(volatile int64_t *value);
/**
* @brief Increments the given size atomically.
* @param value The target value to increment
* @return Returns the value after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api size_t fplAtomicAddAndFetchSize(volatile size_t *value);
/**
* @brief Increments the given pointer atomically.
* @param value The target pointer to increment
* @return Returns the pointer after the increment.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api void *fplAtomicAddAndFetchPtr(volatile void **value);
/**
* @brief Compares a 32-bit unsigned integer with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapU32() when you want to check if the exchange has happened or not.
*/
fpl_platform_api uint32_t fplAtomicCompareAndSwapU32(volatile uint32_t *dest, const uint32_t comparand, const uint32_t exchange);
/**
* @brief Compares a 64-bit unsigned integer with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapU64() when you want to check if the exchange has happened or not.
*/
fpl_platform_api uint64_t fplAtomicCompareAndSwapU64(volatile uint64_t *dest, const uint64_t comparand, const uint64_t exchange);
/**
* @brief Compares a 32-bit signed integer with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapS32() when you want to check if the exchange has happened or not.
*/
fpl_platform_api int32_t fplAtomicCompareAndSwapS32(volatile int32_t *dest, const int32_t comparand, const int32_t exchange);
/**
* @brief Compares a 64-bit signed integer with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapS64() when you want to check if the exchange has happened or not.
*/
fpl_platform_api int64_t fplAtomicCompareAndSwapS64(volatile int64_t *dest, const int64_t comparand, const int64_t exchange);
/**
* @brief Compares a size with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapPtr() when you want to check if the exchange has happened or not.
*/
fpl_common_api size_t fplAtomicCompareAndSwapSize(volatile size_t *dest, const size_t comparand, const size_t exchange);
/**
* @brief Compares a pointer with a comparand and swaps it when comparand matches destination.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns the value of the destination before the swap, regardless of the result.
* @note Ensures that memory operations are completed in order.
* @note Use @ref fplIsAtomicCompareAndSwapPtr() when you want to check if the exchange has happened or not.
*/
fpl_common_api void *fplAtomicCompareAndSwapPtr(volatile void **dest, const void *comparand, const void *exchange);
/**
* @brief Compares a 32-bit unsigned integer with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api bool fplIsAtomicCompareAndSwapU32(volatile uint32_t *dest, const uint32_t comparand, const uint32_t exchange);
/**
* @brief Compares a 64-bit unsigned integer with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api bool fplIsAtomicCompareAndSwapU64(volatile uint64_t *dest, const uint64_t comparand, const uint64_t exchange);
/**
* @brief Compares a 32-bit signed integer with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api bool fplIsAtomicCompareAndSwapS32(volatile int32_t *dest, const int32_t comparand, const int32_t exchange);
/**
* @brief Compares a 64-bit signed integer with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_platform_api bool fplIsAtomicCompareAndSwapS64(volatile int64_t *dest, const int64_t comparand, const int64_t exchange);
/**
* @brief Compares a size with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api bool fplIsAtomicCompareAndSwapSize(volatile size_t *dest, const size_t comparand, const size_t exchange);
/**
* @brief Compares a pointer with a comparand and swaps it when comparand matches destination and returns a bool indicating the result.
* @param dest The target value to write into
* @param comparand The value to compare with
* @param exchange The value to exchange with
* @return Returns true when the exchange happened, false otherwise.
* @note Ensures that memory operations are completed in order.
*/
fpl_common_api bool fplIsAtomicCompareAndSwapPtr(volatile void **dest, const void *comparand, const void *exchange);
/**
* @brief Loads the 32-bit unsigned value atomically and returns the value.
* @param source The source value to read from
* @return Returns the atomically loaded source value
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
*/
fpl_platform_api uint32_t fplAtomicLoadU32(volatile uint32_t *source);
/**
* @brief Loads the 64-bit unsigned value atomically and returns the value.
* @param source The source value to read from
* @return Returns the atomically loaded source value
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
*/
fpl_platform_api uint64_t fplAtomicLoadU64(volatile uint64_t *source);
/**
* @brief Loads the 32-bit signed value atomically and returns the value.
* @param source The source value to read from
* @return Returns the atomically loaded source value
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
*/
fpl_platform_api int32_t fplAtomicLoadS32(volatile int32_t *source);
/**
* @brief Loads the 64-bit signed value atomically and returns the value.
* @param source The source value to read from
* @return Returns the atomically loaded source value
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
*/
fpl_platform_api int64_t fplAtomicLoadS64(volatile int64_t *source);
/**
* @brief Loads the size value atomically and returns the value.
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
* @param source The source value to read from
* @return Returns the atomically loaded source value
*/
fpl_common_api size_t fplAtomicLoadSize(volatile size_t *source);
/**
* @brief Loads the pointer value atomically and returns the value.
* @note Ensures that memory operations are completed before the read.
* @note This may use a CAS instruction when there is no suitable compiler intrinsics found.
* @param source The source value to read from
* @return Returns the atomically loaded source value
*/
fpl_common_api void *fplAtomicLoadPtr(volatile void **source);
/**
* @brief Overwrites the 32-bit unsigned value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_platform_api void fplAtomicStoreU32(volatile uint32_t *dest, const uint32_t value);
/**
* @brief Overwrites the 64-bit unsigned value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_platform_api void fplAtomicStoreU64(volatile uint64_t *dest, const uint64_t value);
/**
* @brief Overwrites the 32-bit signed value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_platform_api void fplAtomicStoreS32(volatile int32_t *dest, const int32_t value);
/**
* @brief Overwrites the 64-bit signed value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_platform_api void fplAtomicStoreS64(volatile int64_t *dest, const int64_t value);
/**
* @brief Overwrites the size value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_common_api void fplAtomicStoreSize(volatile size_t *dest, const size_t value);
/**
* @brief Overwrites the pointer value atomically.
* @param dest The destination to write to
* @param value The value to exchange with
* @note Ensures that memory operations are completed before the write.
*/
fpl_common_api void fplAtomicStorePtr(volatile void **dest, const void *value);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup OS Operating system infos
* @brief This category contains functions for retrievement several operating system informations such as version, name etc.
* @{
*
*/
// ----------------------------------------------------------------------------
//! A type definition mapping a part of a version number
typedef char fplVersionNumberPart[4 + 1];
//! A structure that contains version information
typedef struct fplVersionInfo {
//! Full name
char fullName[FPL_MAX_NAME_LENGTH];
union {
//! Version number as array
fplVersionNumberPart values[4];
struct {
//! Major version
fplVersionNumberPart major;
//! Minor version
fplVersionNumberPart minor;
//! Fix version
fplVersionNumberPart fix;
//! Build version
fplVersionNumberPart build;
};
};
} fplVersionInfo;
//! A structure that contains operating system infos
typedef struct fplOSInfos {
//! Name of the operating system
char osName[FPL_MAX_NAME_LENGTH];
//! Name of the distribution (May be empty)
char distributionName[FPL_MAX_NAME_LENGTH];
//! Version of the operating system
fplVersionInfo osVersion;
//! Version of the distribution (May be empty)
fplVersionInfo distributionVersion;
} fplOSInfos;
/**
* @brief Gets system informations from the operating system
* @param outInfos The target @ref fplOSInfos structure
* @return Returns true when the infos could be retrieved, false otherwise.
* @note This may be called without initializing the platform
*/
fpl_platform_api bool fplGetOperatingSystemInfos(fplOSInfos *outInfos);
/**
* @brief Gets the username of the current logged-in user
* @param nameBuffer The target buffer
* @param maxNameBufferLen The max length of the target buffer
* @return Returns true when a username could be retrieved, false otherwise.
*/
fpl_platform_api bool fplGetCurrentUsername(char *nameBuffer, const size_t maxNameBufferLen);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Hardware Hardware infos
* @brief This category contains functions for retrievement hardware informations such as memory usage, cpu infos, etc.
* @{
*
*/
// ----------------------------------------------------------------------------
//! A structure that contains informations about current memory usage
typedef struct fplMemoryInfos {
//! Size of physical installed memory in bytes
uint64_t installedPhysicalSize;
//! Total size of physical memory in bytes (May be less than size of installed physical memory, due to shared memory stuff)
uint64_t totalPhysicalSize;
//! Available physical memory in bytes
uint64_t freePhysicalSize;
//! Total size of memory cache in bytes
uint64_t totalCacheSize;
//! Available size of the memory cache in bytes
uint64_t freeCacheSize;
//! Total number of memory pages
uint64_t totalPageCount;
//! Number of available memory pages
uint64_t freePageCount;
//! Page size in bytes
uint64_t pageSize;
} fplMemoryInfos;
//! An enumeration of architecture types
typedef enum fplArchType {
//! Unknown architecture
fplArchType_Unknown = 0,
//! X86 architecture
fplArchType_x86,
//! X86 with 64-bit architecture
fplArchType_x86_64,
//! X64 only architecture
fplArchType_x64,
//! ARM32 architecture
fplArchType_Arm32,
//! ARM64 architecture
fplArchType_Arm64,
} fplArchType;
/**
* @brief Gets the string representation of the given architecture type
* @param type The @ref fplArchType enumeration value
* @return Returns a string for the given architecture type
*/
fpl_common_api const char *fplGetArchTypeString(const fplArchType type);
/**
* @brief Retrieves the total number of processor cores.
* @return Returns the total number of processor cores.
*/
fpl_platform_api size_t fplGetProcessorCoreCount();
/**
* @brief Retrieves the name of the processor.
* @param destBuffer The destination buffer
* @param maxDestBufferLen The max length of the destination buffer
* @return Returns a pointer to the last written character or @ref fpl_null otherwise.
*/
fpl_platform_api char *fplGetProcessorName(char *destBuffer, const size_t maxDestBufferLen);
/**
* @brief Gets the processor architecture type
* @return Returns the processor architecture type
*/
fpl_platform_api fplArchType fplGetProcessorArchitecture();
/**
* @brief Retrieves the current system memory usage.
* @param outInfos The target @ref fplMemoryInfos structure
* @return Returns true when the memory infos was retrieved, false otherwise.
*/
fpl_platform_api bool fplGetRunningMemoryInfos(fplMemoryInfos *outInfos);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Settings Settings & Configurations
* @brief This category contains global settings structures/enumerations and functions to initialize/set them
* @{
*/
// ----------------------------------------------------------------------------
//! An enumeration of initialization flags
typedef enum fplInitFlags {
//! No init flags
fplInitFlags_None = 0,
//! Create a console window
fplInitFlags_Console = 1 << 0,
//! Create a single window
fplInitFlags_Window = 1 << 1,
//! Use a video backbuffer (This flag ensures that @ref fplInitFlags_Window is included always)
fplInitFlags_Video = 1 << 2,
//! Use asyncronous audio playback
fplInitFlags_Audio = 1 << 3,
//! Support for game controllers
fplInitFlags_GameController = 1 << 4,
} fplInitFlags;
//! InitFlags operator overloads for C++
FPL_ENUM_AS_FLAGS_OPERATORS(fplInitFlags);
//! Default init flags for initializing everything
static const fplInitFlags fplInitFlags_All = fplInitFlags_Console | fplInitFlags_Window | fplInitFlags_Video | fplInitFlags_Audio | fplInitFlags_GameController;
//! An enumeration of platform types
typedef enum fplPlatformType {
//! Unknown platform
fplPlatformType_Unknown = 0,
//! Windows platform
fplPlatformType_Windows,
//! Linux platform
fplPlatformType_Linux,
//! Unix platform
fplPlatformType_Unix,
} fplPlatformType;
//! An emnumeration of platform result types
typedef enum fplPlatformResultType {
//! Window creation failed
fplPlatformResultType_FailedWindow = -50,
//! Audio initialization failed
fplPlatformResultType_FailedAudio = -40,
//! Video initialization failed
fplPlatformResultType_FailedVideo = -30,
//! Platform initialization failed
fplPlatformResultType_FailedPlatform = -20,
//! Failed allocating required memory
fplPlatformResultType_FailedAllocatingMemory = -10,
//! Platform is already initialized
fplPlatformResultType_AlreadyInitialized = -1,
//! Platform is not initialized
fplPlatformResultType_NotInitialized = 0,
//! Everything is fine
fplPlatformResultType_Success = 1,
} fplPlatformResultType;
/**
* @brief Gets the string representation of a platform result type.
* @param type The platform result type as @ref fplPlatformResultType
* @return Returns the string representation of a platform result type.
*/
fpl_common_api const char *fplGetPlatformResultTypeString(const fplPlatformResultType type);
//! An enumeration of video driver types
typedef enum fplVideoDriverType {
//! No video driver
fplVideoDriverType_None = 0,
//! OpenGL
fplVideoDriverType_OpenGL,
//! Software
fplVideoDriverType_Software
} fplVideoDriverType;
#if defined(FPL_ENABLE_VIDEO_OPENGL)
//! An enumeration of OpenGL compability flags
typedef enum fplOpenGLCompabilityFlags {
//! Use legacy context
fplOpenGLCompabilityFlags_Legacy = 0,
//! Use core profile
fplOpenGLCompabilityFlags_Core = 1 << 1,
//! Use compability profile
fplOpenGLCompabilityFlags_Compability = 1 << 2,
//! Remove features marked as deprecated
fplOpenGLCompabilityFlags_Forward = 1 << 3,
} fplOpenGLCompabilityFlags;
//! A structure that contains OpenGL video settings
typedef struct fplOpenGLVideoSettings {
//! Compability flags
fplOpenGLCompabilityFlags compabilityFlags;
//! Desired major version
uint32_t majorVersion;
//! Desired minor version
uint32_t minorVersion;
//! Multisampling count
uint8_t multiSamplingCount;
} fplOpenGLVideoSettings;
#endif // FPL_ENABLE_VIDEO_OPENGL
//! A union that contains graphics api settings
typedef union fplGraphicsApiSettings {
#if defined(FPL_ENABLE_VIDEO_OPENGL)
//! OpenGL settings
fplOpenGLVideoSettings opengl;
#endif
//! Dummy field when no graphics drivers are available
int dummy;
} fplGraphicsApiSettings;
//! A structure that contains video settings such as driver, vsync, api-settings etc.
typedef struct fplVideoSettings {
//! Graphics Api settings
fplGraphicsApiSettings graphics;
//! Video driver type
fplVideoDriverType driver;
//! Is vertical syncronisation enabled. Useable only for hardware rendering!
fpl_b32 isVSync;
//! Is backbuffer automatically resized. Useable only for software rendering!
fpl_b32 isAutoSize;
} fplVideoSettings;
/**
* @brief Resets the given video settings to default values
* @param video The target @ref fplVideoSettings structure
* @note This will not change any video settings! To change the actual settings you have to pass the entire @ref fplSettings container to a argument in @ref fplPlatformInit().
*/
fpl_common_api void fplSetDefaultVideoSettings(fplVideoSettings *video);
//! An enumeration of audio driver types
typedef enum fplAudioDriverType {
//! No audio driver
fplAudioDriverType_None = 0,
//! Auto detection
fplAudioDriverType_Auto,
//! DirectSound
fplAudioDriverType_DirectSound,
//! ALSA
fplAudioDriverType_Alsa,
} fplAudioDriverType;
//! An enumeration of audio format types
typedef enum fplAudioFormatType {
// No audio format
fplAudioFormatType_None = 0,
// Unsigned 8-bit integer PCM
fplAudioFormatType_U8,
// Signed 16-bit integer PCM
fplAudioFormatType_S16,
// Signed 24-bit integer PCM
fplAudioFormatType_S24,
// Signed 32-bit integer PCM
fplAudioFormatType_S32,
// Signed 64-bit integer PCM
fplAudioFormatType_S64,
// 32-bit IEEE_FLOAT
fplAudioFormatType_F32,
// 64-bit IEEE_FLOAT
fplAudioFormatType_F64,
} fplAudioFormatType;
//! A structure containing audio device format runtime properties, such as type, samplerate, channels, etc.
typedef struct fplAudioDeviceFormat {
//! Buffer size in frames
uint32_t bufferSizeInFrames;
//! Buffer size in bytes
uint32_t bufferSizeInBytes;
//! Samples per seconds
uint32_t sampleRate;
//! Number of channels
uint32_t channels;
//! Number of periods
uint32_t periods;
//! Audio format
fplAudioFormatType type;
} fplAudioDeviceFormat;
//! A structure containing audio target format configurations, such as type, samplerate, channels, etc.
typedef struct fplAudioTargetFormat {
//! Buffer size in frames (First choice)
uint32_t bufferSizeInFrames;
//! Buffer size in milliseconds (Second choice)
uint32_t bufferSizeInMilliseconds;
//! Samples per seconds
uint32_t sampleRate;
//! Number of channels
uint32_t channels;
//! Number of periods
uint32_t periods;
//! Audio format
fplAudioFormatType type;
//! Is exclude mode prefered
fpl_b32 preferExclusiveMode;
} fplAudioTargetFormat;
//! A union containing a id of the underlying driver
typedef union fplAudioDeviceID {
#if defined(FPL_ENABLE_AUDIO_DIRECTSOUND)
//! DirectShow Device GUID
GUID dshow;
#endif
#if defined(FPL_ENABLE_AUDIO_ALSA)
//! ALSA Device ID
char alsa[256];
#endif
//! Dummy field (When no drivers are available)
int dummy;
} fplAudioDeviceID;
//! A structure containing the name and the id of the audio device
typedef struct fplAudioDeviceInfo {
//! Device name
char name[FPL_MAX_NAME_LENGTH];
//! Device id
fplAudioDeviceID id;
} fplAudioDeviceInfo;
#if defined(FPL_ENABLE_AUDIO_ALSA)
//! A structure containing settings for the ALSA audio driver
typedef struct fplAlsaAudioSettings {
//! Disable the usage of MMap in ALSA
fpl_b32 noMMap;
} fplAlsaAudioSettings;
#endif
//! A union containing driver specific audio settings
typedef union fplSpecificAudioSettings {
#if defined(FPL_ENABLE_AUDIO_ALSA)
//! Alsa specific settings
fplAlsaAudioSettings alsa;
#endif
//! Dummy field (When no drivers are available)
int dummy;
} fplSpecificAudioSettings;
/**
* @brief A callback for reading audio samples from the client
* @param deviceFormat The pointer to the @ref fplAudioDeviceFormat structure, the audio cards expects
* @param frameCount The numbers if frames the client should write at max
* @param outputSamples The pointer to the target samples
* @param userData The pointer to the user data specified in @ref fplAudioSettings
* @return Returns the number written frames
*/
typedef uint32_t(fpl_audio_client_read_callback)(const fplAudioDeviceFormat *deviceFormat, const uint32_t frameCount, void *outputSamples, void *userData);
//! A structure containing audio settings, such as format, device info, callbacks, driver, etc.
typedef struct fplAudioSettings {
//! The target format
fplAudioTargetFormat targetFormat;
//! The target device
fplAudioDeviceInfo targetDevice;
//! Specific settings
fplSpecificAudioSettings specific;
//! The callback for retrieving audio data from the client
fpl_audio_client_read_callback *clientReadCallback;
//! User data pointer for client read callback
void *userData;
//! The targeted driver
fplAudioDriverType driver;
//! Start playing of audio samples after platform initialization automatically
fpl_b32 startAuto;
//! Stop playing of audio samples before platform release automatically
fpl_b32 stopAuto;
} fplAudioSettings;
/**
* @brief Resets the given audio settings to default settings (S16 PCM, 48 KHz, 2 Channels)
* @param audio The target @ref fplAudioSettings structure
* @note This will not change any audio settings! To change the actual settings you have to pass the entire @ref fplSettings container to a argument in @ref fplPlatformInit().
*/
fpl_common_api void fplSetDefaultAudioSettings(fplAudioSettings *audio);
//! An enumeration of image types
typedef enum fplImageType {
//! No image type
fplImageType_None = 0,
//! RGBA image type
fplImageType_RGBA,
} fplImageType;
//! A structure containing data for working with a image source
typedef struct fplImageSource {
//! Pointer to the source data
const uint8_t *data;
//! Width in pixels
uint32_t width;
//! Height in pixels
uint32_t height;
//! Image type
fplImageType type;
} fplImageSource;
//! OS window event is going to be processed callback type
typedef bool (fpl_window_event_callback)(const fplPlatformType platform, void *windowState, void *eventData, void *userData);
//! Window has been exposed callback type
typedef fpl_window_event_callback fpl_window_exposed_callback;
//! A structure containing the window callbacks
typedef struct fplWindowCallbacks {
//! Expose callback
fpl_window_exposed_callback *exposedCallback;
//! User data pointer for the expose callback
void *exposedUserData;
//! Expose callback
fpl_window_event_callback *eventCallback;
//! User data pointer for the event callback
void *eventUserData;
} fplWindowCallbacks;
//! A structure containing window settings, such as size, title etc.
typedef struct fplWindowSettings {
//! Window title
char windowTitle[FPL_MAX_NAME_LENGTH];
//! Window icons (0 = Small, 1 = Large)
fplImageSource icons[2];
//! Window callbacks
fplWindowCallbacks callbacks;
//! Window width in screen coordinates
uint32_t windowWidth;
//! Window height in screen coordinates
uint32_t windowHeight;
//! Fullscreen width in screen coordinates
uint32_t fullscreenWidth;
//! Fullscreen height in screen coordinates
uint32_t fullscreenHeight;
//! Is window resizable
fpl_b32 isResizable;
//! Is window decorated
fpl_b32 isDecorated;
//! Is floating
fpl_b32 isFloating;
//! Is window in fullscreen mode
fpl_b32 isFullscreen;
} fplWindowSettings;
/**
* @brief Resets the given window settings container to default settings
* @param window The target @ref fplWindowSettings structure
* @note This will not change any window settings! To change the actual settings you have to pass the entire @ref fplSettings container to a argument in @ref fplPlatformInit().
*/
fpl_common_api void fplSetDefaultWindowSettings(fplWindowSettings *window);
//! A structure containing input settings
typedef struct fplInputSettings {
//! Frequency in ms for detecting new or removed controllers (Default: 200)
uint32_t controllerDetectionFrequency;
//! Disable input events entirely (Default: false)
fpl_b32 disabledEvents;
} fplInputSettings;
/**
* @brief Resets the given input settings contains to default values.
* @param input The target @ref fplInputSettings structure
* @note This will not change any input settings! To change the actual settings you have to pass the entire @ref fplSettings container to a argument in @ref fplPlatformInit().
*/
fpl_common_api void fplSetDefaultInputSettings(fplInputSettings *input);
//! A structure containg settings, such as window, video, etc.
typedef struct fplSettings {
//! Window settings
fplWindowSettings window;
//! Video settings
fplVideoSettings video;
//! Audio settings
fplAudioSettings audio;
//! Input settings
fplInputSettings input;
} fplSettings;
/**
* @brief Resets the given settings container to default values for window, video, audio, etc.
* @param settings The target @ref fplSettings structure
* @note This will not change the active settings! To change the actual settings you have to pass this settings container to a argument in @ref fplPlatformInit().
*/
fpl_common_api void fplSetDefaultSettings(fplSettings *settings);
/**
* @brief Creates a full settings structure containing default values
* @return Returns a defaulted @ref fplSettings structure
*/
fpl_common_api fplSettings fplMakeDefaultSettings();
/**
* @brief Gets the current settings
* @return Returns a pointer to the @ref fplSettings structure
*/
fpl_common_api const fplSettings *fplGetCurrentSettings();
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Platform Platform functions
* @brief This category contains structures, enumerations and functions for initializing/releasing the platform.
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Gets the string representation of the given platform type
* @param type The platform type @ref fplPlatformType
* @return Returns the string representation for the given platform type @ref fplPlatformType
*/
fpl_common_api const char *fplGetPlatformTypeString(const fplPlatformType type);
/**
* @brief Initializes the platform layer.
* @param initFlags The init flags @ref fplInitFlags used for enable certain features, like video/audio etc.
* @param initSettings The @ref fplSettings structure to control the platform layer behavior or systems, if null is passed here default values are used automatically.
* @return Returns true when it was successful, false otherwise.
* @note @ref fplPlatformRelease() must be called when you are done! After @ref fplPlatformRelease() has been called you can call this function again if needed.
*/
fpl_common_api bool fplPlatformInit(const fplInitFlags initFlags, const fplSettings *initSettings);
/**
* @brief Gets the result type of the platform initialization
* @return Returns the result type as @ref fplPlatformResultType
*/
fpl_common_api fplPlatformResultType fplGetPlatformResult();
/**
* @brief Releases the resources allocated by the platform layer.
* @note Can only be called when @ref fplPlatformInit() was successful.
*/
fpl_common_api void fplPlatformRelease();
/**
* @brief Gets the type of the platform
* @return Returns the @ref fplPlatformType
*/
fpl_common_api fplPlatformType fplGetPlatformType();
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Logging Logging
* @brief This category contains functions and types for controlling logging output
* @{
*/
// ----------------------------------------------------------------------------
//! An enumeration of log levels
typedef enum fplLogLevel {
//! All
fplLogLevel_All = -1,
//! Critical
fplLogLevel_Critical = 0,
//! Error
fplLogLevel_Error = 1,
//! Warning
fplLogLevel_Warning = 2,
//! Info
fplLogLevel_Info = 3,
//! Verbose
fplLogLevel_Verbose = 4,
//! Debug
fplLogLevel_Debug = 5,
} fplLogLevel;
#if defined(FPL_ENABLE_LOGGING)
/**
* @brief A callback for printing a log message
* @param level The log level @ref fplLogLevel
* @param message The log message string
*/
typedef void (fpl_log_func_callback)(const fplLogLevel level, const char *message);
//! An enumeration of log writer flags
typedef enum fplLogWriterFlags {
//! No appender flags
fplLogWriterFlags_None = 0,
//! Standard-Console output
fplLogWriterFlags_StandardConsole = 1 << 0,
//! Error-Console output
fplLogWriterFlags_ErrorConsole = 1 << 1,
//! Debug output
fplLogWriterFlags_DebugOut = 1 << 2,
//! Custom output
fplLogWriterFlags_Custom = 1 << 3,
} fplLogWriterFlags;
//! Log writer flags enumeration operators
FPL_ENUM_AS_FLAGS_OPERATORS(fplLogWriterFlags);
//! A structure containing console logging properties
typedef struct fplLogWriterConsole {
//! Dummy field
int dummy;
} fplLogWriterConsole;
//! A structure containing properties custom logging properties
typedef struct fplLogWriterCustom {
//! User callback
fpl_log_func_callback *callback;
} fplLogWriterCustom;
//! A structure containing log writer settings
typedef struct fplLogWriter {
//! Flags
fplLogWriterFlags flags;
//! Console
fplLogWriterConsole console;
//! Custom
fplLogWriterCustom custom;
} fplLogWriter;
//! A structure containing log settings
typedef struct fplLogSettings {
#if defined(FPL_ENABLE_LOG_MULTIPLE_WRITERS)
union {
//! All writers
fplLogWriter writers[6];
struct {
//! Critical writer
fplLogWriter criticalWriter;
//! Error writer
fplLogWriter errorWriter;
//! Warning writer
fplLogWriter warningWriter;
//! Info writer
fplLogWriter infoWriter;
//! Verbose writer
fplLogWriter verboseWriter;
//! Debug writer
fplLogWriter debugWriter;
};
};
#else
//! Single writer
fplLogWriter writers[1];
#endif // FPL_USE_LOG_SIMPLE
//! Maximum log level
fplLogLevel maxLevel;
//! Is initialized (When set to false all values will be set to default values)
fpl_b32 isInitialized;
} fplLogSettings;
/**
* @brief Overwrites the current log settings
* @param params The source @ref fplLogSettings structure
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api void fplSetLogSettings(const fplLogSettings *params);
/**
* @brief Gets the current log settings
* @return Returns a pointer the @ref fplLogSettings structure
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api const fplLogSettings *fplGetLogSettings();
/**
* @brief Changes the current maximum log level to the given value
* @param maxLevel The new maximum log level @ref fplLogLevel
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api void fplSetMaxLogLevel(const fplLogLevel maxLevel);
/**
* @brief Gets the current maximum allowed log level
* @return Returns the current maximum log level @ref fplLogLevel
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api fplLogLevel fplGetMaxLogLevel();
#endif // FPL_ENABLE_LOGGING
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup ErrorHandling Error Handling
* @brief This category contains functions for handling errors
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Gets the last internal error string
* @return Returns the last error string or empty string when there was no error.
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api const char *fplGetLastError();
/**
* @brief Gets the last error string from the given index
* @param index The index
* @return Returns the last error string from the given index or empty when there was no error.
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api const char *fplGetErrorByIndex(const size_t index);
/**
* @brief Gets the count of total last errors
* @note This function can be called regardless of the initialization state!
* @return Returns the number of last errors or zero when there was no error.
*/
fpl_common_api size_t fplGetErrorCount();
/**
* @brief Clears all the current errors in the platform
* @note This function can be called regardless of the initialization state!
*/
fpl_common_api void fplClearErrors();
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup DynamicLibrary Dynamic library loading
* @brief This category contains functions for loading dynamic libraries.
* @{
*/
// ----------------------------------------------------------------------------
//! A union containing the library handle for any platform
typedef union fplInternalDynamicLibraryHandle {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 library handle
HMODULE win32LibraryHandle;
#elif defined(FPL_SUBPLATFORM_POSIX)
//! Posix library handle
void *posixLibraryHandle;
#endif
} fplInternalDynamicLibraryHandle;
//! A structure containing the internal handle to a dynamic library
typedef struct fplDynamicLibraryHandle {
//! Internal library handle
fplInternalDynamicLibraryHandle internalHandle;
//! Library opened successfully
fpl_b32 isValid;
} fplDynamicLibraryHandle;
/**
* @brief Loads a dynamic library and returns if the load was successful or not.
* @param libraryFilePath The path to the library with included file extension (.dll / .so)
* @param outHandle The output handle @ref fplDynamicLibraryHandle
* @return Returns true when the library was loaded successfully, false otherwise.
*/
fpl_platform_api bool fplDynamicLibraryLoad(const char *libraryFilePath, fplDynamicLibraryHandle *outHandle);
/**
* @brief Returns the dynamic library procedure address for the given procedure name.
* @param handle The @ref fplDynamicLibraryHandle handle to the loaded library
* @param name The name of the procedure
* @return Returns the procedure address for the given procedure name or @ref fpl_null when procedure not found or library is not loaded.
*/
fpl_platform_api void *fplGetDynamicLibraryProc(const fplDynamicLibraryHandle *handle, const char *name);
/**
* @brief Unloads the loaded library and resets the handle to zero.
* @param handle The library handle @ref fplDynamicLibraryHandle
*/
fpl_platform_api void fplDynamicLibraryUnload(fplDynamicLibraryHandle *handle);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Debug Debug
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Writes the given text into the debugger output stream
* @param text The text to write into the debugger output stream
* @note This function will only work in IDEs such as MSVC
*/
fpl_platform_api void fplDebugOut(const char *text);
/**
* @brief Writes the given formatted text into the debugger output stream
* @param format The format used for writing into the debugger output stream
* @param ... The dynamic arguments used for formatting the text.
* @note This function will only work in IDEs such as MSVC
*/
fpl_common_api void fplDebugFormatOut(const char *format, ...);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Console Console functions
* @brief This category contains function for handling console in/out
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Writes the given text to the standard output console buffer.
* @param text The text to write into standard output console.
* @note This is most likely just a wrapper call to fprintf(stdout)
*/
fpl_platform_api void fplConsoleOut(const char *text);
/**
* @brief Writes the given text to the standard error console buffer.
* @param text The text to write into standard error console.
* @note This is most likely just a wrapper call to fprintf(stderr)
*/
fpl_platform_api void fplConsoleError(const char *text);
/**
* @brief Wait for a character to be typed in the console input and return it.
* @note This is most likely just a wrapper call to getchar()
* @return Returns the character typed in in the console input
*/
fpl_platform_api char fplConsoleWaitForCharInput();
/**
* @brief Writes the given formatted text to the standard output console buffer.
* @param format The format used for writing into the standard output console
* @param ... The dynamic arguments used for formatting the text
* @note This is most likely just a wrapper call to vfprintf(stdout)
*/
fpl_common_api void fplConsoleFormatOut(const char *format, ...);
/**
* @brief Writes the given formatted text to the standard error console buffer.
* @param format The format used for writing into the standard error console
* @param ... The dynamic arguments used for formatting the text
* @note This is most likely just a wrapper call to vfprintf(stderr)
*/
fpl_common_api void fplConsoleFormatError(const char *format, ...);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Timings Timing functions
* @brief This category contains functions for time comparisons
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Gets the current system clock in seconds in high precision (micro/nano seconds).
* @return Returns the number of seconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time!
*/
fpl_platform_api double fplGetTimeInSecondsHP();
/**
* @brief Gets the current system clock in seconds in low precision (milliseconds).
* @return Returns the number of seconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time!
*/
fpl_platform_api uint64_t fplGetTimeInSecondsLP();
/**
* @brief Gets the current system clock in seconds in default precision.
* @return Returns the number of seconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time. There is no guarantee to get high precision here, use for high precision @ref fplGetTimeInSecondsHP() instead!
*/
fpl_platform_api double fplGetTimeInSeconds();
/**
* @brief Gets the current system clock in milliseconds in high precision (micro/nano seconds)
* @return Returns the number of milliseconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time!
*/
fpl_platform_api double fplGetTimeInMillisecondsHP();
/**
* @brief Gets the current system clock in milliseconds in low precision (milliseconds)
* @return Returns the number of milliseconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time!
*/
fpl_platform_api uint64_t fplGetTimeInMillisecondsLP();
/**
* @brief Gets the current system clock in milliseconds
* @return Returns the number of milliseconds since some fixed starting point (OS start, System start, etc).
* @note Can only be used to calculate a difference in time!
*/
fpl_platform_api uint64_t fplGetTimeInMilliseconds();
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Threading Threading and syncronisation routines
* @brief This category contains functions/types for dealing with concurrent programming, such as threads, mutexes, conditions, etc.
* @{
*/
// ----------------------------------------------------------------------------
//! A type definition for a timeout value in milliseconds
typedef uint32_t fplTimeoutValue;
//! Infinite timeout constant
#define FPL_TIMEOUT_INFINITE UINT32_MAX
//! An enumeration of thread states
typedef enum fplThreadStates {
//! Thread is stopped
fplThreadState_Stopped = 0,
//! Thread is being started
fplThreadState_Starting,
//! Thread is still running
fplThreadState_Running,
//! Thread is being stopped
fplThreadState_Stopping,
} fplThreadStates;
//! A type definition for mapping @ref fplThreadState into a 32-bit integer
typedef uint32_t fplThreadState;
//! Forward declare thread handle
typedef struct fplThreadHandle fplThreadHandle;
/**
* @brief A callback to execute user code from a @ref fplThreadHandle
* @param thread The thread handle @ref fplThreadHandle
* @param data The user data pointer
*/
//! Run callback type definition for @ref fplThreadCreate()
typedef void (fpl_run_thread_callback)(const fplThreadHandle *thread, void *data);
//! A union containing the thread handle for any platform
typedef union fplInternalThreadHandle {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 thread handle
HANDLE win32ThreadHandle;
#elif defined(FPL_SUBPLATFORM_POSIX)
//! POSIX thread handle
pthread_t posixThread;
#endif
} fplInternalThreadHandle;
//! The thread handle structure
typedef struct fplThreadHandle {
//! The internal thread handle
fplInternalThreadHandle internalHandle;
//! The identifier of the thread
uint64_t id;
//! The stored run callback
fpl_run_thread_callback *runFunc;
//! The user data passed to the run callback
void *data;
//! Thread state
volatile fplThreadState currentState;
//! Is this thread valid
volatile fpl_b32 isValid;
//! Is this thread stopping
volatile fpl_b32 isStopping;
} fplThreadHandle;
#if defined(FPL_PLATFORM_WIN32)
//! A structure containing the semaphore handle and the value for win32
typedef struct fplInternalSemaphoreHandleWin32 {
//! Semaphore handle
HANDLE handle;
//! Semaphore value
volatile int32_t value;
} fplInternalSemaphoreHandleWin32;
#endif
//! A union containing the internal semaphore handle for any platform
typedef union fplInternalSemaphoreHandle {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 semaphore handle
fplInternalSemaphoreHandleWin32 win32;
#elif defined(FPL_SUBPLATFORM_POSIX)
//! Posix semaphore handle
sem_t posixHandle;
#endif
} fplInternalSemaphoreHandle;
//! The semaphore handle structure
typedef struct fplSemaphoreHandle {
//! The internal semaphore handle
fplInternalSemaphoreHandle internalHandle;
//! Is it valid
fpl_b32 isValid;
} fplSemaphoreHandle;
//! A union containing the internal mutex handle for any platform
typedef union fplInternalMutexHandle {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 mutex handle
CRITICAL_SECTION win32CriticalSection;
#elif defined(FPL_SUBPLATFORM_POSIX)
//! Posix mutex handle
pthread_mutex_t posixMutex;
#endif
} fplInternalMutexHandle;
//! The mutex handle structure
typedef struct fplMutexHandle {
//! The internal mutex handle
fplInternalMutexHandle internalHandle;
//! Is it valid
fpl_b32 isValid;
} fplMutexHandle;
//! A union containing the internal signal handle for any platform
typedef union fplInternalSignalHandle {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 event handle
HANDLE win32EventHandle;
#elif defined(FPL_PLATFORM_LINUX)
//! Linux event handle
int linuxEventHandle;
#endif
} fplInternalSignalHandle;
//! The signal handle structure
typedef struct fplSignalHandle {
//! The internal signal handle
fplInternalSignalHandle internalHandle;
//! Is it valid
fpl_b32 isValid;
} fplSignalHandle;
//! An enumeration of signal values
typedef enum fplSignalValue {
//! Value is unset
fplSignalValue_Unset = 0,
//! Value is set
fplSignalValue_Set = 1,
} fplSignalValue;
//! A union containing the internal condition variable for any platform
typedef union fplInternalConditionVariable {
#if defined(FPL_PLATFORM_WIN32)
//! Win32 condition variable
CONDITION_VARIABLE win32Condition;
#elif defined(FPL_SUBPLATFORM_POSIX)
//! POSIX condition variable
pthread_cond_t posixCondition;
#endif //! Dummy field
} fplInternalConditionVariable;
//! The condition variable structure
typedef struct fplConditionVariable {
//! The internal condition handle
fplInternalConditionVariable internalHandle;
//! Is it valid
fpl_b32 isValid;
} fplConditionVariable;
/**
* @brief Gets the current thread state for the given thread
* @param thread The thread handle @ref fplThreadHandle
* @return Returns the current thread state @ref fplThreadState for the given thread
*/
fpl_common_api fplThreadState fplGetThreadState(fplThreadHandle *thread);
/**
* @brief Creates and starts a thread and returns the handle to it.
* @param runFunc The pointer to the @ref fpl_run_thread_callback
* @param data The user data pointer passed to the execution function callback
* @return Returns a pointer to the @ref fplThreadHandle structure or @ref fpl_null when the limit of active threads has been reached.
* @warning Do not free this thread context directly!
* @note The resources are automatically cleaned up when the thread terminates.
*/
fpl_platform_api fplThreadHandle *fplThreadCreate(fpl_run_thread_callback *runFunc, void *data);
/**
* @brief Let the current thread sleep for the given amount of milliseconds.
* @param milliseconds Number of milliseconds to sleep
* @note There is no guarantee that the OS sleeps for the exact amount of milliseconds! This can vary based on the OS scheduler granularity.
*/
fpl_platform_api void fplThreadSleep(const uint32_t milliseconds);
/**
* @brief Let the current thread yield execution to another thread that is ready to run on this core.
* @return Returns true when the functions succeeds, false otherwise.
*/
fpl_platform_api bool fplThreadYield();
/**
* @brief Forces the given thread to stop and release all underlying resources.
* @param thread The pointer to the @ref fplThreadHandle structure
* @return True when the thread was terminated, false otherwise.
* @warning Do not free the given thread context manually!
* @note This thread context may get re-used for another thread in the future.
* @note Returns true when the threads was terminated, false otherwise.
*/
fpl_platform_api bool fplThreadTerminate(fplThreadHandle *thread);
/**
* @brief Wait until the given thread is done running or the given timeout has been reached.
* @param thread The pointer to the @ref fplThreadHandle structure
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when the thread completes or when the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplThreadWaitForOne(fplThreadHandle *thread, const fplTimeoutValue timeout);
/**
* @brief Wait until all given threads are done running or the given timeout has been reached.
* @param threads The array @ref fplThreadHandle pointers
* @param count The number of threads in the array
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when all threads completes or when the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplThreadWaitForAll(fplThreadHandle *threads[], const size_t count, const fplTimeoutValue timeout);
/**
* @brief Wait until one of given threads is done running or the given timeout has been reached.
* @param threads The array @ref fplThreadHandle pointers
* @param count The number of threads in the array
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when one thread completes or when the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplThreadWaitForAny(fplThreadHandle *threads[], const size_t count, const fplTimeoutValue timeout);
/**
* @brief Initializes the given mutex
* @param mutex The pointer to the @ref fplMutexHandle structure
* @return Returns true when the mutex was initialized, false otherwise.
* @note Use @ref fplMutexDestroy() when you are done with this mutex.
*/
fpl_platform_api bool fplMutexInit(fplMutexHandle *mutex);
/**
* @brief Releases the given mutex and clears the structure to zero.
* @param mutex The pointer to the @ref fplMutexHandle structure
*/
fpl_platform_api void fplMutexDestroy(fplMutexHandle *mutex);
/**
* @brief Locks the given mutex and blocks any other threads.
* @param mutex The pointer to the @ref fplMutexHandle structure
* @return Returns true when the mutex was locked, false otherwise.
*/
fpl_platform_api bool fplMutexLock(fplMutexHandle *mutex);
/**
* @brief Tries to lock the given mutex without blocking other threads.
* @param mutex The pointer to the @ref fplMutexHandle structure
* @return Returns true when the mutex was locked, false otherwise.
*/
fpl_platform_api bool fplMutexTryLock(fplMutexHandle *mutex);
/**
* @brief Unlocks the given mutex
* @param mutex The pointer to the @ref fplMutexHandle structure
* @return Returns true when the mutex was unlocked, false otherwise.
*/
fpl_platform_api bool fplMutexUnlock(fplMutexHandle *mutex);
/**
* @brief Initializes the given signal
* @param signal The pointer to the @ref fplSignalHandle structure
* @param initialValue The initial value the signal is set to
* @return Returns true when initialization was successful, false otherwise.
* @note Use @ref fplSignalDestroy() when you are done with this Signal to release it.
*/
fpl_platform_api bool fplSignalInit(fplSignalHandle *signal, const fplSignalValue initialValue);
/**
* @brief Releases the given signal and clears the structure to zero.
* @param signal The pointer to the @ref fplSignalHandle structure
*/
fpl_platform_api void fplSignalDestroy(fplSignalHandle *signal);
/**
* @brief Waits until the given signal are waked up.
* @param signal The pointer to the @ref fplSignalHandle structure
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Retrns true when the signal woke up or the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplSignalWaitForOne(fplSignalHandle *signal, const fplTimeoutValue timeout);
/**
* @brief Waits until all the given signal are waked up.
* @param signals The array of @ref fplSignalHandle pointers
* @param count The number of signals in the array
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when all signals woke up or the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplSignalWaitForAll(fplSignalHandle *signals[], const size_t count, const fplTimeoutValue timeout);
/**
* @brief Waits until any of the given signals wakes up or the timeout has been reached.
* @param signals The array of @ref fplSignalHandle pointers
* @param count The number of signals in the array
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when any of the signals woke up or the timeout has been reached, false otherwise.
*/
fpl_platform_api bool fplSignalWaitForAny(fplSignalHandle *signals[], const size_t count, const fplTimeoutValue timeout);
/**
* @brief Sets the signal and wakes up the given signal.
* @param signal The pointer to the @ref fplSignalHandle structure
* @return Returns true when the signal was set and broadcasted or false otherwise.
*/
fpl_platform_api bool fplSignalSet(fplSignalHandle *signal);
/**
* @brief Resets the signal.
* @param signal The pointer to the @ref fplSignalHandle structure
* @return Returns true when the signal was reset, false otherwise.
*/
fpl_platform_api bool fplSignalReset(fplSignalHandle *signal);
/**
* @brief Initialize
s the given condition
* @param condition The pointer to the @ref fplConditionVariable structure
* @return Returns true when initialization was successful, false otherwise.
* @note Use @ref fplSignalDestroy() when you are done with this Condition Variable to release its resources.
*/
fpl_platform_api bool fplConditionInit(fplConditionVariable *condition);
/**
* @brief Releases the given condition and clears the structure to zero.
* @param condition The pointer to the @ref fplConditionVariable structure
*/
fpl_platform_api void fplConditionDestroy(fplConditionVariable *condition);
/**
* @brief Sleeps on the given condition and releases the mutex when done.
* @param condition The pointer to the @ref fplConditionVariable structure
* @param mutex The pointer to the mutex handle @ref fplMutexHandle structure
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when the function succeeds, false otherwise.
*/
fpl_platform_api bool fplConditionWait(fplConditionVariable *condition, fplMutexHandle *mutex, const fplTimeoutValue timeout);
/**
* @brief Wakes up one thread which waits on the given condition.
* @param condition The pointer to the @ref fplConditionVariable structure
* @return Returns true when the function succeeds, false otherwise.
*/
fpl_platform_api bool fplConditionSignal(fplConditionVariable *condition);
/**
* @brief Wakes up all threads which waits on the given condition.
* @param condition The pointer to the @ref fplConditionVariable structure
* @return Returns true when the function succeeds, false otherwise.
*/
fpl_platform_api bool fplConditionBroadcast(fplConditionVariable *condition);
/**
* @brief Initializes the semaphore with the given initial value
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @param initialValue The initial value
* @return Returns true when the semaphores got initialized, false otherwise.
*/
fpl_platform_api bool fplSemaphoreInit(fplSemaphoreHandle *semaphore, const uint32_t initialValue);
/**
* @brief Releases the internal semaphore resources
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @warning Do not call this when a thread is still waiting on this semaphore
*/
fpl_platform_api void fplSemaphoreDestroy(fplSemaphoreHandle *semaphore);
/**
* @brief Waits for the semaphore until it get signaled or the timeout has been reached.
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @param timeout The number of milliseconds to wait. When this is set to @ref FPL_TIMEOUT_INFINITE it will wait infinitly.
* @return Returns true when the semaphore got signaled, false otherwise.
* @note When a semaphore got signaled, the semaphore value is decreased by one.
*/
fpl_platform_api bool fplSemaphoreWait(fplSemaphoreHandle *semaphore, const fplTimeoutValue timeout);
/**
* @brief Tries to wait for the semaphore until it get signaled or return immediatly.
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @return Returns true when the semaphore got signaled, false otherwise.
* @note When a semaphore got signaled, the semaphore value is decreased by one.
*/
fpl_platform_api bool fplSemaphoreTryWait(fplSemaphoreHandle *semaphore);
/**
* @brief Gets the current semaphore value
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @return Returns the current semaphore value
*/
fpl_platform_api int32_t fplSemaphoreValue(fplSemaphoreHandle *semaphore);
/**
* @brief Increments the semaphore value by one
* @param semaphore The pointer to the @ref fplSemaphoreHandle structure
* @return Returns true when semaphore was incremented, false otherwise.
*/
fpl_platform_api bool fplSemaphoreRelease(fplSemaphoreHandle *semaphore);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Memory Memory functions
* @brief This category contains functions for allocating/manipulating memory
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Clears the given memory by the given size to zero.
* @param mem The pointer to the memory
* @param size The number of bytes to be cleared to zero
*/
fpl_common_api void fplMemoryClear(void *mem, const size_t size);
/**
* @brief Sets the given memory by the given size to the given value.
* @param mem The pointer to the memory
* @param value The value to be set
* @param size The number of bytes to be set
*/
fpl_common_api void fplMemorySet(void *mem, const uint8_t value, const size_t size);
/**
* @brief Copies the given source memory with its length to the target memory.
* @param sourceMem The pointer to the source memory to copy from
* @param sourceSize The size in bytes to be copied
* @param targetMem The pointer to the target memory to copy into
*/
fpl_common_api void fplMemoryCopy(const void *sourceMem, const size_t sourceSize, void *targetMem);
/**
* @brief Allocates memory from the operating system by the given size.
* @param size The size to by allocated in bytes.
* @return Returns a pointer to the new allocated memory.
* @warning Alignment is not ensured here, the OS decides how to handle this. If you want to force a specific alignment use @ref fplMemoryAlignedAllocate() instead.
* @note The memory is guaranteed to be initialized to zero.
* @note This function can be called without the platform to be initialized.
*/
fpl_platform_api void *fplMemoryAllocate(const size_t size);
/**
* @brief Releases the memory allocated from the operating system.
* @param ptr The pointer to the allocated memory
* @warning This should never be called with a aligned memory pointer! For freeing aligned memory, use @ref fplMemoryAlignedFree() instead.
* @note This function can be called without the platform to be initialized.
*/
fpl_platform_api void fplMemoryFree(void *ptr);
/**
* @brief Allocates aligned memory from the operating system by the given alignment.
* @param size The size amount in bytes
* @param alignment The alignment in bytes (Must be a power-of-two!)
* @return Returns the pointer to the new allocated aligned memory.
* @note The memory is guaranteed to be initialized to zero.
* @note This function can be called without the platform to be initialized.
*/
fpl_common_api void *fplMemoryAlignedAllocate(const size_t size, const size_t alignment);
/**
* @brief Releases the aligned memory allocated from the operating system.
* @param ptr The pointer to the aligned allocated memory
* @warning This should never be called with a not-aligned memory pointer! For freeing not-aligned memory, use @ref fplMemoryFree() instead.
* @note This function can be called without the platform to be initialized.
*/
fpl_common_api void fplMemoryAlignedFree(void *ptr);
/** @}*/
// ----------------------------------------------------------------------------
/**
* @defgroup Strings String functions
* @brief This category contains tons of functions for converting/manipulating strings
* @{
*/
// ----------------------------------------------------------------------------
/**
* @brief Matches the given string by the given wildcard and returns a boolean indicating the match.
* @param source The source string
* @param wildcard The wildcard string
* @return Returns true when source string matches the wildcard, false otherwise.
*/
fpl_common_api bool fplIsStringMatchWildcard(const char *source, const char *wildcard);
/**
* @brief Compares two strings with constrained lengths and returns a boolean indicating the equality.
* @param a The first string
* @param aLen The number of characters for the first string
* @param b The second string
* @param bLen The number of characters for the second string
* @return Returns true when both strings are equal, false otherwise.
* @note Len parameters does not include the null-terminator!
*/
fpl_common_api bool fplIsStringEqualLen(const char *a, const size_t aLen, const char *b, const size_t bLen);
/**
* @brief Compares two strings and returns a boolean indicating the equality.
* @param a The first string
* @param b The second string
* @return Returns true when both strings are equal, false otherwise.
*/
fpl_common_api bool fplIsStringEqual(const char *a, const char *b);
/**
* @brief Ensures that the given string always ends with a path separator with length constrained
* @param path The target path string
* @param maxPathLen The max length of the target path
* @return Returns a pointer to the last written character or @ref fpl_null.
*/
fpl_common_api char *fplEnforcePathSeparatorLen(char *path, size_t maxPathLen);
/**
* @brief Ensures that the given string always ends with a path separator
* @param path The path string
* @return Returns a pointer to the last written character or @ref fpl_null.
* @note This function is unsafe as it does not know the maximum length of the string!
*/
fpl_common_api char *fplEnforcePathSeparator(char *path);
/**
* @brief Appends the source string to the given buffer constrained by length
* @param appended The appending source string
* @param appendedLen The length of the appending source string
* @param buffer The target buffer
* @param maxBufferLen The max length of the target buffer
* @return Returns a pointer to the last written character or @ref fpl_null.
*/
fpl_common_api char *fplStringAppendLen(const char *appended, const size_t appendedLen, char *buffer, size_t maxBufferLen);
/**
* @brief Appends the source string to the given buffer
* @param appended The appending source string
* @param buffer The target buffer
* @param maxBufferLen The max length of the target buffer
* @return Returns a pointer to the last written character or @ref fpl_null.
*/
fpl_common_api char *fplStringAppend(const char *appended, char *buffer, size_t maxBufferLen);
/**
* @brief Counts the number of characters without including the zero terminator.
* @param str The string source
* @return Returns the number of characters of the given string or zero when the input string is fpl_null.
*/
fpl_common_api size_t fplGetStringLength(const char *str);
/**
* @brief Copies the given source string with a constrained length into a destination string.
* @param source The source string
* @param sourceLen The number of characters to copy
* @param dest The destination string buffer
* @param maxDestLen The total number of characters available in the destination buffer
* @return Returns the pointer to the last written character or @ref fpl_null.
* @note Null terminator is included always.
*/
fpl_common_api char *fplCopyStringLen(const char *source, const size_t sourceLen, char *dest, const size_t maxDestLen);
/**
* @brief Copies the given source string into a destination string.
* @param source The source string
* @param dest The destination string buffer
* @param maxDestLen The total number of characters available in the destination buffer
* @return Returns the pointer to the last written character or @ref fpl_null.
* @note Null terminator is included always.
*/
fpl_common_api char *fplCopyString(const char *source, char *dest, const size_t maxDestLen);
/**
* @brief Converts the given 16-bit source wide string with length in a 8-bit UTF-8 ansi string.
* @param wideSource The 16-bit source wide string
* @param maxWideSourceLen The number of characters of the source wide string
* @param utf8Dest The 8-bit destination ansi string buffer
* @param maxUtf8DestLen The total number of characters available in the destination buffer
* @return Returns the pointer to the last written character or @ref fpl_null.
* @note Null terminator is included always.
*/
fpl_platform_api char *fplWideStringToUTF8String(const wchar_t *wideSource, const size_t maxWideSourceLen, char *utf8Dest, const size_t maxUtf8DestLen);
/**
* @brief Converts the given 8-bit UTF-8 source ansi string with length in a 16-bit wide string.
* @param utf8Source The 8-bit source ansi string