Advertisement
Kitomas

work for 2024-11-21 (3/10)

Nov 22nd, 2024
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 31.04 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"2024-11-21\src\kit_sdl2\kit_EventWatch.cpp":
  4. #include "_kit_common.hpp"
  5.  
  6.  
  7. namespace kit {
  8.  
  9.  
  10.  
  11.  
  12.  
  13. //found in "kit_func_convertEvent.cpp"
  14. bool _convertEvent(SDL_Event& e_sdl, Event& e_kit);
  15.  
  16.  
  17.  
  18.  
  19.  
  20. static int _EventWatchCallbackWrapper(void* EventWatch_ptr, SDL_Event* e_sdl){
  21.   //ignore all poll sentinel events
  22.   if(e_sdl->type == SDL_POLLSENTINEL) return 0;
  23.  
  24.   //if _disabled is nonzero, exit early
  25.   if(KIT_GET_CLASS_DATA(EventWatch_ptr)&0xff) return 0;
  26.  
  27.   EventWatchCallback callback = (EventWatchCallback)KIT_GET_CLASS_OPAQUE(EventWatch_ptr);
  28.   void*              userdata = KIT_GET_CLASS_OPAQUE2(EventWatch_ptr);
  29.  
  30.  
  31.   Event e_kit;
  32.  
  33.   //only invoke callback if event conversion was successful
  34.   if(_convertEvent(*e_sdl, e_kit)  &&  callback != nullptr){
  35.     try {
  36.       callback(e_kit, userdata);
  37.  
  38.     } catch(const char* errortext){
  39.       kit_LogError("IN EVENTWATCH CALLBACK: \"%s\"", errortext);
  40.       freeThreadErrors();
  41.  
  42.     }
  43.  
  44.   }
  45.  
  46.   return 0;
  47.  
  48. }
  49.  
  50.  
  51.  
  52.  
  53.  
  54. EventWatch::EventWatch(EventWatchCallback callback, void* userdata,
  55.                        EventWatchDestructorCallback onDestruction)
  56. {
  57.   if(_valid) return;
  58.   _type = KIT_CLASSTYPE_EVENTWATCH;
  59.  
  60.   if(callback == nullptr)
  61.     THROW_ERROR("EventWatch::EventWatch(): callback = nullptr");
  62.  
  63.   _callback      = callback;
  64.   _userdata      = userdata;
  65.   _onDestruction = onDestruction;
  66.  
  67.   SDL_AddEventWatch(_EventWatchCallbackWrapper, this);
  68.  
  69.   _valid = true;
  70.   _constructing = false;
  71.  
  72. }
  73.  
  74.  
  75.  
  76.  
  77. EventWatch::~EventWatch(){
  78.   if(!_valid) return;
  79.   _valid = false;
  80.  
  81.   SDL_DelEventWatch(_EventWatchCallbackWrapper, this);
  82.  
  83.   if(_onDestruction != nullptr)
  84.     _onDestruction(_userdata);
  85.  
  86. }
  87.  
  88.  
  89.  
  90.  
  91.  
  92. }; /* namespace kit */
  93. /******************************************************************************/
  94. /******************************************************************************/
  95. //"2024-11-21\src\kit_sdl2\kit_fileio.cpp":
  96. #include "_kit_common.hpp"
  97.  
  98.  
  99. #if defined(_WIN32)
  100.   #include <windows.h>
  101.  
  102. #else
  103.   int remove(const char *); //only used by fileio::remove
  104.   //a wrapper; fileio::remove and remove are treated as the same inside fileio
  105.   static inline int _remove(const char* filePath){ return remove(filePath); }
  106.  
  107. #endif /* _WIN32 */
  108.  
  109.  
  110. namespace kit {
  111.  
  112.  
  113.  
  114.  
  115.  
  116. BinaryData::BinaryData(const char* filePath){
  117.   if(_valid) return;
  118.   _type = KIT_CLASSTYPE_BINARYDATA;
  119.  
  120.  
  121.   _data = (char*)SDL_LoadFile(filePath, &_data_size);
  122.   if(_data == nullptr)
  123.     THROW_ERRORF("BinaryData::BinaryData(file): \"%s\"", SDL_GetError());
  124.  
  125.   //numAllocations is explicitly incremented here, since the other constructor
  126.    //calls memory::alloc, which does that automatically
  127.   //both SDL_LoadFile and memory::alloc use SDL_malloc to allocate memory,
  128.    //numAllocations will be decremented in the destructor properly either way
  129.   ++numAllocations;
  130.  
  131.  
  132.   _valid = true;
  133.   _constructing = false;
  134.  
  135. }
  136.  
  137.  
  138.  
  139.  
  140. BinaryData::BinaryData(const void* data, size_t data_size){
  141.   if(_valid) return;
  142.   _type = KIT_CLASSTYPE_BINARYDATA;
  143.  
  144.   if(data_size == KIT_U64_MAX)
  145.     THROW_ERROR("BinaryData::BinaryData(memory): data_size = KIT_U64_MAX"); //lol
  146.  
  147.  
  148.   _data = (char*)memory::alloc(data_size+1);
  149.   if(_data == nullptr)
  150.     THROW_ERROR("BinaryData::BinaryData(memory): failed to allocate memory for _data");
  151.  
  152.  
  153.   _data_size = data_size;
  154.   _data[data_size] = 0; //add null-terminator for convenience
  155.  
  156.   if(data != nullptr) memory::copy(_data, data, data_size);
  157.  
  158.  
  159.   _valid = true;
  160.   _constructing = false;
  161.  
  162. }
  163.  
  164.  
  165.  
  166.  
  167. BinaryData::~BinaryData(){
  168.   if(!_valid) return;
  169.   _valid = false;
  170.  
  171.  
  172.   if(_data != nullptr) memory::free(&_data);
  173.  
  174. }
  175.  
  176.  
  177.  
  178.  
  179.  
  180. //unlike the other fileio functions and whatnot,
  181.  //this obviously doesn't throw if the file doesn't exist
  182. bool fileio::exists(const char* filePath){
  183.   if(filePath == nullptr)
  184.     THROW_ERROR("fileio::exists(): filePath = nullptr");
  185.  
  186.   SDL_RWops* file = SDL_RWFromFile(filePath, "rb");
  187.  
  188.   if(file != nullptr)
  189.     SDL_RWclose(file);
  190.  
  191.   return file != nullptr;
  192.  
  193. }
  194.  
  195.  
  196.  
  197. size_t fileio::size(const char* filePath){
  198.   if(filePath == nullptr)
  199.     THROW_ERROR("fileio::size(): filePath = nullptr");
  200.  
  201.   SDL_RWops* file = SDL_RWFromFile(filePath, "rb");
  202.   if(file == nullptr)
  203.     THROW_ERRORF("fileio::size(): \"%s\"", SDL_GetError());
  204.  
  205.   if(SDL_RWseek(file, 0, RW_SEEK_END)<0){
  206.     SDL_RWclose(file);
  207.     THROW_ERRORF("fileio::size(): \"%s\"", SDL_GetError());
  208.   }
  209.  
  210.   s64 fileSize = SDL_RWtell(file);
  211.   if(fileSize < 0){
  212.     //since SDL_RWclose() can overwrite the previous result of SDL_GetError(),
  213.      //the result of fstr is cached before SDL_RWclose() is actually called
  214.     const char* fstr_result = fstr("fileio::size(): \"%s\"", SDL_GetError());
  215.  
  216.     SDL_RWclose(file);
  217.  
  218.     THROW_ERROR(fstr_result);
  219.  
  220.   }
  221.  
  222.   SDL_RWclose(file);
  223.  
  224.   return (size_t)fileSize;
  225.  
  226. }
  227.  
  228.  
  229.  
  230. void fileio::remove(const char* filePath){
  231.   if(filePath == nullptr)
  232.     THROW_ERROR("fileio::remove(): filePath = nullptr");
  233.  
  234. #if defined(_WIN32)
  235.   if(DeleteFileA(filePath) == FALSE)
  236. #else
  237.   if(_remove(filePath) != 0) //this is a wrapper for remove() (see line 9)
  238. #endif /* _WIN32 */
  239.     THROW_ERRORF("fileio::remove(): failed to delete file \"%s\"", filePath);
  240.  
  241. }
  242.  
  243.  
  244.  
  245.  
  246.  
  247. //heap memory is allocated here,
  248.  //and should be freed with memory::free()
  249.  //(also, while *dataSize_p won't be populated with resulting
  250.  // filesize if dataSize_p is nullptr, it won't actually error)
  251. void* fileio::readAll(const char* filePath, size_t* dataSize_p){
  252.   if(filePath == nullptr)
  253.     THROW_ERROR("fileio::readAll(): filePath = nullptr");
  254.  
  255.   void* data = SDL_LoadFile(filePath, dataSize_p);
  256.  
  257.   if(data == nullptr)
  258.     THROW_ERRORF("fileio::readAll(): \"%s\"", SDL_GetError());
  259.  
  260.   ++numAllocations; //memory::free'ing data should undo this
  261.  
  262.   return data;
  263.  
  264. }
  265.  
  266.  
  267.  
  268. //writes to a binary file from a buffer
  269. void fileio::writeAll(const char* filePath, const void* data,
  270.                        size_t dataSize, bool append)
  271. {
  272.   if(filePath == nullptr) THROW_ERROR("fileio::writeAll(): filePath = nullptr");
  273.   if(data     == nullptr) THROW_ERROR("fileio::writeAll(): data = nullptr");
  274.  
  275.   SDL_RWops* file = SDL_RWFromFile(filePath, (append) ? "ab" : "wb");
  276.   if(file == nullptr){
  277.     _throw_sdlerr:
  278.     THROW_ERRORF("fileio::writeAll(): \"%s\"", SDL_GetError());
  279.   }
  280.  
  281.   size_t bytesWritten = SDL_RWwrite(file, data, 1, dataSize);
  282.  
  283.   SDL_RWclose(file);
  284.  
  285.   if(bytesWritten < dataSize){
  286.     SDL_SetError("bytesWritten < dataSize");
  287.     goto _throw_sdlerr;
  288.   }
  289.  
  290. }
  291.  
  292.  
  293.  
  294.  
  295.  
  296. }; /* namespace kit */
  297. /******************************************************************************/
  298. /******************************************************************************/
  299. //"2024-11-21\src\kit_sdl2\kit_fileio_File.cpp":
  300. #include "_kit_common.hpp"
  301.  
  302.  
  303. #define KIT_IS_INVALID_FILE (!_valid)
  304. #define KIT_FILE_CHECK(_funcName) \
  305.   if(KIT_IS_INVALID_FILE){ THROW_ERROR(_funcName ": invalid File");           } \
  306.   if(_file == nullptr   ){ THROW_ERROR(_funcName ": _file = nullptr");        } \
  307.   if(_closed            ){ THROW_ERROR(_funcName ": file is already closed"); }
  308.  
  309. #define FILE_PTR ((SDL_RWops*)_file)
  310. #define SIZE()                               size(FILE_PTR)
  311. #define READ(_elems, _elemSize, _elems_len)  read(FILE_PTR, _elems, _elemSize, _elems_len)
  312. #define WRITE(_elems, _elemSize, _elems_len) write(FILE_PTR, _elems, _elemSize, _elems_len)
  313. #define SEEK(_off, _whence)                  seek(FILE_PTR, _off, _whence)
  314. #define TELL()                               seek(FILE_PTR, 0, RW_SEEK_CUR)
  315. #define CLOSE()                              close(FILE_PTR)
  316.  
  317.  
  318. namespace kit {
  319.  
  320.  
  321.  
  322.  
  323.  
  324. File::File(const char* filePath, const char* mode){
  325.   if(_valid) return;
  326.   _type = KIT_CLASSTYPE_FILE;
  327.  
  328.   _file = (GenOpqPtr)SDL_RWFromFile(filePath, mode);
  329.   if(_file == nullptr) THROW_ERRORF("File::File(): \"%s\"", SDL_GetError());
  330.  
  331.   _valid = true;
  332.   _constructing = false;
  333.  
  334. }
  335.  
  336.  
  337.  
  338.  
  339.  
  340. File::~File(){
  341.   if(!_valid) return;
  342.   _valid = false;
  343.  
  344.   if(_file != nullptr){
  345.     _zombie = FILE_PTR->CLOSE()<0;
  346.     _file = nullptr;
  347.   }
  348.  
  349. }
  350.  
  351.  
  352.  
  353.  
  354.  
  355. size_t File::read(void* elements, size_t elementSize, size_t elements_len){
  356.   KIT_FILE_CHECK("File::read()");
  357.  
  358.   size_t result = FILE_PTR->READ(elements, elementSize, elements_len);
  359.   if(!result && !strnCmp("Error", SDL_GetError()))
  360.     THROW_ERRORF("File::read(): \"%s\"", SDL_GetError());
  361.  
  362.   return result;
  363.  
  364. }
  365.  
  366.  
  367.  
  368.  
  369.  
  370. void File::write(const void* elements, size_t elementSize, size_t elements_len){
  371.   KIT_FILE_CHECK("File::write()");
  372.  
  373.   size_t result = FILE_PTR->WRITE(elements, elementSize, elements_len);
  374.   if(result < elements_len)
  375.     THROW_ERRORF("File::write(): \"%s\"", SDL_GetError());
  376.  
  377. }
  378.  
  379.  
  380.  
  381.  
  382.  
  383. size_t File::seek(s64 offset, u32 whence){
  384.   KIT_FILE_CHECK("File::seek()");
  385.  
  386.   if(whence > 2) THROW_ERROR("File::seek(): whence is invalid");
  387.  
  388.   s64 result = FILE_PTR->SEEK(offset, whence);
  389.   if(result < 0) THROW_ERRORF("File::seek(): \"%s\"", SDL_GetError());
  390.  
  391.   return (size_t)result;
  392.  
  393. }
  394.  
  395.  
  396.  
  397.  
  398.  
  399. void File::close(){
  400.   KIT_FILE_CHECK("File::close()");
  401.  
  402.   if(FILE_PTR->CLOSE() < 0)
  403.     THROW_ERROR("File::close(): write error occurred while flushing data");
  404.  
  405.   _closed = true;
  406.   _file   = nullptr;
  407.  
  408. }
  409.  
  410.  
  411.  
  412.  
  413.  
  414. size_t File::size(){
  415.   KIT_FILE_CHECK("File::size()");
  416.  
  417.   s64 result = FILE_PTR->SIZE();
  418.   if(result < 0)
  419.     THROW_ERROR("File::size(): failed to get file's size");
  420.  
  421.   return (size_t)result;
  422.  
  423. }
  424.  
  425.  
  426.  
  427.  
  428.  
  429. }; /* namespace kit */
  430. /******************************************************************************/
  431. /******************************************************************************/
  432. //"2024-11-21\src\kit_sdl2\kit_func.cpp":
  433. #include "_kit_common.hpp"
  434. #include "../stb_sprintf/stb_sprintf.hpp"
  435.  
  436.  
  437. namespace kit {
  438.  
  439.  
  440.  
  441.  
  442.  
  443. void Log(LogPriorityEnum priority, const char* fmt, ...){
  444.   //(unnecessary?)
  445.   //if(priority == 0  ||  priority > LOG_PRIORITY_CRITICAL)
  446.   //  THROW_ERROR("Log(): unknown priority");
  447.  
  448.   va_list args;
  449.   va_start(args, fmt);
  450.   SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, (SDL_LogPriority)priority, fmt, args);
  451.   va_end(args);
  452.  
  453. }
  454.  
  455.  
  456.  
  457.  
  458.  
  459. //(len_max does not include null-terminator!)
  460. //(if !len_max, call is analogous to str(not n)len)
  461. size_t strnLen(const char* str, size_t len_max){
  462.   //if(str == nullptr) THROW_ERROR("strnLen(): str = nullptr");
  463.  
  464.   size_t len = 0;
  465.  
  466.   if(!len_max){
  467.     for(; str[len]; ++len);
  468.  
  469.   } else {
  470.     for(; str[len] && len<len_max; ++len);
  471.  
  472.   }
  473.  
  474.   return len;
  475.  
  476. }
  477.  
  478.  
  479.  
  480.  
  481. //(len_max does not include null-terminator!)
  482. //(if !len_max, call is analogous to str(not n)cmp)
  483. s32 strnCmp(const char* str_a, const char* str_b, size_t len_max){
  484.   //might uncomment these, maybe not though
  485.   //if(str_a == nullptr) THROW_ERROR("strnCmp(): str_a = nullptr");
  486.   //if(str_b == nullptr) THROW_ERROR("strnCmp(): str_b = nullptr");
  487.  
  488.   if(!len_max){
  489.     while(*str_a && (*str_a == *str_b))
  490.       ++str_a, ++str_b;
  491.  
  492.   } else {
  493.     --len_max;
  494.     while(*str_a && (*str_a == *str_b) && len_max)
  495.       ++str_a, ++str_b, --len_max;
  496.  
  497.   }
  498.  
  499.   return (*(const u8*)str_a) - (*(const u8*)str_b);
  500.  
  501. }
  502.  
  503.  
  504.  
  505.  
  506. char* strnCpy(char* str_dst, const char* str_src, size_t len_max){
  507.   char* _str_dst = str_dst; //copy original state of str_dst
  508.  
  509.   if(!len_max){
  510.     while((*str_dst++ = *str_src++));
  511.  
  512.   } else {
  513.     size_t i = 0;
  514.     while(i++ != len_max && (*str_dst++ = *str_src++));
  515.  
  516.   }
  517.  
  518.  
  519.   *str_dst = 0; //null-terminator
  520.  
  521.   return _str_dst;
  522.  
  523. }
  524.  
  525.  
  526.  
  527.  
  528.  
  529. s32 snPrintf(char* str_dst, size_t len_max, const char* str_fmt, ...){
  530.   va_list va;
  531.   va_start(va, str_fmt);
  532.  
  533.   if(len_max > 0  &&  len_max <= KIT_S32_MAX){
  534.     return stbsp_vsnprintf(str_dst, (int)len_max, str_fmt, va);
  535.  
  536.   } else {
  537.     return stbsp_vsprintf(str_dst, str_fmt, va);
  538.  
  539.   }
  540.  
  541.   va_end(va);
  542.  
  543. }
  544.  
  545.  
  546.  
  547.  
  548. s32 vsnPrintf(char* str_dst, size_t len_max, const char* str_fmt, va_list va){
  549.   if(len_max > 0  &&  len_max <= KIT_S32_MAX){
  550.     return stbsp_vsnprintf(str_dst, (int)len_max, str_fmt, va);
  551.  
  552.   } else {
  553.     return stbsp_vsprintf(str_dst, str_fmt, va);
  554.  
  555.   }
  556.  
  557. }
  558.  
  559.  
  560.  
  561.  
  562.  
  563. const char* getLastSysError(){
  564.   return SDL_GetError();
  565.  
  566. }
  567.  
  568.  
  569.  
  570. void clearSysError(){
  571.   SDL_ClearError();
  572.  
  573. }
  574.  
  575.  
  576.  
  577. void freeThreadErrors(){
  578.   while(_freeError()); //frees errors of *current* thread
  579.  
  580. }
  581.  
  582.  
  583.  
  584.  
  585.  
  586. #define MSGBOX_EWI_FLAGS (MSGBOX_ERROR|MSGBOX_WARNING|MSGBOX_INFO)
  587.  
  588. void showMsgBox(const char* text, const char* title, u32 flags, Window* win){
  589.   flags &= MSGBOX_EWI_FLAGS;
  590.  
  591.   SDL_Window* win_sdl = nullptr;
  592.   if(win != nullptr){
  593.     if(KIT_GET_CLASS_TYPE(win) != KIT_CLASSTYPE_WINDOW)
  594.       THROW_ERROR("showMsgBoxSimple(): win does not point to a Window object");
  595.     win_sdl = (SDL_Window*)KIT_GET_CLASS_OPAQUE(win);
  596.   }
  597.  
  598.   if(SDL_ShowSimpleMessageBox(flags, title, text, win_sdl)<0)
  599.     THROW_ERRORF("showMsgBoxSimple(): \"%s\"", SDL_GetError());
  600.  
  601. }
  602.  
  603.  
  604.  
  605.  
  606.  
  607. bool clipboardHasText(){
  608.   return SDL_HasClipboardText();
  609.  
  610. }
  611.  
  612.  
  613.  
  614. char* clipboardGetText(){
  615.   char* txt = SDL_GetClipboardText();
  616.  
  617.   //txt will be an empty string on error
  618.   if(!txt[0]){
  619.     //according to the SDL2 wiki, you need to
  620.      //free the returned pointer, even on error
  621.     SDL_free(txt);
  622.  
  623.     THROW_ERRORF("clipboardGetText(): \"%s\"", SDL_GetError());
  624.  
  625.   }
  626.  
  627.   ++numAllocations; //a subsequent call to memory::free should undo this
  628.  
  629.   return txt;
  630.  
  631. }
  632.  
  633.  
  634.  
  635. void clipboardSetText(const char* txt){
  636.   if(SDL_SetClipboardText(txt)<0)
  637.     THROW_ERRORF("clipboardSetText(): \"%s\"", SDL_GetError());
  638.  
  639. }
  640.  
  641.  
  642.  
  643.  
  644.  
  645. bool showCursor(s32 toggle){
  646.   s32 result = SDL_ShowCursor((toggle < 0) ? -1 : toggle&1);
  647.  
  648.   if(result < 0)
  649.     THROW_ERRORF("showCursor(): \"%s\"", SDL_GetError());
  650.  
  651.   return (bool)result;
  652.  
  653. }
  654.  
  655.  
  656.  
  657.  
  658.  
  659. void warpMouseGlobal(s32 x, s32 y){
  660.   if(SDL_WarpMouseGlobal(x, y) < 0)
  661.     THROW_ERRORF("warpMouseGlobal(): \"%s\"", SDL_GetError());
  662.  
  663. }
  664.  
  665.  
  666.  
  667.  
  668.  
  669. bool getRelativeMouseMode(){
  670.   return SDL_GetRelativeMouseMode() != 0;
  671.  
  672. }
  673.  
  674.  
  675.  
  676.  
  677.  
  678. void setRelativeMouseMode(bool enable){
  679.   if(SDL_SetRelativeMouseMode((SDL_bool)enable) < 0)
  680.     THROW_ERRORF("setRelativeMouseMode(): %s", SDL_GetError());
  681.  
  682. }
  683.  
  684.  
  685.  
  686.  
  687.  
  688. }; /* namespace kit */
  689. /******************************************************************************/
  690. /******************************************************************************/
  691. //"2024-11-21\src\kit_sdl2\kit_func_convertEvent.cpp":
  692. #include "_kit_common.hpp"
  693.  
  694. #define ETYPE(_event_type) e_kit.common.type = _event_type
  695.  
  696.  
  697. namespace kit {
  698.  
  699.  
  700.  
  701.  
  702.  
  703. //returns false if that sdl event is unsupported or is otherwise unknown
  704. bool _convertEvent(SDL_Event& e_sdl, Event& e_kit){
  705.   e_kit.common.timestamp = e_sdl.common.timestamp;
  706.  
  707.  
  708.   switch(e_sdl.type){
  709.     case SDL_QUIT:  ETYPE(KEVENT_QUIT);  break;
  710.  
  711.  
  712.  
  713.     case SDL_DISPLAYEVENT:
  714.     {
  715.       switch(e_sdl.display.event){
  716.         case SDL_DISPLAYEVENT_ORIENTATION :  ETYPE(KEVENT_DISPLAY_ORIENTATION );  break;
  717.         case SDL_DISPLAYEVENT_CONNECTED   :  ETYPE(KEVENT_DISPLAY_CONNECTED   );  break;
  718.         case SDL_DISPLAYEVENT_DISCONNECTED:  ETYPE(KEVENT_DISPLAY_DISCONNECTED);  break;
  719.         case SDL_DISPLAYEVENT_MOVED       :  ETYPE(KEVENT_DISPLAY_MOVED       );  break;
  720.         default                           :  return false; //this shouldn't happen
  721.       }
  722.       e_kit.display.id   = e_sdl.display.display;
  723.       e_kit.display.data = e_sdl.display.data1;
  724.     } break;
  725.  
  726.  
  727.  
  728.     case SDL_WINDOWEVENT:
  729.     {
  730.       switch(e_sdl.window.event){
  731.         case SDL_WINDOWEVENT_SHOWN          :  ETYPE(KEVENT_WIN_SHOWN          );  break;
  732.         case SDL_WINDOWEVENT_HIDDEN         :  ETYPE(KEVENT_WIN_HIDDEN         );  break;
  733.         case SDL_WINDOWEVENT_EXPOSED        :  ETYPE(KEVENT_WIN_EXPOSED        );  break;
  734.         case SDL_WINDOWEVENT_MOVED          :  ETYPE(KEVENT_WIN_MOVED          );  break;
  735.         case SDL_WINDOWEVENT_RESIZED        :  ETYPE(KEVENT_WIN_RESIZED        );  break;
  736.         case SDL_WINDOWEVENT_SIZE_CHANGED   :  ETYPE(KEVENT_WIN_SIZE_CHANGED   );  break;
  737.         case SDL_WINDOWEVENT_MINIMIZED      :  ETYPE(KEVENT_WIN_MINIMIZED      );  break;
  738.         case SDL_WINDOWEVENT_MAXIMIZED      :  ETYPE(KEVENT_WIN_MAXIMIZED      );  break;
  739.         case SDL_WINDOWEVENT_RESTORED       :  ETYPE(KEVENT_WIN_RESTORED       );  break;
  740.         case SDL_WINDOWEVENT_ENTER          :  ETYPE(KEVENT_WIN_MFOCUS_GAINED  );  break;
  741.         case SDL_WINDOWEVENT_LEAVE          :  ETYPE(KEVENT_WIN_MFOCUS_LOST    );  break;
  742.         case SDL_WINDOWEVENT_FOCUS_GAINED   :  ETYPE(KEVENT_WIN_KFOCUS_GAINED  );  break;
  743.         case SDL_WINDOWEVENT_FOCUS_LOST     :  ETYPE(KEVENT_WIN_KFOCUS_LOST    );  break;
  744.         case SDL_WINDOWEVENT_CLOSE          :  ETYPE(KEVENT_WIN_CLOSE          );  break;
  745.         case SDL_WINDOWEVENT_TAKE_FOCUS     :  ETYPE(KEVENT_WIN_TAKE_FOCUS     );  break;
  746.         case SDL_WINDOWEVENT_HIT_TEST       :  ETYPE(KEVENT_WIN_HIT_TEST       );  break;
  747.         case SDL_WINDOWEVENT_ICCPROF_CHANGED:  ETYPE(KEVENT_WIN_ICCPROF_CHANGED);  break;
  748.         case SDL_WINDOWEVENT_DISPLAY_CHANGED:  ETYPE(KEVENT_WIN_DISPLAY_CHANGED);  break;
  749.         default                             :  return false; //this shouldn't happen
  750.       }
  751.       e_kit.win.id    = e_sdl.window.windowID;
  752.       e_kit.win.data1 = e_sdl.window.data1;
  753.       e_kit.win.data2 = e_sdl.window.data2;
  754.     } break;
  755.  
  756.  
  757.  
  758.     case SDL_KEYDOWN:  ETYPE(KEVENT_KEY_DOWN);  goto _event_key;
  759.     case SDL_KEYUP  :  ETYPE(KEVENT_KEY_UP  );       _event_key:
  760.     {
  761.       e_kit.key.window  = e_sdl.key.windowID;
  762.       e_kit.key.pressed = e_sdl.key.state == SDL_PRESSED;
  763.       e_kit.key.repeat  = e_sdl.key.repeat != 0;
  764.       e_kit.key.vkey    = e_sdl.key.keysym.sym;
  765.       e_kit.key.pkey    = e_sdl.key.keysym.scancode;
  766.       e_kit.key.kmods   = e_sdl.key.keysym.mod;
  767.     } break;
  768.  
  769.  
  770.  
  771.     //not to be confused with key events, as they are separate
  772.     case SDL_KEYMAPCHANGED:  ETYPE(KEVENT_KEYMAPCHANGED);  break;
  773.  
  774.  
  775.  
  776.     case SDL_MOUSEMOTION    :  ETYPE(KEVENT_MOUSE_MOVED);
  777.     {
  778.       e_kit.mouse.button  = e_sdl.motion.state;
  779.       e_kit.mouse.pressed = e_kit.mouse.button != 0;
  780.       e_kit.mouse.x       = e_sdl.motion.x;
  781.       e_kit.mouse.y       = e_sdl.motion.y;
  782.       e_kit.mouse.dx      = e_sdl.motion.xrel;
  783.       e_kit.mouse.dy      = e_sdl.motion.yrel;
  784.     } goto _set_mouse_common;
  785.  
  786.     case SDL_MOUSEBUTTONDOWN:  ETYPE(KEVENT_MOUSE_DOWN);  goto _event_mouse_bt;
  787.     case SDL_MOUSEBUTTONUP  :  ETYPE(KEVENT_MOUSE_UP  );       _event_mouse_bt:
  788.     {
  789.       //(turn button index into button flag using SDL_BUTTON)
  790.       e_kit.mouse.button   = SDL_BUTTON(e_sdl.button.button);
  791.       e_kit.mouse.pressed  = e_sdl.button.state == SDL_PRESSED;
  792.       e_kit.mouse.dblClick = ((MAX(1,e_sdl.button.clicks)-1)&1) > 0;
  793.       e_kit.mouse.x        = e_sdl.button.x;
  794.       e_kit.mouse.y        = e_sdl.button.y;
  795.     } goto _set_mouse_common;
  796.  
  797.     case SDL_MOUSEWHEEL     :  ETYPE(KEVENT_MOUSE_WHEEL);
  798.     {
  799.       e_kit.mouse.flipped = e_sdl.wheel.direction == SDL_MOUSEWHEEL_FLIPPED;
  800.       e_kit.mouse.x       = e_sdl.wheel.mouseX;
  801.       e_kit.mouse.y       = e_sdl.wheel.mouseY;
  802.       e_kit.mouse.dx      = e_sdl.wheel.x;
  803.       e_kit.mouse.dy      = e_sdl.wheel.y;
  804.       e_kit.mouse.pdx     = e_sdl.wheel.preciseX;
  805.       e_kit.mouse.pdy     = e_sdl.wheel.preciseY;
  806.     } //goto _set_mouse_common; //(redundant)
  807.  
  808.     _set_mouse_common: //(common to all Mouse events)
  809.     {
  810.       e_kit.mouse.window = e_sdl.motion.windowID;
  811.     } break;
  812.  
  813.  
  814.  
  815.     case SDL_JOYAXISMOTION    :  ETYPE(KEVENT_JOY_AXIS          );
  816.     {
  817.       e_kit.joy.axis.which = e_sdl.jaxis.axis;
  818.       e_kit.joy.axis.value = e_sdl.jaxis.value;
  819.     } goto _set_joy_common;
  820.  
  821.     case SDL_JOYBALLMOTION    :  ETYPE(KEVENT_JOY_TRACKBALL     );
  822.     {
  823.       e_kit.joy.trackball.which = e_sdl.jball.ball;
  824.       e_kit.joy.trackball.dx    = e_sdl.jball.xrel;
  825.       e_kit.joy.trackball.dy    = e_sdl.jball.yrel;
  826.     } goto _set_joy_common;
  827.  
  828.     case SDL_JOYHATMOTION     :  ETYPE(KEVENT_JOY_HAT           );
  829.     {
  830.       e_kit.joy.hat.which = e_sdl.jhat.hat;
  831.       e_kit.joy.hat.value = e_sdl.jhat.value;
  832.     } goto _set_joy_common;
  833.  
  834.     case SDL_JOYBUTTONDOWN    :  ETYPE(KEVENT_JOY_BUTTON_DOWN   );  goto _event_joy_bt;
  835.     case SDL_JOYBUTTONUP      :  ETYPE(KEVENT_JOY_BUTTON_UP     );       _event_joy_bt:
  836.     {
  837.       e_kit.joy.button.which   = e_sdl.jbutton.button;
  838.       e_kit.joy.button.pressed = e_sdl.jbutton.state == SDL_PRESSED;
  839.     } goto _set_joy_common;
  840.  
  841.     case SDL_JOYDEVICEADDED   :  ETYPE(KEVENT_JOY_DEVICE_ADDED  );  goto _event_joy_dv;
  842.     case SDL_JOYDEVICEREMOVED :  ETYPE(KEVENT_JOY_DEVICE_REMOVED);       _event_joy_dv:
  843.     {
  844.       e_kit.joy.device.added = e_sdl.jdevice.type == SDL_JOYDEVICEADDED;
  845.     } goto _set_joy_common;
  846.  
  847.     case SDL_JOYBATTERYUPDATED:  ETYPE(KEVENT_JOY_BATTERY       );
  848.     {
  849.       e_kit.joy.battery.level = e_sdl.jbattery.level;
  850.     } //goto _set_joy_common; //redundant
  851.  
  852.     _set_joy_common: //(common to all Joystick events)
  853.     {
  854.       e_kit.joy.id = e_sdl.jdevice.which;
  855.     } break;
  856.  
  857.  
  858.  
  859.     case SDL_CONTROLLERAXISMOTION    :  ETYPE(KEVENT_CTLR_AXIS           );
  860.     {
  861.       e_kit.ctlr.axis.which = e_sdl.caxis.axis;
  862.       e_kit.ctlr.axis.value = e_sdl.caxis.value;
  863.     } goto _set_ctlr_common;
  864.  
  865.     case SDL_CONTROLLERBUTTONDOWN    :  ETYPE(KEVENT_CTLR_BUTTON_DOWN    );  goto _event_ctlr_bt;
  866.     case SDL_CONTROLLERBUTTONUP      :  ETYPE(KEVENT_CTLR_BUTTON_UP      );       _event_ctlr_bt:
  867.     {
  868.       e_kit.ctlr.button.which   = e_sdl.cbutton.button;
  869.       e_kit.ctlr.button.pressed = e_sdl.cbutton.state == SDL_PRESSED;
  870.     } goto _set_ctlr_common;
  871.  
  872.     case SDL_CONTROLLERDEVICEADDED   :  ETYPE(KEVENT_CTLR_DEVICE_ADDED   );  goto _event_ctlr_dv;
  873.     case SDL_CONTROLLERDEVICEREMOVED :  ETYPE(KEVENT_CTLR_DEVICE_REMOVED );  goto _event_ctlr_dv;
  874.     case SDL_CONTROLLERDEVICEREMAPPED:  ETYPE(KEVENT_CTLR_DEVICE_REMAPPED);       _event_ctlr_dv:
  875.     {
  876.       e_kit.ctlr.device.subtype = KIT_SUBEVENT_ID(e_kit.type);
  877.     } goto _set_ctlr_common;
  878.  
  879.     case SDL_CONTROLLERTOUCHPADDOWN  :  ETYPE(KEVENT_CTLR_TOUCHPAD_DOWN  );  goto _event_ctlr_tp;
  880.     case SDL_CONTROLLERTOUCHPADMOTION:  ETYPE(KEVENT_CTLR_TOUCHPAD_MOVED );  goto _event_ctlr_tp;
  881.     case SDL_CONTROLLERTOUCHPADUP    :  ETYPE(KEVENT_CTLR_TOUCHPAD_UP    );       _event_ctlr_tp:
  882.     {
  883.       e_kit.ctlr.touchpad.which    = e_sdl.ctouchpad.touchpad;
  884.       e_kit.ctlr.touchpad.finger   = e_sdl.ctouchpad.finger;
  885.       e_kit.ctlr.touchpad.x        = e_sdl.ctouchpad.x;
  886.       e_kit.ctlr.touchpad.y        = e_sdl.ctouchpad.y;
  887.       e_kit.ctlr.touchpad.pressure = e_sdl.ctouchpad.pressure;
  888.     } goto _set_ctlr_common;
  889.  
  890.     case SDL_CONTROLLERSENSORUPDATE  :  ETYPE(KEVENT_CTLR_SENSOR         );
  891.     {
  892.       e_kit.ctlr.sensor.which        = e_sdl.csensor.sensor;
  893.       e_kit.ctlr.sensor.data[0]      = e_sdl.csensor.data[0];
  894.       e_kit.ctlr.sensor.data[1]      = e_sdl.csensor.data[1];
  895.       e_kit.ctlr.sensor.data[2]      = e_sdl.csensor.data[2];
  896.       e_kit.ctlr.sensor.timestamp_us = e_sdl.csensor.timestamp_us;
  897.     } //goto _set_ctlr_common; //(redundant)
  898.  
  899.     _set_ctlr_common: //(common to all GameController events)
  900.     {
  901.       e_kit.ctlr.id = e_sdl.cdevice.which;
  902.     } break;
  903.  
  904.  
  905.  
  906.     case SDL_CLIPBOARDUPDATE:  ETYPE(KEVENT_CLIPBOARDUPDATE);  break;
  907.  
  908.  
  909.  
  910.     case SDL_DROPFILE    :  ETYPE(KEVENT_DROP_FILE    );  goto _event_drop;
  911.     case SDL_DROPTEXT    :  ETYPE(KEVENT_DROP_TEXT    );  goto _event_drop;
  912.     case SDL_DROPBEGIN   :  ETYPE(KEVENT_DROP_BEGIN   );  goto _event_drop;
  913.     case SDL_DROPCOMPLETE:  ETYPE(KEVENT_DROP_COMPLETE);       _event_drop:
  914.     {
  915.       e_kit.drop.window   = e_sdl.drop.windowID;
  916.       e_kit.drop.filePath = e_sdl.drop.file;
  917.     } break;
  918.  
  919.  
  920.  
  921.     case SDL_AUDIODEVICEADDED  :  ETYPE(KEVENT_ADEV_ADDED  );  goto _event_adev;
  922.     case SDL_AUDIODEVICEREMOVED:  ETYPE(KEVENT_ADEV_REMOVED);       _event_adev:
  923.     {
  924.       e_kit.adev.id      = e_sdl.adevice.which;
  925.       e_kit.adev.isInput = e_sdl.adevice.iscapture;
  926.     } break;
  927.  
  928.  
  929.  
  930.     case SDL_RENDER_TARGETS_RESET:  ETYPE(KEVENT_RENDER_TARGETS_RESET);  break;
  931.     case SDL_RENDER_DEVICE_RESET :  ETYPE(KEVENT_RENDER_DEVICE_RESET );  break;
  932.  
  933.  
  934.  
  935.     case SDL_USEREVENT:  ETYPE(KEVENT_USER);
  936.     {
  937.       e_kit.user.window = e_sdl.user.windowID;
  938.       e_kit.user.id     = e_sdl.user.code;
  939.       e_kit.user.data1  = e_sdl.user.data1;
  940.       e_kit.user.data2  = e_sdl.user.data2;
  941.     } break;
  942.  
  943.  
  944.  
  945.     //event is not recognized, so return false
  946.     default: return false;
  947.  
  948.   }
  949.  
  950.  
  951.   return true;
  952.  
  953. }
  954.  
  955.  
  956.  
  957.  
  958.  
  959. }; /* namespace kit */
  960. /******************************************************************************/
  961. /******************************************************************************/
  962. //"2024-11-21\src\kit_sdl2\kit_func_CPUCapabilities.cpp":
  963. #include "_kit_common.hpp"
  964.  
  965.  
  966. namespace kit {
  967.  
  968.  
  969.  
  970.  
  971.  
  972. u32 getCPUCapabilities(){
  973.   if(!_gl.CPUCapabilities){
  974.     if(SDL_HasRDTSC  ()) _gl.CPUCapabilities |= CPU_HAS_RDTSC;
  975.     if(SDL_HasAltiVec()) _gl.CPUCapabilities |= CPU_HAS_ALTIVEC;
  976.     if(SDL_HasMMX    ()) _gl.CPUCapabilities |= CPU_HAS_MMX;
  977.     if(SDL_Has3DNow  ()) _gl.CPUCapabilities |= CPU_HAS_3DNOW;
  978.     if(SDL_HasSSE    ()) _gl.CPUCapabilities |= CPU_HAS_SSE;
  979.     if(SDL_HasSSE2   ()) _gl.CPUCapabilities |= CPU_HAS_SSE2;
  980.     if(SDL_HasSSE3   ()) _gl.CPUCapabilities |= CPU_HAS_SSE3;
  981.     if(SDL_HasSSE41  ()) _gl.CPUCapabilities |= CPU_HAS_SSE41;
  982.     if(SDL_HasSSE42  ()) _gl.CPUCapabilities |= CPU_HAS_SSE42;
  983.     if(SDL_HasAVX    ()) _gl.CPUCapabilities |= CPU_HAS_AVX;
  984.     if(SDL_HasAVX512F()) _gl.CPUCapabilities |= CPU_HAS_AVX512F;
  985.     if(SDL_HasARMSIMD()) _gl.CPUCapabilities |= CPU_HAS_ARMSIMD;
  986.     if(SDL_HasNEON   ()) _gl.CPUCapabilities |= CPU_HAS_NEON;
  987.     if(SDL_HasLSX    ()) _gl.CPUCapabilities |= CPU_HAS_LSX;
  988.     if(SDL_HasLASX   ()) _gl.CPUCapabilities |= CPU_HAS_LASX;
  989.   }
  990.  
  991.   return _gl.CPUCapabilities;
  992.  
  993. }
  994.  
  995.  
  996.  
  997.  
  998.  
  999. u32 getCPUCacheLineSize(){
  1000.   return SDL_GetCPUCacheLineSize();
  1001.  
  1002. }
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008. u32 getNumLogicalCPUCores(){
  1009.   return SDL_GetCPUCount();
  1010.  
  1011. }
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017. }; /* namespace kit */
  1018. /******************************************************************************/
  1019. /******************************************************************************/
  1020. //"2024-11-21\src\kit_sdl2\kit_func_init-quit.cpp":
  1021. #include "_kit_common.hpp"
  1022.  
  1023.  
  1024. namespace kit {
  1025.  
  1026.  
  1027. _globalStates _gl;
  1028. const char _fstr_failure[] = "(FSTR FAILED)";
  1029.  
  1030. const char _boolStr_false[] = "false";
  1031. const char _boolStr_true[]  = "true";
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037. #define FLAG_SET(_flag) (flags&(_flag))
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043. #define SHOULD_INIT(_flag, _member) (FLAG_SET(_flag) && !_gl.init._member)
  1044.  
  1045. #define INIT_CHECK(_sdl_flag) { \
  1046.   if(SDL_InitSubSystem(_sdl_flag)<0){ THROW_ERRORF("initSubsystems(): \"%s\"", SDL_GetError()); } }
  1047.  
  1048. #define KINIT_JOYSTICK_IMPLICIT (0x40)
  1049. #define KINIT_EVENTS_IMPLICIT   (0x80)
  1050.  
  1051. void initSubsystems(u32 flags){
  1052.   SDL_version ver;
  1053.   SDL_GetVersion(&ver);
  1054.  
  1055.   if(ver.major != SDL_MAJOR_VERSION){
  1056.     THROW_ERRORF("kit_sdl%u requires SDL%u, not SDL%u",
  1057.                       SDL_MAJOR_VERSION, SDL_MAJOR_VERSION, ver.major);
  1058.   }
  1059.  
  1060.   if(ver.minor < SDL_MINOR_VERSION) {
  1061.     THROW_ERRORF("SDL%u version must be >= %u.%u.x, not %u.%u.x",
  1062.                       SDL_MAJOR_VERSION,
  1063.                       SDL_MAJOR_VERSION, SDL_MINOR_VERSION,
  1064.                       ver.major, ver.minor);
  1065.   }
  1066.  
  1067.   //just warn instead of error if patch level is less than what it should be
  1068.   if(ver.patch < SDL_PATCHLEVEL  &&  ver.minor == SDL_MINOR_VERSION  &&
  1069.      !_gl.patch_warning_disabled)
  1070.   {
  1071.     _log("\b\b\b\b\b\bWARN: SDL%u patch version should be >= x.x.%u, not x.x.%u",
  1072.          SDL_MAJOR_VERSION, SDL_PATCHLEVEL, ver.patch);
  1073.   }
  1074.  
  1075.  
  1076.   //disable these flags just in case the user set them for whatever reason
  1077.   flags &= ~(KINIT_JOYSTICK_IMPLICIT|KINIT_EVENTS_IMPLICIT);
  1078.  
  1079.  
  1080.  
  1081.   if(SHOULD_INIT(KINIT_TIMER, timer)){
  1082.     INIT_CHECK(SDL_INIT_TIMER);
  1083.     _gl.init.timer = true;
  1084.   }
  1085.  
  1086.  
  1087.  
  1088.   if(SHOULD_INIT(KINIT_AUDIO, audio)){
  1089.     INIT_CHECK(SDL_INIT_AUDIO);
  1090.     _gl.init.audio = true;
  1091.   }
  1092.  
  1093.  
  1094.  
  1095.   if(SHOULD_INIT(KINIT_VIDEO, video)){
  1096.     INIT_CHECK(SDL_INIT_VIDEO);
  1097.     _gl.init.video = true;
  1098.     flags |= KINIT_EVENTS_IMPLICIT; //indicate that events should auto-init
  1099.   }
  1100.  
  1101.  
  1102.  
  1103.   if(SHOULD_INIT(KINIT_GAMECONTROLLER, gamecontroller)){
  1104.     INIT_CHECK(SDL_INIT_GAMECONTROLLER);
  1105.     _gl.init.gamecontroller = true;
  1106.     flags |= KINIT_JOYSTICK_IMPLICIT; //indicate that joystick should auto-init
  1107.   }
  1108.  
  1109.  
  1110.  
  1111.   if(SHOULD_INIT(KINIT_JOYSTICK|KINIT_JOYSTICK_IMPLICIT, joystick)){
  1112.     if(FLAG_SET(KINIT_JOYSTICK)){
  1113.       INIT_CHECK(SDL_INIT_JOYSTICK);
  1114.       _gl.init.joystick_sdl = true;
  1115.     }
  1116.     _gl.init.joystick = true;
  1117.     flags |= KINIT_EVENTS_IMPLICIT; //indicate that events should auto-init
  1118.   }
  1119.  
  1120.  
  1121.  
  1122.   if(SHOULD_INIT(KINIT_EVENTS|KINIT_EVENTS_IMPLICIT, events)){
  1123.     if(FLAG_SET(KINIT_EVENTS)){
  1124.       INIT_CHECK(SDL_INIT_EVENTS);
  1125.       _gl.init.events_sdl = true;
  1126.     }
  1127.     _gl.init.events = true;
  1128.   }
  1129.  
  1130.  
  1131.  
  1132.   bool errors_just_created = false;
  1133.   if(flags && _gl.errors == nullptr){
  1134.     _gl.errors_len = 1;
  1135.     _gl.errors     = (Error*)memory::alloc( sizeof(Error) * _gl.errors_len );
  1136.  
  1137.     if(_gl.errors == nullptr){
  1138.       _gl.errors_len = 0;
  1139.       THROW_ERROR("initSubsystems(): failed to allocate internal memory");
  1140.  
  1141.     }
  1142.  
  1143.     errors_just_created = true;
  1144.  
  1145.     memory::set(_gl.errors, 0, sizeof(Error) * _gl.errors_len );
  1146.  
  1147.   }
  1148.  
  1149.  
  1150.  
  1151.   if(_gl.init_value && _gl.lock == nullptr){
  1152.     _gl.lock = SDL_CreateMutex();
  1153.     if(_gl.lock == nullptr){
  1154.       if(errors_just_created) _freeErrors();
  1155.       THROW_ERROR("initSubsystems(): failed to create internal mutex");
  1156.     }
  1157.   }
  1158.  
  1159. }
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165. #define SHOULD_QUIT(_flag, _member) (FLAG_SET(_flag) && _gl.init._member)
  1166. #define QUIT_SUB(_flag) SDL_QuitSubSystem(_flag)
  1167.  
  1168. void quitSubsystems(u32 flags){
  1169.   flags &= ~(KINIT_JOYSTICK_IMPLICIT|KINIT_EVENTS_IMPLICIT);
  1170.  
  1171.  
  1172.   if(SHOULD_QUIT(KINIT_TIMER, timer)){
  1173.     QUIT_SUB(SDL_INIT_TIMER);
  1174.     _gl.init.timer = false;
  1175.   }
  1176.  
  1177.  
  1178.   if(SHOULD_QUIT(KINIT_AUDIO, audio)){
  1179.     QUIT_SUB(SDL_INIT_AUDIO);
  1180.     _gl.init.audio = false;
  1181.   }
  1182.  
  1183.  
  1184.   if(SHOULD_QUIT(KINIT_VIDEO, video)){
  1185.     QUIT_SUB(SDL_INIT_VIDEO);
  1186.     _gl.init.video = false;
  1187.   }
  1188.  
  1189.  
  1190.   if(SHOULD_QUIT(KINIT_GAMECONTROLLER, gamecontroller)){
  1191.     QUIT_SUB(SDL_INIT_GAMECONTROLLER);
  1192.     _gl.init.gamecontroller = false;
  1193.   }
  1194.  
  1195.  
  1196.   if(SHOULD_QUIT(KINIT_JOYSTICK, joystick)){
  1197.     if(_gl.init.joystick_sdl){
  1198.       QUIT_SUB(SDL_INIT_JOYSTICK);
  1199.       _gl.init.joystick_sdl = false;
  1200.     }
  1201.     _gl.init.joystick = false;
  1202.   }
  1203.  
  1204.  
  1205.   if(SHOULD_QUIT(KINIT_EVENTS, events)){
  1206.     if(_gl.init.events_sdl){
  1207.       QUIT_SUB(SDL_INIT_EVENTS);
  1208.       _gl.init.events_sdl = false;
  1209.     }
  1210.     _gl.init.events = false;
  1211.   }
  1212.  
  1213.  
  1214.  
  1215.   if(!_gl.init_value){
  1216.     _freeErrors();
  1217.  
  1218.     if(_gl.lock != nullptr){
  1219.       LOCK_GLOBALS();   //to lessen the chance that the mutex is destroyed
  1220.       UNLOCK_GLOBALS();  //before all the other threads unlock it (hopefully)
  1221.  
  1222.       SDL_DestroyMutex(_gl.lock);
  1223.       _gl.lock = nullptr;
  1224.  
  1225.     }
  1226.  
  1227.     //apparently you still need to call SDL_Quit,
  1228.      //(even if you've already closed any open subsystems)
  1229.     SDL_Quit();
  1230.  
  1231.   }
  1232.  
  1233. }
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239. }; /* namespace kit */
  1240.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement