Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_EventWatch.hpp":
- #ifndef _INC__MISC_EVENTWATCH_HPP
- #define _INC__MISC_EVENTWATCH_HPP
- #include "commondef.hpp"
- #include "_misc_Event.hpp"
- namespace kit {
- typedef void (*EventWatchCallback)(Event& event, void* userdata);
- typedef void (*EventWatchDestructorCallback)(void* userdata);
- class EventWatch { //40B
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- bool _disabled = false;
- u8 _padding8;
- EventWatchCallback _callback = nullptr;
- void* _userdata = nullptr;
- EventWatchDestructorCallback _onDestruction = nullptr;
- public:
- EventWatch(EventWatchCallback callback, void* userdata = nullptr,
- EventWatchDestructorCallback onDestruction = nullptr);
- ~EventWatch(); //will call _onDestruction if != nullptr
- inline void setState(bool enabled){ _disabled = !enabled; }
- };
- };
- #endif /* _INC__MISC_EVENTWATCH_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_fileio.hpp":
- #ifndef _INC__MISC_FILEIO_HPP
- #define _INC__MISC_FILEIO_HPP
- #include "commondef.hpp"
- namespace kit {
- union BinaryData_magic {
- u8 n8;
- u16 n16;
- u32 n32;
- u64 n64;
- char str[8];
- //(str may not be null-terminated!)
- };
- class BinaryData {
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- u16 _padding16;
- char* _data = nullptr;
- size_t _data_size = 0;
- public:
- //tbd: make this less wacky
- BinaryData_magic** const magic =
- (BinaryData_magic**)&this->_data;
- BinaryData(const char* filePath);
- //this will allocate dataSize bytes for _data, before copying data to _data
- //(it is safe to pass nullptr to data, though that would make the class
- // instance sorta equivalent to a garbage collected memory::alloc())
- BinaryData(const void* data, size_t data_size);
- ~BinaryData();
- inline bool isValid() { return _valid; }
- inline bool isConstructing(){ return _constructing; }
- char* getData(){ return _data; }
- size_t getSize(){ return _data_size; }
- };
- #define KIT_FILE_SEEK_SET 0
- #define KIT_FILE_SEEK_CUR 1
- #define KIT_FILE_SEEK_END 2
- class File { //16B
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- bool _closed = false;
- bool _zombie = false;
- GenOpqPtr _file = nullptr;
- public:
- File(const char* filePath, const char* mode);
- ~File();
- inline bool isValid() { return _valid; }
- inline bool isConstructing(){ return _constructing; }
- inline bool isClosed() { return _closed; }
- //WARNING: make sure to call clearSysError() before starting any
- //string of calls to read(), otherwise an error might be thrown
- //if the thread's previously set error was equal to "Error"
- //returns number of elements read (or 0 if EOF)
- size_t read(void* elements, size_t elementSize, size_t elements_len);
- //returns number of bytes read (or 0 if EOF)
- inline size_t read(void* data, size_t dataSize){ return read(data, 1, dataSize); }
- void write(const void* elements, size_t elementSize, size_t elements_len);
- inline void write(const void* data, size_t dataSize){ write(data, 1, dataSize); }
- //seek to offset relative of whence (one of KIT_FILE_SEEK_<SET/CUR/END>)
- //returns new absolute offset of data stream, in bytes
- size_t seek(s64 offset, u32 whence);
- //returns current file offset
- inline size_t tell(){ return seek(0, KIT_FILE_SEEK_CUR); }
- //closes file handle
- //(file is considered invalid after this point!)
- void close();
- //returns size of file, in bytes
- size_t size();
- };
- namespace fileio {
- bool exists(const char* filePath);
- size_t size(const char* filePath);
- void remove(const char* filePath);
- //heap memory is allocated here,
- //and should be freed with memory::free()
- //(also, while *dataSize_p won't be populated with resulting
- // filesize if dataSize_p is nullptr, it won't actually error)
- void* readAll(const char* filePath, size_t* dataSize_p);
- //writes to a binary file from a buffer
- void writeAll(const char* filePath, const void* data,
- size_t dataSize, bool append = false);
- }; /* namespace fileio */
- }; /* namespace kit */
- #endif /* _INC__MISC_FILEIO_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_func.hpp":
- #ifndef _INC__MISC_FUNC_HPP
- #define _INC__MISC_FUNC_HPP
- #include "commondef.hpp"
- #include <stdarg.h> //for vsnPrintf
- namespace kit {
- enum InitFlagsEnum {
- KINIT_TIMER = 0x01,
- KINIT_AUDIO = 0x02,
- KINIT_VIDEO = 0x04,
- KINIT_JOYSTICK = 0x08,
- KINIT_GAMECONTROLLER = 0x10,
- KINIT_EVENTS = 0x20,
- KINIT_EVERYTHING = 0x3F,
- };
- //these should only be called from the main thread, only after
- //guaranteeing that no other threads are currently running
- void initSubsystems(u32 flags = KINIT_EVERYTHING);
- void quitSubsystems(u32 flags = KINIT_EVERYTHING);
- //(quitting with KINIT_EVERYTHING is safe even if
- //there are no currently active subsystems)
- enum LogPriorityEnum {
- LOG_PRIORITY_VERBOSE = 1,
- LOG_PRIORITY_DEBUG,
- LOG_PRIORITY_INFO,
- LOG_PRIORITY_WARN,
- LOG_PRIORITY_ERROR,
- LOG_PRIORITY_CRITICAL,
- };
- //kit::Log(), except it suppresses some format string stuff
- //this macro is especially useful if you're using %llu, (long long unsigned)
- //and gcc would otherwise complain about an unknown format specifier
- //(at least, that's what happened when i used plain ol' SDL_Log,
- //even though it prints 18446744073709551615 with %llu just fine)
- #define kit_LogS(...) \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wformat=\"") \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wformat-extra-args\"") \
- kit::Log(__VA_ARGS__); \
- _Pragma("GCC diagnostic pop") \
- _Pragma("GCC diagnostic pop")
- #define kit_LogVerbose(...) kit::Log(LOG_PRIORITY_VERBOSE , __VA_ARGS__)
- #define kit_LogDebug(...) kit::Log(LOG_PRIORITY_DEBUG , __VA_ARGS__)
- #define kit_LogInfo(...) kit::Log(LOG_PRIORITY_INFO , __VA_ARGS__)
- #define kit_LogWarn(...) kit::Log(LOG_PRIORITY_WARN , __VA_ARGS__)
- #define kit_LogError(...) kit::Log(LOG_PRIORITY_ERROR , __VA_ARGS__)
- #define kit_LogCritical(...) kit::Log(LOG_PRIORITY_CRITICAL, __VA_ARGS__)
- #define kit_LogVerboseS(...) kit_LogS(LOG_PRIORITY_VERBOSE , __VA_ARGS__)
- #define kit_LogDebugS(...) kit_LogS(LOG_PRIORITY_DEBUG , __VA_ARGS__)
- #define kit_LogInfoS(...) kit_LogS(LOG_PRIORITY_INFO , __VA_ARGS__)
- #define kit_LogWarnS(...) kit_LogS(LOG_PRIORITY_WARN , __VA_ARGS__)
- #define kit_LogErrorS(...) kit_LogS(LOG_PRIORITY_ERROR , __VA_ARGS__)
- #define kit_LogCriticalS(...) kit_LogS(LOG_PRIORITY_CRITICAL, __VA_ARGS__)
- //basically SDL_LogMessage, except with the category always set to application
- void Log(LogPriorityEnum priority, const char* fmt, ...);
- //len_max does not include null-terminator!
- //if len_max == 0, call is analogous to str(not n)len
- size_t strnLen(const char* str, size_t len_max = 0);
- //(mostly) yoinked from stackoverflow :D
- //len_max does not include null-terminator!
- //if len_max == 0, call is analogous to str(not n)cmp
- s32 strnCmp(const char* str_a, const char* str_b, size_t len_max = 0);
- //null-terminator is added at the end of the copy destination!
- //if len_max == 0, call is analogous to str(not n)cpy
- char* strnCpy(char* str_dst, const char* str_src, size_t len_max);
- /* taken from stb_sprintf.h (what these 2 functions use under-the-hood):
- 64-BIT INTS:
- ============
- This library also supports 64-bit integers and you can use MSVC style or
- GCC style indicators (%I64d or %lld). It supports the C99 specifiers
- for size_t and ptr_diff_t (%jd %zd) as well.
- EXTRAS:
- =======
- Like some GCCs, for integers and floats, you can use a ' (single quote)
- specifier and commas will be inserted on the thousands: "%'d" on 12345
- would print 12,345.
- For integers and floats, you can use a "$" specifier and the number
- will be converted to float and then divided to get kilo, mega, giga or
- tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is
- "2.53 M", etc. For byte values, use two $:s, like "%$$d" to turn
- 2536000 to "2.42 Mi". If you prefer JEDEC suffixes to SI ones, use three
- $:s: "%$$$d" -> "2.42 M". To remove the space between the number and the
- suffix, add "_" specifier: "%_$d" -> "2.53M".
- In addition to octal and hexadecimal conversions, you can print
- integers in binary: "%b" for 256 would print 100.
- PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC):
- ===================================================================
- "%d" across all 32-bit ints (4.8x/4.0x faster than 32-/64-bit MSVC)
- "%24d" across all 32-bit ints (4.5x/4.2x faster)
- "%x" across all 32-bit ints (4.5x/3.8x faster)
- "%08x" across all 32-bit ints (4.3x/3.8x faster)
- "%f" across e-10 to e+10 floats (7.3x/6.0x faster)
- "%e" across e-10 to e+10 floats (8.1x/6.0x faster)
- "%g" across e-10 to e+10 floats (10.0x/7.1x faster)
- "%f" for values near e-300 (7.9x/6.5x faster)
- "%f" for values near e+300 (10.0x/9.1x faster)
- "%e" for values near e-300 (10.1x/7.0x faster)
- "%e" for values near e+300 (9.2x/6.0x faster)
- "%.320f" for values near e-300 (12.6x/11.2x faster)
- "%a" for random values (8.6x/4.3x faster)
- "%I64d" for 64-bits with 32-bit values (4.8x/3.4x faster)
- "%I64d" for 64-bits > 32-bit values (4.9x/5.5x faster)
- "%s%s%s" for 64 char strings (7.1x/7.3x faster)
- "...512 char string..." ( 35.0x/32.5x faster!)
- */
- //if len_max == 0 OR > KIT_S32_MAX, call is analogous to s(not n)printf
- s32 snPrintf(char* str_dst, size_t len_max, const char* str_fmt, ...);
- //^^ VV unlike normal snprintf, these'll always return a null-terminated string
- //if len_max == 0 OR > KIT_S32_MAX, call is analogous to vs(not n)printf
- s32 vsnPrintf(char* str_dst, size_t len_max, const char* str_fmt, va_list va);
- const char* getLastSysError();
- void clearSysError();
- //frees any error strings managed by kit_sdl2 on the calling thread
- //this must be called whenever a const char* exception is caught,
- //only after that Error has been handled by the user.
- //(as in, the pointer should be considered invalid after exiting this function!)
- //since this will work even if there is no kit_sdl2-managed error message,
- //it is best practice to call this even if you're mostly sure that
- //the const char* was thrown by the user!
- //also, a call of quitSubsystem(KINIT_EVERYTHING)
- //will free all thread errors automatically
- //also also, mixups might occur if another thread error is pushed before
- //a call to freeThreadErrors() has the chance to free the previous one(s)
- //on the same thread, resulting in the wrong reference (not an invalid
- //error string, just not the right one) being accessed
- void freeThreadErrors();
- //TL;DR: best practice is to call this during any catch(const char*) exceptions,
- //after you're done handling the thrown string!
- enum CPUCapabilityFlagsEnum {
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_RDTSC = 0x0001, //'does CPU have RDTSC instruction?'
- //(always false on CPUs that aren't using PowerPC instruction sets)
- CPU_HAS_ALTIVEC = 0x0002, //'does CPU have AltiVec features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_MMX = 0x0004, //'does CPU have MMX features?'
- //(always false on CPUs that aren't using AMD instruction sets)
- CPU_HAS_3DNOW = 0x0008, //'does CPU have 3DNow! features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_SSE = 0x0010, //'does CPU have SSE features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_SSE2 = 0x0020, //'does CPU have SSE2 features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_SSE3 = 0x0040, //'does CPU have SSE3 features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_SSE41 = 0x0080, //'does CPU have SSE4.1 features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_SSE42 = 0x0100, //'does CPU have SSE4.2 features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_AVX = 0x0200, //'does CPU have AVX features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_AVX2 = 0x0400, //'does CPU have AVX2 features?'
- //(always false on CPUs that aren't using Intel instruction sets)
- CPU_HAS_AVX512F = 0x0800, //'does CPU have AVX-512F (foundation) features?'
- //(always false on CPUs that aren't using ARM instruction sets)
- CPU_HAS_ARMSIMD = 0x1000, //'does CPU have ARM SIMD (ARMv6) features?'
- //(always false on CPUs that aren't using ARM instruction sets)
- CPU_HAS_NEON = 0x2000, //'does CPU have NEON (ARM SIMD) features?'
- //(always false on CPUs that aren't using LOONGARCH instruction sets)
- CPU_HAS_LSX = 0x4000, //'does CPU have LSX (LOONGARCH SIMD) features?'
- //(always false on CPUs that aren't using LOONGARCH instruction sets)
- CPU_HAS_LASX = 0x8000, //'does CPU have LASX (LOONGARCH SIMD) features?'
- };
- u32 getCPUCapabilities(); //returns a combination of CPUCapabilityFlagsEnum flags
- u32 getCPUCacheLineSize(); //in bytes (L1 cache specifically)
- u32 getNumLogicalCPUCores(); //(might be > core count if hyperthreading is enabled)
- enum MessageBoxFlagsEnum {
- MSGBOX_ERROR = 0x0010,
- MSGBOX_WARNING = 0x0020,
- MSGBOX_INFO = 0x0040,
- MSGBOX_BTNS_L2R = 0x0080, //buttons placed left-to-right (showMsgBoxEx only)
- MSGBOX_BTNS_R2L = 0x0100, //buttons placed right-to-left (showMsgBoxEx only)
- };
- class Window; //forward declaration
- void showMsgBox(const char* text = nullptr, const char* title = nullptr,
- u32 flags = MSGBOX_INFO, Window* win = nullptr);
- //showMsgBoxEx is TBD (i don't want to deal with SDL's message boxes right now)
- union Event; //forward declaration
- //returns false if there were no events in queue
- //(if event_p is left as nullptr, the next event will not be dequeued)
- //(also, only call this function in the thread that set the video mode,
- // which is usually the main thread!)
- bool pollEvent(Event* event_p = nullptr); //requires events subsystem
- const char* getEventText(u32 type);
- //(clipboard text uses utf-8 encoding)
- bool clipboardHasText();
- char* clipboardGetText(); //(allocates memory; returned ptr must be memory::free'd)
- void clipboardSetText(const char* txt);
- bool showCursor(s32 toggle); //boolean, or -1 to query state without changing
- void warpMouseGlobal(s32 x, s32 y);
- bool getRelativeMouseMode();
- void setRelativeMouseMode(bool enable);
- }; /* namespace kit */
- #endif /* _INC__MISC_FUNC_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_memory.hpp":
- #ifndef _INC__MISC_MEMORY_HPP
- #define _INC__MISC_MEMORY_HPP
- #include "commondef.hpp"
- namespace kit {
- namespace memory {
- void* alloc(size_t size);
- //this version of free is especially useful, because it's safe to pass nullptr to!
- //this rule goes for both ptr_p and *ptr_p
- void free(void* ptr_p);
- void* realloc(void* ptr_p, size_t newSize);
- //^^(for both free and realloc, a void** declared in function as void*,
- // so you don't need to explicitly cast it to void**)
- //same as alloc and free, now with exception throwing!
- void* alloc2(size_t size);
- void free2(void* ptr_p); //(unlike free, this will throw if nullptr is given)
- void* realloc2(void* ptr_p, size_t newSize);
- size_t getNumAllocations();
- void* set(void* ptr, s32 value, size_t size);
- //throws exceptions, unlike set
- void* set2(void* ptr, s32 value, size_t size);
- void* copy(void* destination, const void* source, size_t size);
- //throws exceptions, unlike copy
- void* copy2(void* destination, const void* source, size_t size);
- u32 getSystemRAM_MiB(); //returns amount of RAM configured in the system, in MiB
- u32 getSIMDAlignment(); //returns required alignment for SIMD instructions, in bytes
- //xSIMD are basically the same as their non-SIMD counterparts,
- //except these are aligned and padded for use with SIMD instructions.
- //by padded, i mean that it's safe to read/write an incomplete
- //vector at the end of a memory block
- //(allocSIMD pointers must be freed using freeSIMD,
- //not free, and vice-versa)
- void* allocSIMD(size_t size);
- void freeSIMD(void* ptr_p);
- void* reallocSIMD(void* ptr_p, size_t newSize);
- void* allocSIMD2(size_t size);
- void freeSIMD2(void* ptr_p);
- void* reallocSIMD2(void* ptr_p, size_t newSize);
- struct Wrapper {
- void* ptr = nullptr;
- Wrapper(size_t size); //new memory::alloc
- Wrapper(void* _ptr) : ptr(_ptr) {} //existing memory::alloc
- ~Wrapper(){ memory::free(&ptr); };
- //capital A in the middle to avoid name conflict with actual memory::realloc
- inline void* reAlloc(size_t newSize){ return memory::realloc(&ptr, newSize); }
- };
- struct WrapperSIMD {
- void* ptr = nullptr;
- WrapperSIMD(size_t size); //new memory::allocSIMD
- WrapperSIMD(void* _ptr) : ptr(_ptr) {} //existing memory::allocSIMD
- ~WrapperSIMD(){ memory::freeSIMD(&ptr); };
- //capital A in the middle to remain consistent with Wrapper::reAlloc()
- inline void* reAlloc(size_t newSize){ return memory::reallocSIMD(&ptr, newSize); }
- };
- }; /* namespace memory */
- }; /* namespace kit */
- #endif /* _INC__MISC_MEMORY_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_Mutex.hpp":
- #ifndef _INC__MISC_MUTEX_HPP
- #define _INC__MISC_MUTEX_HPP
- #include "commondef.hpp"
- namespace kit {
- //this mutex is non-blocking within the same thread!
- //(that means you can lock multiple times in one thread
- // as long as you unlock it the same number of times)
- class Mutex { //16B; does not require an active subsystem
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- u16 _padding16;
- GenOpqPtr _mutex_p = nullptr;
- public:
- Mutex();
- ~Mutex();
- inline bool isValid() { return _valid; }
- inline bool isConstructing(){ return _constructing; }
- void lock(bool locked = true);
- inline void unlock(){ lock(false); }
- bool tryLock(); //returns true if locked successfully
- };
- }; /* namespace kit */
- #endif /* _INC__MISC_MUTEX_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_Thread.hpp":
- #ifndef _INC__MISC_THREAD_HPP
- #define _INC__MISC_THREAD_HPP
- #include "commondef.hpp"
- namespace kit {
- enum ThreadPriorityEnum {
- THREAD_LOW = -1,
- THREAD_NORMAL = 0,
- THREAD_HIGH = 1,
- THREAD_HIGHEST = 2, //for time critical tasks
- };
- //if a thread function throws an unhandled exception,
- //it will be outputted to stdout
- typedef s32 (*ThreadFunction)(void* userdata);
- //returns whether or not priority of current thread was successfully set
- //may fail if setting priority requires elevated privileges (or at least when
- //setting a higher priority), if it's even allowed at all
- bool Thread_setPriority(s32 priority, bool throwOnFailure = false);
- class Thread { //16B; does not require an active subsystem
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- bool _waitInDestructor = false; //otherwise thread auto-detaches
- bool _detached = false;
- GenOpqPtr _thread = nullptr;
- //(real opaque is separate from Thread object and is very temporary)
- public:
- //if waitInDestructor is false, the Thread object will not
- //wait for func to return inside the Thread's destructor
- //(stackSize = 0 to use whatever default stack size is)
- Thread(ThreadFunction func, void* userdata = nullptr,
- bool waitInDestructor = false, size_t stackSize = 0,
- const char* threadName = nullptr);
- //(threadName should be UTF-8 string if not nullptr)
- ~Thread();
- inline bool isValid() { return _valid; }
- inline bool isConstructing(){ return _constructing; }
- inline bool isDetached() { return _detached; }
- u32 getID();
- //returns UTF-8 string, or nullptr if thread doesn't have a name
- const char* getName();
- //returns result of func (if detached, returns 0 immediately)
- //(afaik, SDL_WaitThread doesn't time out, so be careful!)
- s32 waitUntilDone();
- //make thread automatically clean up after returning
- //(otherwise, you'll need to call waitUntilDone() to do that)
- void detach();
- };
- }; /* namespace kit */
- #endif /* _INC__MISC_THREAD_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_misc_time.hpp":
- #ifndef _INC__MISC_TIME_HPP
- #define _INC__MISC_TIME_HPP
- #include "commondef.hpp"
- namespace kit {
- /* from the SDL2 wiki: "
- The callback function is passed the current timer interval
- and returns the next timer interval. If the returned value
- is the same as the one passed in, the periodic alarm continues,
- otherwise a new alarm is scheduled. If the callback returns 0,
- the periodic alarm is cancelled. "*/
- typedef u32 (*timerCallback)(u32 interval_ms, void* userdata);
- typedef s32 timerID;
- //(these 2 functions require the timer subsystem)
- timerID timerAdd(timerCallback func, u32 interval_ms, void* userdata = nullptr);
- void timerRemove(timerID id);
- namespace time {
- //returns current tick count, and how
- //many ticks are in a second, respectively
- u64 getTicks();
- u64 getTicksPerSecond();
- //returns # of milliseconds since init
- u64 getMS();
- u32 getMS_32();
- //returns # of seconds since init
- //(uses integer milliseconds internally;
- // do "(f64)getTicks()/getTicksPerSecond()"
- // if more accuracy is needed)
- f64 getSeconds();
- //will wait AT LEAST the given number
- //of milliseconds (possibly longer)
- void sleep(u32 milliseconds);
- }; /* namespace time */
- }; /* namespace kit */
- #endif /* _INC__MISC_TIME_HPP */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\include\kit\_video_BFont_Surface.hpp":
- #ifndef _INC__VIDEO_BFONT_SURFACE_HPP
- #define _INC__VIDEO_BFONT_SURFACE_HPP
- #include "commondef.hpp"
- #include "_video_Surface.hpp"
- namespace kit {
- //set x and/or y to this to center the text on that axis
- #ifndef KIT_CENTER_TEXT
- #define KIT_CENTER_TEXT (-2147483647) //aka 0x80000001
- #endif
- #ifndef KIT_DEFAULT_TEXT_COLOR
- #define KIT_DEFAULT_TEXT_COLOR 0xFFFFFF //0xBBGGRR
- #endif
- class Window;
- //class for software rendering monospaced, 256-char, bitmap fonts
- class BFont_Surface { //80B
- u32 _type;
- bool _valid = false;
- bool _constructing = true;
- public:
- //'add 1 pixel of spacing on bottom-right side?' (affected by scale)
- bool box_padded = false; //what the default font uses
- //if false, negative positions are treated normally, without using the
- //bottom-right side as the text's (or text box's) origin
- //(setting to false will by extension ignore KIT_CENTER_TEXT)
- bool neg_pos_margin = true;
- private:
- GenOpqPtr _surf_src = nullptr;
- GenOpqPtr _surf_dst = nullptr; //a reference; swapped every draw call
- u8* _fmtBuffer = nullptr;
- shape::point _glyphSize = {8, 8}; //8x8 is the size of the default font
- shape::rect _lastBounds = {0, 0, 0, 0};
- u31 _fmtBuffer_len = 4096;
- colors::ABGR _txt_fg = KIT_DEFAULT_TEXT_COLOR; //for the text itself; 0xBBGGRR
- void _constructor(GenOpqPtr surf_opq, colors::ABGR txt_fg, u31 fmtBuffer_len,
- const char* funcName = nullptr);
- shape::point _getTextSize(bool bordered);
- shape::rect _getRect(s32 x, s32 y, bool bordered);
- shape::rect _draw(s32 x, s32 y, u31 maxLen);
- shape::point _drawBoxNoText(shape::rect dst_rect); //(positions are absolute)
- shape::rect _drawBox(s32 x, s32 y, u31 maxLen);
- public:
- //color of the text box's background; 0xBBGGRR
- colors::ABGR txt_bg = 0x000000; //(alpha component is ignored)
- //color of the text box's border; 0xBBGGRR
- colors::ABGR txt_bd = 0xC0C0C0; //(alpha component is ignored)
- //the multiplier for text and box scaling
- shape::fpoint scale = {1.0f, 1.0f};
- //(WHEN CONSTRUCTING, USE BLACK (0x00000000) TO INDICATE
- //TRANSPARENCY, AND NONZERO PIXELS TO INDICATE OPAQUENESS!
- //ACTUAL TEXT COLOR IS DETERMINED BY "txt_fg" EVERY DRAW CALL!)
- //if img_filePath is nullptr, the default built-in
- //font will be used (8x8, public domain :D)
- //(img_callback is ignored if img_filePath is nullptr)
- BFont_Surface(const char* img_filePath = nullptr,
- SurfaceLoaderCallback img_callback = nullptr,
- colors::ABGR txt_fg = KIT_DEFAULT_TEXT_COLOR,
- u31 fmtBuffer_len = 4096);
- //copies the surface and all of its pixel data
- inline BFont_Surface(const Surface& surf,
- colors::ABGR txt_fg = KIT_DEFAULT_TEXT_COLOR,
- u31 fmtBuffer_len = 4096)
- { _constructor((GenOpqPtr)&surf, txt_fg, fmtBuffer_len); }
- ~BFont_Surface();
- inline u8* getFmtBuffer(){ return _fmtBuffer; }
- inline u32 getFmtBufferLen(){ return _fmtBuffer_len.n; }
- inline shape::rect getLastBounds(){ return _lastBounds; }
- inline colors::ABGR getGlyphColor(){ return _txt_fg; }
- inline shape::point getGlyphSize(){ return _glyphSize; }
- inline shape::point getGlyphSizeScaled(){
- if(scale.x != 1.0f || scale.y != 1.0f){
- return {MAX((s32)(_glyphSize.x*scale.x), 1),
- MAX((s32)(_glyphSize.y*scale.y), 1)};
- } else {
- return _glyphSize;
- }
- }
- shape::point getTextSize(const char* fmt, bool bordered = false, ...);
- shape::rect getRect(Surface& dst_surf, s32 x, s32 y, const char* fmt,
- bool bordered = false, ...);
- shape::rect getRect(Window& dst_surf, s32 x, s32 y, const char* fmt,
- bool bordered = false, ...);
- //(will calculate the rect of whatever is currently in _fmtBuffer)
- shape::rect getRect(Surface& dst_surf, s32 x, s32 y, bool bordered = false);
- shape::rect getRect(Window& dst_surf, s32 x, s32 y, bool bordered = false);
- //aside from KIT_CENTER_TEXT, there's another non-absolute positioning option,
- //as negative x/y positions will change the text's origin point from the
- //top-left to the bottom-right (unless neg_pos_margin = false), like so:
- //'surface_width-text_width+x+1', and 'surface_height-text_height+y+1'
- //(+x & +y, as in adding by a negative)
- //if !maxLen, the entire resulting string will be drawn
- //returns the resulting string's calculated bounding box, in pixels
- shape::rect draw(Surface& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen = 0, ...);
- shape::rect draw(Window& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen = 0, ...);
- //(will draw whatever is currently in _fmtBuffer)
- shape::rect draw(Surface& dst_surf, s32 x, s32 y, u31 maxLen = 0);
- shape::rect draw(Window& dst_surf, s32 x, s32 y, u31 maxLen = 0);
- //same behavior as draw, but the x & y (and returned bounding box)
- //are adjusted to match a 2-pixel border around the text
- shape::rect drawBox(Surface& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen = 0, ...);
- shape::rect drawBox(Window& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen = 0, ...);
- //(will draw whatever is currently in _fmtBuffer)
- shape::rect drawBox(Surface& dst_surf, s32 x, s32 y, u31 maxLen = 0);
- shape::rect drawBox(Window& dst_surf, s32 x, s32 y, u31 maxLen = 0);
- //positions used here are absolute, in that negative values
- //will always make the box appear past the top-left side
- //returns the number of pixels to shift the text by
- //to make it fit inside the box
- shape::point drawBoxNoText(Surface& dst_surf, s32 x, s32 y, u31 w, u31 h);
- shape::point drawBoxNoText(Window& dst_surf, s32 x, s32 y, u31 w, u31 h);
- //returns final rect of char, after negative margin check
- //(does not update _lastBounds!)
- shape::rect drawChar(Surface& dst_surf, u8 chr, s32 x, s32 y);
- shape::rect drawChar(Window& dst_surf, u8 chr, s32 x, s32 y);
- //formats fmt into _fmtBuffer, before returning _fmtBuffer
- u8* format(const char* fmt, ...);
- //same thing but without formatting basically
- inline u8* copy(const char* str)
- { return (u8*)strnCpy((char*)_fmtBuffer, str, _fmtBuffer_len.n); }
- };
- }; /* namespace kit */
- #endif /* _INC__VIDEO_BFONT_SURFACE_HPP */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement