Final Platform Layer 0.9.8-beta
Loading...
Searching...
No Matches
final_platform_layer.h
Go to the documentation of this file.
1/*
2final_platform_layer.h
3
4-------------------------------------------------------------------------------
5 About
6-------------------------------------------------------------------------------
7
8Final 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.).
9
10The main focus is game/media/simulation development, so the default settings will create a window, set up an OpenGL rendering context, and initialize audio playback on any platform.
11
12It is written in C99 for simplicity and best portability but is C++ compatible as well.
13
14FPL supports the platforms Windows/Linux/Unix for the architectures x86/x64/arm.
15
16The only dependencies are built-in operating system libraries and a C99 compliant compiler.
17
18It is licensed under the MIT-License. This license allows you to use FPL freely in any software.
19
20-------------------------------------------------------------------------------
21 Getting started
22-------------------------------------------------------------------------------
23
24- Drop this file into any C/C++ projects you want and include it in any place you want
25- In your main translation unit provide the typical main() entry point
26- Define FPL_IMPLEMENTATION in at least one translation unit before including this header file
27- Init the platform using fplPlatformInit()
28- Use the features you want
29- Release the platform when you are done using fplPlatformRelease()
30
31-------------------------------------------------------------------------------
32 Usage: Hello world console application
33-------------------------------------------------------------------------------
34
35#define FPL_IMPLEMENTATION
36#include <final_platform_layer.h>
37
38int main(int argc, char **args){
39 if (fplPlatformInit(fplInitFlags_None, fpl_null)) {
40 fplConsoleOut("Hello World!");
41 fplPlatformRelease();
42 return 0;
43 } else {
44 return -1;
45 }
46}
47
48-------------------------------------------------------------------------------
49 Usage: OpenGL legacy or modern application
50-------------------------------------------------------------------------------
51
52#define FPL_IMPLEMENTATION
53#include <final_platform_layer.h>
54
55int main(int argc, char **args){
56 // Create default settings
57 fplSettings settings = fplMakeDefaultSettings();
58
59 // Overwrite the video backend
60 settings.video.backend = fplVideoBackendType_OpenGL;
61
62 // Legacy OpenGL
63 settings.video.graphics.opengl.compabilityFlags = fplOpenGLCompabilityFlags_Legacy;
64
65 // or
66
67 // Modern OpenGL
68 settings.video.graphics.opengl.compabilityFlags = fplOpenGLCompabilityFlags_Core;
69 settings.video.graphics.opengl.majorVersion = 3;
70 settings.video.graphics.opengl.minorVersion = 3;
71
72 if (fplPlatformInit(fplInitFlags_Video, &settings)) {
73 // Event/Main loop
74 while (fplWindowUpdate()) {
75 // Poll events
76 fplEvent ev;
77 while (fplPollEvent(&ev)) {
79 }
80
81 // your code goes here
82
83 fplVideoFlip();
84 }
85 fplPlatformRelease();
86 return 0;
87 } else {
88 return -1;
89 }
90}
91
92-------------------------------------------------------------------------------
93 License
94-------------------------------------------------------------------------------
95
96Final Platform Layer is released under the following license:
97
98MIT License
99
100Copyright (c) 2017-2023 Torsten Spaete
101
102Permission is hereby granted, free of charge, to any person obtaining a copy
103of this software and associated documentation files (the "Software"), to deal
104in the Software without restriction, including without limitation the rights
105to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
106copies of the Software, and to permit persons to whom the Software is
107furnished to do so, subject to the following conditions:
108
109The above copyright notice and this permission notice shall be included in all
110copies or substantial portions of the Software.
111
112THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
113IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
114FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
115AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
116LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
117OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
118SOFTWARE.
119*/
120
128// ----------------------------------------------------------------------------
129// > CHANGELOG
130// ----------------------------------------------------------------------------
1525// ****************************************************************************
1526//
1527// > HEADER
1528//
1529// ****************************************************************************
1530#ifndef FPL_HEADER_H
1531#define FPL_HEADER_H
1532
1533//
1534// C99 detection
1535//
1536// https://en.wikipedia.org/wiki/C99#Version_detection
1537// C99 is partially supported since MSVC 2015
1538#if !defined(__cplusplus) && ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(_MSC_VER) && (_MSC_VER >= 1900)))
1540# define FPL_IS_C99
1541#elif defined(__cplusplus)
1543# define FPL_IS_CPP
1544# if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (__cplusplus >= 201103L) || (_MSC_VER >= 1900)
1546# define FPL_IS_CPP11
1547# endif
1548#else
1549# error "This C/C++ compiler is not supported!"
1550#endif
1551
1552//
1553// Architecture detection (x86, x64)
1554// https://sourceforge.net/p/predef/wiki/Architectures/
1555//
1556#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__)
1557# define FPL_ARCH_X64
1558#elif defined(__i386__) || defined(_M_IX86) || defined(__X86__) || defined(_X86_)
1559# define FPL_ARCH_X86
1560#elif defined(__aarch64__) || defined(_M_ARM64)
1561# define FPL_ARCH_ARM64
1562#elif defined(__arm__) || defined(_M_ARM)
1563# define FPL_ARCH_ARM32
1564#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || defined(_ARCH_PPC64)
1565# define FPL_ARCH_POWERPC64
1566#elif defined(__powerpc__) || defined(__POWERPC__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
1567# define FPL_ARCH_POWERPC32
1568#else
1569# error "This architecture is not supported!"
1570#endif // FPL_ARCH
1571
1572//
1573// 32-bit or 64-bit
1574//
1575#if defined(_WIN32)
1576# if defined(_WIN64)
1577# define FPL__M_CPU_64BIT
1578# else
1579# define FPL__M_CPU_32BIT
1580# endif
1581#elif defined(__GNUC__)
1582# if defined(__LP64__)
1583# define FPL__M_CPU_64BIT
1584# else
1585# define FPL__M_CPU_32BIT
1586# endif
1587#else
1588# if (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8) || (sizeof(void *) == 8)
1589# define FPL__M_CPU_64BIT
1590# else
1591# define FPL__M_CPU_32BIT
1592# endif
1593#endif
1594
1595#if defined(FPL__M_CPU_64BIT)
1597# define FPL_CPU_64BIT
1598#elif defined(FPL__M_CPU_32BIT)
1600# define FPL_CPU_32BIT
1601#endif
1602
1603//
1604// Compiler detection
1605// http://beefchunk.com/documentation/lang/c/pre-defined-c/precomp.html
1606// http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros
1607//
1608#if defined(__clang__)
1610# define FPL_COMPILER_CLANG
1611#elif defined(__INTEL_COMPILER)
1613# define FPL_COMPILER_INTEL
1614#elif defined(__MINGW32__)
1616# define FPL_COMPILER_MINGW
1617#elif defined(__CC_ARM)
1619# define FPL_COMPILER_ARM
1620#elif defined(__GNUC__)
1622# define FPL_COMPILER_GCC
1623#elif defined(_MSC_VER)
1625# define FPL_COMPILER_MSVC
1626#else
1628#error "This compiler is not supported!"
1629#endif // FPL_COMPILER
1630
1631//
1632// Platform detection
1633// https://sourceforge.net/p/predef/wiki/OperatingSystems/
1634//
1635#if defined(_WIN32) || defined(_WIN64)
1636# define FPL_PLATFORM_WINDOWS
1637# define FPL_PLATFORM_NAME "Windows"
1638#elif defined(__ANDROID__)
1639# define FPL_PLATFORM_ANDROID
1640# define FPL_PLATFORM_NAME "Android"
1641# define FPL_SUBPLATFORM_POSIX
1642# define FPL_SUBPLATFORM_STD_STRINGS
1643# define FPL_SUBPLATFORM_STD_CONSOLE
1644#elif defined(__linux__) || defined(__gnu_linux__)
1645# define FPL_PLATFORM_LINUX
1646# define FPL_PLATFORM_NAME "Linux"
1647# define FPL_SUBPLATFORM_POSIX
1648# define FPL_SUBPLATFORM_X11
1649# define FPL_SUBPLATFORM_STD_STRINGS
1650# define FPL_SUBPLATFORM_STD_CONSOLE
1651#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__bsdi__)
1652 // @NOTE(final): BSD is treated as a subplatform for now
1653# define FPL_PLATFORM_UNIX
1654# define FPL_PLATFORM_NAME "BSD"
1655# define FPL_SUBPLATFORM_BSD
1656# define FPL_SUBPLATFORM_POSIX
1657# define FPL_SUBPLATFORM_X11
1658# define FPL_SUBPLATFORM_STD_STRINGS
1659# define FPL_SUBPLATFORM_STD_CONSOLE
1660#elif defined(unix) || defined(__unix) || defined(__unix__)
1661# define FPL_PLATFORM_UNIX
1662# define FPL_PLATFORM_NAME "Unix"
1663# define FPL_SUBPLATFORM_POSIX
1664# define FPL_SUBPLATFORM_X11
1665# define FPL_SUBPLATFORM_STD_STRINGS
1666# define FPL_SUBPLATFORM_STD_CONSOLE
1667#else
1668# error "This platform is not supported!"
1669#endif // FPL_PLATFORM
1670
1671// Assembler keyword is compiler specific
1672#if defined(FPL_COMPILER_CLANG) || defined(FPL_COMPILER_GCC)
1673#define fpl__m_Asm __asm__
1674#elif defined(FPL_COMPILER_MSVC)
1675#define fpl__m_Asm __asm
1676#else
1677#define fpl__m_Asm asm
1678#endif
1679
1681#define fplAsm fpl__m_Asm
1682
1683// Minimum alignment
1684#if defined(FPL_COMPILER_MSVC)
1685# define fpl__MinAlignment 8
1686#elif defined(FPL_COMPILER_GCC) || defined(FPL_COMPILER_CLANG)
1687# if defined(FPL_CPU_64BIT)
1688# define fpl__MinAlignment 8
1689# else
1690# define fpl__MinAlignment 4
1691# endif
1692#else
1693# define fpl__MinAlignment 8
1694#endif
1696#define fplMinAlignment fpl__MinAlignment
1697
1698// Alignment keyword
1699#if defined(FPL_IS_CPP11)
1700#define fpl__m_AlignAs(N) alignas(N)
1701#elif defined(FPL_COMPILER_MSVC)
1702#define fpl__m_AlignAs(N) __declspec(align(N))
1703#elif defined(FPL_COMPILER_GCC) || defined(FPL_COMPILER_CLANG)
1704#define fpl__m_AlignAs(N) __attribute__((aligned(N)))
1705#else
1706#define fpl__m_AlignAs(N)
1707#endif
1708#define fpl__m_AlignAsAuto(N) fpl__m_AlignAs(((N) < fplMinAlignment ? fplMinAlignment : (N)))
1709
1711#define fplAlignAs(N) fpl__m_AlignAsAuto(N)
1712
1713//
1714// Defines required for POSIX (mmap, 64-bit file io, etc.)
1715//
1716#if defined(FPL_SUBPLATFORM_POSIX)
1717# if !defined(_XOPEN_SOURCE)
1718# define _XOPEN_SOURCE 600
1719# endif
1720# if !defined(_DEFAULT_SOURCE)
1721# define _DEFAULT_SOURCE 1
1722# endif
1723# if !defined(__STDC_FORMAT_MACROS)
1724# define __STDC_FORMAT_MACROS
1725# endif
1726# if !defined(__STDC_LIMIT_MACROS)
1727# define __STDC_LIMIT_MACROS
1728# endif
1729# if !defined(_LARGEFILE_SOURCE)
1730# define _LARGEFILE_SOURCE
1731# endif
1732# if !defined(_LARGEFILE64_SOURCE)
1733# define _LARGEFILE64_SOURCE
1734# endif
1735# if !defined(_FILE_OFFSET_BITS)
1736# define _FILE_OFFSET_BITS 64
1737# endif
1738#endif
1739
1740#if defined(FPL_PLATFORM_LINUX)
1741# define FPL__INCLUDE_ALLOCA
1742#else
1743# define FPL__INCLUDE_MALLOC
1744#endif
1745
1746// MingW compiler hack
1747#if defined(FPL_PLATFORM_WINDOWS) && defined(FPL_COMPILER_MINGW)
1748# if !defined(_WIN32_WINNT)
1749# define _WIN32_WINNT 0x0600
1750# endif
1751#endif // FPL_COMPILER_MINGW
1752
1753//
1754// Storage class identifiers
1755//
1756
1764#define fpl_globalvar static
1766#define fpl_localvar static
1768#define fpl_internal static
1770#define fpl_inline inline
1772#define fpl_internal_inline inline
1774#if defined(FPL_IS_CPP)
1775# define fpl_extern
1776#else
1777# define fpl_extern extern
1778#endif
1779
1780//
1781// DLL Export/Import definition
1782//
1783#if defined(_WIN32) || defined(__CYGWIN__)
1784# ifdef __GNUC__
1785# define fpl__m_dllexport __attribute__ ((dllexport))
1786# define fpl__m_dllimport __attribute__ ((dllimport))
1787# else
1788# define fpl__m_dllexport __declspec(dllexport)
1789# define fpl__m_dllimport __declspec(dllimport)
1790# endif
1791# define fpl__m_dlllocal
1792#else
1793# if __GNUC__ >= 4
1794# define fpl__m_dllimport __attribute__((visibility("default")))
1795# define fpl__m_dllexport __attribute__((visibility("default")))
1796# define fpl__m_dlllocal __attribute__((visibility("hidden")))
1797# else
1798# define fpl__m_dllimport
1799# define fpl__m_dllexport
1800# define fpl__m_dlllocal
1801# endif
1802#endif
1803
1805#define fpl_dllimport fpl__m_dllimport
1807#define fpl_dllexport fpl__m_dllexport
1809#define fpl_dlllocal fpl__m_dlllocal
1810
1811//
1812// API Call
1813//
1814#if defined(FPL_API_AS_PRIVATE)
1815# define fpl__m_api static
1816#elif defined(FPL_DLLEXPORT)
1817# define fpl__m_api fpl_dllexport
1818#elif defined(FPL_DLLIMPORT)
1819# define fpl__m_api fpl_dllimport
1820#else
1821# define fpl__m_api fpl_extern
1822#endif // FPL_API_AS_PRIVATE
1823
1825#define fpl_api fpl__m_api
1826
1828#define fpl_main
1829
1830#if defined(FPL_IS_CPP)
1831# define fpl__m_platform_api extern "C" fpl_api
1832# define fpl__m_common_api extern "C" fpl_api
1833#else
1834# define fpl__m_platform_api fpl_api
1835# define fpl__m_common_api fpl_api
1836#endif
1837
1839#define fpl_platform_api fpl__m_platform_api
1841#define fpl_common_api fpl__m_common_api
1842
1843//
1844// Inlining
1845//
1846#if defined(FPL_COMPILER_MSVC)
1847# define fpl__m_force_inline __forceinline
1848# define fpl__m_no_inline __declspec(noinline)
1849#elif defined(FPL_COMPILER_GCC) || defined(FPL_COMPILER_CLANG)
1850# define fpl__m_force_inline __attribute__((__always_inline__)) inline
1851# define fpl__m_no_inline __attribute__((noinline))
1852#else
1853# define fpl__m_force_inline inline
1854# define fpl__m_no_inline
1855#endif
1856
1858#define fpl_force_inline fpl__m_force_inline
1860#define fpl_no_inline fpl__m_no_inline
1861
1864//
1865// When C-Runtime is disabled we cannot use any function from the C-Standard Library <stdio.h> or <stdlib.h>
1866//
1867#if defined(FPL_NO_CRT)
1868# if defined(FPL_SUBPLATFORM_STD_CONSOLE)
1869# undef FPL_SUBPLATFORM_STD_CONSOLE
1870# endif
1871# if defined(FPL_SUBPLATFORM_STD_STRINGS)
1872# undef FPL_SUBPLATFORM_STD_STRINGS
1873# endif
1874# if !defined(FPL_USERFUNC_vsnprintf)
1875# error "You need to provide a replacement for vsnprintf() by defining FPL_USERFUNC_vsnprintf!"
1876# endif
1877#endif
1878
1879//
1880// Application type detection
1881// - Can be disabled by FPL_NO_APPTYPE
1882// - Must be explicitly set for No-CRT on Win32
1883//
1884#if defined(FPL_APPTYPE_CONSOLE) && defined(FPL_APPTYPE_WINDOW)
1885# error "Its now allowed to define both FPL_APPTYPE_CONSOLE and FPL_APPTYPE_WINDOW!"
1886#endif
1887#if defined(FPL_NO_CRT)
1888# if !defined(FPL_APPTYPE_CONSOLE) && !defined(FPL_APPTYPE_WINDOW)
1889# error "In 'No-CRT' mode you need to define either FPL_APPTYPE_CONSOLE or FPL_APPTYPE_WINDOW manually!"
1890# endif
1891#elif !defined(FPL_NO_APPTYPE) && !(defined(FPL_APPTYPE_CONSOLE) || defined(FPL_APPTYPE_WINDOW))
1892# if !defined(FPL_NO_WINDOW)
1894# define FPL_APPTYPE_WINDOW
1895# else
1897# define FPL_APPTYPE_CONSOLE
1898# endif
1899#endif
1900
1901//
1902// Include entry points always when its not disabled and implementation block is compiled in
1903//
1904#if defined(FPL_IMPLEMENTATION) && !defined(FPL_NO_ENTRYPOINT)
1905# define FPL_ENTRYPOINT
1906#endif
1907
1908//
1909// Debug/Release detection
1910//
1911#if defined(FPL_DEBUG)
1912# define FPL__ENABLE_DEBUG
1913#elif defined(FPL_RELEASE)
1914# define FPL__ENABLE_RELEASE
1915#endif
1916
1917//
1918// Compiler settings
1919//
1920#if defined(FPL_COMPILER_MSVC)
1921 // Debug/Release detection
1922# if !defined(FPL__ENABLE_DEBUG) && !defined(FPL__ENABLE_RELEASE)
1923# if defined(_DEBUG) || (!defined(NDEBUG))
1924# define FPL__ENABLE_DEBUG
1925# else
1926# define FPL__ENABLE_RELEASE
1927# endif
1928# endif
1929
1930 // Function name macro (Win32)
1931# define FPL__M_FUNCTION_NAME __FUNCTION__
1932
1933 // Setup MSVC subsystem hints
1934# if defined(FPL_APPTYPE_WINDOW)
1935# pragma comment(linker, "/SUBSYSTEM:WINDOWS")
1936# elif defined(FPL_APPTYPE_CONSOLE)
1937# pragma comment(linker, "/SUBSYSTEM:CONSOLE")
1938# endif
1939
1940 // Setup MSVC linker hints
1941# pragma comment(lib, "kernel32.lib")
1942#else
1943 // Function name macro (Other compilers)
1944# define FPL__M_FUNCTION_NAME __FUNCTION__
1945#endif // FPL_COMPILER
1946
1947// Debug Release fallback
1948#if !defined(FPL__ENABLE_DEBUG) && !defined(FPL__ENABLE_RELEASE)
1949# define FPL__ENABLE_DEBUG
1950#endif
1951
1953#if defined(__INTELLISENSE__) || defined(__JETBRAINS_IDE__)
1954# define FPL_IS_IDE 1
1955#else
1956# define FPL_IS_IDE 0
1957#endif
1958
1960#define FPL_FUNCTION_NAME FPL__M_FUNCTION_NAME
1961
1962//
1963// Options & Feature detection
1964//
1965
1966//
1967// CPU Instruction Set Detection based on compiler settings
1968//
1969#if defined(__AVX512F__)
1970# define FPL__COMPILED_X86_CPU_INSTR_SET 9
1971#elif defined(__AVX2__)
1972# define FPL__COMPILED_X86_CPU_INSTR_SET 8
1973#elif defined(__AVX__)
1974# define FPL__COMPILED_X86_CPU_INSTR_SET 7
1975#elif defined(__SSE4_2__)
1976# define FPL__COMPILED_X86_CPU_INSTR_SET 6
1977#elif defined(__SSE4_1__)
1978# define FPL__COMPILED_X86_CPU_INSTR_SET 5
1979#elif defined(__SSSE3__)
1980# define FPL__COMPILED_X86_CPU_INSTR_SET 4
1981#elif defined(__SSE3__)
1982# define FPL__COMPILED_X86_CPU_INSTR_SET 3
1983#elif defined(__SSE2__) || (_M_IX86_FP >= 2)
1984# define FPL__COMPILED_X86_CPU_INSTR_SET 2
1985#elif defined(__SSE__) || (_M_IX86_FP >= 1)
1986# define FPL__COMPILED_X86_CPU_INSTR_SET 1
1987#elif defined(_M_IX86_FP)
1988# define FPL__COMPILED_X86_CPU_INSTR_SET _M_IX86_FP
1989#else
1990# define FPL__COMPILED_X86_CPU_INSTR_SET 0
1991#endif
1992
1993//
1994// Assertions
1995//
1996#if !defined(FPL_NO_ASSERTIONS)
1997# if !defined(FPL_FORCE_ASSERTIONS)
1998# if defined(FPL__ENABLE_DEBUG)
1999# define FPL__ENABLE_ASSERTIONS
2000# endif
2001# else
2002# define FPL__ENABLE_ASSERTIONS
2003# endif
2004#endif // !FPL_NO_ASSERTIONS
2005#if defined(FPL__ENABLE_ASSERTIONS)
2006# if !defined(FPL_NO_C_ASSERT) && !defined(FPL_NO_CRT)
2007# define FPL__ENABLE_C_ASSERT
2008# endif
2009#endif // FPL__ENABLE_ASSERTIONS
2010
2011//
2012// HasInclude
2013//
2014#if defined(__has_include)
2015# define fpl__m_HasInclude(inc) __has_include(inc)
2016#else
2017# define fpl__m_HasInclude(inc) (1)
2018#endif
2020#define fplHasInclude(inc) fpl__m_HasInclude(inc)
2021
2022//
2023// Window
2024//
2025#if !defined(FPL_NO_WINDOW) && !defined(FPL_APPTYPE_CONSOLE)
2026# define FPL__SUPPORT_WINDOW
2027#endif
2028
2029//
2030// Video
2031//
2032#if !defined(FPL_NO_VIDEO)
2033# define FPL__SUPPORT_VIDEO
2034#endif
2035#if defined(FPL__SUPPORT_VIDEO)
2036# if !defined(FPL_NO_VIDEO_OPENGL)
2037# define FPL__SUPPORT_VIDEO_OPENGL
2038# endif
2039# if !defined(FPL_NO_VIDEO_VULKAN)
2040# define FPL__SUPPORT_VIDEO_VULKAN
2041# endif
2042# if !defined(FPL_NO_VIDEO_SOFTWARE)
2043# define FPL__SUPPORT_VIDEO_SOFTWARE
2044# endif
2045#endif // FPL__SUPPORT_VIDEO
2046
2047//
2048// Audio
2049//
2050#if !defined(FPL_NO_AUDIO)
2051 // Audio support
2052# define FPL__SUPPORT_AUDIO
2053#endif
2054#if defined(FPL__SUPPORT_AUDIO)
2055# if !defined(FPL_NO_AUDIO_DIRECTSOUND) && defined(FPL_PLATFORM_WINDOWS)
2056# define FPL__SUPPORT_AUDIO_DIRECTSOUND // <dsound.h> is always present on windows
2057# endif
2058# if !defined(FPL_NO_AUDIO_ALSA) && defined(FPL_PLATFORM_LINUX)
2059# if fplHasInclude(<alsa/asoundlib.h>)
2060# define FPL__SUPPORT_AUDIO_ALSA
2061# else
2062# warning "FPL-Warning: ALSA audio development library is missing. Please install 'libasound2-dev' and try again!"
2063# endif
2064# endif
2065#endif // FPL__SUPPORT_AUDIO
2066
2067//
2068// Remove video support when the window is disabled
2069//
2070#if !defined(FPL__SUPPORT_WINDOW)
2071# if defined(FPL_SUBPLATFORM_X11)
2072# undef FPL_SUBPLATFORM_X11
2073# endif
2074
2075# if defined(FPL__SUPPORT_VIDEO)
2076# undef FPL__SUPPORT_VIDEO
2077# endif
2078# if defined(FPL__SUPPORT_VIDEO_OPENGL)
2079# undef FPL__SUPPORT_VIDEO_OPENGL
2080# endif
2081# if defined(FPL__SUPPORT_VIDEO_VULKAN)
2082# undef FPL__SUPPORT_VIDEO_VULKAN
2083# endif
2084# if defined(FPL__SUPPORT_VIDEO_SOFTWARE)
2085# undef FPL__SUPPORT_VIDEO_SOFTWARE
2086# endif
2087#endif // !FPL__SUPPORT_WINDOW
2088
2089//
2090// Enable supports (FPL uses _ENABLE_ internally only)
2091//
2092#if defined(FPL__SUPPORT_WINDOW)
2093# define FPL__ENABLE_WINDOW
2094#endif
2095
2096#if defined(FPL__SUPPORT_VIDEO)
2097# define FPL__ENABLE_VIDEO
2098# if defined(FPL__SUPPORT_VIDEO_OPENGL)
2099# define FPL__ENABLE_VIDEO_OPENGL
2100# endif
2101# if defined(FPL__SUPPORT_VIDEO_VULKAN)
2102# define FPL__ENABLE_VIDEO_VULKAN
2103# endif
2104# if defined(FPL__SUPPORT_VIDEO_SOFTWARE)
2105# define FPL__ENABLE_VIDEO_SOFTWARE
2106# endif
2107#endif // FPL__SUPPORT_VIDEO
2108
2109#if defined(FPL__SUPPORT_AUDIO)
2110# define FPL__ENABLE_AUDIO
2111# if defined(FPL__SUPPORT_AUDIO_DIRECTSOUND)
2112# define FPL__ENABLE_AUDIO_DIRECTSOUND
2113# endif
2114# if defined(FPL__SUPPORT_AUDIO_ALSA)
2115# define FPL__ENABLE_AUDIO_ALSA
2116# endif
2117#endif // FPL__SUPPORT_AUDIO
2118
2119#if defined(FPL_LOGGING)
2120# define FPL__ENABLE_LOGGING
2121# if defined(FPL_LOG_MULTIPLE_WRITERS)
2122# define FPL__ENABLE_LOG_MULTIPLE_WRITERS
2123# endif
2124#endif
2125
2126//
2127// Assertions & Debug
2128//
2129
2136#if defined(FPL__ENABLE_ASSERTIONS)
2137# if defined(FPL__ENABLE_C_ASSERT) && !defined(FPL_FORCE_ASSERTIONS)
2138# define FPL__INCLUDE_ASSERT
2139# define fpl__m_Assert(exp) assert(exp)
2140# if defined(__cplusplus)
2141# define fpl__m_StaticAssert(exp) static_assert(exp, "fpl_static_assert")
2142# endif
2143# else
2144# define fpl__m_Assert(exp) if(!(exp)) {*(int *)0 = 0;}
2145# endif // FPL__ENABLE_C_ASSERT
2146# if !defined(fpl__m_StaticAssert)
2147# define FPL__M_STATICASSERT_0(exp, line, counter) \
2148 int fpl__ct_assert_##line_##counter(int ct_assert_failed[(exp)?1:-1])
2149# define fpl__m_StaticAssert(exp) \
2150 FPL__M_STATICASSERT_0(exp, __LINE__, __COUNTER__)
2151# endif
2152#else
2153# define fpl__m_Assert(exp)
2154# define fpl__m_StaticAssert(exp)
2155#endif // FPL__ENABLE_ASSERTIONS
2156
2158#define fplAssert(exp) fpl__m_Assert(exp)
2160#define fplStaticAssert(exp) fpl__m_StaticAssert(exp)
2162#define fplAlwaysAssert(exp) if(!(exp)) {*(int *)0 = 0;}
2164#define fplAssertPtr(ptr) fpl__m_Assert((ptr) != fpl_null)
2165
2166//
2167// Debug-Break
2168// Based on: https://stackoverflow.com/questions/173618/is-there-a-portable-equivalent-to-debugbreak-debugbreak
2169//
2170#if defined(__has_builtin)
2171# if __has_builtin(__builtin_debugtrap)
2172# define fpl__m_DebugBreak() __builtin_debugtrap()
2173# elif __has_builtin(__debugbreak)
2174# define fpl__m_DebugBreak() __debugbreak()
2175# endif
2176#endif
2177#if !defined(fpl__m_DebugBreak)
2178# if defined(FPL_COMPILER_MSVC) || defined(FPL_COMPILER_INTEL)
2179# define fpl__m_DebugBreak() __debugbreak()
2180# elif defined(FPL_COMPILER_ARM)
2181# define fpl__m_DebugBreak() __breakpoint(42)
2182# elif defined(FPL_ARCH_X86) || defined(FPL_ARCH_X64)
2183fpl_internal fpl_force_inline void fpl__m_DebugBreak() { __asm__ __volatile__("int $03"); }
2184# elif defined(__thumb__)
2185fpl_internal fpl_force_inline void fpl__m_DebugBreak() { __asm__ __volatile__(".inst 0xde01"); }
2186# elif defined(FPL_ARCH_ARM64)
2187fpl_internal fpl_force_inline void fpl__m_DebugBreak() { __asm__ __volatile__(".inst 0xd4200000"); }
2188# elif defined(FPL_ARCH_ARM32)
2189fpl_internal fpl_force_inline void fpl__m_DebugBreak() { __asm__ __volatile__(".inst 0xe7f001f0"); }
2190# elif defined(FPL_COMPILER_GCC)
2191# define fpl__m_DebugBreak() __builtin_trap()
2192# else
2193# define FPL__INCLUDE_SIGNAL
2194# if defined(SIGTRAP)
2195# define fpl__m_DebugBreak() raise(SIGTRAP)
2196# else
2197# define fpl__m_DebugBreak() raise(SIGABRT)
2198# endif
2199# endif
2200#endif
2201
2203#define fplDebugBreak() fpl__m_DebugBreak()
2204
2207//
2208// Memory macros
2209//
2210
2217#if !defined(FPL_NO_MEMORY_MACROS) || defined(FPL_FORCE_MEMORY_MACROS)
2218# define FPL__ENABLE_MEMORY_MACROS
2219#endif
2220
2223//
2224// Types & Limits
2225//
2226#include <stdint.h> // uint32_t, ...
2227#include <stddef.h> // size_t
2228#include <stdbool.h> // bool
2229#include <stdarg.h> // va_start, va_end, va_list, va_arg
2230#include <limits.h> // UINT32_MAX, ...
2231#if defined(FPL__INCLUDE_ASSERT)
2232# include <assert.h>
2233#endif
2234#if defined(FPL__INCLUDE_SIGNAL)
2235# include <signal.h>
2236#endif
2237#if defined(FPL__INCLUDE_MALLOC)
2238# include <malloc.h>
2239#endif
2240#if defined(FPL__INCLUDE_ALLOCA)
2241# include <alloca.h>
2242#endif
2243
2245#if !defined(UINT32_MAX)
2246 // On android or older posix versions there is no UINT32_MAX
2247# define UINT32_MAX ((uint32_t)-1)
2248#endif
2250
2251#if defined(FPL_IS_CPP11)
2252# define fpl__m_null nullptr
2253#elif defined(NULL)
2254# define fpl__m_null NULL
2255#else
2256# define fpl__m_null 0
2257#endif
2259#define fpl_null fpl__m_null
2260
2262typedef int32_t fpl_b32;
2263
2264//
2265// Test sizes
2266//
2268#if defined(FPL_CPU_64BIT)
2269fplStaticAssert(sizeof(uintptr_t) >= sizeof(uint64_t));
2270fplStaticAssert(sizeof(size_t) >= sizeof(uint64_t));
2271#elif defined(FPL_CPU_32BIT)
2272fplStaticAssert(sizeof(uintptr_t) >= sizeof(uint32_t));
2273fplStaticAssert(sizeof(size_t) >= sizeof(uint32_t));
2274#endif
2276
2277//
2278// Macro functions
2279//
2280
2288#define FPL_NOT_IMPLEMENTED {*(int *)0 = 0xBAD;}
2289
2290#if defined(FPL_IS_C99)
2291# define fpl__m_ZeroInit {0}
2292# define fpl__m_StructSet(ptr, type, value) *(ptr) = (type)value
2293# define fpl__m_StructInit(type, ...) (type){__VA_ARGS__}
2294#else
2295# define fpl__m_ZeroInit {}
2296# define fpl__m_StructSet(ptr, type, value) *(ptr) = value
2297# define fpl__m_StructInit(type, ...) {__VA_ARGS__}
2298#endif
2299
2301#define fplZeroInit fpl__m_ZeroInit
2303#define fplStructSet fpl__m_StructSet
2305#define fplStructInit fpl__m_StructInit
2306
2308#define fplGetAlignmentOffset(value, alignment) ( (((alignment) > 1) && (((value) & ((alignment) - 1)) != 0)) ? ((alignment) - ((value) & (alignment - 1))) : 0)
2310#define fplGetAlignedSize(size, alignment) (((size) > 0 && (alignment) > 0) ? ((size) + fplGetAlignmentOffset(size, alignment)) : (size))
2312#define fplIsAligned(ptr, alignment) (((uintptr_t)(const void *)(ptr)) % (alignment) == 0)
2314#define fplIsPowerOfTwo(value) (((value) != 0) && (((value) & (~(value) + 1)) == (value)))
2316#define fplIsBigEndian() (*(uint16_t *)"\0\xff" < 0x100)
2318#define fplIsLittleEndian() (!fplIsBigEndian())
2320#define fplIsBitSet(value, bit) (((value) >> (bit)) & 0x1)
2321
2323#define fplKiloBytes(value) (((value) * 1024ull))
2325#define fplMegaBytes(value) ((fplKiloBytes(value) * 1024ull))
2327#define fplGigaBytes(value) ((fplMegaBytes(value) * 1024ull))
2329#define fplTeraBytes(value) ((fplGigaBytes(value) * 1024ull))
2330
2332#define fplClearStruct(ptr) fplMemoryClear((void *)(ptr), sizeof(*(ptr)))
2334#define fplCopyStruct(src, dst) fplMemoryCopy(src, sizeof(*(src)), dst);
2335
2336// Array count
2337#if defined(FPL_COMPILER_MSVC) && !defined(FPL_NO_CRT) // @TODO(final): Find a better way to detect no-crt inclusion!
2338# define fpl__m_ArrayCount(arr) _countof(arr)
2339#elif defined(ARRAY_SIZE)
2340# define fpl__m_ArrayCount(arr) ARRAY_SIZE(arr)
2341#else
2343# define FPL__NO_ARRAYCOUNT_VALIDATION
2344# define fpl__m_ArrayCount(arr) (sizeof(arr) / sizeof((arr)[0]))
2345#endif
2347#define fplArrayCount(arr) fpl__m_ArrayCount(arr)
2348
2350#define fplOffsetOf(type, field) ((size_t)(&(((type*)(0))->field)))
2351
2353#define fplMin(a, b) ((a) < (b) ? (a) : (b))
2354
2356#define fplMax(a, b) ((a) > (b) ? (a) : (b))
2357
2358#if defined(FPL_PLATFORM_WINDOWS)
2359# define fpl__m_StackAllocate(size) _alloca(size)
2360#else
2361# define fpl__m_StackAllocate(size) alloca(size)
2362#endif
2363
2365#define fplStackAllocate(size) fpl__m_StackAllocate(size)
2366
2369#if defined(FPL_IS_CPP)
2370# define FPL__M_ENUM_AS_FLAGS_OPERATORS(etype) \
2371 inline etype operator | (etype a, etype b) { \
2372 return static_cast<etype>(static_cast<int>(a) | static_cast<int>(b)); \
2373 } \
2374 inline etype& operator |= (etype &a, etype b) { \
2375 return a = a | b; \
2376 } \
2377 inline etype operator & (etype a, etype b) { \
2378 return static_cast<etype>(static_cast<int>(a) & static_cast<int>(b)); \
2379 } \
2380 inline etype& operator &= (etype &a, etype b) { \
2381 return a = a & b; \
2382 } \
2383 inline etype operator ~ (etype a) { \
2384 return static_cast<etype>(~static_cast<int>(a)); \
2385 } \
2386 inline etype operator ^ (etype a, etype b) { \
2387 return static_cast<etype>(static_cast<int>(a) ^ static_cast<int>(b)); \
2388 } \
2389 inline etype& operator ^= (etype &a, etype b) { \
2390 return a = a ^ b; \
2391 }
2392#else
2393# define FPL__M_ENUM_AS_FLAGS_OPERATORS(etype)
2394#endif
2395
2397#define FPL_ENUM_AS_FLAGS_OPERATORS(type) FPL__M_ENUM_AS_FLAGS_OPERATORS(type)
2398
2399// ****************************************************************************
2400//
2401// Platform Includes
2402//
2403// ****************************************************************************
2404#if !defined(FPL_NO_PLATFORM_INCLUDES) && !defined(FPL__HAS_PLATFORM_INCLUDES)
2405# define FPL__HAS_PLATFORM_INCLUDES
2406
2407# if defined(FPL_PLATFORM_WINDOWS)
2408 // @NOTE(final): windef.h defines min/max macros in lowerspace, this will break for example std::min/max, so we have to tell the header we dont want this!
2409# if !defined(NOMINMAX)
2410# define NOMINMAX
2411# endif
2412 // @NOTE(final): For now we dont want any network, com or gdi stuff at all, maybe later who knows.
2413# if !defined(WIN32_LEAN_AND_MEAN)
2414# define WIN32_LEAN_AND_MEAN 1
2415# endif
2416 // @STUPID(final): Workaround for "combaseapi.h(229): error C2187: syntax error: 'identifier' was unexpected here"
2417struct IUnknown;
2418# include <windows.h> // Win32 api
2419# if _WIN32_WINNT < 0x0600
2420# error "Windows Vista or higher required!"
2421# endif
2422# endif // FPL_PLATFORM_WINDOWS
2423
2424# if defined(FPL_SUBPLATFORM_POSIX)
2425# include <pthread.h> // pthread_t, pthread_mutex_, pthread_cond_, pthread_barrier_
2426# include <sched.h> // sched_param, sched_get_priority_max, SCHED_FIFO
2427# include <semaphore.h> // sem_t
2428# include <dirent.h> // DIR, dirent
2429# endif // FPL_SUBPLATFORM_POSIX
2430
2431# if defined(FPL_SUBPLATFORM_X11)
2432# include <X11/X.h> // Window
2433# include <X11/Xlib.h> // Display
2434# include <X11/Xutil.h> // XVisualInfo
2435# include <X11/Xatom.h> // XA_CARDINAL
2436# endif // FPL_SUBPLATFORM_X11
2437
2438#endif // !FPL_NO_PLATFORM_INCLUDES
2439
2440//
2441// Platform handles
2442//
2443#if !defined(FPL__HAS_PLATFORM_INCLUDES) || defined(FPL_OPAQUE_HANDLES)
2444
2445# if defined(FPL_PLATFORM_WINDOWS)
2446
2448typedef uint64_t fpl__Win32Guid[4];
2450typedef void *fpl__Win32Handle;
2452typedef fpl__Win32Handle fpl__Win32InstanceHandle;
2454typedef fpl__Win32Handle fpl__Win32LibraryHandle;
2456typedef fpl__Win32Handle fpl__Win32FileHandle;
2458typedef fpl__Win32Handle fpl__Win32ThreadHandle;
2460typedef uint64_t fpl__Win32MutexHandle[16];
2462typedef fpl__Win32Handle fpl__Win32SignalHandle;
2464typedef void *fpl__Win32ConditionVariable;
2466typedef fpl__Win32Handle fpl__Win32SemaphoreHandle;
2468typedef fpl__Win32Handle fpl__Win32WindowHandle;
2470typedef fpl__Win32Handle fpl__Win32DeviceContext;
2472typedef fpl__Win32Handle fpl__Win32RenderingContext;
2474typedef union fpl__Win32LargeInteger {
2476 int64_t QuadPart;
2477 struct {
2479 int32_t LowPart;
2481 int32_t HighPart;
2482 };
2483} fpl__Win32LargeInteger;
2484
2485# endif // FPL_PLATFORM_WINDOWS
2486
2487# if defined(FPL_SUBPLATFORM_POSIX)
2488
2490typedef void *fpl__POSIXLibraryHandle;
2492typedef int fpl__POSIXFileHandle;
2494typedef void *fpl__POSIXDirHandle;
2496typedef uint64_t fpl__POSIXThreadHandle;
2498typedef uint64_t fpl__POSIXMutexHandle[16];
2500typedef uint64_t fpl__POSIXSemaphoreHandle[8];
2502typedef uint64_t fpl__POSIXConditionVariable[16];
2503
2504# endif // FPL_SUBPLATFORM_POSIX
2505
2506# if defined(FPL_SUBPLATFORM_X11)
2507
2509typedef void *fpl__X11Display;
2511typedef int fpl__X11Window;
2513typedef void *fpl__X11Visual;
2515typedef void *fpl__X11GC;
2517typedef void *fpl__X11Image;
2519typedef void *fpl__GLXContext;
2520
2521# endif // FPL_SUBPLATFORM_X11
2522
2523# if defined(FPL_PLATFORM_LINUX)
2524
2526typedef int fpl__LinuxSignalHandle;
2527
2528# endif // FPL_PLATFORM_LINUX
2529
2530#else
2531
2532# if defined(FPL_PLATFORM_WINDOWS)
2533
2535typedef GUID fpl__Win32Guid;
2537typedef HANDLE fpl__Win32Handle;
2539typedef HINSTANCE fpl__Win32InstanceHandle;
2541typedef HMODULE fpl__Win32LibraryHandle;
2543typedef HANDLE fpl__Win32ThreadHandle;
2545typedef HANDLE fpl__Win32FileHandle;
2547typedef CRITICAL_SECTION fpl__Win32MutexHandle;
2549typedef HANDLE fpl__Win32SignalHandle;
2551typedef CONDITION_VARIABLE fpl__Win32ConditionVariable;
2553typedef HANDLE fpl__Win32SemaphoreHandle;
2555typedef HWND fpl__Win32WindowHandle;
2557typedef HDC fpl__Win32DeviceContext;
2559typedef HGLRC fpl__Win32RenderingContext;
2561typedef LARGE_INTEGER fpl__Win32LargeInteger;
2562
2563# endif // FPL_PLATFORM_WINDOWS
2564
2565# if defined(FPL_SUBPLATFORM_POSIX)
2566
2568typedef void *fpl__POSIXLibraryHandle;
2570typedef int fpl__POSIXFileHandle;
2572typedef DIR *fpl__POSIXDirHandle;
2574typedef pthread_t fpl__POSIXThreadHandle;
2576typedef pthread_mutex_t fpl__POSIXMutexHandle;
2578typedef sem_t fpl__POSIXSemaphoreHandle;
2580typedef pthread_cond_t fpl__POSIXConditionVariable;
2581
2582# endif // FPL_SUBPLATFORM_POSIX
2583
2584# if defined(FPL_SUBPLATFORM_X11)
2585
2587typedef Display *fpl__X11Display;
2589typedef Window fpl__X11Window;
2591typedef Visual *fpl__X11Visual;
2593typedef GC fpl__X11GC;
2595typedef XImage *fpl__X11Image;
2597typedef void *fpl__GLXContext;
2598
2599# endif // FPL_SUBPLATFORM_X11
2600
2601
2602# if defined(FPL_PLATFORM_LINUX)
2603
2605typedef int fpl__LinuxSignalHandle;
2606
2607# endif // FPL_PLATFORM_LINUX
2608
2609
2610#endif
2611
2612//
2613// Constants
2614//
2615
2621#if defined(FPL_PLATFORM_WINDOWS)
2622# if defined(MAX_PATH)
2623# define FPL__M_MAX_FILENAME_LENGTH (MAX_PATH)
2624# define FPL__M_MAX_PATH_LENGTH (MAX_PATH * 2)
2625# else
2626# define FPL__M_MAX_FILENAME_LENGTH (260)
2627# define FPL__M_MAX_PATH_LENGTH (260 * 2)
2628# endif
2629# define FPL__M_PATH_SEPARATOR '\\'
2630# define FPL__M_FILE_EXT_SEPARATOR '.'
2631#else
2632# define FPL__M_MAX_FILENAME_LENGTH (512)
2633# define FPL__M_MAX_PATH_LENGTH (2048)
2634# define FPL__M_PATH_SEPARATOR '/'
2635# define FPL__M_FILE_EXT_SEPARATOR '.'
2636#endif
2637
2639#define FPL_MAX_FILENAME_LENGTH FPL__M_MAX_FILENAME_LENGTH
2641#define FPL_MAX_PATH_LENGTH FPL__M_MAX_PATH_LENGTH
2643#define FPL_PATH_SEPARATOR FPL__M_PATH_SEPARATOR
2645#define FPL_FILE_EXT_SEPARATOR FPL__M_FILE_EXT_SEPARATOR
2647#define FPL_MAX_NAME_LENGTH (256)
2649#define FPL_MAX_BUFFER_LENGTH (2048)
2650
2653// ****************************************************************************
2654//
2655// > API
2656//
2657// ****************************************************************************
2658
2659// ----------------------------------------------------------------------------
2666// ----------------------------------------------------------------------------
2667
2668//
2669// Barrier/Fence
2670//
2671
2690
2691//
2692// Exchange
2693//
2694
2703fpl_platform_api uint32_t fplAtomicExchangeU32(volatile uint32_t *target, const uint32_t value);
2712fpl_platform_api uint64_t fplAtomicExchangeU64(volatile uint64_t *target, const uint64_t value);
2721fpl_platform_api int32_t fplAtomicExchangeS32(volatile int32_t *target, const int32_t value);
2730fpl_platform_api int64_t fplAtomicExchangeS64(volatile int64_t *target, const int64_t value);
2739fpl_common_api void *fplAtomicExchangePtr(volatile void **target, const void *value);
2748fpl_common_api size_t fplAtomicExchangeSize(volatile size_t *target, const size_t value);
2749
2750//
2751// Fetch and Add
2752//
2753
2762fpl_platform_api uint32_t fplAtomicFetchAndAddU32(volatile uint32_t *value, const uint32_t addend);
2771fpl_platform_api uint64_t fplAtomicFetchAndAddU64(volatile uint64_t *value, const uint64_t addend);
2780fpl_platform_api int32_t fplAtomicFetchAndAddS32(volatile int32_t *value, const int32_t addend);
2789fpl_platform_api int64_t fplAtomicFetchAndAddS64(volatile int64_t *value, const int64_t addend);
2798fpl_common_api size_t fplAtomicFetchAndAddSize(volatile size_t *dest, const size_t addend);
2807fpl_common_api void *fplAtomicFetchAndAddPtr(volatile void **dest, const intptr_t addend);
2808
2809//
2810// Add and Fetch
2811//
2812
2821fpl_platform_api uint32_t fplAtomicAddAndFetchU32(volatile uint32_t *dest, const uint32_t addend);
2830fpl_platform_api uint64_t fplAtomicAddAndFetchU64(volatile uint64_t *dest, const uint64_t addend);
2839fpl_platform_api int32_t fplAtomicAddAndFetchS32(volatile int32_t *dest, const int32_t addend);
2848fpl_platform_api int64_t fplAtomicAddAndFetchS64(volatile int64_t *dest, const int64_t addend);
2857fpl_common_api size_t fplAtomicAddAndFetchSize(volatile size_t *dest, const size_t addend);
2866fpl_common_api void *fplAtomicAddAndFetchPtr(volatile void **dest, const intptr_t addend);
2867
2868//
2869// Increment
2870//
2871
2879fpl_platform_api uint32_t fplAtomicIncrementU32(volatile uint32_t *dest);
2887fpl_platform_api uint64_t fplAtomicIncrementU64(volatile uint64_t *dest);
2895fpl_platform_api int32_t fplAtomicIncrementS32(volatile int32_t *dest);
2903fpl_platform_api int64_t fplAtomicIncrementS64(volatile int64_t *dest);
2911fpl_common_api size_t fplAtomicIncrementSize(volatile size_t *dest);
2919fpl_common_api void *fplAtomicIncrementPtr(volatile void **dest);
2920
2921//
2922// CAS
2923//
2924
2935fpl_platform_api uint32_t fplAtomicCompareAndSwapU32(volatile uint32_t *dest, const uint32_t comparand, const uint32_t exchange);
2946fpl_platform_api uint64_t fplAtomicCompareAndSwapU64(volatile uint64_t *dest, const uint64_t comparand, const uint64_t exchange);
2957fpl_platform_api int32_t fplAtomicCompareAndSwapS32(volatile int32_t *dest, const int32_t comparand, const int32_t exchange);
2968fpl_platform_api int64_t fplAtomicCompareAndSwapS64(volatile int64_t *dest, const int64_t comparand, const int64_t exchange);
2979fpl_common_api size_t fplAtomicCompareAndSwapSize(volatile size_t *dest, const size_t comparand, const size_t exchange);
2990fpl_common_api void *fplAtomicCompareAndSwapPtr(volatile void **dest, const void *comparand, const void *exchange);
2991
3001fpl_platform_api bool fplAtomicIsCompareAndSwapU32(volatile uint32_t *dest, const uint32_t comparand, const uint32_t exchange);
3011fpl_platform_api bool fplAtomicIsCompareAndSwapU64(volatile uint64_t *dest, const uint64_t comparand, const uint64_t exchange);
3021fpl_platform_api bool fplAtomicIsCompareAndSwapS32(volatile int32_t *dest, const int32_t comparand, const int32_t exchange);
3031fpl_platform_api bool fplAtomicIsCompareAndSwapS64(volatile int64_t *dest, const int64_t comparand, const int64_t exchange);
3041fpl_common_api bool fplAtomicIsCompareAndSwapSize(volatile size_t *dest, const size_t comparand, const size_t exchange);
3051fpl_common_api bool fplAtomicIsCompareAndSwapPtr(volatile void **dest, const void *comparand, const void *exchange);
3052
3053//
3054// Load
3055//
3056
3065fpl_platform_api uint32_t fplAtomicLoadU32(volatile uint32_t *source);
3074fpl_platform_api uint64_t fplAtomicLoadU64(volatile uint64_t *source);
3083fpl_platform_api int32_t fplAtomicLoadS32(volatile int32_t *source);
3092fpl_platform_api int64_t fplAtomicLoadS64(volatile int64_t *source);
3101fpl_common_api size_t fplAtomicLoadSize(volatile size_t *source);
3110fpl_common_api void *fplAtomicLoadPtr(volatile void **source);
3111
3112//
3113// Store
3114//
3115
3123fpl_platform_api void fplAtomicStoreU32(volatile uint32_t *dest, const uint32_t value);
3131fpl_platform_api void fplAtomicStoreU64(volatile uint64_t *dest, const uint64_t value);
3139fpl_platform_api void fplAtomicStoreS32(volatile int32_t *dest, const int32_t value);
3147fpl_platform_api void fplAtomicStoreS64(volatile int64_t *dest, const int64_t value);
3155fpl_common_api void fplAtomicStoreSize(volatile size_t *dest, const size_t value);
3163fpl_common_api void fplAtomicStorePtr(volatile void **dest, const void *value);
3164
3167// ----------------------------------------------------------------------------
3173// ----------------------------------------------------------------------------
3174
3176typedef struct fplMemoryBlock {
3178 void *base;
3180 size_t size;
3182
3202
3209fpl_common_api void fplMemoryClear(void *mem, const size_t size);
3217fpl_common_api void fplMemorySet(void *mem, const uint8_t value, const size_t size);
3225fpl_common_api void fplMemoryCopy(const void *sourceMem, const size_t sourceSize, void *targetMem);
3235fpl_platform_api void *fplMemoryAllocate(const size_t size);
3253fpl_common_api void *fplMemoryAlignedAllocate(const size_t size, const size_t alignment);
3269
3272// ----------------------------------------------------------------------------
3278// ----------------------------------------------------------------------------
3279
3281typedef char fplVersionNumberPart[4 + 1];
3282
3302
3314
3323
3326// ----------------------------------------------------------------------------
3332// ----------------------------------------------------------------------------
3333
3341fpl_platform_api size_t fplSessionGetUsername(char *nameBuffer, const size_t maxNameBufferLen);
3342
3345// ----------------------------------------------------------------------------
3352// ----------------------------------------------------------------------------
3353
3374
3400
3402typedef union fplCPUIDLeaf {
3403 struct {
3405 uint32_t eax;
3407 uint32_t ebx;
3409 uint32_t ecx;
3411 uint32_t edx;
3412 };
3414 uint32_t raw[4];
3416
3423fpl_common_api void fplCPUID(fplCPUIDLeaf *outLeaf, const uint32_t functionId);
3456fpl_common_api size_t fplCPUGetName(char *destBuffer, const size_t maxDestBufferLen);
3470
3473// ----------------------------------------------------------------------------
3479// ----------------------------------------------------------------------------
3480
3500
3517
3542
3550
3567
3568#if defined(FPL__ENABLE_VIDEO_OPENGL)
3580
3594#endif // FPL__ENABLE_VIDEO_OPENGL
3595
3596#if defined(FPL__ENABLE_VIDEO_VULKAN)
3597
3599typedef void (fplVulkanValidationLayerCallback)(void *userData, const char *message, const uint32_t messageSeverity, const uint32_t messageType, const void *debugUtilsMessengerCallbackData);
3600
3610
3626
3654#endif // FPL__ENABLE_VIDEO_VULKAN
3655
3658#if defined(FPL__ENABLE_VIDEO_OPENGL)
3661#endif
3662#if defined(FPL__ENABLE_VIDEO_VULKAN)
3665#endif
3669
3681
3689
3706
3731
3749
3757
3777
3797
3799typedef union fplAudioDeviceID {
3800#if defined(FPL__ENABLE_AUDIO_DIRECTSOUND)
3802 fpl__Win32Guid dshow;
3803#endif
3804#if defined(FPL__ENABLE_AUDIO_ALSA)
3806 char alsa[256];
3807#endif
3811
3819
3820#if defined(FPL__ENABLE_AUDIO_ALSA)
3822typedef struct fplAlsaAudioSettings {
3824 fpl_b32 noMMap;
3825} fplAlsaAudioSettings;
3826#endif
3827
3830#if defined(FPL__ENABLE_AUDIO_ALSA)
3832 fplAlsaAudioSettings alsa;
3833#endif
3837
3847typedef uint32_t(fpl_audio_client_read_callback)(const fplAudioDeviceFormat *deviceFormat, const uint32_t frameCount, void *outputSamples, void *userData);
3848
3868
3876
3884
3886typedef struct fplImageSource {
3888 const uint8_t *data;
3890 uint32_t width;
3892 uint32_t height;
3896
3905typedef bool (fpl_window_event_callback)(const fplPlatformType platformType, void *windowState, void *rawEventData, void *userData);
3906
3916
3928
3930typedef struct fplWindowSize {
3932 uint32_t width;
3934 uint32_t height;
3936
3938typedef struct fplWindowPosition {
3940 int32_t left;
3942 int32_t top;
3944
3946typedef union fplColor32 {
3947 struct {
3949 uint8_t b;
3951 uint8_t g;
3953 uint8_t r;
3955 uint8_t a;
3956 };
3958 uint32_t value;
3960 uint8_t m[4];
3962
3971fpl_inline fplColor32 fplCreateColorRGBA(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) {
3972 fplColor32 result = fplStructInit(fplColor32, b, g, r, a);
3973 return(result);
3974}
3975
4005
4013
4019
4026
4034
4042
4044typedef void *(fpl_memory_allocate_callback)(void *userData, const size_t size, const size_t alignment);
4046typedef void (fpl_memory_release_callback)(void *userData, void *ptr);
4047
4055
4067
4075
4091
4111
4114// ----------------------------------------------------------------------------
4120// ----------------------------------------------------------------------------
4121
4143fpl_common_api bool fplPlatformInit(const fplInitFlags initFlags, const fplSettings *initSettings);
4160
4163// ----------------------------------------------------------------------------
4169// ----------------------------------------------------------------------------
4170
4195
4196#if defined(FPL__ENABLE_LOGGING)
4205typedef void (fpl_log_func_callback)(const char *funcName, const int lineNumber, const fplLogLevel level, const char *message);
4206
4222
4228
4234
4244
4246typedef struct fplLogSettings {
4247#if defined(FPL__ENABLE_LOG_MULTIPLE_WRITERS)
4248 union {
4251 struct {
4253 fplLogWriter criticalWriter;
4255 fplLogWriter errorWriter;
4257 fplLogWriter warningWriter;
4259 fplLogWriter infoWriter;
4261 fplLogWriter verboseWriter;
4263 fplLogWriter debugWriter;
4264 };
4265 };
4266#else
4269#endif // FPL_USE_LOG_SIMPLE
4271 fplLogLevel maxLevel;
4275
4304#endif // FPL__ENABLE_LOGGING
4305
4308// ----------------------------------------------------------------------------
4314// ----------------------------------------------------------------------------
4315
4330fpl_common_api const char *fplGetErrorByIndex(const size_t index);
4344
4347// ----------------------------------------------------------------------------
4353// ----------------------------------------------------------------------------
4354
4357#if defined(FPL_PLATFORM_WINDOWS)
4359 fpl__Win32LibraryHandle win32LibraryHandle;
4360#elif defined(FPL_SUBPLATFORM_POSIX)
4362 fpl__POSIXLibraryHandle posixLibraryHandle;
4363#endif
4365
4373
4381fpl_platform_api bool fplDynamicLibraryLoad(const char *libraryFilePath, fplDynamicLibraryHandle *outHandle);
4396
4399// ----------------------------------------------------------------------------
4404// ----------------------------------------------------------------------------
4405
4412fpl_platform_api void fplDebugOut(const char *text);
4420fpl_common_api void fplDebugFormatOut(const char *format, ...);
4421
4424// ----------------------------------------------------------------------------
4430// ----------------------------------------------------------------------------
4431
4437fpl_platform_api void fplConsoleOut(const char *text);
4443fpl_platform_api void fplConsoleError(const char *text);
4450
4457fpl_common_api void fplConsoleFormatOut(const char *format, ...);
4464fpl_common_api void fplConsoleFormatError(const char *format, ...);
4465
4468// ----------------------------------------------------------------------------
4474// ----------------------------------------------------------------------------
4475
4477typedef union fplTimestamp {
4478#if defined(FPL_PLATFORM_WINDOWS)
4480 struct {
4482 fpl__Win32LargeInteger qpc;
4484 uint64_t ticks;
4485 } win32;
4486#elif defined(FPL_SUBPLATFORM_POSIX)
4488 struct {
4490 uint64_t seconds;
4492 int64_t nanoSeconds;
4493 } posix;
4494#endif
4496 uint64_t unused;
4498
4500typedef uint32_t fplTimeoutValue;
4502#define FPL_TIMEOUT_INFINITE UINT32_MAX
4503
4505typedef double fplSeconds;
4506
4508typedef uint64_t fplMilliseconds;
4509
4526
4529// ----------------------------------------------------------------------------
4535// ----------------------------------------------------------------------------
4536
4548
4550typedef uint32_t fplThreadState;
4551
4578
4581
4587typedef void (fpl_run_thread_callback)(const fplThreadHandle *thread, void *data);
4588
4591#if defined(FPL_PLATFORM_WINDOWS)
4593 fpl__Win32ThreadHandle win32ThreadHandle;
4594#elif defined(FPL_SUBPLATFORM_POSIX)
4596 fpl__POSIXThreadHandle posixThread;
4597#endif
4599
4611
4627
4628#if defined(FPL_PLATFORM_WINDOWS)
4629typedef struct fpl__Win32InternalSemaphore {
4631 fpl__Win32SemaphoreHandle handle;
4633 volatile int32_t value;
4634} fpl__Win32InternalSemaphore;
4635#endif
4636
4639#if defined(FPL_PLATFORM_WINDOWS)
4641 fpl__Win32InternalSemaphore win32;
4642#elif defined(FPL_SUBPLATFORM_POSIX)
4644 fpl__POSIXSemaphoreHandle posixHandle;
4645#endif
4647
4655
4658#if defined(FPL_PLATFORM_WINDOWS)
4660 fpl__Win32MutexHandle win32CriticalSection;
4661#elif defined(FPL_SUBPLATFORM_POSIX)
4663 fpl__POSIXMutexHandle posixMutex;
4664#endif
4666
4674
4677#if defined(FPL_PLATFORM_WINDOWS)
4679 fpl__Win32SignalHandle win32EventHandle;
4680#elif defined(FPL_PLATFORM_LINUX)
4682 fpl__LinuxSignalHandle linuxEventHandle;
4683#endif
4685
4693
4701
4704#if defined(FPL_PLATFORM_WINDOWS)
4706 fpl__Win32ConditionVariable win32Condition;
4707#elif defined(FPL_SUBPLATFORM_POSIX)
4709 fpl__POSIXConditionVariable posixCondition;
4710#endif
4714
4722
4786fpl_platform_api void fplThreadSleep(const uint32_t milliseconds);
4819fpl_platform_api bool fplThreadWaitForAll(fplThreadHandle **threads, const size_t count, const size_t stride, const fplTimeoutValue timeout);
4829fpl_platform_api bool fplThreadWaitForAny(fplThreadHandle **threads, const size_t count, const size_t stride, const fplTimeoutValue timeout);
4830
4866
4899fpl_platform_api bool fplSignalWaitForAll(fplSignalHandle **signals, const size_t count, const size_t stride, const fplTimeoutValue timeout);
4909fpl_platform_api bool fplSignalWaitForAny(fplSignalHandle **signals, const size_t count, const size_t stride, const fplTimeoutValue timeout);
4924
4963
4971fpl_platform_api bool fplSemaphoreInit(fplSemaphoreHandle *semaphore, const uint32_t initialValue);
5010
5013// ----------------------------------------------------------------------------
5019// ----------------------------------------------------------------------------
5020
5027fpl_common_api bool fplIsStringMatchWildcard(const char *source, const char *wildcard);
5037fpl_common_api bool fplIsStringEqualLen(const char *a, const size_t aLen, const char *b, const size_t bLen);
5044fpl_common_api bool fplIsStringEqual(const char *a, const char *b);
5051fpl_common_api char *fplEnforcePathSeparatorLen(char *path, size_t maxPathLen);
5067fpl_common_api char *fplStringAppendLen(const char *appended, const size_t appendedLen, char *buffer, size_t maxBufferLen);
5075fpl_common_api char *fplStringAppend(const char *appended, char *buffer, size_t maxBufferLen);
5081fpl_common_api size_t fplGetStringLength(const char *str);
5091fpl_common_api char *fplCopyStringLen(const char *source, const size_t sourceLen, char *dest, const size_t maxDestLen);
5100fpl_common_api char *fplCopyString(const char *source, char *dest, const size_t maxDestLen);
5110fpl_platform_api size_t fplWideStringToUTF8String(const wchar_t *wideSource, const size_t wideSourceLen, char *utf8Dest, const size_t maxUtf8DestLen);
5120fpl_platform_api size_t fplUTF8StringToWideString(const char *utf8Source, const size_t utf8SourceLen, wchar_t *wideDest, const size_t maxWideDestLen);
5130fpl_common_api size_t fplStringFormat(char *destBuffer, const size_t maxDestBufferLen, const char *format, ...);
5140fpl_common_api size_t fplStringFormatArgs(char *destBuffer, const size_t maxDestBufferLen, const char *format, va_list argList);
5141
5148fpl_common_api int32_t fplStringToS32Len(const char *str, const size_t len);
5149
5155fpl_common_api int32_t fplStringToS32(const char *str);
5156
5164fpl_common_api size_t fplS32ToString(const int32_t value, char *buffer, const size_t maxBufferLen);
5165
5168// ----------------------------------------------------------------------------
5174// ----------------------------------------------------------------------------
5175
5178#if defined(FPL_PLATFORM_WINDOWS)
5180 fpl__Win32FileHandle win32FileHandle;
5181#elif defined(FPL_SUBPLATFORM_POSIX)
5183 fpl__POSIXFileHandle posixFileHandle;
5184#endif
5186
5194
5204
5214
5228
5242
5244typedef union fplFilePermissions {
5245 struct {
5247 uint8_t user;
5249 uint8_t group;
5251 uint8_t owner;
5253 uint8_t unused;
5254 };
5256 uint32_t umask;
5258
5274
5277#if defined(FPL_PLATFORM_WINDOWS)
5279 fpl__Win32FileHandle win32FileHandle;
5280#elif defined(FPL_SUBPLATFORM_POSIX)
5282 fpl__POSIXDirHandle posixDirHandle;
5283#endif
5285
5293
5295typedef uint64_t fplFileTimeStamp;
5296
5306
5326
5334fpl_platform_api bool fplFileOpenBinary(const char *filePath, fplFileHandle *outHandle);
5342fpl_platform_api bool fplFileCreateBinary(const char *filePath, fplFileHandle *outHandle);
5353fpl_platform_api uint32_t fplFileReadBlock32(const fplFileHandle *fileHandle, const uint32_t sizeToRead, void *targetBuffer, const uint32_t maxTargetBufferSize);
5364fpl_platform_api uint64_t fplFileReadBlock64(const fplFileHandle *fileHandle, const uint64_t sizeToRead, void *targetBuffer, const uint64_t maxTargetBufferSize);
5375fpl_platform_api size_t fplFileReadBlock(const fplFileHandle *fileHandle, const size_t sizeToRead, void *targetBuffer, const size_t maxTargetBufferSize);
5385fpl_platform_api uint32_t fplFileWriteBlock32(const fplFileHandle *fileHandle, void *sourceBuffer, const uint32_t sourceSize);
5395fpl_platform_api uint64_t fplFileWriteBlock64(const fplFileHandle *fileHandle, void *sourceBuffer, const uint64_t sourceSize);
5405fpl_common_api size_t fplFileWriteBlock(const fplFileHandle *fileHandle, void *sourceBuffer, const size_t sourceSize);
5414fpl_platform_api uint32_t fplFileSetPosition32(const fplFileHandle *fileHandle, const int32_t position, const fplFilePositionMode mode);
5423fpl_platform_api uint64_t fplFileSetPosition64(const fplFileHandle *fileHandle, const int64_t position, const fplFilePositionMode mode);
5432fpl_common_api size_t fplFileSetPosition(const fplFileHandle *fileHandle, const intptr_t position, const fplFilePositionMode mode);
5469
5476fpl_platform_api uint32_t fplFileGetSizeFromPath32(const char *filePath);
5483fpl_platform_api uint64_t fplFileGetSizeFromPath64(const char *filePath);
5490fpl_platform_api size_t fplFileGetSizeFromPath(const char *filePath);
5532fpl_platform_api bool fplFileSetTimestamps(const char *filePath, const fplFileTimeStamps *timeStamps);
5538fpl_platform_api bool fplFileExists(const char *filePath);
5546fpl_platform_api bool fplFileCopy(const char *sourceFilePath, const char *targetFilePath, const bool overwrite);
5553fpl_platform_api bool fplFileMove(const char *sourceFilePath, const char *targetFilePath);
5559fpl_platform_api bool fplFileDelete(const char *filePath);
5560
5589fpl_platform_api bool fplDirectoryListBegin(const char *path, const char *filter, fplFileEntry *entry);
5606
5609// ----------------------------------------------------------------------------
5615// ----------------------------------------------------------------------------
5616
5624fpl_platform_api size_t fplGetExecutableFilePath(char *destPath, const size_t maxDestLen);
5632fpl_platform_api size_t fplGetHomePath(char *destPath, const size_t maxDestLen);
5641fpl_common_api size_t fplExtractFilePath(const char *sourcePath, char *destPath, const size_t maxDestLen);
5648fpl_common_api const char *fplExtractFileExtension(const char *sourcePath);
5655fpl_common_api const char *fplExtractFileName(const char *sourcePath);
5665fpl_common_api size_t fplChangeFileExtension(const char *filePath, const char *newFileExtension, char *destPath, const size_t maxDestLen);
5675fpl_common_api size_t fplPathCombine(char *destPath, const size_t maxDestPathLen, const size_t pathCount, ...);
5676
5679#if defined(FPL__ENABLE_WINDOW)
5680// ----------------------------------------------------------------------------
5686// ----------------------------------------------------------------------------
5687
5689typedef enum fplKey {
5690 fplKey_None = 0,
5691
5692 // 0x0-0x07: Undefined
5693
5694 fplKey_Backspace = 0x08,
5695 fplKey_Tab = 0x09,
5696
5697 // 0x0A-0x0B: Reserved
5698
5699 fplKey_Clear = 0x0C,
5700 fplKey_Return = 0x0D,
5701
5702 // 0x0E-0x0F: Undefined
5703
5704 fplKey_Shift = 0x10,
5705 fplKey_Control = 0x11,
5706 fplKey_Alt = 0x12,
5707 fplKey_Pause = 0x13,
5708 fplKey_CapsLock = 0x14,
5709
5710 // 0x15: IME-Keys
5711 // 0x16: Undefined
5712 // 0x17-0x19 IME-Keys
5713 // 0x1A: Undefined
5714
5715 fplKey_Escape = 0x1B,
5716
5717 // 0x1C-0x1F: IME-Keys
5718
5719 fplKey_Space = 0x20,
5720 fplKey_PageUp = 0x21,
5721 fplKey_PageDown = 0x22,
5722 fplKey_End = 0x23,
5723 fplKey_Home = 0x24,
5724 fplKey_Left = 0x25,
5725 fplKey_Up = 0x26,
5726 fplKey_Right = 0x27,
5727 fplKey_Down = 0x28,
5728 fplKey_Select = 0x29,
5729 fplKey_Print = 0x2A,
5730 fplKey_Execute = 0x2B,
5731 fplKey_Snapshot = 0x2C,
5732 fplKey_Insert = 0x2D,
5733 fplKey_Delete = 0x2E,
5734 fplKey_Help = 0x2F,
5735
5736 fplKey_0 = 0x30,
5737 fplKey_1 = 0x31,
5738 fplKey_2 = 0x32,
5739 fplKey_3 = 0x33,
5740 fplKey_4 = 0x34,
5741 fplKey_5 = 0x35,
5742 fplKey_6 = 0x36,
5743 fplKey_7 = 0x37,
5744 fplKey_8 = 0x38,
5745 fplKey_9 = 0x39,
5746
5747 // 0x3A-0x40: Undefined
5748
5749 fplKey_A = 0x41,
5750 fplKey_B = 0x42,
5751 fplKey_C = 0x43,
5752 fplKey_D = 0x44,
5753 fplKey_E = 0x45,
5754 fplKey_F = 0x46,
5755 fplKey_G = 0x47,
5756 fplKey_H = 0x48,
5757 fplKey_I = 0x49,
5758 fplKey_J = 0x4A,
5759 fplKey_K = 0x4B,
5760 fplKey_L = 0x4C,
5761 fplKey_M = 0x4D,
5762 fplKey_N = 0x4E,
5763 fplKey_O = 0x4F,
5764 fplKey_P = 0x50,
5765 fplKey_Q = 0x51,
5766 fplKey_R = 0x52,
5767 fplKey_S = 0x53,
5768 fplKey_T = 0x54,
5769 fplKey_U = 0x55,
5770 fplKey_V = 0x56,
5771 fplKey_W = 0x57,
5772 fplKey_X = 0x58,
5773 fplKey_Y = 0x59,
5774 fplKey_Z = 0x5A,
5775
5776 fplKey_LeftSuper = 0x5B,
5777 fplKey_RightSuper = 0x5C,
5778 fplKey_Apps = 0x5D,
5779
5780 // 0x5E: Reserved
5781
5782 fplKey_Sleep = 0x5F,
5783 fplKey_NumPad0 = 0x60,
5784 fplKey_NumPad1 = 0x61,
5785 fplKey_NumPad2 = 0x62,
5786 fplKey_NumPad3 = 0x63,
5787 fplKey_NumPad4 = 0x64,
5788 fplKey_NumPad5 = 0x65,
5789 fplKey_NumPad6 = 0x66,
5790 fplKey_NumPad7 = 0x67,
5791 fplKey_NumPad8 = 0x68,
5792 fplKey_NumPad9 = 0x69,
5793 fplKey_Multiply = 0x6A,
5794 fplKey_Add = 0x6B,
5795 fplKey_Separator = 0x6C,
5796 fplKey_Substract = 0x6D,
5797 fplKey_Decimal = 0x6E,
5798 fplKey_Divide = 0x6F,
5799 fplKey_F1 = 0x70,
5800 fplKey_F2 = 0x71,
5801 fplKey_F3 = 0x72,
5802 fplKey_F4 = 0x73,
5803 fplKey_F5 = 0x74,
5804 fplKey_F6 = 0x75,
5805 fplKey_F7 = 0x76,
5806 fplKey_F8 = 0x77,
5807 fplKey_F9 = 0x78,
5808 fplKey_F10 = 0x79,
5809 fplKey_F11 = 0x7A,
5810 fplKey_F12 = 0x7B,
5811 fplKey_F13 = 0x7C,
5812 fplKey_F14 = 0x7D,
5813 fplKey_F15 = 0x7E,
5814 fplKey_F16 = 0x7F,
5815 fplKey_F17 = 0x80,
5816 fplKey_F18 = 0x81,
5817 fplKey_F19 = 0x82,
5818 fplKey_F20 = 0x83,
5819 fplKey_F21 = 0x84,
5820 fplKey_F22 = 0x85,
5821 fplKey_F23 = 0x86,
5822 fplKey_F24 = 0x87,
5823
5824 // 0x88-8F: Unassigned
5825
5826 fplKey_NumLock = 0x90,
5827 fplKey_Scroll = 0x91,
5828
5829 // 0x92-9x96: OEM specific
5830 // 0x97-0x9F: Unassigned
5831
5832 fplKey_LeftShift = 0xA0,
5833 fplKey_RightShift = 0xA1,
5834 fplKey_LeftControl = 0xA2,
5835 fplKey_RightControl = 0xA3,
5836 fplKey_LeftAlt = 0xA4,
5837 fplKey_RightAlt = 0xA5,
5838
5839 // 0xA6-0xAC: Dont care
5840
5841 fplKey_VolumeMute = 0xAD,
5842 fplKey_VolumeDown = 0xAE,
5843 fplKey_VolumeUp = 0xAF,
5844 fplKey_MediaNextTrack = 0xB0,
5845 fplKey_MediaPrevTrack = 0xB1,
5846 fplKey_MediaStop = 0xB2,
5847 fplKey_MediaPlayPause = 0xB3,
5848
5849 // 0xB4-0xB9 Dont care
5850
5865
5866 // 0xC1-0xD7 Reserved
5867 // 0xD8-0xDA Unassigned
5868
5877 fplKey_Oem8 = 0xDF,
5878
5879 // 0xE0-0xFE Dont care
5881
5911
5921
5935
5945
5955
5985
5999
6011
6025
6041
6053
6059
6095
6159
6171
6185
6201
6209
6216
6219// ----------------------------------------------------------------------------
6225// ----------------------------------------------------------------------------
6226
6228#define FPL_MAX_KEYBOARD_STATE_COUNT 256
6229
6239
6241#define FPL_MAX_GAMEPAD_STATE_COUNT 4
6242
6248
6258
6277
6283fpl_platform_api bool fplQueryCursorPosition(int32_t *outX, int32_t *outY);
6284
6287// ----------------------------------------------------------------------------
6293// ----------------------------------------------------------------------------
6294
6308
6318
6349fpl_platform_api void fplSetWindowSize(const uint32_t width, const uint32_t height);
6389fpl_platform_api bool fplSetWindowFullscreenSize(const bool value, const uint32_t fullscreenWidth, const uint32_t fullscreenHeight, const uint32_t refreshRate);
6400fpl_platform_api bool fplSetWindowFullscreenRect(const bool value, const int32_t x, const int32_t y, const int32_t width, const int32_t height);
6429fpl_platform_api void fplSetWindowPosition(const int32_t left, const int32_t top);
6434fpl_platform_api void fplSetWindowTitle(const char *title);
6441fpl_common_api char *fplGetWindowTitle(char *outTitle, const size_t maxOutTitleLength);
6459
6462// ----------------------------------------------------------------------------
6468// ----------------------------------------------------------------------------
6469
6483
6485typedef struct fplDisplayMode {
6487 uint32_t width;
6489 uint32_t height;
6491 uint32_t colorBits;
6493 uint32_t refreshRate;
6495
6507fpl_platform_api size_t fplGetDisplays(fplDisplayInfo *outDisplays, const size_t maxDisplayCount);
6527fpl_platform_api bool fplGetDisplayFromPosition(const int32_t x, const int32_t y, fplDisplayInfo *outInfo);
6535fpl_platform_api size_t fplGetDisplayModes(const char *id, fplDisplayMode *outModes, const size_t maxDisplayModeCount);
6536
6539// ----------------------------------------------------------------------------
6545// ----------------------------------------------------------------------------
6546
6553fpl_platform_api bool fplGetClipboardText(char *dest, const uint32_t maxDestLen);
6560
6562#endif // FPL__ENABLE_WINDOW
6563
6564#if defined(FPL__ENABLE_VIDEO)
6565// ----------------------------------------------------------------------------
6571// ----------------------------------------------------------------------------
6572
6574typedef struct fplVideoRect {
6576 int32_t x;
6578 int32_t y;
6580 int32_t width;
6582 int32_t height;
6584
6593fpl_inline fplVideoRect fplCreateVideoRectFromLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) {
6594 fplVideoRect result = { left, top, (right - left) + 1, (bottom - top) + 1 };
6595 return(result);
6596}
6597
6615
6616#if defined(FPL__ENABLE_VIDEO_VULKAN)
6624#endif
6625
6626#if defined(FPL__ENABLE_VIDEO_OPENGL)
6632#endif
6633
6634#if defined(FPL_PLATFORM_WINDOWS)
6636typedef struct fplVideoWindowWin32 {
6638 fpl__Win32WindowHandle windowHandle;
6640 fpl__Win32DeviceContext deviceContext;
6641} fplVideoWindowWin32;
6642#endif
6643
6644#if defined(FPL_SUBPLATFORM_X11)
6646typedef struct fplVideoWindowX11 {
6648 fpl__X11Window window;
6650 fpl__X11Display display;
6652 fpl__X11Visual visual;
6654 int screen;
6655} fplVideoWindowX11;
6656#endif // FPL_SUBPLATFORM_X11
6657
6659typedef union fplVideoWindow {
6660#if defined(FPL_PLATFORM_WINDOWS)
6661 fplVideoWindowWin32 win32;
6662#elif defined(FPL_SUBPLATFORM_X11)
6663 fplVideoWindowX11 x11;
6664#endif
6668
6670typedef struct fplVideoSurface {
6673
6674#if defined(FPL__ENABLE_VIDEO_VULKAN)
6677#endif
6678
6679#if defined(FPL__ENABLE_VIDEO_OPENGL)
6682#endif
6683
6687
6688#if defined(FPL__ENABLE_VIDEO_VULKAN)
6696#endif // FPL__ENABLE_VIDEO_VULKAN
6697
6698
6701#if defined(FPL__ENABLE_VIDEO_VULKAN)
6704#endif // FPL__ENABLE_VIDEO_VULKAN
6706 int dummy;
6708
6732fpl_common_api bool fplResizeVideoBackBuffer(const uint32_t width, const uint32_t height);
6733
6738
6744fpl_common_api const void *fplGetVideoProcedure(const char *procName);
6745
6751
6759
6761#endif // FPL__ENABLE_VIDEO
6762
6763#if defined(FPL__ENABLE_AUDIO)
6764// ----------------------------------------------------------------------------
6770// ----------------------------------------------------------------------------
6771
6810
6846fpl_common_api uint32_t fplGetAudioDevices(fplAudioDeviceInfo *devices, uint32_t maxDeviceCount);
6871fpl_common_api uint32_t fplGetAudioBufferSizeInFrames(uint32_t sampleRate, uint32_t bufferSizeInMilliSeconds);
6878fpl_common_api uint32_t fplGetAudioBufferSizeInMilliseconds(uint32_t sampleRate, uint32_t frameCount);
6885fpl_common_api uint32_t fplGetAudioFrameSizeInBytes(const fplAudioFormatType format, const uint32_t channelCount);
6893fpl_common_api uint32_t fplGetAudioBufferSizeInBytes(const fplAudioFormatType format, const uint32_t channelCount, const uint32_t frameCount);
6900
6902#endif // FPL__ENABLE_AUDIO
6903
6904// ----------------------------------------------------------------------------
6910// ----------------------------------------------------------------------------
6911
6919
6927fpl_platform_api size_t fplGetUserLocale(const fplLocaleFormat targetFormat, char *buffer, const size_t maxBufferLen);
6928
6936fpl_platform_api size_t fplGetSystemLocale(const fplLocaleFormat targetFormat, char *buffer, const size_t maxBufferLen);
6937
6945fpl_platform_api size_t fplGetInputLocale(const fplLocaleFormat targetFormat, char *buffer, const size_t maxBufferLen);
6946
6949// Ignore any doxygen documentation from here
6951
6952// ****************************************************************************
6953//
6954// > EXPORT
6955//
6956// Internal functions for static library
6957// Entry-Point forward declaration
6958//
6959// ****************************************************************************
6960#if defined(FPL_PLATFORM_WINDOWS)
6961# if defined(FPL_ENTRYPOINT)
6962// @NOTE(final): Required for access "main" from the actual win32 entry point
6963fpl_main int main(int argc, char **args);
6964# endif
6965#endif // FPL_PLATFORM_WINDOWS
6966
6967#endif // FPL_HEADER_H
6968
6969// ****************************************************************************
6970//
6971// > IMPLEMENTATION
6972//
6973// FPL uses several implementation blocks to structure things in categories.
6974// Each block has its own ifdef definition to collapse it down if needed.
6975// But the baseline structure is the following:
6976//
6977// - Compiler settings (Disable warnings, etc.)
6978// - Platform Constants & Types (All required structs, Constants, Global variables, etc.)
6979// - Common implementations
6980// - Actual platform implementations (Win32, Linux)
6981// - Sub platform implementations (X11, POSIX, STD)
6982// - Backend implementations (Video: OpenGL/Software/Vulkan, Audio: DirectSound/Alsa)
6983// - Systems (Audio, Video, Window systems)
6984// - Core (Init & Release of the specific platform by selection)
6985//
6986// You can use the following strings to search for implementation blocks - including the > prefix:
6987//
6988// > COMPILER_CONFIG
6989// > PLATFORM_INCLUDES
6990//
6991// > INTERNAL_TOP
6992// > INTERNAL_LOGGING
6993//
6994// > PLATFORM_CONSTANTS
6995// > UTILITY_FUNCTIONS
6996//
6997// > TYPES
6998// > TYPES_WIN32
6999// > TYPES_POSIX
7000// > TYPES_LINUX
7001// > TYPES_X11
7002//
7003// > PLATFORM_STATES
7004//
7005// > COMMON
7006//
7007// > WIN32_PLATFORM
7008// > POSIX_SUBPLATFORM (Linux, Unix)
7009// > STD_STRINGS_SUBPLATFORM
7010// > STD_CONSOLE_SUBPLATFORM
7011// > X11_SUBPLATFORM
7012// > LINUX_PLATFORM
7013// > UNIX_PLATFORM
7014//
7015// > VIDEO_BACKENDS
7016// > VIDEO_BACKEND_OPENGL_WIN32
7017// > VIDEO_BACKEND_OPENGL_X11
7018// > VIDEO_BACKEND_SOFTWARE_WIN32
7019// > VIDEO_BACKEND_SOFTWARE_X11
7020// > VIDEO_BACKEND_VULKAN
7021//
7022// > AUDIO_BACKENDS
7023// > AUDIO_BACKEND_DIRECTSOUND
7024// > AUDIO_BACKEND_ALSA
7025//
7026// > SYSTEM_AUDIO_L1
7027// > SYSTEM_VIDEO_L1
7028// > SYSTEM_WINDOW
7029// > SYSTEM_AUDIO_L2
7030// > SYSTEM_VIDEO_L2 (Video backbuffer access and present of the frame)
7031// > SYSTEM_INIT (Init & Release of the Platform)
7032//
7033// ****************************************************************************
7034#if (defined(FPL_IMPLEMENTATION) || FPL_IS_IDE) && !defined(FPL__IMPLEMENTED)
7035#define FPL__IMPLEMENTED
7036
7037// ############################################################################
7038//
7039// > COMPILER_CONFIG
7040//
7041// ############################################################################
7042#if !defined(FPL__COMPILER_CONFIG_DEFINED)
7043#define FPL__COMPILER_CONFIG_DEFINED
7044
7045//
7046// Compiler warnings
7047//
7048#if defined(FPL_COMPILER_MSVC)
7049
7050 // Start to overwrite warning settings (MSVC)
7051# pragma warning( push )
7052
7053 // Disable noexcept compiler warning for C++
7054# pragma warning( disable : 4577 )
7055 // Disable "switch statement contains 'default' but no 'case' labels" compiler warning for C++
7056# pragma warning( disable : 4065 )
7057 // Disable "conditional expression is constant" warning
7058# pragma warning( disable : 4127 )
7059 // Disable "unreferenced formal parameter" warning
7060# pragma warning( disable : 4100 )
7061 // Disable "nonstandard extension used: nameless struct/union" warning
7062# pragma warning( disable : 4201 )
7063 // Disable "local variable is initialized but not referenced" warning
7064# pragma warning( disable : 4189 )
7065 // Disable "nonstandard extension used: non-constant aggregate initializer" warning
7066# pragma warning( disable : 4204 )
7067
7068#elif defined(FPL_COMPILER_GCC)
7069
7070 // Start to overwrite warning settings (GCC)
7071# pragma GCC diagnostic push
7072// Disable warning -Wunused-variable
7073# pragma GCC diagnostic ignored "-Wunused-variable"
7074// Disable warning -Wunused-function
7075# pragma GCC diagnostic ignored "-Wunused-function"
7076
7077#elif defined(FPL_COMPILER_CLANG)
7078
7079 // Start to overwrite warning settings (Clang)
7080# pragma clang diagnostic push
7081
7082// Disable warning -Wunused-variable
7083# pragma clang diagnostic ignored "-Wunused-variable"
7084// Disable warning -Wunused-function
7085# pragma clang diagnostic ignored "-Wunused-function"
7086
7087#endif // FPL_COMPILER
7088
7089#endif // FPL__COMPILER_CONFIG_DEFINED
7090
7091// ############################################################################
7092//
7093// > PLATFORM_INCLUDES
7094//
7095// ############################################################################
7096#if !defined(FPL__PLATFORM_INCLUDES_DEFINED)
7097#define FPL__PLATFORM_INCLUDES_DEFINED
7098
7099#if !defined(FPL__HAS_PLATFORM_INCLUDES)
7100# define FPL__HAS_PLATFORM_INCLUDES
7101
7102# if defined(FPL_PLATFORM_WINDOWS)
7103 // @NOTE(final): windef.h defines min/max macros in lowerspace, this will break for example std::min/max so we have to tell the header we dont want this!
7104# if !defined(NOMINMAX)
7105# define NOMINMAX
7106# endif
7107 // @NOTE(final): For now we dont want any network, com or gdi stuff at all, maybe later who knows.
7108# if !defined(WIN32_LEAN_AND_MEAN)
7109# define WIN32_LEAN_AND_MEAN 1
7110# endif
7111 // @STUPID(final): Workaround for "combaseapi.h(229): error C2187: syntax error: 'identifier' was unexpected here"
7112struct IUnknown;
7113# include <windows.h> // Win32 api
7114# if _WIN32_WINNT < 0x0600
7115# error "Windows Vista or higher required!"
7116# endif
7117# endif // FPL_PLATFORM_WINDOWS
7118
7119# if defined(FPL_SUBPLATFORM_POSIX)
7120# include <pthread.h> // pthread_t, pthread_mutex_, pthread_cond_, pthread_barrier_
7121# include <sched.h> // sched_param, sched_get_priority_max, SCHED_FIFO
7122# include <semaphore.h> // sem_t
7123# include <dirent.h> // DIR, dirent
7124# endif // FPL_SUBPLATFORM_POSIX
7125
7126# if defined(FPL_SUBPLATFORM_X11)
7127# include <X11/X.h> // Window
7128# include <X11/Xlib.h> // Display
7129# include <X11/Xutil.h> // XVisualInfo
7130# include <X11/Xatom.h> // XA_CARDINAL
7131# endif // FPL_SUBPLATFORM_X11
7132
7133#endif // !FPL__HAS_PLATFORM_INCLUDES
7134
7135//
7136// Test OS handles
7137//
7138#if defined(FPL_PLATFORM_WINDOWS)
7139fplStaticAssert(sizeof(fpl__Win32Handle) >= sizeof(HANDLE));
7140fplStaticAssert(sizeof(fpl__Win32LibraryHandle) >= sizeof(HANDLE));
7141fplStaticAssert(sizeof(fpl__Win32FileHandle) >= sizeof(HANDLE));
7142fplStaticAssert(sizeof(fpl__Win32ThreadHandle) >= sizeof(HANDLE));
7143fplStaticAssert(sizeof(fpl__Win32MutexHandle) >= sizeof(CRITICAL_SECTION));
7144fplStaticAssert(sizeof(fpl__Win32SemaphoreHandle) >= sizeof(HANDLE));
7145fplStaticAssert(sizeof(fpl__Win32ConditionVariable) >= sizeof(CONDITION_VARIABLE));
7146#elif defined(FPL_SUBPLATFORM_POSIX)
7147fplStaticAssert(sizeof(fpl__POSIXLibraryHandle) >= sizeof(void *));
7148fplStaticAssert(sizeof(fpl__POSIXFileHandle) >= sizeof(int));
7149fplStaticAssert(sizeof(fpl__POSIXDirHandle) >= sizeof(DIR *));
7150fplStaticAssert(sizeof(fpl__POSIXThreadHandle) >= sizeof(pthread_t));
7151fplStaticAssert(sizeof(fpl__POSIXMutexHandle) >= sizeof(pthread_mutex_t));
7152fplStaticAssert(sizeof(fpl__POSIXSemaphoreHandle) >= sizeof(sem_t));
7153fplStaticAssert(sizeof(fpl__POSIXConditionVariable) >= sizeof(pthread_cond_t));
7154#endif // FPL_PLATFORM_WINDOWS / FPL_SUBPLATFORM_POSIX
7155#if defined(FPL_PLATFORM_LINUX)
7156fplStaticAssert(sizeof(fpl__LinuxSignalHandle) >= sizeof(int));
7157#endif // FPL_PLATFORM_LINUX
7158
7159//
7160// Compiler Includes
7161//
7162#if defined(FPL_COMPILER_MSVC)
7163# include <intrin.h> // __cpuid, _Interlocked*
7164#elif defined(FPL_COMPILER_GCC) || defined(FPL_COMPILER_CLANG)
7165# if defined(FPL_ARCH_X86) || defined(FPL_ARCH_X64)
7166# include <cpuid.h> // __cpuid_count
7167# endif // X86 or X64
7168#endif
7169
7170// Only include C-Runtime functions when CRT is enabled
7171#if !defined(FPL_NO_CRT)
7172# include <stdio.h> // stdin, stdout, stderr, fprintf, vfprintf, vsnprintf, getchar
7173# include <stdlib.h> // wcstombs, mbstowcs, getenv
7174# include <locale.h> // setlocale, struct lconv, localeconv
7175#endif
7176
7177#endif // FPL__PLATFORM_INCLUDES_DEFINED
7178
7179// ############################################################################
7180//
7181// > INTERNAL_TOP
7182//
7183// ############################################################################
7184#if !defined(FPL__INTERNAL_TOP_DEFINED)
7185#define FPL__INTERNAL_TOP_DEFINED
7186
7187// Module constants used for logging
7188#define FPL__MODULE_CORE "Core"
7189#define FPL__MODULE_FILES "Files"
7190#define FPL__MODULE_THREADING "Threading"
7191#define FPL__MODULE_MEMORY "Memory"
7192#define FPL__MODULE_WINDOW "Window"
7193#define FPL__MODULE_LIBRARIES "Libraries"
7194#define FPL__MODULE_OS "OS"
7195#define FPL__MODULE_HARDWARE "Hardware"
7196#define FPL__MODULE_STRINGS "Strings"
7197#define FPL__MODULE_PATHS "Paths"
7198#define FPL__MODULE_ARGS "Arguments"
7199
7200#define FPL__MODULE_AUDIO "Audio"
7201#define FPL__MODULE_AUDIO_DIRECTSOUND "DirectSound"
7202#define FPL__MODULE_AUDIO_ALSA "ALSA"
7203
7204#define FPL__MODULE_VIDEO "Video"
7205#define FPL__MODULE_VIDEO_OPENGL "OpenGL"
7206#define FPL__MODULE_VIDEO_VULKAN "Vulkan"
7207#define FPL__MODULE_VIDEO_SOFTWARE "Software"
7208
7209#define FPL__MODULE_WIN32 "Win32"
7210#define FPL__MODULE_XINPUT "XInput"
7211
7212#define FPL__MODULE_LINUX "Linux"
7213#define FPL__MODULE_UNIX "Unix"
7214#define FPL__MODULE_POSIX "POSIX"
7215#define FPL__MODULE_PTHREAD "pthread"
7216#define FPL__MODULE_X11 "X11"
7217#define FPL__MODULE_GLX "GLX"
7218
7219//
7220// Enum macros
7221//
7222#define FPL__ENUM_COUNT(first, last) ((last) - (first) + 1)
7223#define FPL__ENUM_VALUE_TO_ARRAY_INDEX(value, first, last) (((value) >= (first) && (value) <= (last)) ? ((value) - (first)) : 0)
7224
7225//
7226// Internal memory
7227//
7228fpl_internal void *fpl__AllocateMemory(const fplMemoryAllocationSettings *allocSettings, const size_t size, const size_t alignment);
7229fpl_internal void fpl__ReleaseMemory(const fplMemoryAllocationSettings *allocSettings, void *ptr);
7230
7231#endif // FPL__INTERNAL_TOP_DEFINED
7232
7233// ############################################################################
7234//
7235// > INTERNAL_LOGGING
7236//
7237// ############################################################################
7238#if !defined(FPL__INTERNAL_LOGGING_DEFINED)
7239#define FPL__INTERNAL_LOGGING_DEFINED
7240
7241#define FPL__MODULE_CONCAT(mod, format) "[" mod "] " format
7242
7243#if defined(FPL__ENABLE_LOGGING)
7244fpl_globalvar fplLogSettings fpl__global__LogSettings = fplZeroInit;
7245
7246#define FPL__LOGLEVEL_COUNT FPL__ENUM_COUNT(fplLogLevel_First, fplLogLevel_Last)
7247fpl_globalvar const char *fpl__LogLevelNameTable[] = {
7248 "All", // fplLogLevel_All (-1)
7249 "Critical", // fplLogLevel_Critical (0)
7250 "Error", // fplLogLevel_Error (1)
7251 "Warning", // fplLogLevel_Warning (2)
7252 "Info", // fplLogLevel_Info (3)
7253 "Verbose", // fplLogLevel_Verbose (4)
7254 "Debug", // fplLogLevel_Debug (5)
7255 "Trace", // fplLogLevel_Trace (6)
7256};
7257fplStaticAssert(fplArrayCount(fpl__LogLevelNameTable) == FPL__LOGLEVEL_COUNT);
7258
7259fpl_internal const char *fpl__LogLevelToString(const fplLogLevel level) {
7260 uint32_t index = FPL__ENUM_VALUE_TO_ARRAY_INDEX(level, fplLogLevel_First, fplLogLevel_Last);
7261 const char *result = fpl__LogLevelNameTable[index];
7262 return(result);
7263}
7264
7265fpl_internal void fpl__LogWrite(const char *funcName, const int lineNumber, const fplLogLevel level, const char *message) {
7266 fplLogSettings *settings = &fpl__global__LogSettings;
7267 if (!settings->isInitialized) {
7268#if defined(FPL_LOG_MULTIPLE_WRITERS)
7269 settings->criticalWriter.console.logToError = true;
7270 settings->criticalWriter.flags = fplLogWriterFlags_ErrorConsole | fplLogWriterFlags_DebugOut;
7271 settings->errorWriter = settings->criticalWriter;
7272 settings->warningWriter = settings->criticalWriter;
7274 settings->verboseWriter = settings->infoWriter;
7275 settings->debugWriter.flags = fplLogWriterFlags_DebugOut;
7276#else
7278#endif
7279 settings->maxLevel = fplLogLevel_Warning;
7280 settings->isInitialized = true;
7281 }
7282
7283 if ((settings->maxLevel == -1) || (level <= settings->maxLevel)) {
7284#if defined(FPL_LOG_MULTIPLE_WRITERS)
7285 fplAssert(level < fplArrayCount(settings->writers));
7286 const fplLogWriter *writer = &settings->writers[(int)level];
7287#else
7288 const fplLogWriter *writer = &settings->writers[0];
7289#endif
7290 const char *levelStr = fpl__LogLevelToString(level);
7291
7293 fplConsoleFormatOut("[%s:%d][%s] %s\n", funcName, lineNumber, levelStr, message);
7294 }
7295 if (writer->flags & fplLogWriterFlags_ErrorConsole) {
7296 fplConsoleFormatError("[%s:%d][%s] %s\n", funcName, lineNumber, levelStr, message);
7297 }
7298 if (writer->flags & fplLogWriterFlags_DebugOut) {
7299 fplDebugFormatOut("[%s:%d][%s] %s\n", funcName, lineNumber, levelStr, message);
7300 }
7301 if (writer->flags & fplLogWriterFlags_Custom && writer->custom.callback != fpl_null) {
7302 writer->custom.callback(funcName, lineNumber, level, message);
7303 }
7304 }
7305}
7306fpl_internal void fpl__LogWriteArgs(const char *funcName, const int lineNumber, const fplLogLevel level, const char *format, va_list argList) {
7307 va_list listCopy;
7308 va_copy(listCopy, argList);
7309 char buffer[FPL_MAX_BUFFER_LENGTH];
7310 size_t formattedLen = fplStringFormatArgs(buffer, fplArrayCount(buffer), format, listCopy);
7311 if (formattedLen > 0) {
7312 fpl__LogWrite(funcName, lineNumber, level, buffer);
7313 }
7314 va_end(listCopy);
7315}
7316
7317fpl_internal void fpl__LogWriteVarArgs(const char *funcName, const int lineNumber, const fplLogLevel level, const char *format, ...) {
7318 va_list argList;
7319 va_start(argList, format);
7320 fpl__LogWriteArgs(funcName, lineNumber, level, format, argList);
7321 va_end(argList);
7322}
7323
7324# define FPL_LOG(lvl, mod, format, ...) fpl__LogWriteVarArgs(FPL_FUNCTION_NAME, __LINE__, lvl, FPL__MODULE_CONCAT(mod, format), ## __VA_ARGS__)
7325# define FPL_LOG_CRITICAL(mod, format, ...) FPL_LOG(fplLogLevel_Critical, mod, format, ## __VA_ARGS__)
7326# define FPL_LOG_ERROR(mod, format, ...) FPL_LOG(fplLogLevel_Error, mod, format, ## __VA_ARGS__)
7327# define FPL_LOG_WARN(mod, format, ...) FPL_LOG(fplLogLevel_Warning, mod, format, ## __VA_ARGS__)
7328# define FPL_LOG_INFO(mod, format, ...) FPL_LOG(fplLogLevel_Info, mod, format, ## __VA_ARGS__)
7329# define FPL_LOG_VERBOSE(mod, format, ...) FPL_LOG(fplLogLevel_Verbose, mod, format, ## __VA_ARGS__)
7330# define FPL_LOG_DEBUG(mod, format, ...) FPL_LOG(fplLogLevel_Debug, mod, format, ## __VA_ARGS__)
7331# define FPL_LOG_TRACE(mod, format, ...) FPL_LOG(fplLogLevel_Trace, mod, format, ## __VA_ARGS__)
7332
7333# define FPL__LOG_FUNCTION_N(mod, name) FPL_LOG(fplLogLevel_Debug, mod, "-> %s()", name)
7334# define FPL_LOG_FUNCTION(mod) FPL__LOG_FUNCTION_N(mod, FPL_FUNCTION_NAME)
7335
7336#else
7337
7338# define FPL_LOG(lvl, mod, format, ...)
7339# define FPL_LOG_CRITICAL(mod, format, ...)
7340# define FPL_LOG_ERROR(mod, format, ...)
7341# define FPL_LOG_WARN(mod, format, ...)
7342# define FPL_LOG_INFO(mod, format, ...)
7343# define FPL_LOG_VERBOSE(mod, format, ...)
7344# define FPL_LOG_DEBUG(mod, format, ...)
7345# define FPL_LOG_FUNCTION(mod)
7346
7347#endif
7348
7349//
7350// Error handling
7351//
7352
7353#define FPL__M_CRITICAL(funcName, line, mod, format, ...) fpl__HandleError(funcName, line, fplLogLevel_Critical, FPL__MODULE_CONCAT(mod, format), ## __VA_ARGS__)
7354#define FPL__M_ERROR(funcName, line, mod, format, ...) fpl__HandleError(funcName, line, fplLogLevel_Error, FPL__MODULE_CONCAT(mod, format), ## __VA_ARGS__)
7355#define FPL__M_WARNING(funcName, line, mod, format, ...) fpl__HandleError(funcName, line, fplLogLevel_Warning, FPL__MODULE_CONCAT(mod, format), ## __VA_ARGS__)
7356
7357#define FPL__CRITICAL(mod, format, ...) FPL__M_CRITICAL(FPL_FUNCTION_NAME, __LINE__, mod, format, ## __VA_ARGS__)
7358#define FPL__ERROR(mod, format, ...) FPL__M_ERROR(FPL_FUNCTION_NAME, __LINE__, mod, format, ## __VA_ARGS__)
7359#define FPL__WARNING(mod, format, ...) FPL__M_WARNING(FPL_FUNCTION_NAME, __LINE__, mod, format, ## __VA_ARGS__)
7360
7361#endif // FPL__INTERNAL_LOGGING_DEFINED
7362
7363// ############################################################################
7364//
7365// > PLATFORM_CONSTANTS
7366//
7367// ############################################################################
7368#if !defined(FPL__PLATFORM_CONSTANTS_DEFINED)
7369#define FPL__PLATFORM_CONSTANTS_DEFINED
7370
7371// One cacheline worth of padding
7372#define FPL__ARBITARY_PADDING 64
7373// Small padding to split sections in memory blocks
7374#define FPL__MEMORY_PADDING sizeof(uintptr_t)
7375
7376fpl_globalvar struct fpl__PlatformAppState *fpl__global__AppState = fpl_null;
7377
7378fpl_internal void fpl__HandleError(const char *funcName, const int lineNumber, const fplLogLevel level, const char *format, ...);
7379#endif // FPL__PLATFORM_CONSTANTS_DEFINED
7380
7381// ############################################################################
7382//
7383// > UTILITY_FUNCTIONS
7384//
7385// ############################################################################
7386fpl_internal void *fpl__AllocateMemory(const fplMemoryAllocationSettings *allocSettings, const size_t size, const size_t alignment) {
7387 if (allocSettings->mode == fplMemoryAllocationMode_Custom) {
7388 if (allocSettings->allocateCallback != fpl_null && allocSettings->releaseCallback != fpl_null) {
7389 return allocSettings->allocateCallback(allocSettings->userData, size, alignment);
7390 }
7391 }
7392 return fplMemoryAlignedAllocate(size, alignment);
7393}
7394
7395fpl_internal void fpl__ReleaseMemory(const fplMemoryAllocationSettings *allocSettings, void *ptr) {
7396 if (allocSettings->mode == fplMemoryAllocationMode_Custom) {
7397 if (allocSettings->allocateCallback != fpl_null && allocSettings->releaseCallback != fpl_null) {
7398 allocSettings->releaseCallback(allocSettings->userData, ptr);
7399 return;
7400 }
7401 }
7403}
7404
7405// Forward declarations of internal memory
7406fpl_internal void *fpl__AllocateDynamicMemory(const size_t size, const size_t alignment);
7407fpl_internal void fpl__ReleaseDynamicMemory(void *ptr);
7408fpl_internal void *fpl__AllocateTemporaryMemory(const size_t size, const size_t alignment);
7409fpl_internal void fpl__ReleaseTemporaryMemory(void *ptr);
7410
7411fpl_internal uint32_t fpl__NextPowerOfTwo(const uint32_t input) {
7412 uint32_t x = input;
7413 x--;
7414 x |= x >> 1;
7415 x |= x >> 2;
7416 x |= x >> 4;
7417 x |= x >> 8;
7418 x |= x >> 16;
7419 x++;
7420 return(x);
7421}
7422fpl_internal uint32_t fpl__PrevPowerOfTwo(const uint32_t input) {
7423 uint32_t result = fpl__NextPowerOfTwo(input) >> 1;
7424 return(result);
7425}
7426
7427fpl_internal uint32_t fpl__RoundToPowerOfTwo(const uint32_t input) {
7428 uint32_t prev = fpl__PrevPowerOfTwo(input);
7429 uint32_t next = fpl__NextPowerOfTwo(input);
7430 if ((next - input) < (input - prev)) {
7431 return prev;
7432 } else {
7433 return next;
7434 }
7435}
7436
7437fpl_internal bool fpl__AddLineWhenAnyMatches(const char *line, const char **wildcards, const size_t maxWildcardCount, const size_t maxLineSize, const size_t maxLineCount, char **outLines, size_t *outCount) {
7438 for (size_t i = 0; i < maxWildcardCount; ++i) {
7439 const char *wildcard = wildcards[i];
7440 if (fplIsStringMatchWildcard(line, wildcard)) {
7441 size_t index = *outCount;
7442 char *target = outLines[index];
7443 fplCopyString(line, target, maxLineSize);
7444 *outCount = index + 1;
7445 break;
7446 }
7447 }
7448 bool result = *outCount < maxLineCount;
7449 return(result);
7450}
7451
7452fpl_internal size_t fpl__ParseTextFile(const char *filePath, const char **wildcards, const size_t maxWildcardCount, const size_t maxLineSize, const size_t maxLineCount, char **outLines) {
7453 if (filePath == fpl_null || wildcards == fpl_null || maxWildcardCount == 0 || maxLineSize == 0 || maxLineCount == 0 || outLines == fpl_null) {
7454 return(0);
7455 }
7456 // @NOTE(final): Forced Zero-Terminator is not nessecary here, but we do it here to debug it better
7457 // This function supports maxLineSize < fplArrayCount(buffer)
7458 // We allocate the line buffer on the stack because we do not know how large the line will be on compile time
7459 size_t result = 0;
7460 fplFileHandle fileHandle = fplZeroInit;
7461 if (fplFileOpenBinary(filePath, &fileHandle)) {
7462 char *line = (char *)fpl__AllocateTemporaryMemory(maxLineSize, 8);
7463 char buffer[FPL_MAX_BUFFER_LENGTH];
7464 const size_t maxBufferSize = fplArrayCount(buffer) - 1;
7465 size_t bytesRead = 0;
7466 size_t posLineBytes = 0;
7467 bool done = false;
7468 while (!done && ((bytesRead = fplFileReadBlock(&fileHandle, maxBufferSize, &buffer[0], maxBufferSize)) > 0)) {
7469 buffer[bytesRead] = 0;
7470 char *start = &buffer[0];
7471 char *p = start;
7472 size_t readPos = 0;
7473 size_t lineSizeToRead = 0;
7474 while (readPos < bytesRead) {
7475 if (*p == '\n') {
7476 size_t remainingLineBytes = maxLineSize - posLineBytes;
7477 char *lineTargetP = line + posLineBytes;
7478 if (lineSizeToRead < remainingLineBytes) {
7479 fplCopyStringLen(start, lineSizeToRead, lineTargetP, remainingLineBytes);
7480 } else {
7481 fplCopyStringLen(start, remainingLineBytes - 1, lineTargetP, remainingLineBytes);
7482 }
7483 if (!fpl__AddLineWhenAnyMatches(line, wildcards, maxWildcardCount, maxLineSize, maxLineCount, outLines, &result)) {
7484 done = true;
7485 break;
7486 }
7487 start = p + 1;
7488 line[0] = 0;
7489 lineSizeToRead = 0;
7490 posLineBytes = 0;
7491 } else {
7492 ++lineSizeToRead;
7493 }
7494 ++p;
7495 ++readPos;
7496 }
7497 if (done) {
7498 break;
7499 }
7500 if (lineSizeToRead > 0) {
7501 size_t remainingLineBytes = maxLineSize - posLineBytes;
7502 char *lineTargetP = line + posLineBytes;
7503 if (lineSizeToRead < remainingLineBytes) {
7504 fplCopyStringLen(start, lineSizeToRead, lineTargetP, remainingLineBytes);
7505 posLineBytes += lineSizeToRead;
7506 if (bytesRead <= maxBufferSize) {
7507 if (!fpl__AddLineWhenAnyMatches(line, wildcards, maxWildcardCount, maxLineSize, maxLineCount, outLines, &result)) {
7508 done = true;
7509 }
7510 }
7511 } else {
7512 fplCopyStringLen(start, remainingLineBytes - 1, lineTargetP, remainingLineBytes);
7513 line[0] = 0;
7514 lineSizeToRead = 0;
7515 posLineBytes = 0;
7516 if (!fpl__AddLineWhenAnyMatches(line, wildcards, maxWildcardCount, maxLineSize, maxLineCount, outLines, &result)) {
7517 done = true;
7518 }
7519 }
7520 }
7521 }
7522 fpl__ReleaseTemporaryMemory(line);
7523 fplFileClose(&fileHandle);
7524 }
7525 return(result);
7526}
7527
7528fpl_internal void fpl__ParseVersionString(const char *versionStr, fplVersionInfo *versionInfo) {
7529 fplCopyString(versionStr, versionInfo->fullName, fplArrayCount(versionInfo->fullName));
7530 if (versionStr != fpl_null) {
7531 const char *p = versionStr;
7532 for (int i = 0; i < 4; ++i) {
7533 const char *digitStart = p;
7534 while (*p >= '0' && *p <= '9') {
7535 ++p;
7536 }
7537 size_t len = p - digitStart;
7538 if (len <= fplArrayCount(versionInfo->values[i])) {
7539 fplCopyStringLen(digitStart, len, versionInfo->values[i], fplArrayCount(versionInfo->values[i]));
7540 } else {
7541 versionInfo->values[i][0] = 0;
7542 }
7543 if (*p != '.' && *p != '-') break;
7544 ++p;
7545 }
7546 }
7547}
7548
7549// ****************************************************************************
7550//
7551// > TYPES
7552//
7553// This implementation block includes all the required platform-specific
7554// header files and defines all the constants, structures and types.
7555//
7556// ****************************************************************************
7557
7558// ############################################################################
7559//
7560// > TYPES_WIN32
7561//
7562// ############################################################################
7563#if defined(FPL_PLATFORM_WINDOWS)
7564# include <windowsx.h> // Macros for window messages
7565# include <shlobj.h> // SHGetFolderPath
7566# include <xinput.h> // XInputGetState
7567# include <shellapi.h> // HDROP
7568
7569# if defined(FPL_IS_CPP)
7570# define fpl__Win32IsEqualGuid(a, b) InlineIsEqualGUID(a, b)
7571# else
7572# define fpl__Win32IsEqualGuid(a, b) InlineIsEqualGUID(&a, &b)
7573# endif
7574
7575fpl_internal const char *fpl__Win32FormatGuidString(char *buffer, const size_t maxBufferLen, const GUID *guid) {
7576 fplStringFormat(buffer, maxBufferLen, "{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}",
7577 guid->Data1, guid->Data2, guid->Data3,
7578 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
7579 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
7580 return(buffer);
7581}
7582
7583// Little macro to not write 5 lines of code all the time
7584#define FPL__WIN32_LOAD_LIBRARY_BREAK(mod, target, libName) \
7585 (target) = LoadLibraryA(libName); \
7586 if((target) == fpl_null) { \
7587 FPL__WARNING(mod, "Failed loading library '%s'", (libName)); \
7588 break; \
7589 }
7590#define FPL__WIN32_GET_FUNCTION_ADDRESS_BREAK(mod, libHandle, libName, target, type, name) \
7591 (target)->name = (type *)GetProcAddress(libHandle, #name); \
7592 if ((target)->name == fpl_null) { \
7593 FPL__WARNING(mod, "Failed getting procedure address '%s' from library '%s'", #name, libName); \
7594 break; \
7595 }
7596#if !defined(FPL_NO_RUNTIME_LINKING)
7597# define FPL__WIN32_LOAD_LIBRARY FPL__WIN32_LOAD_LIBRARY_BREAK
7598# define FPL__WIN32_GET_FUNCTION_ADDRESS FPL__WIN32_GET_FUNCTION_ADDRESS_BREAK
7599#else
7600# define FPL__WIN32_LOAD_LIBRARY(mod, target, libName)
7601# define FPL__WIN32_GET_FUNCTION_ADDRESS(mod, libHandle, libName, target, type, name) \
7602 (target)->name = name
7603#endif
7604
7605//
7606// XInput
7607//
7608#define FPL__FUNC_XINPUT_XInputGetState(name) DWORD WINAPI name(DWORD dwUserIndex, XINPUT_STATE *pState)
7609typedef FPL__FUNC_XINPUT_XInputGetState(fpl__win32_func_XInputGetState);
7610FPL__FUNC_XINPUT_XInputGetState(fpl__Win32XInputGetStateStub) {
7611 return(ERROR_DEVICE_NOT_CONNECTED);
7612}
7613#define FPL__FUNC_XINPUT_XInputGetCapabilities(name) DWORD WINAPI name(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
7614typedef FPL__FUNC_XINPUT_XInputGetCapabilities(fpl__win32_func_XInputGetCapabilities);
7615FPL__FUNC_XINPUT_XInputGetCapabilities(fpl__Win32XInputGetCapabilitiesStub) {
7616 return(ERROR_DEVICE_NOT_CONNECTED);
7617}
7618typedef struct fpl__Win32XInputApi {
7619 HMODULE xinputLibrary;
7620 fpl__win32_func_XInputGetState *XInputGetState;
7621 fpl__win32_func_XInputGetCapabilities *XInputGetCapabilities;
7622} fpl__Win32XInputApi;
7623
7624fpl_internal void fpl__Win32UnloadXInputApi(fpl__Win32XInputApi *xinputApi) {
7625 fplAssert(xinputApi != fpl_null);
7626 if (xinputApi->xinputLibrary) {
7627 FPL_LOG_DEBUG("XInput", "Unload XInput Library");
7628 FreeLibrary(xinputApi->xinputLibrary);
7629 xinputApi->xinputLibrary = fpl_null;
7630 xinputApi->XInputGetState = fpl__Win32XInputGetStateStub;
7631 xinputApi->XInputGetCapabilities = fpl__Win32XInputGetCapabilitiesStub;
7632 }
7633}
7634
7635fpl_internal void fpl__Win32LoadXInputApi(fpl__Win32XInputApi *xinputApi) {
7636 fplAssert(xinputApi != fpl_null);
7637 const char *xinputFileNames[] = {
7638 "xinput1_4.dll",
7639 "xinput1_3.dll",
7640 "xinput9_1_0.dll",
7641 };
7642 bool result = false;
7643 for (uint32_t index = 0; index < fplArrayCount(xinputFileNames); ++index) {
7644 const char *libName = xinputFileNames[index];
7645 fplClearStruct(xinputApi);
7646 do {
7647 HMODULE libHandle = fpl_null;
7648 FPL__WIN32_LOAD_LIBRARY_BREAK(FPL__MODULE_XINPUT, libHandle, libName);
7649 xinputApi->xinputLibrary = libHandle;
7650 FPL__WIN32_GET_FUNCTION_ADDRESS_BREAK(FPL__MODULE_XINPUT, libHandle, libName, xinputApi, fpl__win32_func_XInputGetState, XInputGetState);
7651 FPL__WIN32_GET_FUNCTION_ADDRESS_BREAK(FPL__MODULE_XINPUT, libHandle, libName, xinputApi, fpl__win32_func_XInputGetCapabilities, XInputGetCapabilities);
7652 result = true;
7653 } while (0);
7654 if (result) {
7655 break;
7656 }
7657 fpl__Win32UnloadXInputApi(xinputApi);
7658 }
7659
7660 if (!result) {
7661 xinputApi->XInputGetState = fpl__Win32XInputGetStateStub;
7662 xinputApi->XInputGetCapabilities = fpl__Win32XInputGetCapabilitiesStub;
7663 }
7664}
7665
7666//
7667// WINAPI functions
7668//
7669
7670// GDI32
7671#define FPL__FUNC_WIN32_ChoosePixelFormat(name) int WINAPI name(HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd)
7672typedef FPL__FUNC_WIN32_ChoosePixelFormat(fpl__win32_func_ChoosePixelFormat);
7673#define FPL__FUNC_WIN32_SetPixelFormat(name) BOOL WINAPI name(HDC hdc, int format, CONST PIXELFORMATDESCRIPTOR *ppfd)
7674typedef FPL__FUNC_WIN32_SetPixelFormat(fpl__win32_func_SetPixelFormat);
7675#define FPL__FUNC_WIN32_DescribePixelFormat(name) int WINAPI name(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
7676typedef FPL__FUNC_WIN32_DescribePixelFormat(fpl__win32_func_DescribePixelFormat);
7677#define FPL__FUNC_WIN32_GetDeviceCaps(name) int WINAPI name(HDC hdc, int index)
7678typedef FPL__FUNC_WIN32_GetDeviceCaps(fpl__win32_func_GetDeviceCaps);
7679#define FPL__FUNC_WIN32_StretchDIBits(name) int WINAPI name(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc, int SrcWidth, int SrcHeight, CONST VOID *lpBits, CONST BITMAPINFO *lpbmi, UINT iUsage, DWORD rop)
7680typedef FPL__FUNC_WIN32_StretchDIBits(fpl__win32_func_StretchDIBits);
7681#define FPL__FUNC_WIN32_DeleteObject(name) BOOL WINAPI name( _In_ HGDIOBJ ho)
7682typedef FPL__FUNC_WIN32_DeleteObject(fpl__win32_func_DeleteObject);
7683#define FPL__FUNC_WIN32_SwapBuffers(name) BOOL WINAPI name(HDC)
7684typedef FPL__FUNC_WIN32_SwapBuffers(fpl__win32_func_SwapBuffers);
7685#define FPL__FUNC_WIN32_CreateDIBSection(name) HBITMAP WINAPI name(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset)
7686typedef FPL__FUNC_WIN32_CreateDIBSection(fpl__win32_func_CreateDIBSection);
7687#define FPL__FUNC_WIN32_CreateBitmap(name) HBITMAP WINAPI name(int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, CONST VOID *lpBits)
7688typedef FPL__FUNC_WIN32_CreateBitmap(fpl__win32_func_CreateBitmap);
7689#define FPL__FUNC_WIN32_CreateSolidBrush(name) HBRUSH WINAPI name(COLORREF color)
7690typedef FPL__FUNC_WIN32_CreateSolidBrush(fpl__win32_func_CreateSolidBrush);
7691
7692// ShellAPI
7693#define FPL__FUNC_WIN32_SHGetFolderPathW(name) HRESULT WINAPI name(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
7694typedef FPL__FUNC_WIN32_SHGetFolderPathW(fpl__win32_func_SHGetFolderPathW);
7695#define FPL__FUNC_WIN32_DragQueryFileW(name) UINT WINAPI name(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch)
7696typedef FPL__FUNC_WIN32_DragQueryFileW(fpl__win32_func_DragQueryFileW);
7697#define FPL__FUNC_WIN32_DragAcceptFiles(name) void WINAPI name(HWND hWnd, BOOL fAccept)
7698typedef FPL__FUNC_WIN32_DragAcceptFiles(fpl__win32_func_DragAcceptFiles);
7699
7700// User32
7701#define FPL__FUNC_WIN32_RegisterClassExW(name) ATOM WINAPI name(CONST WNDCLASSEXW *)
7702typedef FPL__FUNC_WIN32_RegisterClassExW(fpl__win32_func_RegisterClassExW);
7703#define FPL__FUNC_WIN32_UnregisterClassW(name) BOOL WINAPI name(LPCWSTR lpClassName, HINSTANCE hInstance)
7704typedef FPL__FUNC_WIN32_UnregisterClassW(fpl__win32_func_UnregisterClassW);
7705#define FPL__FUNC_WIN32_ShowWindow(name) BOOL WINAPI name(HWND hWnd, int nCmdShow)
7706typedef FPL__FUNC_WIN32_ShowWindow(fpl__win32_func_ShowWindow);
7707#define FPL__FUNC_WIN32_DestroyWindow(name) BOOL WINAPI name(HWND hWnd)
7708typedef FPL__FUNC_WIN32_DestroyWindow(fpl__win32_func_DestroyWindow);
7709#define FPL__FUNC_WIN32_UpdateWindow(name) BOOL WINAPI name(HWND hWnd)
7710typedef FPL__FUNC_WIN32_UpdateWindow(fpl__win32_func_UpdateWindow);
7711#define FPL__FUNC_WIN32_TranslateMessage(name) BOOL WINAPI name(CONST MSG *lpMsg)
7712typedef FPL__FUNC_WIN32_TranslateMessage(fpl__win32_func_TranslateMessage);
7713#define FPL__FUNC_WIN32_DispatchMessageW(name) LRESULT WINAPI name(CONST MSG *lpMsg)
7714typedef FPL__FUNC_WIN32_DispatchMessageW(fpl__win32_func_DispatchMessageW);
7715#define FPL__FUNC_WIN32_PeekMessageW(name) BOOL WINAPI name(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg)
7716typedef FPL__FUNC_WIN32_PeekMessageW(fpl__win32_func_PeekMessageW);
7717#define FPL__FUNC_WIN32_DefWindowProcW(name) LRESULT WINAPI name(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
7718typedef FPL__FUNC_WIN32_DefWindowProcW(fpl__win32_func_DefWindowProcW);
7719#define FPL__FUNC_WIN32_CreateWindowExW(name) HWND WINAPI name(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
7720typedef FPL__FUNC_WIN32_CreateWindowExW(fpl__win32_func_CreateWindowExW);
7721#define FPL__FUNC_WIN32_SetWindowPos(name) BOOL WINAPI name(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
7722typedef FPL__FUNC_WIN32_SetWindowPos(fpl__win32_func_SetWindowPos);
7723#define FPL__FUNC_WIN32_GetWindowPlacement(name) BOOL WINAPI name(HWND hWnd, WINDOWPLACEMENT *lpwndpl)
7724typedef FPL__FUNC_WIN32_GetWindowPlacement(fpl__win32_func_GetWindowPlacement);
7725#define FPL__FUNC_WIN32_SetWindowPlacement(name) BOOL WINAPI name(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl)
7726typedef FPL__FUNC_WIN32_SetWindowPlacement(fpl__win32_func_SetWindowPlacement);
7727#define FPL__FUNC_WIN32_GetClientRect(name) BOOL WINAPI name(HWND hWnd, LPRECT lpRect)
7728typedef FPL__FUNC_WIN32_GetClientRect(fpl__win32_func_GetClientRect);
7729#define FPL__FUNC_WIN32_GetWindowRect(name) BOOL WINAPI name(HWND hWnd, LPRECT lpRect)
7730typedef FPL__FUNC_WIN32_GetWindowRect(fpl__win32_func_GetWindowRect);
7731#define FPL__FUNC_WIN32_AdjustWindowRect(name) BOOL WINAPI name(LPRECT lpRect, DWORD dwStyle, BOOL bMenu)
7732typedef FPL__FUNC_WIN32_AdjustWindowRect(fpl__win32_func_AdjustWindowRect);
7733#define FPL__FUNC_WIN32_ClientToScreen(name) BOOL WINAPI name(HWND hWnd, LPPOINT lpPoint)
7734typedef FPL__FUNC_WIN32_ClientToScreen(fpl__win32_func_ClientToScreen);
7735#define FPL__FUNC_WIN32_GetAsyncKeyState(name) SHORT WINAPI name(int vKey)
7736typedef FPL__FUNC_WIN32_GetAsyncKeyState(fpl__win32_func_GetAsyncKeyState);
7737#define FPL__FUNC_WIN32_GetKeyState(name) SHORT WINAPI name(int vKey)
7738typedef FPL__FUNC_WIN32_GetKeyState(fpl__win32_func_GetKeyState);
7739#define FPL__FUNC_WIN32_MapVirtualKeyW(name) UINT WINAPI name(UINT uCode, UINT uMapType)
7740typedef FPL__FUNC_WIN32_MapVirtualKeyW(fpl__win32_func_MapVirtualKeyW);
7741#define FPL__FUNC_WIN32_SetCursor(name) HCURSOR WINAPI name(HCURSOR hCursor)
7742typedef FPL__FUNC_WIN32_SetCursor(fpl__win32_func_SetCursor);
7743#define FPL__FUNC_WIN32_GetCursor(name) HCURSOR WINAPI name(VOID)
7744typedef FPL__FUNC_WIN32_GetCursor(fpl__win32_func_GetCursor);
7745#define FPL__FUNC_WIN32_GetCursorPos(name) BOOL WINAPI name(LPPOINT lpPoint)
7746typedef FPL__FUNC_WIN32_GetCursorPos(fpl__win32_func_GetCursorPos);
7747#define FPL__FUNC_WIN32_WindowFromPoint(name) HWND WINAPI name(POINT Point)
7748typedef FPL__FUNC_WIN32_WindowFromPoint(fpl__win32_func_WindowFromPoint);
7749#define FPL__FUNC_WIN32_PtInRect(name) BOOL WINAPI name(CONST RECT *lprc, POINT pt)
7750typedef FPL__FUNC_WIN32_PtInRect(fpl__win32_func_PtInRect);
7751#define FPL__FUNC_WIN32_LoadCursorA(name) HCURSOR WINAPI name(HINSTANCE hInstance, LPCSTR lpCursorName)
7752typedef FPL__FUNC_WIN32_LoadCursorA(fpl__win32_func_LoadCursorA);
7753#define FPL__FUNC_WIN32_LoadCursorW(name) HCURSOR WINAPI name(HINSTANCE hInstance, LPCWSTR lpCursorName)
7754typedef FPL__FUNC_WIN32_LoadCursorW(fpl__win32_func_LoadCursorW);
7755#define FPL__FUNC_WIN32_LoadIconA(name) HICON WINAPI name(HINSTANCE hInstance, LPCSTR lpIconName)
7756typedef FPL__FUNC_WIN32_LoadIconA(fpl__win32_func_LoadIconA);
7757#define FPL__FUNC_WIN32_LoadIconW(name) HICON WINAPI name(HINSTANCE hInstance, LPCWSTR lpIconName)
7758typedef FPL__FUNC_WIN32_LoadIconW(fpl__win32_func_LoadIconW);
7759#define FPL__FUNC_WIN32_SetWindowTextW(name) BOOL WINAPI name(HWND hWnd, LPCWSTR lpString)
7760typedef FPL__FUNC_WIN32_SetWindowTextW(fpl__win32_func_SetWindowTextW);
7761#define FPL__FUNC_WIN32_GetWindowTextW(name) int WINAPI name(HWND hWnd, LPWSTR lpString, int nMaxCount)
7762typedef FPL__FUNC_WIN32_GetWindowTextW(fpl__win32_func_GetWindowTextW);
7763#define FPL__FUNC_WIN32_SetWindowLongW(name) LONG WINAPI name(HWND hWnd, int nIndex, LONG dwNewLong)
7764typedef FPL__FUNC_WIN32_SetWindowLongW(fpl__win32_func_SetWindowLongW);
7765#define FPL__FUNC_WIN32_GetWindowLongW(name) LONG WINAPI name(HWND hWnd, int nIndex)
7766typedef FPL__FUNC_WIN32_GetWindowLongW(fpl__win32_func_GetWindowLongW);
7767
7768#if defined(FPL_ARCH_X64)
7769#define FPL__FUNC_WIN32_SetWindowLongPtrW(name) LONG_PTR WINAPI name(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
7770typedef FPL__FUNC_WIN32_SetWindowLongPtrW(fpl__win32_func_SetWindowLongPtrW);
7771#define FPL__FUNC_WIN32_GetWindowLongPtrW(name) LONG_PTR WINAPI name(HWND hWnd, int nIndex)
7772typedef FPL__FUNC_WIN32_GetWindowLongPtrW(fpl__win32_func_GetWindowLongPtrW);
7773#endif
7774
7775#define FPL__FUNC_WIN32_ReleaseDC(name) int WINAPI name(HWND hWnd, HDC hDC)
7776typedef FPL__FUNC_WIN32_ReleaseDC(fpl__win32_func_ReleaseDC);
7777#define FPL__FUNC_WIN32_GetDC(name) HDC WINAPI name(HWND hWnd)
7778typedef FPL__FUNC_WIN32_GetDC(fpl__win32_func_GetDC);
7779#define FPL__FUNC_WIN32_ChangeDisplaySettingsW(name) LONG WINAPI name(DEVMODEW* lpDevMode, DWORD dwFlags)
7780typedef FPL__FUNC_WIN32_ChangeDisplaySettingsW(fpl__win32_func_ChangeDisplaySettingsW);
7781#define FPL__FUNC_WIN32_EnumDisplaySettingsW(name) BOOL WINAPI name(LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode)
7782typedef FPL__FUNC_WIN32_EnumDisplaySettingsW(fpl__win32_func_EnumDisplaySettingsW);
7783#define FPL__FUNC_WIN32_OpenClipboard(name) BOOL WINAPI name(HWND hWndNewOwner)
7784typedef FPL__FUNC_WIN32_OpenClipboard(fpl__win32_func_OpenClipboard);
7785#define FPL__FUNC_WIN32_CloseClipboard(name) BOOL WINAPI name(VOID)
7786typedef FPL__FUNC_WIN32_CloseClipboard(fpl__win32_func_CloseClipboard);
7787#define FPL__FUNC_WIN32_EmptyClipboard(name) BOOL WINAPI name(VOID)
7788typedef FPL__FUNC_WIN32_EmptyClipboard(fpl__win32_func_EmptyClipboard);
7789#define FPL__FUNC_WIN32_IsClipboardFormatAvailable(name) BOOL WINAPI name(UINT format)
7790typedef FPL__FUNC_WIN32_IsClipboardFormatAvailable(fpl__win32_func_IsClipboardFormatAvailable);
7791#define FPL__FUNC_WIN32_SetClipboardData(name) HANDLE WINAPI name(UINT uFormat, HANDLE hMem)
7792typedef FPL__FUNC_WIN32_SetClipboardData(fpl__win32_func_SetClipboardData);
7793#define FPL__FUNC_WIN32_GetClipboardData(name) HANDLE WINAPI name(UINT uFormat)
7794typedef FPL__FUNC_WIN32_GetClipboardData(fpl__win32_func_GetClipboardData);
7795#define FPL__FUNC_WIN32_GetDesktopWindow(name) HWND WINAPI name(VOID)
7796typedef FPL__FUNC_WIN32_GetDesktopWindow(fpl__win32_func_GetDesktopWindow);
7797#define FPL__FUNC_WIN32_GetForegroundWindow(name) HWND WINAPI name(VOID)
7798typedef FPL__FUNC_WIN32_GetForegroundWindow(fpl__win32_func_GetForegroundWindow);
7799#define FPL__FUNC_WIN32_IsZoomed(name) BOOL WINAPI name(HWND hWnd)
7800typedef FPL__FUNC_WIN32_IsZoomed(fpl__win32_func_IsZoomed);
7801#define FPL__FUNC_WIN32_IsIconic(name) BOOL WINAPI name(HWND hWnd)
7802typedef FPL__FUNC_WIN32_IsIconic(fpl__win32_func_IsIconic);
7803#define FPL__FUNC_WIN32_SendMessageW(name) LRESULT WINAPI name(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
7804typedef FPL__FUNC_WIN32_SendMessageW(fpl__win32_func_SendMessageW);
7805#define FPL__FUNC_WIN32_GetMonitorInfoW(name) BOOL WINAPI name(HMONITOR hMonitor, LPMONITORINFO lpmi)
7806typedef FPL__FUNC_WIN32_GetMonitorInfoW(fpl__win32_func_GetMonitorInfoW);
7807#define FPL__FUNC_WIN32_EnumDisplayMonitors(name) BOOL WINAPI name(HDC hdc, LPCRECT lprcClip, MONITORENUMPROC lpfnEnum,LPARAM dwData)
7808typedef FPL__FUNC_WIN32_EnumDisplayMonitors(fpl__win32_func_EnumDisplayMonitors);
7809#define FPL__FUNC_WIN32_MonitorFromRect(name) HMONITOR WINAPI name(LPCRECT lprc, DWORD dwFlags)
7810typedef FPL__FUNC_WIN32_MonitorFromRect(fpl__win32_func_MonitorFromRect);
7811#define FPL__FUNC_WIN32_MonitorFromPoint(name) HMONITOR WINAPI name(POINT pt, DWORD dwFlags)
7812typedef FPL__FUNC_WIN32_MonitorFromPoint(fpl__win32_func_MonitorFromPoint);
7813#define FPL__FUNC_WIN32_MonitorFromWindow(name) HMONITOR WINAPI name(HWND hwnd, DWORD dwFlags)
7814typedef FPL__FUNC_WIN32_MonitorFromWindow(fpl__win32_func_MonitorFromWindow);
7815#define FPL__FUNC_WIN32_RegisterRawInputDevices(name) BOOL WINAPI name(PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize)
7816typedef FPL__FUNC_WIN32_RegisterRawInputDevices(fpl__win32_func_RegisterRawInputDevices);
7817#define FPL__FUNC_WIN32_ClipCursor(name) BOOL WINAPI name(CONST RECT *lpRect)
7818typedef FPL__FUNC_WIN32_ClipCursor(fpl__win32_func_ClipCursor);
7819#define FPL__FUNC_WIN32_PostQuitMessage(name) VOID WINAPI name(int nExitCode)
7820typedef FPL__FUNC_WIN32_PostQuitMessage(fpl__win32_func_PostQuitMessage);
7821#define FPL__FUNC_WIN32_CreateIconIndirect(name) HICON WINAPI name(PICONINFO piconinfo)
7822typedef FPL__FUNC_WIN32_CreateIconIndirect(fpl__win32_func_CreateIconIndirect);
7823#define FPL__FUNC_WIN32_GetKeyboardLayout(name) HKL WINAPI name(DWORD idThread)
7824typedef FPL__FUNC_WIN32_GetKeyboardLayout(fpl__win32_func_GetKeyboardLayout);
7825#define FPL__FUNC_WIN32_SetCapture(name) HWND WINAPI name(HWND hWnd)
7826typedef FPL__FUNC_WIN32_SetCapture(fpl__win32_func_SetCapture);
7827#define FPL__FUNC_WIN32_ReleaseCapture(name) BOOL WINAPI name(VOID)
7828typedef FPL__FUNC_WIN32_ReleaseCapture(fpl__win32_func_ReleaseCapture);
7829#define FPL__FUNC_WIN32_ScreenToClient(name) BOOL WINAPI name(HWND hWnd, LPPOINT lpPoint)
7830typedef FPL__FUNC_WIN32_ScreenToClient(fpl__win32_func_ScreenToClient);
7831#define FPL__FUNC_WIN32_BeginPaint(name) HDC WINAPI name(_In_ HWND hWnd, _Out_ LPPAINTSTRUCT lpPaint)
7832typedef FPL__FUNC_WIN32_BeginPaint(fpl__win32_func_BeginPaint);
7833#define FPL__FUNC_WIN32_EndPaint(name) BOOL WINAPI name(_In_ HWND hWnd, _In_ CONST PAINTSTRUCT *lpPaint)
7834typedef FPL__FUNC_WIN32_EndPaint(fpl__win32_func_EndPaint);
7835#define FPL__FUNC_WIN32_SetForegroundWindow(name) BOOL WINAPI name(_In_ HWND hWnd)
7836typedef FPL__FUNC_WIN32_SetForegroundWindow(fpl__win32_func_SetForegroundWindow);
7837#define FPL__FUNC_WIN32_SetFocus(name) HWND WINAPI name(_In_opt_ HWND hWnd)
7838typedef FPL__FUNC_WIN32_SetFocus(fpl__win32_func_SetFocus);
7839#define FPL__FUNC_WIN32_SetTimer(name) UINT_PTR WINAPI name(_In_opt_ HWND hWnd, _In_ UINT_PTR nIDEvent, _In_ UINT uElapse, _In_opt_ TIMERPROC lpTimerFunc)
7840typedef FPL__FUNC_WIN32_SetTimer(fpl__win32_func_SetTimer);
7841#define FPL__FUNC_WIN32_GetSysColorBrush(name) HBRUSH WINAPI name(_In_ int nIndex)
7842typedef FPL__FUNC_WIN32_GetSysColorBrush(fpl__win32_func_GetSysColorBrush);
7843#define FPL__FUNC_WIN32_GetSysColorBrush(name) HBRUSH WINAPI name(_In_ int nIndex)
7844typedef FPL__FUNC_WIN32_GetSysColorBrush(fpl__win32_func_GetSysColorBrush);
7845
7846// OLE32
7847#define FPL__FUNC_WIN32_CoInitializeEx(name) HRESULT WINAPI name(LPVOID pvReserved, DWORD dwCoInit)
7848typedef FPL__FUNC_WIN32_CoInitializeEx(fpl__win32_func_CoInitializeEx);
7849#define FPL__FUNC_WIN32_CoUninitialize(name) void WINAPI name(void)
7850typedef FPL__FUNC_WIN32_CoUninitialize(fpl__win32_func_CoUninitialize);
7851#define FPL__FUNC_WIN32_CoCreateInstance(name) HRESULT WINAPI name(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv)
7852typedef FPL__FUNC_WIN32_CoCreateInstance(fpl__win32_func_CoCreateInstance);
7853#define FPL__FUNC_WIN32_CoTaskMemFree(name) void WINAPI name(LPVOID pv)
7854typedef FPL__FUNC_WIN32_CoTaskMemFree(fpl__win32_func_CoTaskMemFree);
7855#define FPL__FUNC_WIN32_PropVariantClear(name) HRESULT WINAPI name(PROPVARIANT *pvar)
7856typedef FPL__FUNC_WIN32_PropVariantClear(fpl__win32_func_PropVariantClear);
7857
7858typedef struct fpl__Win32GdiApi {
7859 HMODULE gdiLibrary;
7860 fpl__win32_func_ChoosePixelFormat *ChoosePixelFormat;
7861 fpl__win32_func_SetPixelFormat *SetPixelFormat;
7862 fpl__win32_func_DescribePixelFormat *DescribePixelFormat;
7863 fpl__win32_func_GetDeviceCaps *GetDeviceCaps;
7864 fpl__win32_func_StretchDIBits *StretchDIBits;
7865 fpl__win32_func_DeleteObject *DeleteObject;
7866 fpl__win32_func_SwapBuffers *SwapBuffers;
7867 fpl__win32_func_CreateDIBSection *CreateDIBSection;
7868 fpl__win32_func_CreateBitmap *CreateBitmap;
7869 fpl__win32_func_CreateSolidBrush *CreateSolidBrush;
7870} fpl__Win32GdiApi;
7871
7872typedef struct fpl__Win32ShellApi {
7873 HMODULE shellLibrary;
7874 fpl__win32_func_SHGetFolderPathW *SHGetFolderPathW;
7875 fpl__win32_func_DragQueryFileW *DragQueryFileW;
7876 fpl__win32_func_DragAcceptFiles *DragAcceptFiles;
7877} fpl__Win32ShellApi;
7878
7879typedef struct fpl__Win32UserApi {
7880 HMODULE userLibrary;
7881 fpl__win32_func_RegisterClassExW *RegisterClassExW;
7882 fpl__win32_func_UnregisterClassW *UnregisterClassW;
7883 fpl__win32_func_ShowWindow *ShowWindow;
7884 fpl__win32_func_DestroyWindow *DestroyWindow;
7885 fpl__win32_func_UpdateWindow *UpdateWindow;
7886 fpl__win32_func_TranslateMessage *TranslateMessage;
7887 fpl__win32_func_DispatchMessageW *DispatchMessageW;
7888 fpl__win32_func_PeekMessageW *PeekMessageW;
7889 fpl__win32_func_DefWindowProcW *DefWindowProcW;
7890 fpl__win32_func_CreateWindowExW *CreateWindowExW;
7891 fpl__win32_func_SetWindowPos *SetWindowPos;
7892 fpl__win32_func_GetWindowPlacement *GetWindowPlacement;
7893 fpl__win32_func_SetWindowPlacement *SetWindowPlacement;
7894 fpl__win32_func_GetClientRect *GetClientRect;
7895 fpl__win32_func_GetWindowRect *GetWindowRect;
7896 fpl__win32_func_AdjustWindowRect *AdjustWindowRect;
7897 fpl__win32_func_GetAsyncKeyState *GetAsyncKeyState;
7898 fpl__win32_func_MapVirtualKeyW *MapVirtualKeyW;
7899 fpl__win32_func_SetCursor *SetCursor;
7900 fpl__win32_func_GetCursor *GetCursor;
7901 fpl__win32_func_LoadCursorA *LoadCursorA;
7902 fpl__win32_func_LoadCursorW *LoadCursorW;
7903 fpl__win32_func_LoadIconA *LoadIconA;
7904 fpl__win32_func_LoadIconW *LoadIconW;
7905 fpl__win32_func_SetWindowTextW *SetWindowTextW;
7906 fpl__win32_func_GetWindowTextW *GetWindowTextW;
7907 fpl__win32_func_SetWindowLongW *SetWindowLongW;
7908 fpl__win32_func_GetWindowLongW *GetWindowLongW;
7909#if defined(FPL_ARCH_X64)
7910 fpl__win32_func_SetWindowLongPtrW *SetWindowLongPtrW;
7911 fpl__win32_func_GetWindowLongPtrW *GetWindowLongPtrW;
7912#endif
7913 fpl__win32_func_ReleaseDC *ReleaseDC;
7914 fpl__win32_func_GetDC *GetDC;
7915 fpl__win32_func_ChangeDisplaySettingsW *ChangeDisplaySettingsW;
7916 fpl__win32_func_EnumDisplaySettingsW *EnumDisplaySettingsW;
7917 fpl__win32_func_OpenClipboard *OpenClipboard;
7918 fpl__win32_func_CloseClipboard *CloseClipboard;
7919 fpl__win32_func_EmptyClipboard *EmptyClipboard;
7920 fpl__win32_func_IsClipboardFormatAvailable *IsClipboardFormatAvailable;
7921 fpl__win32_func_SetClipboardData *SetClipboardData;
7922 fpl__win32_func_GetClipboardData *GetClipboardData;
7923 fpl__win32_func_GetDesktopWindow *GetDesktopWindow;
7924 fpl__win32_func_GetForegroundWindow *GetForegroundWindow;
7925 fpl__win32_func_IsZoomed *IsZoomed;
7926 fpl__win32_func_IsIconic *IsIconic;
7927 fpl__win32_func_SendMessageW *SendMessageW;
7928 fpl__win32_func_GetMonitorInfoW *GetMonitorInfoW;
7929 fpl__win32_func_EnumDisplayMonitors *EnumDisplayMonitors;
7930 fpl__win32_func_MonitorFromRect *MonitorFromRect;
7931 fpl__win32_func_MonitorFromPoint *MonitorFromPoint;
7932 fpl__win32_func_MonitorFromWindow *MonitorFromWindow;
7933 fpl__win32_func_GetCursorPos *GetCursorPos;
7934 fpl__win32_func_WindowFromPoint *WindowFromPoint;
7935 fpl__win32_func_ClientToScreen *ClientToScreen;
7936 fpl__win32_func_PtInRect *PtInRect;
7937 fpl__win32_func_RegisterRawInputDevices *RegisterRawInputDevices;
7938 fpl__win32_func_ClipCursor *ClipCursor;
7939 fpl__win32_func_PostQuitMessage *PostQuitMessage;
7940 fpl__win32_func_CreateIconIndirect *CreateIconIndirect;
7941 fpl__win32_func_GetKeyboardLayout *GetKeyboardLayout;
7942 fpl__win32_func_GetKeyState *GetKeyState;
7943 fpl__win32_func_SetCapture *SetCapture;
7944 fpl__win32_func_ReleaseCapture *ReleaseCapture;
7945 fpl__win32_func_ScreenToClient *ScreenToClient;
7946 fpl__win32_func_BeginPaint *BeginPaint;
7947 fpl__win32_func_EndPaint *EndPaint;
7948 fpl__win32_func_SetForegroundWindow *SetForegroundWindow;
7949 fpl__win32_func_SetFocus *SetFocus;
7950 fpl__win32_func_SetTimer *SetTimer;
7951 fpl__win32_func_GetSysColorBrush *GetSysColorBrush;
7952} fpl__Win32UserApi;
7953
7954typedef struct fpl__Win32OleApi {
7955 HMODULE oleLibrary;
7956 fpl__win32_func_CoInitializeEx *CoInitializeEx;
7957 fpl__win32_func_CoUninitialize *CoUninitialize;
7958 fpl__win32_func_CoCreateInstance *CoCreateInstance;
7959 fpl__win32_func_CoTaskMemFree *CoTaskMemFree;
7960 fpl__win32_func_PropVariantClear *PropVariantClear;
7961} fpl__Win32OleApi;
7962
7963typedef struct fpl__Win32Api {
7964 fpl__Win32GdiApi gdi;
7965 fpl__Win32ShellApi shell;
7966 fpl__Win32UserApi user;
7967 fpl__Win32OleApi ole;
7968 fpl_b32 isValid;
7969} fpl__Win32Api;
7970
7971fpl_internal void fpl__Win32UnloadApi(fpl__Win32Api *wapi) {
7972 fplAssert(wapi != fpl_null);
7973 if (wapi->ole.oleLibrary != fpl_null) {
7974 FreeLibrary(wapi->ole.oleLibrary);
7975 }
7976 fplClearStruct(&wapi->ole);
7977 if (wapi->gdi.gdiLibrary != fpl_null) {
7978 FreeLibrary(wapi->gdi.gdiLibrary);
7979 }
7980 fplClearStruct(&wapi->gdi);
7981 if (wapi->user.userLibrary != fpl_null) {
7982 FreeLibrary(wapi->user.userLibrary);
7983 }
7984 fplClearStruct(&wapi->user);
7985 if (wapi->shell.shellLibrary != fpl_null) {
7986 FreeLibrary(wapi->shell.shellLibrary);
7987 }
7988 fplClearStruct(&wapi->shell);
7989 wapi->isValid = false;
7990}
7991
7992fpl_internal bool fpl__Win32LoadApi(fpl__Win32Api *wapi) {
7993 fplAssert(wapi != fpl_null);
7994 bool result = false;
7995 fplClearStruct(wapi);
7996 do {
7997 // Shell32
7998 const char *shellLibraryName = "shell32.dll";
7999 HMODULE shellLibrary = fpl_null;
8000 FPL__WIN32_LOAD_LIBRARY(FPL__MODULE_WIN32, shellLibrary, shellLibraryName);
8001 wapi->shell.shellLibrary = shellLibrary;
8002 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, shellLibrary, shellLibraryName, &wapi->shell, fpl__win32_func_SHGetFolderPathW, SHGetFolderPathW);
8003 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, shellLibrary, shellLibraryName, &wapi->shell, fpl__win32_func_DragQueryFileW, DragQueryFileW);
8004 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, shellLibrary, shellLibraryName, &wapi->shell, fpl__win32_func_DragAcceptFiles, DragAcceptFiles);
8005
8006 // User32
8007 const char *userLibraryName = "user32.dll";
8008 HMODULE userLibrary = fpl_null;
8009 FPL__WIN32_LOAD_LIBRARY(FPL__MODULE_WIN32, userLibrary, userLibraryName);
8010 wapi->user.userLibrary = userLibrary;
8011 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_RegisterClassExW, RegisterClassExW);
8012 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_UnregisterClassW, UnregisterClassW);
8013 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ShowWindow, ShowWindow);
8014 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_DestroyWindow, DestroyWindow);
8015 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_UpdateWindow, UpdateWindow);
8016 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_TranslateMessage, TranslateMessage);
8017 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_DispatchMessageW, DispatchMessageW);
8018 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_PeekMessageW, PeekMessageW);
8019 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_DefWindowProcW, DefWindowProcW);
8020 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_CreateWindowExW, CreateWindowExW);
8021 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetWindowPos, SetWindowPos);
8022 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetWindowPlacement, GetWindowPlacement);
8023 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetWindowPlacement, SetWindowPlacement);
8024 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetClientRect, GetClientRect);
8025 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetWindowRect, GetWindowRect);
8026 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_AdjustWindowRect, AdjustWindowRect);
8027 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetAsyncKeyState, GetAsyncKeyState);
8028 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_MapVirtualKeyW, MapVirtualKeyW);
8029 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetCursor, SetCursor);
8030 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetCursor, GetCursor);
8031 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_LoadCursorA, LoadCursorA);
8032 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_LoadCursorW, LoadCursorW);
8033 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetCursorPos, GetCursorPos);
8034 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_WindowFromPoint, WindowFromPoint);
8035 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_LoadIconA, LoadIconA);
8036 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_LoadIconW, LoadIconW);
8037 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetWindowTextW, SetWindowTextW);
8038 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetWindowLongW, SetWindowLongW);
8039 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetWindowLongW, GetWindowLongW);
8040
8041# if defined(FPL_ARCH_X64)
8042 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetWindowLongPtrW, SetWindowLongPtrW);
8043 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetWindowLongPtrW, GetWindowLongPtrW);
8044# endif
8045
8046 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ReleaseDC, ReleaseDC);
8047 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetDC, GetDC);
8048 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ChangeDisplaySettingsW, ChangeDisplaySettingsW);
8049 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_EnumDisplaySettingsW, EnumDisplaySettingsW);
8050 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_IsClipboardFormatAvailable, IsClipboardFormatAvailable);
8051 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_OpenClipboard, OpenClipboard);
8052 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_CloseClipboard, CloseClipboard);
8053 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_EmptyClipboard, EmptyClipboard);
8054 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetClipboardData, SetClipboardData);
8055 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetClipboardData, GetClipboardData);
8056 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetDesktopWindow, GetDesktopWindow);
8057 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetForegroundWindow, GetForegroundWindow);
8058 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_IsZoomed, IsZoomed);
8059 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_IsIconic, IsIconic);
8060 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SendMessageW, SendMessageW);
8061 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetMonitorInfoW, GetMonitorInfoW);
8062 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_EnumDisplayMonitors, EnumDisplayMonitors);
8063 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_MonitorFromRect, MonitorFromRect);
8064 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_MonitorFromPoint, MonitorFromPoint);
8065 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_MonitorFromWindow, MonitorFromWindow);
8066 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ClientToScreen, ClientToScreen);
8067 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_PtInRect, PtInRect);
8068 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_RegisterRawInputDevices, RegisterRawInputDevices);
8069 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ClipCursor, ClipCursor);
8070 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_PostQuitMessage, PostQuitMessage);
8071 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_CreateIconIndirect, CreateIconIndirect);
8072 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetKeyboardLayout, GetKeyboardLayout);
8073 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetKeyState, GetKeyState);
8074 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetCapture, SetCapture);
8075 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ReleaseCapture, ReleaseCapture);
8076 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_ScreenToClient, ScreenToClient);
8077 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_BeginPaint, BeginPaint);
8078 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_EndPaint, EndPaint);
8079 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetForegroundWindow, SetForegroundWindow);
8080 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetFocus, SetFocus);
8081 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_SetTimer, SetTimer);
8082 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, userLibrary, userLibraryName, &wapi->user, fpl__win32_func_GetSysColorBrush, GetSysColorBrush);
8083
8084 // GDI32
8085 const char *gdiLibraryName = "gdi32.dll";
8086 HMODULE gdiLibrary = fpl_null;
8087 FPL__WIN32_LOAD_LIBRARY(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName);
8088 wapi->gdi.gdiLibrary = gdiLibrary;
8089 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_ChoosePixelFormat, ChoosePixelFormat);
8090 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_SetPixelFormat, SetPixelFormat);
8091 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_DescribePixelFormat, DescribePixelFormat);
8092 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_StretchDIBits, StretchDIBits);
8093 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_DeleteObject, DeleteObject);
8094 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_SwapBuffers, SwapBuffers);
8095 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_GetDeviceCaps, GetDeviceCaps);
8096 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_CreateDIBSection, CreateDIBSection);
8097 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_CreateBitmap, CreateBitmap);
8098 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, gdiLibrary, gdiLibraryName, &wapi->gdi, fpl__win32_func_CreateSolidBrush, CreateSolidBrush);
8099
8100 // OLE32
8101 const char *oleLibraryName = "ole32.dll";
8102 HMODULE oleLibrary = fpl_null;
8103 FPL__WIN32_LOAD_LIBRARY(FPL__MODULE_WIN32, oleLibrary, oleLibraryName);
8104 wapi->ole.oleLibrary = oleLibrary;
8105 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, oleLibrary, oleLibraryName, &wapi->ole, fpl__win32_func_CoInitializeEx, CoInitializeEx);
8106 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, oleLibrary, oleLibraryName, &wapi->ole, fpl__win32_func_CoUninitialize, CoUninitialize);
8107 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, oleLibrary, oleLibraryName, &wapi->ole, fpl__win32_func_CoCreateInstance, CoCreateInstance);
8108 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, oleLibrary, oleLibraryName, &wapi->ole, fpl__win32_func_CoTaskMemFree, CoTaskMemFree);
8109 FPL__WIN32_GET_FUNCTION_ADDRESS(FPL__MODULE_WIN32, oleLibrary, oleLibraryName, &wapi->ole, fpl__win32_func_PropVariantClear, PropVariantClear);
8110
8111 result = true;
8112 } while (0);
8113 if (!result) {
8114 fpl__Win32UnloadApi(wapi);
8115 }
8116 wapi->isValid = result;
8117 return(result);
8118}
8119
8120// Win32 unicode dependend stuff
8121#define FPL__WIN32_CLASSNAME L"FPLWindowClassW"
8122#define FPL__WIN32_UNNAMED_WINDOW L"Unnamed FPL Unicode Window"
8123#define FPL__WIN32_UNNAMED_CONSOLE L"Unnamed FPL Unicode Console"
8124#if defined(FPL_ARCH_X64)
8125# define fpl__win32_SetWindowLongPtr fpl__global__AppState->win32.winApi.user.SetWindowLongPtrW
8126#else
8127# define fpl__win32_SetWindowLongPtr fpl__global__AppState->win32.winApi.user.SetWindowLongW
8128#endif
8129#define fpl__win32_SetWindowLong fpl__global__AppState->win32.winApi.user.SetWindowLongW
8130#define fpl__win32_GetWindowLong fpl__global__AppState->win32.winApi.user.GetWindowLongW
8131#if UNICODE
8132# define fpl__win32_LoadIcon fpl__global__AppState->win32.winApi.user.LoadIconW
8133# define fpl__win32_LoadCursor fpl__global__AppState->win32.winApi.user.LoadCursorW
8134#else
8135# define fpl__win32_LoadIcon fpl__global__AppState->win32.winApi.user.LoadIconA
8136# define fpl__win32_LoadCursor fpl__global__AppState->win32.winApi.user.LoadCursorA
8137#endif
8138
8139typedef char fpl__GameControllerName[FPL_MAX_NAME_LENGTH];
8140
8141typedef struct fpl__Win32XInputState {
8142 fpl__GameControllerName deviceNames[XUSER_MAX_COUNT];
8143 fpl_b32 isConnected[XUSER_MAX_COUNT];
8144 fpl__Win32XInputApi xinputApi;
8145 LARGE_INTEGER lastDeviceSearchTime;
8146} fpl__Win32XInputState;
8147
8148typedef struct fpl__Win32InitState {
8149 HINSTANCE appInstance;
8150 LARGE_INTEGER qpf;
8151} fpl__Win32InitState;
8152
8153typedef struct fpl__Win32AppState {
8154 fpl__Win32XInputState xinput;
8155 fpl__Win32Api winApi;
8156} fpl__Win32AppState;
8157
8158#if defined(FPL__ENABLE_WINDOW)
8159typedef struct fpl__Win32LastWindowInfo {
8160 WINDOWPLACEMENT placement;
8161 DWORD style;
8162 DWORD exStyle;
8163 fpl_b32 isMaximized;
8164 fpl_b32 isMinimized;
8165 fpl_b32 wasResolutionChanged;
8166} fpl__Win32LastWindowInfo;
8167
8168typedef struct fpl__Win32WindowState {
8169 wchar_t windowClass[256];
8170 fpl__Win32LastWindowInfo lastFullscreenInfo;
8171 void *mainFiber;
8172 void *messageFiber;
8173 HWND windowHandle;
8174 HDC deviceContext;
8175 HBRUSH backgroundBrush;
8176 HCURSOR defaultCursor;
8177 int pixelFormat;
8178 fpl_b32 isCursorActive;
8179 fpl_b32 isFrameInteraction;
8180} fpl__Win32WindowState;
8181#endif // FPL__ENABLE_WINDOW
8182
8183#endif // FPL_PLATFORM_WINDOWS
8184
8185// ############################################################################
8186//
8187// > TYPES_POSIX
8188//
8189// ############################################################################
8190#if defined(FPL_SUBPLATFORM_POSIX)
8191# include <sys/types.h> // data types
8192# include <sys/mman.h> // mmap, munmap
8193# include <sys/stat.h> // mkdir
8194# include <sys/errno.h> // errno
8195# include <sys/time.h> // gettimeofday
8196# include <sys/utsname.h> // uname
8197# include <signal.h> // pthread_kill
8198# include <time.h> // clock_gettime, nanosleep
8199# include <dlfcn.h> // dlopen, dlclose
8200# include <fcntl.h> // open
8201# include <unistd.h> // read, write, close, access, rmdir, getpid, sysconf, geteuid
8202# include <ctype.h> // isspace
8203# include <pwd.h> // getpwuid
8204
8205// @TODO(final): Detect the case of (Older POSIX versions where st_atim != st_atime)
8206#if !defined(FPL_PLATFORM_ANDROID)
8207# define st_atime st_atim.tv_sec
8208# define st_mtime st_mtim.tv_sec
8209# define st_ctime st_ctim.tv_sec
8210#endif
8211
8212#if defined(FPL_PLATFORM_LINUX)
8213# define fpl__lseek64 lseek64
8214# define fpl__off64_t off64_t
8215#else
8216# define fpl__lseek64 lseek
8217# define fpl__off64_t off_t
8218#endif
8219
8220// Little macros for loading a library and getting proc address for POSIX
8221#define FPL__POSIX_LOAD_LIBRARY_BREAK(mod, target, libName) \
8222 (target) = dlopen(libName, FPL__POSIX_DL_LOADTYPE); \
8223 if((target) == fpl_null) { \
8224 FPL__WARNING(mod, "Failed loading library '%s'", (libName)); \
8225 break; \
8226 }
8227
8228#define FPL__POSIX_GET_FUNCTION_ADDRESS_OPTIONAL(mod, libHandle, libName, target, type, name) \
8229 (target)->name = (type *)dlsym(libHandle, #name)
8230
8231#define FPL__POSIX_GET_FUNCTION_ADDRESS_BREAK(mod, libHandle, libName, target, type, name) \
8232 (target)->name = (type *)dlsym(libHandle, #name); \
8233 if ((target)->name == fpl_null) { \
8234 FPL__WARNING(mod, "Failed getting procedure address '%s' from library '%s'", #name, libName); \
8235 break; \
8236 }
8237#if !defined(FPL_NO_RUNTIME_LINKING)
8238# define FPL__POSIX_LOAD_LIBRARY FPL__POSIX_LOAD_LIBRARY_BREAK
8239# define FPL__POSIX_GET_FUNCTION_ADDRESS FPL__POSIX_GET_FUNCTION_ADDRESS_BREAK
8240#else
8241# define FPL__POSIX_LOAD_LIBRARY(mod, target, libName)
8242# define FPL__POSIX_GET_FUNCTION_ADDRESS_OPTIONAL(mod, libHandle, libName, target, type, name) \
8243 (target)->name = name
8244# define FPL__POSIX_GET_FUNCTION_ADDRESS(mod, libHandle, libName, target, type, name) \
8245 (target)->name = name
8246#endif
8247
8248#define FPL__FUNC_PTHREAD_pthread_self(name) pthread_t name(void)
8249typedef FPL__FUNC_PTHREAD_pthread_self(fpl__pthread_func_pthread_self);
8250#define FPL__FUNC_PTHREAD_pthread_setschedparam(name) int name(pthread_t thread, int policy, const struct sched_param *param)
8251typedef FPL__FUNC_PTHREAD_pthread_setschedparam(fpl__pthread_func_pthread_setschedparam);
8252#define FPL__FUNC_PTHREAD_pthread_getschedparam(name) int name(pthread_t thread, int *policy, struct sched_param *param)
8253typedef FPL__FUNC_PTHREAD_pthread_getschedparam(fpl__pthread_func_pthread_getschedparam);
8254#define FPL__FUNC_PTHREAD_pthread_setschedprio(name) int name(pthread_t thread, int prio)
8255typedef FPL__FUNC_PTHREAD_pthread_setschedprio(fpl__pthread_func_pthread_setschedprio);
8256
8257#define FPL__FUNC_PTHREAD_pthread_attr_init(name) int name(pthread_attr_t *attr)
8258typedef FPL__FUNC_PTHREAD_pthread_attr_init(fpl__pthread_func_pthread_attr_init);
8259#define FPL__FUNC_PTHREAD_pthread_attr_getschedparam(name) int name(const pthread_attr_t *__restrict__ attr, struct sched_param *__restrict__ param)
8260typedef FPL__FUNC_PTHREAD_pthread_attr_getschedparam(fpl__pthread_func_pthread_attr_getschedparam);
8261#define FPL__FUNC_PTHREAD_pthread_attr_setschedparam(name) int name(pthread_attr_t *__restrict__ attr, const struct sched_param *__restrict__ param)
8262typedef FPL__FUNC_PTHREAD_pthread_attr_setschedparam(fpl__pthread_func_pthread_attr_setschedparam);
8263#define FPL__FUNC_PTHREAD_pthread_attr_setstacksize(name) int name(pthread_attr_t *attr, size_t stacksize)
8264typedef FPL__FUNC_PTHREAD_pthread_attr_setstacksize(fpl__pthread_func_pthread_attr_setstacksize);
8265#define FPL__FUNC_PTHREAD_pthread_attr_setdetachstate(name) int name(pthread_attr_t *attr, int detachstate);
8266typedef FPL__FUNC_PTHREAD_pthread_attr_setdetachstate(fpl__pthread_func_pthread_attr_setdetachstate);
8267#define FPL__FUNC_PTHREAD_pthread_attr_setschedpolicy(name) int name(pthread_attr_t *__attr, int __policy)
8268typedef FPL__FUNC_PTHREAD_pthread_attr_setschedpolicy(fpl__pthread_func_pthread_attr_setschedpolicy);
8269
8270#define FPL__FUNC_PTHREAD_pthread_create(name) int name(pthread_t *, const pthread_attr_t *, void *(*__start_routine) (void *), void *)
8271typedef FPL__FUNC_PTHREAD_pthread_create(fpl__pthread_func_pthread_create);
8272#define FPL__FUNC_PTHREAD_pthread_kill(name) int name(pthread_t thread, int sig)
8273typedef FPL__FUNC_PTHREAD_pthread_kill(fpl__pthread_func_pthread_kill);
8274#define FPL__FUNC_PTHREAD_pthread_join(name) int name(pthread_t __th, void **retval)
8275typedef FPL__FUNC_PTHREAD_pthread_join(fpl__pthread_func_pthread_join);
8276#define FPL__FUNC_PTHREAD_pthread_exit(name) void name(void *__retval)
8277typedef FPL__FUNC_PTHREAD_pthread_exit(fpl__pthread_func_pthread_exit);
8278#define FPL__FUNC_PTHREAD_pthread_yield(name) int name(void)
8279typedef FPL__FUNC_PTHREAD_pthread_yield(fpl__pthread_func_pthread_yield);
8280#define FPL__FUNC_PTHREAD_pthread_timedjoin_np(name) int name(pthread_t thread, void **retval, const struct timespec *abstime)
8281typedef FPL__FUNC_PTHREAD_pthread_timedjoin_np(fpl__pthread_func_pthread_timedjoin_np);
8282
8283#define FPL__FUNC_PTHREAD_pthread_mutex_init(name) int name(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
8284typedef FPL__FUNC_PTHREAD_pthread_mutex_init(fpl__pthread_func_pthread_mutex_init);
8285#define FPL__FUNC_PTHREAD_pthread_mutex_destroy(name) int name(pthread_mutex_t *mutex)
8286typedef FPL__FUNC_PTHREAD_pthread_mutex_destroy(fpl__pthread_func_pthread_mutex_destroy);
8287#define FPL__FUNC_PTHREAD_pthread_mutex_lock(name) int name(pthread_mutex_t *mutex)
8288typedef FPL__FUNC_PTHREAD_pthread_mutex_lock(fpl__pthread_func_pthread_mutex_lock);
8289#define FPL__FUNC_PTHREAD_pthread_mutex_trylock(name) int name(pthread_mutex_t *mutex)
8290typedef FPL__FUNC_PTHREAD_pthread_mutex_trylock(fpl__pthread_func_pthread_mutex_trylock);
8291#define FPL__FUNC_PTHREAD_pthread_mutex_unlock(name) int name(pthread_mutex_t *mutex)
8292typedef FPL__FUNC_PTHREAD_pthread_mutex_unlock(fpl__pthread_func_pthread_mutex_unlock);
8293
8294#define FPL__FUNC_PTHREAD_pthread_cond_init(name) int name(pthread_cond_t *cond, const pthread_condattr_t *attr)
8295typedef FPL__FUNC_PTHREAD_pthread_cond_init(fpl__pthread_func_pthread_cond_init);
8296#define FPL__FUNC_PTHREAD_pthread_cond_destroy(name) int name(pthread_cond_t *cond)
8297typedef FPL__FUNC_PTHREAD_pthread_cond_destroy(fpl__pthread_func_pthread_cond_destroy);
8298#define FPL__FUNC_PTHREAD_pthread_cond_timedwait(name) int name(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
8299typedef FPL__FUNC_PTHREAD_pthread_cond_timedwait(fpl__pthread_func_pthread_cond_timedwait);
8300#define FPL__FUNC_PTHREAD_pthread_cond_wait(name) int name(pthread_cond_t *cond, pthread_mutex_t *mutex)
8301typedef FPL__FUNC_PTHREAD_pthread_cond_wait(fpl__pthread_func_pthread_cond_wait);
8302#define FPL__FUNC_PTHREAD_pthread_cond_broadcast(name) int name(pthread_cond_t *cond)
8303typedef FPL__FUNC_PTHREAD_pthread_cond_broadcast(fpl__pthread_func_pthread_cond_broadcast);
8304#define FPL__FUNC_PTHREAD_pthread_cond_signal(name) int name(pthread_cond_t *cond)
8305typedef FPL__FUNC_PTHREAD_pthread_cond_signal(fpl__pthread_func_pthread_cond_signal);
8306
8307#define FPL__FUNC_PTHREAD_sem_init(name) int name(sem_t *__sem, int __pshared, unsigned int __value)
8308typedef FPL__FUNC_PTHREAD_sem_init(fpl__pthread_func_sem_init);
8309#define FPL__FUNC_PTHREAD_sem_destroy(name) int name(sem_t *__sem)
8310typedef FPL__FUNC_PTHREAD_sem_destroy(fpl__pthread_func_sem_destroy);
8311#define FPL__FUNC_PTHREAD_sem_wait(name) int name(sem_t *__sem)
8312typedef FPL__FUNC_PTHREAD_sem_wait(fpl__pthread_func_sem_wait);
8313#define FPL__FUNC_PTHREAD_sem_timedwait(name) int name(sem_t *__restrict __sem, const struct timespec *__restrict __abstime)
8314typedef FPL__FUNC_PTHREAD_sem_timedwait(fpl__pthread_func_sem_timedwait);
8315#define FPL__FUNC_PTHREAD_sem_trywait(name) int name(sem_t *__sem)
8316typedef FPL__FUNC_PTHREAD_sem_trywait(fpl__pthread_func_sem_trywait);
8317#define FPL__FUNC_PTHREAD_sem_post(name) int name(sem_t *__sem)
8318typedef FPL__FUNC_PTHREAD_sem_post(fpl__pthread_func_sem_post);
8319#define FPL__FUNC_PTHREAD_sem_getvalue(name) int name(sem_t *__restrict __sem, int *__restrict __sval)
8320typedef FPL__FUNC_PTHREAD_sem_getvalue(fpl__pthread_func_sem_getvalue);
8321
8322typedef struct fpl__PThreadApi {
8323 void *libHandle;
8324
8325 // pthread_t
8326 fpl__pthread_func_pthread_self *pthread_self;
8327 fpl__pthread_func_pthread_setschedparam *pthread_setschedparam;
8328 fpl__pthread_func_pthread_getschedparam *pthread_getschedparam;
8329 fpl__pthread_func_pthread_setschedprio *pthread_setschedprio;
8330
8331 fpl__pthread_func_pthread_create *pthread_create;
8332 fpl__pthread_func_pthread_kill *pthread_kill;
8333 fpl__pthread_func_pthread_join *pthread_join;
8334 fpl__pthread_func_pthread_exit *pthread_exit;
8335 fpl__pthread_func_pthread_yield *pthread_yield;
8336 fpl__pthread_func_pthread_timedjoin_np *pthread_timedjoin_np;
8337
8338 // pthread_attr_t
8339 fpl__pthread_func_pthread_attr_init *pthread_attr_init;
8340 fpl__pthread_func_pthread_attr_getschedparam *pthread_attr_getschedparam;
8341 fpl__pthread_func_pthread_attr_setschedparam *pthread_attr_setschedparam;
8342 fpl__pthread_func_pthread_attr_setstacksize *pthread_attr_setstacksize;
8343 fpl__pthread_func_pthread_attr_setdetachstate *pthread_attr_setdetachstate;
8344 fpl__pthread_func_pthread_attr_setschedpolicy *pthread_attr_setschedpolicy;
8345
8346 // pthread_mutex_t
8347 fpl__pthread_func_pthread_mutex_init *pthread_mutex_init;
8348 fpl__pthread_func_pthread_mutex_destroy *pthread_mutex_destroy;
8349 fpl__pthread_func_pthread_mutex_lock *pthread_mutex_lock;
8350 fpl__pthread_func_pthread_mutex_trylock *pthread_mutex_trylock;
8351 fpl__pthread_func_pthread_mutex_unlock *pthread_mutex_unlock;
8352
8353 // pthread_cond_t
8354 fpl__pthread_func_pthread_cond_init *pthread_cond_init;
8355 fpl__pthread_func_pthread_cond_destroy *pthread_cond_destroy;
8356 fpl__pthread_func_pthread_cond_timedwait *pthread_cond_timedwait;
8357 fpl__pthread_func_pthread_cond_wait *pthread_cond_wait;
8358 fpl__pthread_func_pthread_cond_broadcast *pthread_cond_broadcast;
8359 fpl__pthread_func_pthread_cond_signal *pthread_cond_signal;
8360
8361 // sem_t
8362 fpl__pthread_func_sem_init *sem_init;
8363 fpl__pthread_func_sem_destroy *sem_destroy;
8364 fpl__pthread_func_sem_wait *sem_wait;
8365 fpl__pthread_func_sem_timedwait *sem_timedwait;
8366 fpl__pthread_func_sem_trywait *sem_trywait;
8367 fpl__pthread_func_sem_post *sem_post;
8368 fpl__pthread_func_sem_getvalue *sem_getvalue;
8369} fpl__PThreadApi;
8370
8371#define FPL__POSIX_DL_LOADTYPE RTLD_NOW
8372
8373fpl_internal void fpl__PThreadUnloadApi(fpl__PThreadApi *pthreadApi) {
8374 fplAssert(pthreadApi != fpl_null);
8375 if (pthreadApi->libHandle != fpl_null) {
8376 dlclose(pthreadApi->libHandle);
8377 }
8378 fplClearStruct(pthreadApi);
8379}
8380
8381fpl_internal bool fpl__PThreadLoadApi(fpl__PThreadApi *pthreadApi) {
8382 const char *libpthreadFileNames[] = {
8383 "libpthread.so",
8384 "libpthread.so.0",
8385 };
8386 bool result = false;
8387 for (uint32_t index = 0; index < fplArrayCount(libpthreadFileNames); ++index) {
8388 const char *libName = libpthreadFileNames[index];
8389 fplClearStruct(pthreadApi);
8390 do {
8391 void *libHandle = fpl_null;
8392 FPL__POSIX_LOAD_LIBRARY(FPL__MODULE_PTHREAD, libHandle, libName);
8393
8394 // pthread_t
8395 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_self, pthread_self);
8396 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_setschedparam, pthread_setschedparam);
8397 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_getschedparam, pthread_getschedparam);
8398 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_setschedprio, pthread_setschedprio);
8399
8400 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_create, pthread_create);
8401 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_kill, pthread_kill);
8402 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_join, pthread_join);
8403 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_exit, pthread_exit);
8404 FPL__POSIX_GET_FUNCTION_ADDRESS_OPTIONAL(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_yield, pthread_yield);
8405 FPL__POSIX_GET_FUNCTION_ADDRESS_OPTIONAL(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_timedjoin_np, pthread_timedjoin_np);
8406
8407 // pthread_attr_t
8408 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_init, pthread_attr_init);
8409 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_getschedparam, pthread_attr_getschedparam);
8410 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_setschedparam, pthread_attr_setschedparam);
8411 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_setstacksize, pthread_attr_setstacksize);
8412 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_setdetachstate, pthread_attr_setdetachstate);
8413 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
8414
8415 // pthread_mutex_t
8416 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_mutex_init, pthread_mutex_init);
8417 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_mutex_destroy, pthread_mutex_destroy);
8418 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_mutex_lock, pthread_mutex_lock);
8419 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_mutex_trylock, pthread_mutex_trylock);
8420 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_mutex_unlock, pthread_mutex_unlock);
8421
8422 // pthread_cond_t
8423 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_init, pthread_cond_init);
8424 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_destroy, pthread_cond_destroy);
8425 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_timedwait, pthread_cond_timedwait);
8426 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_wait, pthread_cond_wait);
8427 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_broadcast, pthread_cond_broadcast);
8428 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_pthread_cond_signal, pthread_cond_signal);
8429
8430 // sem_t
8431 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_init, sem_init);
8432 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_destroy, sem_destroy);
8433 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_wait, sem_wait);
8434 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_timedwait, sem_timedwait);
8435 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_trywait, sem_trywait);
8436 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_post, sem_post);
8437 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_PTHREAD, libHandle, libName, pthreadApi, fpl__pthread_func_sem_getvalue, sem_getvalue);
8438
8439 pthreadApi->libHandle = libHandle;
8440 result = true;
8441 } while (0);
8442 if (result) {
8443 break;
8444 }
8445 fpl__PThreadUnloadApi(pthreadApi);
8446 }
8447 return(result);
8448}
8449
8450typedef struct fpl__PosixInitState {
8451 int dummy;
8452} fpl__PosixInitState;
8453
8454typedef struct fpl__PosixAppState {
8455 fpl__PThreadApi pthreadApi;
8456} fpl__PosixAppState;
8457#endif // FPL_SUBPLATFORM_POSIX
8458
8459// ############################################################################
8460//
8461// > TYPES_LINUX
8462//
8463// ############################################################################
8464#if defined(FPL_PLATFORM_LINUX)
8465typedef struct fpl__LinuxInitState {
8466 int dummy;
8467} fpl__LinuxInitState;
8468
8469#if defined(FPL__ENABLE_WINDOW)
8470#define FPL__LINUX_MAX_GAME_CONTROLLER_COUNT 4
8471typedef struct fpl__LinuxGameController {
8472 char deviceName[512 + 1];
8473 char displayName[FPL_MAX_NAME_LENGTH];
8474 int fd;
8475 uint8_t axisCount;
8476 uint8_t buttonCount;
8477 fplGamepadState state;
8478} fpl__LinuxGameController;
8479
8480typedef struct fpl__LinuxGameControllersState {
8481 fpl__LinuxGameController controllers[FPL__LINUX_MAX_GAME_CONTROLLER_COUNT];
8482 uint64_t lastCheckTime;
8483} fpl__LinuxGameControllersState;
8484#endif
8485
8486typedef struct fpl__LinuxAppState {
8487#if defined(FPL__ENABLE_WINDOW)
8488 fpl__LinuxGameControllersState controllersState;
8489#endif
8490 int dummy;
8491} fpl__LinuxAppState;
8492
8493// Forward declarations
8494#if defined(FPL__ENABLE_WINDOW)
8495fpl_internal void fpl__LinuxFreeGameControllers(fpl__LinuxGameControllersState *controllersState);
8496fpl_internal void fpl__LinuxPollGameControllers(const fplSettings *settings, fpl__LinuxGameControllersState *controllersState, const bool useEvents);
8497#endif
8498
8499#endif // FPL_PLATFORM_LINUX
8500
8501// ############################################################################
8502//
8503// > TYPES_UNIX
8504//
8505// ############################################################################
8506#if defined(FPL_PLATFORM_UNIX)
8507typedef struct fpl__UnixInitState {
8508 int dummy;
8509} fpl__UnixInitState;
8510
8511typedef struct fpl__UnixAppState {
8512 int dummy;
8513} fpl__UnixAppState;
8514#endif // FPL_PLATFORM_UNIX
8515
8516// ############################################################################
8517//
8518// > TYPES_X11
8519//
8520// ############################################################################
8521#if defined(FPL_SUBPLATFORM_X11)
8522
8523#include <X11/keysym.h> // Keyboard symbols (XK_Escape, etc.)
8524
8525//
8526// X11 Api
8527//
8528#define FPL__FUNC_X11_XFree(name) int name(void *data)
8529typedef FPL__FUNC_X11_XFree(fpl__func_x11_XFree);
8530#define FPL__FUNC_X11_XFlush(name) int name(Display *display)
8531typedef FPL__FUNC_X11_XFlush(fpl__func_x11_XFlush);
8532#define FPL__FUNC_X11_XOpenDisplay(name) Display *name(char *display_name)
8533typedef FPL__FUNC_X11_XOpenDisplay(fpl__func_x11_XOpenDisplay);
8534#define FPL__FUNC_X11_XCloseDisplay(name) int name(Display *display)
8535typedef FPL__FUNC_X11_XCloseDisplay(fpl__func_x11_XCloseDisplay);
8536#define FPL__FUNC_X11_XDefaultScreen(name) int name(Display *display)
8537typedef FPL__FUNC_X11_XDefaultScreen(fpl__func_x11_XDefaultScreen);
8538#define FPL__FUNC_X11_XRootWindow(name) Window name(Display *display, int screen_number)
8539typedef FPL__FUNC_X11_XRootWindow(fpl__func_x11_XRootWindow);
8540#define FPL__FUNC_X11_XCreateWindow(name) Window name(Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes)
8541typedef FPL__FUNC_X11_XCreateWindow(fpl__func_x11_XCreateWindow);
8542#define FPL__FUNC_X11_XDestroyWindow(name) int name(Display *display, Window w)
8543typedef FPL__FUNC_X11_XDestroyWindow(fpl__func_x11_XDestroyWindow);
8544#define FPL__FUNC_X11_XCreateColormap(name) Colormap name(Display *display, Window w, Visual *visual, int alloc)
8545typedef FPL__FUNC_X11_XCreateColormap(fpl__func_x11_XCreateColormap);
8546#define FPL__FUNC_X11_XDefaultColormap(name) Colormap name(Display *display, int screen_number)
8547typedef FPL__FUNC_X11_XDefaultColormap(fpl__func_x11_XDefaultColormap);
8548#define FPL__FUNC_X11_XFreeColormap(name) int name(Display *display, Colormap colormap)
8549typedef FPL__FUNC_X11_XFreeColormap(fpl__func_x11_XFreeColormap);
8550#define FPL__FUNC_X11_XMapWindow(name) int name(Display *display, Window w)
8551typedef FPL__FUNC_X11_XMapWindow(fpl__func_x11_XMapWindow);
8552#define FPL__FUNC_X11_XUnmapWindow(name) int name(Display *display, Window w)
8553typedef FPL__FUNC_X11_XUnmapWindow(fpl__func_x11_XUnmapWindow);
8554#define FPL__FUNC_X11_XStoreName(name) int name(Display *display, Window w, _Xconst char *window_name)
8555typedef FPL__FUNC_X11_XStoreName(fpl__func_x11_XStoreName);
8556#define FPL__FUNC_X11_XDefaultVisual(name) Visual *name(Display *display, int screen_number)
8557typedef FPL__FUNC_X11_XDefaultVisual(fpl__func_x11_XDefaultVisual);
8558#define FPL__FUNC_X11_XDefaultDepth(name) int name(Display *display, int screen_number)
8559typedef FPL__FUNC_X11_XDefaultDepth(fpl__func_x11_XDefaultDepth);
8560#define FPL__FUNC_X11_XInternAtom(name) Atom name(Display *display, const char *atom_name, Bool only_if_exists)
8561typedef FPL__FUNC_X11_XInternAtom(fpl__func_x11_XInternAtom);
8562#define FPL__FUNC_X11_XSetWMProtocols(name) Status name(Display *display, Window w, Atom *protocols, int count)
8563typedef FPL__FUNC_X11_XSetWMProtocols(fpl__func_x11_XSetWMProtocols);
8564#define FPL__FUNC_X11_XPending(name) int name(Display *display)
8565typedef FPL__FUNC_X11_XPending(fpl__func_x11_XPending);
8566#define FPL__FUNC_X11_XSync(name) int name(Display *display, Bool discard)
8567typedef FPL__FUNC_X11_XSync(fpl__func_x11_XSync);
8568#define FPL__FUNC_X11_XNextEvent(name) int name(Display *display, XEvent *event_return)
8569typedef FPL__FUNC_X11_XNextEvent(fpl__func_x11_XNextEvent);
8570#define FPL__FUNC_X11_XPeekEvent(name) int name(Display *display, XEvent *event_return)
8571typedef FPL__FUNC_X11_XPeekEvent(fpl__func_x11_XPeekEvent);
8572#define FPL__FUNC_X11_XEventsQueued(name) int name(Display *display, int mode)
8573typedef FPL__FUNC_X11_XEventsQueued(fpl__func_x11_XEventsQueued);
8574#define FPL__FUNC_X11_XGetWindowAttributes(name) Status name(Display *display, Window w, XWindowAttributes *window_attributes_return)
8575typedef FPL__FUNC_X11_XGetWindowAttributes(fpl__func_x11_XGetWindowAttributes);
8576#define FPL__FUNC_X11_XResizeWindow(name) int name(Display *display, Window w, unsigned int width, unsigned int height)
8577typedef FPL__FUNC_X11_XResizeWindow(fpl__func_x11_XResizeWindow);
8578#define FPL__FUNC_X11_XMoveWindow(name) int name(Display *display, Window w, int x, int y)
8579typedef FPL__FUNC_X11_XMoveWindow(fpl__func_x11_XMoveWindow);
8580#define FPL__FUNC_X11_XGetKeyboardMapping(name) KeySym *name(Display *display, KeyCode first_keycode, int keycode_count, int *keysyms_per_keycode_return)
8581typedef FPL__FUNC_X11_XGetKeyboardMapping(fpl__func_x11_XGetKeyboardMapping);
8582#define FPL__FUNC_X11_XLookupString(name) int name(XKeyEvent* event_struct, char* buffer_return, int bytes_buffer, KeySym* keysym_return, XComposeStatus* status_in_out)
8583typedef FPL__FUNC_X11_XLookupString(fpl__func_x11_XLookupString);
8584#define FPL__FUNC_X11_XSendEvent(name) Status name(Display *display, Window w, Bool propagate, long event_mask, XEvent *event_send)
8585typedef FPL__FUNC_X11_XSendEvent(fpl__func_x11_XSendEvent);
8586#define FPL__FUNC_X11_XMatchVisualInfo(name) Status name(Display* display, int screen, int depth, int clazz, XVisualInfo* vinfo_return)
8587typedef FPL__FUNC_X11_XMatchVisualInfo(fpl__func_x11_XMatchVisualInfo);
8588#define FPL__FUNC_X11_XCreateGC(name) GC name(Display* display, Drawable d, unsigned long valuemask, XGCValues* values)
8589typedef FPL__FUNC_X11_XCreateGC(fpl__func_x11_XCreateGC);
8590#define FPL__FUNC_X11_XGetImage(name) XImage *name(Display* display, Drawable d, int x, int y, unsigned int width, unsigned int height, unsigned long plane_mask, int format)
8591typedef FPL__FUNC_X11_XGetImage(fpl__func_x11_XGetImage);
8592#define FPL__FUNC_X11_XCreateImage(name) XImage *name(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line)
8593typedef FPL__FUNC_X11_XCreateImage(fpl__func_x11_XCreateImage);
8594#define FPL__FUNC_X11_XPutImage(name) int name(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height)
8595typedef FPL__FUNC_X11_XPutImage(fpl__func_x11_XPutImage);
8596#define FPL__FUNC_X11_XMapRaised(name) int name(Display *display, Window w)
8597typedef FPL__FUNC_X11_XMapRaised(fpl__func_x11_XMapRaised);
8598#define FPL__FUNC_X11_XCreatePixmap(name) Pixmap name(Display * display, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
8599typedef FPL__FUNC_X11_XCreatePixmap(fpl__func_x11_XCreatePixmap);
8600#define FPL__FUNC_X11_XSelectInput(name) int name(Display * display, Window w, long eventMask)
8601typedef FPL__FUNC_X11_XSelectInput(fpl__func_x11_XSelectInput);
8602#define FPL__FUNC_X11_XGetWindowProperty(name) int name(Display* display, Window w, Atom prop, long long_offset, long long_length, Bool del, Atom req_type, Atom* actual_type_return, int* actual_format_return, unsigned long* nitems_return, unsigned long* bytes_after_return, unsigned char** prop_return)
8603typedef FPL__FUNC_X11_XGetWindowProperty(fpl__func_x11_XGetWindowProperty);
8604#define FPL__FUNC_X11_XChangeProperty(name) int name(Display* display, Window w, Atom property, Atom type, int format, int mode, _Xconst unsigned char* data, int nelements)
8605typedef FPL__FUNC_X11_XChangeProperty(fpl__func_x11_XChangeProperty);
8606#define FPL__FUNC_X11_XDeleteProperty(name) int name(Display* display, Window w,Atom prop)
8607typedef FPL__FUNC_X11_XDeleteProperty(fpl__func_x11_XDeleteProperty);
8608#define FPL__FUNC_X11_XStringListToTextProperty(name) Status name(char** list, int count, XTextProperty* text_prop_return)
8609typedef FPL__FUNC_X11_XStringListToTextProperty(fpl__func_x11_XStringListToTextProperty);
8610#define FPL__FUNC_X11_XSetWMIconName(name) void name(Display* display, Window w, XTextProperty *text_prop)
8611typedef FPL__FUNC_X11_XSetWMIconName(fpl__func_x11_XSetWMIconName);
8612#define FPL__FUNC_X11_XSetWMName(name) void name(Display* display, Window w, XTextProperty *text_prop)
8613typedef FPL__FUNC_X11_XSetWMName(fpl__func_x11_XSetWMName);
8614#define FPL__FUNC_X11_XQueryKeymap(name) int name(Display* display, char [32])
8615typedef FPL__FUNC_X11_XQueryKeymap(fpl__func_x11_XQueryKeymap);
8616#define FPL__FUNC_X11_XQueryPointer(name) Bool name(Display* display, Window w, Window* root_return, Window* child_return, int* root_x_return, int* root_y_return, int* win_x_return, int* win_y_return, unsigned int* mask_return)
8617typedef FPL__FUNC_X11_XQueryPointer(fpl__func_x11_XQueryPointer);
8618#define FPL__FUNC_X11_XConvertSelection(name) int name(Display *display, Atom selection, Atom target, Atom property, Window requestor, Time time)
8619typedef FPL__FUNC_X11_XConvertSelection(fpl__func_x11_XConvertSelection);
8620#define FPL__FUNC_X11_XInitThreads(name) Status name(void)
8621typedef FPL__FUNC_X11_XInitThreads(fpl__func_x11_XInitThreads);
8622#define FPL__FUNC_X11_XSetErrorHandler(name) XErrorHandler name(XErrorHandler *handler)
8623typedef FPL__FUNC_X11_XSetErrorHandler(fpl__func_x11_XSetErrorHandler);
8624
8625typedef struct fpl__X11Api {
8626 void *libHandle;
8627 fpl__func_x11_XFlush *XFlush;
8628 fpl__func_x11_XFree *XFree;
8629 fpl__func_x11_XOpenDisplay *XOpenDisplay;
8630 fpl__func_x11_XCloseDisplay *XCloseDisplay;
8631 fpl__func_x11_XDefaultScreen *XDefaultScreen;
8632 fpl__func_x11_XRootWindow *XRootWindow;
8633 fpl__func_x11_XCreateWindow *XCreateWindow;
8634 fpl__func_x11_XDestroyWindow *XDestroyWindow;
8635 fpl__func_x11_XCreateColormap *XCreateColormap;
8636 fpl__func_x11_XFreeColormap *XFreeColormap;
8637 fpl__func_x11_XDefaultColormap *XDefaultColormap;
8638 fpl__func_x11_XMapWindow *XMapWindow;
8639 fpl__func_x11_XUnmapWindow *XUnmapWindow;
8640 fpl__func_x11_XStoreName *XStoreName;
8641 fpl__func_x11_XDefaultVisual *XDefaultVisual;
8642 fpl__func_x11_XDefaultDepth *XDefaultDepth;
8643 fpl__func_x11_XInternAtom *XInternAtom;
8644 fpl__func_x11_XSetWMProtocols *XSetWMProtocols;
8645 fpl__func_x11_XPending *XPending;
8646 fpl__func_x11_XSync *XSync;
8647 fpl__func_x11_XNextEvent *XNextEvent;
8648 fpl__func_x11_XPeekEvent *XPeekEvent;
8649 fpl__func_x11_XEventsQueued *XEventsQueued;
8650 fpl__func_x11_XGetWindowAttributes *XGetWindowAttributes;
8651 fpl__func_x11_XResizeWindow *XResizeWindow;
8652 fpl__func_x11_XMoveWindow *XMoveWindow;
8653 fpl__func_x11_XGetKeyboardMapping *XGetKeyboardMapping;
8654 fpl__func_x11_XLookupString *XLookupString;
8655 fpl__func_x11_XSendEvent *XSendEvent;
8656 fpl__func_x11_XMatchVisualInfo *XMatchVisualInfo;
8657 fpl__func_x11_XCreateGC *XCreateGC;
8658 fpl__func_x11_XGetImage *XGetImage;
8659 fpl__func_x11_XPutImage *XPutImage;
8660 fpl__func_x11_XMapRaised *XMapRaised;
8661 fpl__func_x11_XCreateImage *XCreateImage;
8662 fpl__func_x11_XCreatePixmap *XCreatePixmap;
8663 fpl__func_x11_XSelectInput *XSelectInput;
8664 fpl__func_x11_XGetWindowProperty *XGetWindowProperty;
8665 fpl__func_x11_XChangeProperty *XChangeProperty;
8666 fpl__func_x11_XDeleteProperty *XDeleteProperty;
8667 fpl__func_x11_XStringListToTextProperty *XStringListToTextProperty;
8668 fpl__func_x11_XSetWMIconName *XSetWMIconName;
8669 fpl__func_x11_XSetWMName *XSetWMName;
8670 fpl__func_x11_XQueryKeymap *XQueryKeymap;
8671 fpl__func_x11_XQueryPointer *XQueryPointer;
8672 fpl__func_x11_XConvertSelection *XConvertSelection;
8673 fpl__func_x11_XInitThreads *XInitThreads;
8674 fpl__func_x11_XSetErrorHandler *XSetErrorHandler;
8675} fpl__X11Api;
8676
8677fpl_internal void fpl__UnloadX11Api(fpl__X11Api *x11Api) {
8678 fplAssert(x11Api != fpl_null);
8679 if (x11Api->libHandle != fpl_null) {
8680 dlclose(x11Api->libHandle);
8681 }
8682 fplClearStruct(x11Api);
8683}
8684
8685fpl_internal bool fpl__LoadX11Api(fpl__X11Api *x11Api) {
8686 fplAssert(x11Api != fpl_null);
8687 const char *libFileNames[] = {
8688 "libX11.so",
8689 "libX11.so.7",
8690 "libX11.so.6",
8691 "libX11.so.5",
8692 };
8693 bool result = false;
8694 for (uint32_t index = 0; index < fplArrayCount(libFileNames); ++index) {
8695 const char *libName = libFileNames[index];
8696 fplClearStruct(x11Api);
8697 do {
8698 void *libHandle = fpl_null;
8699 FPL__POSIX_LOAD_LIBRARY(FPL__MODULE_X11, libHandle, libName);
8700 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XFlush, XFlush);
8701 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XFree, XFree);
8702 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XOpenDisplay, XOpenDisplay);
8703 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCloseDisplay, XCloseDisplay);
8704 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDefaultScreen, XDefaultScreen);
8705 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XRootWindow, XRootWindow);
8706 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCreateWindow, XCreateWindow);
8707 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDestroyWindow, XDestroyWindow);
8708 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCreateColormap, XCreateColormap);
8709 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XFreeColormap, XFreeColormap);
8710 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDefaultColormap, XDefaultColormap);
8711 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XMapWindow, XMapWindow);
8712 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XUnmapWindow, XUnmapWindow);
8713 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XStoreName, XStoreName);
8714 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDefaultVisual, XDefaultVisual);
8715 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDefaultDepth, XDefaultDepth);
8716 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XInternAtom, XInternAtom);
8717 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSetWMProtocols, XSetWMProtocols);
8718 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XPending, XPending);
8719 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSync, XSync);
8720 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XNextEvent, XNextEvent);
8721 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XPeekEvent, XPeekEvent);
8722 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XEventsQueued, XEventsQueued);
8723 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XGetWindowAttributes, XGetWindowAttributes);
8724 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XResizeWindow, XResizeWindow);
8725 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XMoveWindow, XMoveWindow);
8726 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XGetKeyboardMapping, XGetKeyboardMapping);
8727 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XLookupString, XLookupString);
8728 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSendEvent, XSendEvent);
8729 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XMatchVisualInfo, XMatchVisualInfo);
8730 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCreateGC, XCreateGC);
8731 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XGetImage, XGetImage);
8732 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XPutImage, XPutImage);
8733 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XMapRaised, XMapRaised);
8734 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCreateImage, XCreateImage);
8735 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XCreatePixmap, XCreatePixmap);
8736 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSelectInput, XSelectInput);
8737 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XGetWindowProperty, XGetWindowProperty);
8738 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XChangeProperty, XChangeProperty);
8739 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XDeleteProperty, XDeleteProperty);
8740 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XStringListToTextProperty, XStringListToTextProperty);
8741 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSetWMIconName, XSetWMIconName);
8742 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSetWMName, XSetWMName);
8743 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XQueryKeymap, XQueryKeymap);
8744 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XQueryPointer, XQueryPointer);
8745 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XConvertSelection, XConvertSelection);
8746 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XInitThreads, XInitThreads);
8747 FPL__POSIX_GET_FUNCTION_ADDRESS(FPL__MODULE_X11, libHandle, libName, x11Api, fpl__func_x11_XSetErrorHandler, XSetErrorHandler);
8748 x11Api->libHandle = libHandle;
8749 result = true;
8750 } while (0);
8751 if (result) {
8752 break;
8753 }
8754 fpl__UnloadX11Api(x11Api);
8755 }
8756 return(result);
8757}
8758
8759typedef struct fpl__X11SubplatformState {
8760 fpl__X11Api api;
8761} fpl__X11SubplatformState;
8762
8763typedef struct fpl__X11WindowStateInfo {
8764 fplWindowState state;
8765 fplWindowVisibilityState visibility;
8766 fplWindowPosition position;
8767 fplWindowSize size;
8768} fpl__X11WindowStateInfo;
8769
8770typedef struct fpl__X11Xdnd {
8771 int version;
8772 Window source;
8773 Atom format;
8774} fpl__X11Xdnd;
8775
8776#define FPL__FUNC_X11_ErrorHandlerCallback(name) int name(Display *display, XErrorEvent *ev)
8777typedef FPL__FUNC_X11_ErrorHandlerCallback(fpl__func_X11ErrorHandlerCallback);
8778
8779typedef struct fpl__X11WindowState {
8780 fpl__X11WindowStateInfo lastWindowStateInfo;
8781 Colormap colorMap;
8782 Display *display;
8783 fpl__func_X11ErrorHandlerCallback *lastErrorHandler;
8784 fpl__X11Xdnd xdnd;
8785 Window root;
8786 Window window;
8787 Visual *visual;
8788 Atom wmProtocols;
8789 Atom wmDeleteWindow;
8790 Atom wmState;
8791 Atom netWMPing;
8792 Atom netWMState;
8793 Atom netWMStateFocused;
8794 Atom netWMStateFullscreen;
8795 Atom netWMStateHidden;
8796 Atom netWMStateMaximizedVert;
8797 Atom netWMStateMaximizedHorz;
8798 Atom netWMPid;
8799 Atom netWMIcon;
8800 Atom netWMName;
8801 Atom netWMIconName;
8802 Atom utf8String;
8803 Atom motifWMHints;
8804 // drag and drop
8805 Atom xdndAware;
8806 Atom xdndEnter;
8807 Atom xdndPosition;
8808 Atom xdndStatus;
8809 Atom xdndActionCopy;
8810 Atom xdndDrop;
8811 Atom xdndFinished;
8812 Atom xdndSelection;
8813 Atom xdndTypeList;
8814 Atom textUriList;
8815 int screen;
8816 int colorDepth;
8817} fpl__X11WindowState;
8818
8819#define FPL__XDND_VERSION 5
8820
8821#endif // FPL_SUBPLATFORM_X11
8822
8823// ****************************************************************************
8824//
8825// > PLATFORM_STATES
8826//
8827// - Defines the final PlatformInitState and PlatformAppState
8828// - Declares all required global variables
8829//
8830// ****************************************************************************
8831#if !defined(FPL__PLATFORM_STATES_DEFINED)
8832#define FPL__PLATFORM_STATES_DEFINED
8833//
8834// Platform initialization state
8835//
8836typedef struct fpl__PlatformInitSettings {
8837 fplMemorySettings memorySettings;
8838} fpl__PlatformInitSettings;
8839
8840typedef struct fpl__PlatformInitState {
8841#if defined(FPL_SUBPLATFORM_POSIX)
8842 fpl__PosixInitState posix;
8843#endif
8844
8845 fpl__PlatformInitSettings initSettings;
8846 fplPlatformResultType initResult;
8847 fpl_b32 isInitialized;
8848
8849 union {
8850# if defined(FPL_PLATFORM_WINDOWS)
8851 fpl__Win32InitState win32;
8852# elif defined(FPL_PLATFORM_LINUX)
8853 fpl__LinuxInitState plinux;
8854# elif defined(FPL_PLATFORM_UNIX)
8855 fpl__UnixInitState punix;
8856# endif
8857 };
8858} fpl__PlatformInitState;
8859fpl_globalvar fpl__PlatformInitState fpl__global__InitState = fplZeroInit;
8860
8861#if defined(FPL__ENABLE_WINDOW)
8862#define FPL__MAX_EVENT_COUNT 32768
8863typedef struct fpl__EventQueue {
8864 // @FIXME(final): Internal events are not Thread-Safe!
8865 fplEvent events[FPL__MAX_EVENT_COUNT];
8866 uint32_t pollIndex;
8867 uint32_t pushCount;
8868} fpl__EventQueue;
8869
8870typedef struct fpl__PlatformWindowState {
8871 fpl__EventQueue eventQueue;
8872 fplKey keyMap[256];
8873 fplButtonState keyStates[256];
8874 uint64_t keyPressTimes[256];
8875 fplButtonState mouseStates[5];
8876 fpl_b32 isRunning;
8877
8878#if defined(FPL_PLATFORM_WINDOWS)
8879 fpl__Win32WindowState win32;
8880#endif
8881#if defined(FPL_SUBPLATFORM_X11)
8882 fpl__X11WindowState x11;
8883#endif
8884} fpl__PlatformWindowState;
8885#endif // FPL__ENABLE_WINDOW
8886
8887#if defined(FPL__ENABLE_VIDEO)
8888typedef struct fpl__PlatformVideoState {
8889 void *mem; // Points to fpl__VideoState
8890 size_t memSize;
8891} fpl__PlatformVideoState;
8892#endif // FPL__ENABLE_VIDEO
8893
8894#if defined(FPL__ENABLE_AUDIO)
8895typedef struct fpl__PlatformAudioState {
8896 void *mem; // Points to fpl__AudioState
8897 size_t memSize;
8898} fpl__PlatformAudioState;
8899#endif
8900
8901//
8902// Platform application state
8903//
8904typedef struct fpl__PlatformAppState fpl__PlatformAppState;
8905struct fpl__PlatformAppState {
8906 // Subplatforms
8907#if defined(FPL_SUBPLATFORM_POSIX)
8908 fpl__PosixAppState posix;
8909#endif
8910#if defined(FPL_SUBPLATFORM_X11)
8911 fpl__X11SubplatformState x11;
8912#endif
8913
8914 // Window/video/audio
8915#if defined(FPL__ENABLE_WINDOW)
8916 fpl__PlatformWindowState window;
8917#endif
8918#if defined(FPL__ENABLE_VIDEO)
8919 fpl__PlatformVideoState video;
8920#endif
8921#if defined(FPL__ENABLE_AUDIO)
8922 fpl__PlatformAudioState audio;
8923#endif
8924
8925 // Settings
8926 fplSettings initSettings;
8927 fplSettings currentSettings;
8928 fplInitFlags initFlags;
8929
8930 // Platforms
8931 union {
8932# if defined(FPL_PLATFORM_WINDOWS)
8933 fpl__Win32AppState win32;
8934# elif defined(FPL_PLATFORM_LINUX)
8935 fpl__LinuxAppState plinux;
8936# elif defined(FPL_PLATFORM_UNIX)
8937 fpl__UnixAppState plinux;
8938# endif
8939 };
8940};
8941
8942//
8943// Internal window
8944//
8945#if defined(FPL__ENABLE_WINDOW)
8946fpl_internal fplKey fpl__GetMappedKey(const fpl__PlatformWindowState *windowState, const uint64_t keyCode) {
8947 fplKey result;
8948 if (keyCode < fplArrayCount(windowState->keyMap))
8949 result = windowState->keyMap[keyCode];
8950 else
8951 result = fplKey_None;
8952 return(result);
8953}
8954
8955fpl_internal void fpl__ClearInternalEvents() {
8956 fpl__PlatformAppState *appState = fpl__global__AppState;
8957 fplAssert(appState != fpl_null);
8958 fpl__EventQueue *eventQueue = &appState->window.eventQueue;
8959 // @FIXME(final): Internal events are not thread-safe, introduce a proper thread-safe queue here!
8960 uint32_t eventCount = eventQueue->pollIndex;
8961 eventQueue->pollIndex = 0;
8962 for (size_t eventIndex = 0; eventIndex < eventCount; ++eventIndex) {
8963 fplEvent *ev = &eventQueue->events[eventIndex];
8965 fpl__ReleaseDynamicMemory(ev->window.dropFiles.internalMemory.base);
8967 }
8968 }
8969 eventQueue->pushCount = 0;
8970}
8971