Advertisement
Kitomas

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

Nov 22nd, 2024
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.83 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"2024-11-21\src\kit_sdl2\kit_func_pollEvent.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. bool pollEvent(Event* event_p){
  21.   if(!_gl.init.events)
  22.     THROW_ERROR("pollEvent(): events subsystem is uninitialized");
  23.  
  24.   SDL_Event e_sdl;
  25.   Event     e_kit;
  26.   bool queueWasNotEmpty;
  27.  
  28.  
  29.  
  30.   _get_another_event:
  31.  
  32.   queueWasNotEmpty = SDL_PollEvent((event_p != nullptr) ? &e_sdl : nullptr);
  33.  
  34.   if(event_p == nullptr) return queueWasNotEmpty;
  35.   e_kit.common.timestamp = e_sdl.common.timestamp;
  36.  
  37.  
  38.  
  39.   //if queue had an event but its type was not recognized by _convertEvent,
  40.    //poll another event until either a supported one is found, or queue empties
  41.   if(queueWasNotEmpty && !_convertEvent(e_sdl, e_kit))
  42.     goto _get_another_event;
  43.  
  44.  
  45.  
  46.   *event_p = e_kit; //should be impossible for event_p to be null here
  47.  
  48.   return queueWasNotEmpty;
  49.  
  50. }
  51.  
  52.  
  53.  
  54.  
  55.  
  56. const char* getEventText(u32 type){
  57. #ifdef _DEBUG
  58.   const char* eventName;
  59.  
  60.   switch(type){
  61.     case KEVENT_NULL                : eventName = "KEVENT_NULL";                 break;
  62.  
  63.     case KEVENT_COMMON              : eventName = "KEVENT_COMMON";               break;
  64.  
  65.     case KEVENT_DISPLAY             : eventName = "KEVENT_DISPLAY";              break;
  66.     case KEVENT_DISPLAY_ORIENTATION : eventName = "KEVENT_DISPLAY_ORIENTATION";  break;
  67.     case KEVENT_DISPLAY_DISCONNECTED: eventName = "KEVENT_DISPLAY_DISCONNECTED"; break;
  68.     case KEVENT_DISPLAY_CONNECTED   : eventName = "KEVENT_DISPLAY_CONNECTED";    break;
  69.     case KEVENT_DISPLAY_MOVED       : eventName = "KEVENT_DISPLAY_MOVED";        break;
  70.  
  71.     case KEVENT_WIN                 : eventName = "KEVENT_WIN";                  break;
  72.     case KEVENT_WIN_EXPOSED         : eventName = "KEVENT_WIN_EXPOSED";          break;
  73.     case KEVENT_WIN_HIDDEN          : eventName = "KEVENT_WIN_HIDDEN";           break;
  74.     case KEVENT_WIN_SHOWN           : eventName = "KEVENT_WIN_SHOWN";            break;
  75.     case KEVENT_WIN_MOVED           : eventName = "KEVENT_WIN_MOVED";            break;
  76.     case KEVENT_WIN_RESIZED         : eventName = "KEVENT_WIN_RESIZED";          break;
  77.     case KEVENT_WIN_SIZE_CHANGED    : eventName = "KEVENT_WIN_SIZE_CHANGED";     break;
  78.     case KEVENT_WIN_RESTORED        : eventName = "KEVENT_WIN_RESTORED";         break;
  79.     case KEVENT_WIN_MINIMIZED       : eventName = "KEVENT_WIN_MINIMIZED";        break;
  80.     case KEVENT_WIN_MAXIMIZED       : eventName = "KEVENT_WIN_MAXIMIZED";        break;
  81.     case KEVENT_WIN_MFOCUS_LOST     : eventName = "KEVENT_WIN_MFOCUS_LOST";      break;
  82.     case KEVENT_WIN_MFOCUS_GAINED   : eventName = "KEVENT_WIN_MFOCUS_GAINED";    break;
  83.     case KEVENT_WIN_KFOCUS_LOST     : eventName = "KEVENT_WIN_KFOCUS_LOST";      break;
  84.     case KEVENT_WIN_KFOCUS_GAINED   : eventName = "KEVENT_WIN_KFOCUS_GAINED";    break;
  85.     case KEVENT_WIN_CLOSE           : eventName = "KEVENT_WIN_CLOSE";            break;
  86.     case KEVENT_WIN_TAKE_FOCUS      : eventName = "KEVENT_WIN_TAKE_FOCUS";       break;
  87.     case KEVENT_WIN_HIT_TEST        : eventName = "KEVENT_WIN_HIT_TEST";         break;
  88.     case KEVENT_WIN_ICCPROF_CHANGED : eventName = "KEVENT_WIN_ICCPROF_CHANGED";  break;
  89.     case KEVENT_WIN_DISPLAY_CHANGED : eventName = "KEVENT_WIN_DISPLAY_CHANGED";  break;
  90.  
  91.     case KEVENT_KEY                 : eventName = "KEVENT_KEY";                  break;
  92.     case KEVENT_KEY_DOWN            : eventName = "KEVENT_KEY_DOWN";             break;
  93.     case KEVENT_KEY_UP              : eventName = "KEVENT_KEY_UP";               break;
  94.  
  95.     case KEVENT_KEYMAPCHANGED       : eventName = "KEVENT_KEYMAPCHANGED";        break;
  96.  
  97.     case KEVENT_MOUSE               : eventName = "KEVENT_MOUSE";                break;
  98.     case KEVENT_MOUSE_MOVED         : eventName = "KEVENT_MOUSE_MOVED";          break;
  99.     case KEVENT_MOUSE_UP            : eventName = "KEVENT_MOUSE_UP";             break;
  100.     case KEVENT_MOUSE_DOWN          : eventName = "KEVENT_MOUSE_DOWN";           break;
  101.     case KEVENT_MOUSE_WHEEL         : eventName = "KEVENT_MOUSE_WHEEL";          break;
  102.  
  103.     case KEVENT_JOY                 : eventName = "KEVENT_JOY";                  break;
  104.     case KEVENT_JOY_AXIS            : eventName = "KEVENT_JOY_AXIS";             break;
  105.     case KEVENT_JOY_TRACKBALL       : eventName = "KEVENT_JOY_TRACKBALL";        break;
  106.     case KEVENT_JOY_HAT             : eventName = "KEVENT_JOY_HAT";              break;
  107.     case KEVENT_JOY_BUTTON_UP       : eventName = "KEVENT_JOY_BUTTON_UP";        break;
  108.     case KEVENT_JOY_BUTTON_DOWN     : eventName = "KEVENT_JOY_BUTTON_DOWN";      break;
  109.     case KEVENT_JOY_DEVICE_REMOVED  : eventName = "KEVENT_JOY_DEVICE_REMOVED";   break;
  110.     case KEVENT_JOY_DEVICE_ADDED    : eventName = "KEVENT_JOY_DEVICE_ADDED";     break;
  111.     case KEVENT_JOY_BATTERY         : eventName = "KEVENT_JOY_BATTERY";          break;
  112.  
  113.     case KEVENT_CTLR                : eventName = "KEVENT_CTLR";                 break;
  114.     case KEVENT_CTLR_AXIS           : eventName = "KEVENT_CTLR_AXIS";            break;
  115.     case KEVENT_CTLR_BUTTON_UP      : eventName = "KEVENT_CTLR_BUTTON_UP";       break;
  116.     case KEVENT_CTLR_BUTTON_DOWN    : eventName = "KEVENT_CTLR_BUTTON_DOWN";     break;
  117.     case KEVENT_CTLR_DEVICE_REMOVED : eventName = "KEVENT_CTLR_DEVICE_REMOVED";  break;
  118.     case KEVENT_CTLR_DEVICE_ADDED   : eventName = "KEVENT_CTLR_DEVICE_ADDED";    break;
  119.     case KEVENT_CTLR_DEVICE_REMAPPED: eventName = "KEVENT_CTLR_DEVICE_REMAPPED"; break;
  120.     case KEVENT_CTLR_TOUCHPAD_UP    : eventName = "KEVENT_CTLR_TOUCHPAD_UP";     break;
  121.     case KEVENT_CTLR_TOUCHPAD_DOWN  : eventName = "KEVENT_CTLR_TOUCHPAD_DOWN";   break;
  122.     case KEVENT_CTLR_TOUCHPAD_MOVED : eventName = "KEVENT_CTLR_TOUCHPAD_MOVED";  break;
  123.     case KEVENT_CTLR_SENSOR         : eventName = "KEVENT_CTLR_SENSOR";          break;
  124.  
  125.     case KEVENT_ADEV                : eventName = "KEVENT_ADEV";                 break;
  126.     case KEVENT_ADEV_ADDED          : eventName = "KEVENT_ADEV_ADDED";           break;
  127.     case KEVENT_ADEV_REMOVED        : eventName = "KEVENT_ADEV_REMOVED";         break;
  128.  
  129.     case KEVENT_DROP                : eventName = "KEVENT_DROP";                 break;
  130.     case KEVENT_DROP_FILE           : eventName = "KEVENT_DROP_FILE";            break;
  131.     case KEVENT_DROP_TEXT           : eventName = "KEVENT_DROP_TEXT";            break;
  132.     case KEVENT_DROP_BEGIN          : eventName = "KEVENT_DROP_BEGIN";           break;
  133.     case KEVENT_DROP_COMPLETE       : eventName = "KEVENT_DROP_COMPLETE";        break;
  134.  
  135.     case KEVENT_QUIT                : eventName = "KEVENT_QUIT";                 break;
  136.  
  137.     case KEVENT_USER                : eventName = "KEVENT_USER";                 break;
  138.  
  139.     case KEVENT_RENDER              : eventName = "KEVENT_RENDER";               break;
  140.     case KEVENT_RENDER_TARGETS_RESET: eventName = "KEVENT_RENDER_TARGETS_RESET"; break;
  141.     case KEVENT_RENDER_DEVICE_RESET : eventName = "KEVENT_RENDER_DEVICE_RESET "; break;
  142.  
  143.     case KEVENT_CLIPBOARDUPDATE     : eventName = "KEVENT_CLIPBOARDUPDATE";      break;
  144.  
  145.     default                         : eventName = "KEVENT_UNKNOWN";
  146.   }
  147.  
  148.   return eventName;
  149.  
  150.  
  151. #else
  152.   (void)type; //be gone, unused parameter warning
  153.   return "\"getEventText()\" is only available in the debug build!";
  154.  
  155.  
  156. #endif /* _DEBUG */
  157. }
  158.  
  159.  
  160.  
  161.  
  162.  
  163. }; /* namespace kit */
  164. /******************************************************************************/
  165. /******************************************************************************/
  166. //"2024-11-21\src\kit_sdl2\kit_lodepng_custom.cpp":
  167. #include "_kit_common.hpp"
  168.  
  169.  
  170. namespace kit {
  171.  
  172. namespace png {
  173.  
  174.  
  175.  
  176.  
  177.  
  178. void* lodepng_malloc(size_t size){
  179. #ifdef LODEPNG_MAX_ALLOC
  180.   if(size > LODEPNG_MAX_ALLOC) return 0;
  181. #endif
  182.   return memory::alloc(size);
  183.  
  184. }
  185.  
  186.  
  187.  
  188.  
  189.  
  190. // NOTE: when realloc returns NULL, it leaves the original memory untouched
  191. void* lodepng_realloc(void* ptr, size_t new_size){
  192. #ifdef LODEPNG_MAX_ALLOC
  193.   if(new_size > LODEPNG_MAX_ALLOC) return 0;
  194. #endif
  195.   return memory::realloc(&ptr, new_size);
  196.  
  197. }
  198.  
  199.  
  200.  
  201.  
  202.  
  203. void lodepng_free(void* ptr){
  204.   memory::free(&ptr);
  205.  
  206. }
  207.  
  208.  
  209.  
  210.  
  211.  
  212. //i rewrote lodepng's file io functions to only use SDL functions
  213.  
  214. #ifndef LODEPNG_NO_COMPILE_DISK
  215.  
  216.  
  217. #undef LONG_MAX
  218. #define LONG_MAX (2147483647)
  219.  
  220.  
  221. unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) {
  222.   *out = (unsigned char*)SDL_LoadFile(filename, outsize);
  223.  
  224.   if(*out == nullptr){
  225.     return 78;
  226.  
  227.   } else {
  228.     ++numAllocations; //a subsequent call to memory::free should undo this
  229.  
  230.     return 0;
  231.   }
  232.  
  233. }
  234.  
  235.  
  236. // write given buffer to the file, overwriting the file, it doesn't append to it.
  237. unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) {
  238.   SDL_RWops* file = SDL_RWFromFile(filename, "wb");
  239.   if(file == nullptr) return 79;
  240.  
  241.   size_t bytesWritten = SDL_RWwrite(file, buffer, 1, buffersize);
  242.  
  243.   SDL_RWclose(file);
  244.  
  245.   if(bytesWritten < buffersize) return 79;
  246.   else                          return  0;
  247.  
  248. }
  249.  
  250.  
  251.  
  252. /*
  253. #undef LONG_MAX
  254. #define LONG_MAX (2147483647)
  255. #include <stdio.h>
  256.  
  257. // returns negative value on error. This should be pure C compatible, so no fstat.
  258. static long lodepng_filesize(const char* filename) {
  259.   FILE* file;
  260.   long size;
  261.   file = fopen(filename, "rb");
  262.   if(!file) return -1;
  263.  
  264.   if(fseek(file, 0, SEEK_END) != 0) {
  265.     fclose(file);
  266.     return -1;
  267.   }
  268.  
  269.   size = ftell(file);
  270.   // It may give LONG_MAX as directory size, this is invalid for us.
  271.   if(size == LONG_MAX) size = -1;
  272.  
  273.   fclose(file);
  274.   return size;
  275. }
  276.  
  277. // load file into buffer that already has the correct allocated size. Returns error code.
  278. static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) {
  279.   FILE* file;
  280.   size_t readsize;
  281.   file = fopen(filename, "rb");
  282.   if(!file) return 78;
  283.  
  284.   readsize = fread(out, 1, size, file);
  285.   fclose(file);
  286.  
  287.   if(readsize != size) return 78;
  288.   return 0;
  289. }
  290.  
  291. unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) {
  292.   long size = lodepng_filesize(filename);
  293.   if(size < 0) return 78;
  294.   *outsize = (size_t)size;
  295.  
  296.   *out = (unsigned char*)lodepng_malloc((size_t)size);
  297.   if(!(*out) && size > 0) return 83; // the above malloc failed
  298.  
  299.   return lodepng_buffer_file(*out, (size_t)size, filename);
  300. }
  301.  
  302. // write given buffer to the file, overwriting the file, it doesn't append to it.
  303. unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) {
  304.   FILE* file;
  305.   file = fopen(filename, "wb" );
  306.   if(!file) return 79;
  307.   fwrite(buffer, 1, buffersize, file);
  308.   fclose(file);
  309.   return 0;
  310. }
  311. */
  312.  
  313. #endif /* LODEPNG_NO_COMPILE_DISK */
  314.  
  315. }; /* namespace png */
  316.  
  317. }; /* namespace kit */
  318. /******************************************************************************/
  319. /******************************************************************************/
  320. //"2024-11-21\src\kit_sdl2\kit_memory.cpp":
  321. #include "_kit_common.hpp"
  322.  
  323.  
  324. //turns something into a void**
  325.  //(this makes some code here easier for me to read)
  326. #define VPP(_ptr_p) ((void**)(_ptr_p))
  327.  
  328.  
  329. namespace kit {
  330.  
  331.  
  332. size_t numAllocations = 0;
  333.  
  334.  
  335.  
  336.  
  337.  
  338. void* memory::alloc(size_t size){
  339.   void* newHeapMemory = SDL_malloc(size);
  340.   if(newHeapMemory != nullptr) ++numAllocations;
  341.   return newHeapMemory;
  342.  
  343. }
  344.  
  345.  
  346.  
  347.  
  348. void memory::free(void* ptr_p){
  349.   if(VPP(ptr_p) != nullptr  &&  *VPP(ptr_p) != nullptr){
  350.     --numAllocations;
  351.     SDL_free(*VPP(ptr_p));
  352.     *VPP(ptr_p) = nullptr;
  353.  
  354.   }
  355.  
  356. }
  357.  
  358.  
  359.  
  360.  
  361. void* memory::realloc(void* ptr_p, size_t newSize){
  362.   void* ptr_new = nullptr;
  363.  
  364.   if(VPP(ptr_p) != nullptr){
  365.     ptr_new = SDL_realloc(*VPP(ptr_p), newSize);
  366.  
  367.     if(ptr_new != nullptr){
  368.       if(*VPP(ptr_p) == nullptr) ++numAllocations;
  369.       *VPP(ptr_p) = ptr_new;
  370.  
  371.     }
  372.  
  373.   }
  374.  
  375.   return ptr_new;
  376.  
  377. }
  378.  
  379.  
  380.  
  381.  
  382.  
  383. void* memory::alloc2(size_t size){
  384.   void* newHeapMemory = SDL_malloc(size);
  385.   if(newHeapMemory == nullptr)
  386.     THROW_ERROR("memory::alloc2(): failed to allocate memory");
  387.   ++numAllocations;
  388.   return newHeapMemory;
  389.  
  390. }
  391.  
  392.  
  393.  
  394.  
  395. void memory::free2(void* ptr_p){
  396.   if( VPP(ptr_p) == nullptr) THROW_ERROR("memory::free2(): ptr_p == nullptr");
  397.   if(*VPP(ptr_p) == nullptr) THROW_ERROR("memory::free2(): *ptr_p == nullptr");
  398.   --numAllocations;
  399.   SDL_free(*VPP(ptr_p));
  400.   *VPP(ptr_p) = nullptr;
  401.  
  402. }
  403.  
  404.  
  405.  
  406.  
  407. void* memory::realloc2(void* ptr_p, size_t newSize){
  408.   void* ptr_new = nullptr;
  409.  
  410.   if(VPP(ptr_p) != nullptr){
  411.     ptr_new = SDL_realloc(*VPP(ptr_p), newSize);
  412.  
  413.     if(ptr_new != nullptr){
  414.       if(*VPP(ptr_p) == nullptr) ++numAllocations; //if memory is new, not realloc'd
  415.       *VPP(ptr_p) = ptr_new;
  416.  
  417.     }
  418.  
  419.   } else {
  420.     THROW_ERROR("memory::realloc2(): ptr_p = nullptr");
  421.  
  422.   }
  423.  
  424.  
  425.   if(ptr_new == nullptr)
  426.     THROW_ERROR("memory::realloc2(): failed to reallocate memory");
  427.  
  428.  
  429.   return ptr_new;
  430.  
  431. }
  432.  
  433.  
  434.  
  435.  
  436.  
  437. size_t memory::getNumAllocations(){
  438.   return numAllocations;
  439.  
  440. }
  441.  
  442.  
  443.  
  444.  
  445.  
  446. //currently just a wrapper, but now i can make my own implementation
  447.  //whenever i want, without replacing every call to memset with it
  448. void* memory::set(void* ptr, s32 value, size_t size){
  449.   if(ptr == nullptr) return nullptr; //now it's safe to pass nullptr :D
  450.   return SDL_memset(ptr, value, size);
  451.  
  452. }
  453.  
  454.  
  455.  
  456.  
  457. void* memory::set2(void* ptr, s32 value, size_t size){
  458.   if(ptr == nullptr) THROW_ERROR("memory::set2(): ptr = nullptr");
  459.   return SDL_memset(ptr, value, size);
  460.  
  461. }
  462.  
  463.  
  464.  
  465.  
  466.  
  467. void* memory::copy(void* destination, const void* source, size_t size){
  468.   //tbd: maybe make it so that memcpy is only called if dst&src aren't nullptr
  469.   return SDL_memcpy(destination, source, size);
  470.  
  471. }
  472.  
  473.  
  474.  
  475.  
  476. void* memory::copy2(void* destination, const void* source, size_t size){
  477.   if(destination == nullptr) THROW_ERROR("memory::copy2(): destination = nullptr");
  478.   if(source      == nullptr) THROW_ERROR("memory::copy2(): source = nullptr");
  479.   return SDL_memcpy(destination, source, size);
  480.  
  481. }
  482.  
  483.  
  484.  
  485.  
  486.  
  487. u32 memory::getSystemRAM_MiB(){
  488.   s32 result = SDL_GetSystemRAM();
  489.  
  490.   if(result < 0) //hopefully this can't happen
  491.     THROW_ERROR("memory::getSystemRAM_MiB(): SDL_GetSystemRAM() < 0");
  492.  
  493.   return (u32)result;
  494.  
  495. }
  496.  
  497.  
  498.  
  499.  
  500. u32 memory::getSIMDAlignment(){
  501.   return SDL_SIMDGetAlignment(); //this shouldn't be any more than 64...
  502.  
  503. }
  504.  
  505.  
  506.  
  507.  
  508.  
  509. void* memory::allocSIMD(size_t size){
  510.   void* newHeapMemory = SDL_SIMDAlloc(size);
  511.   if(newHeapMemory != nullptr) ++numAllocations;
  512.   return newHeapMemory;
  513.  
  514. }
  515.  
  516.  
  517.  
  518.  
  519. void memory::freeSIMD(void* ptr_p){
  520.   if(VPP(ptr_p) != nullptr  &&  *VPP(ptr_p) != nullptr){
  521.     --numAllocations;
  522.     SDL_SIMDFree(*VPP(ptr_p));
  523.     *VPP(ptr_p) = nullptr;
  524.  
  525.   }
  526.  
  527. }
  528.  
  529.  
  530.  
  531.  
  532. void* memory::reallocSIMD(void* ptr_p, size_t newSize){
  533.   void* ptr_new = nullptr;
  534.  
  535.   if(VPP(ptr_p) != nullptr){
  536.     ptr_new = SDL_SIMDRealloc(*VPP(ptr_p), newSize);
  537.  
  538.     if(ptr_new != nullptr){
  539.       if(*VPP(ptr_p) == nullptr) ++numAllocations;
  540.       *VPP(ptr_p) = ptr_new;
  541.  
  542.     }
  543.  
  544.   }
  545.  
  546.   return ptr_new;
  547.  
  548. }
  549.  
  550.  
  551.  
  552.  
  553.  
  554. void* memory::allocSIMD2(size_t size){
  555.   void* newHeapMemory = SDL_SIMDAlloc(size);
  556.   if(newHeapMemory == nullptr)
  557.     THROW_ERROR("memory::allocSIMD2(): failed to allocate memory");
  558.   ++numAllocations;
  559.   return newHeapMemory;
  560.  
  561. }
  562.  
  563.  
  564.  
  565.  
  566. void memory::freeSIMD2(void* ptr_p){
  567.   if( VPP(ptr_p) == nullptr) THROW_ERROR("memory::freeSIMD2(): ptr_p == nullptr");
  568.   if(*VPP(ptr_p) == nullptr) THROW_ERROR("memory::freeSIMD2(): *ptr_p == nullptr");
  569.   --numAllocations;
  570.   SDL_SIMDFree(*VPP(ptr_p));
  571.   *VPP(ptr_p) = nullptr;
  572.  
  573. }
  574.  
  575.  
  576.  
  577.  
  578. void* memory::reallocSIMD2(void* ptr_p, size_t newSize){
  579.   void* ptr_new = nullptr;
  580.  
  581.   if(VPP(ptr_p) != nullptr){
  582.     ptr_new = SDL_SIMDRealloc(*VPP(ptr_p), newSize);
  583.  
  584.     if(ptr_new != nullptr){
  585.       if(*VPP(ptr_p) == nullptr) ++numAllocations; //if memory is new, not realloc'd
  586.       *VPP(ptr_p) = ptr_new;
  587.  
  588.     }
  589.  
  590.   } else {
  591.     THROW_ERROR("memory::reallocSIMD2(): ptr_p = nullptr");
  592.  
  593.   }
  594.  
  595.  
  596.   if(ptr_new == nullptr)
  597.     THROW_ERROR("memory::reallocSIMD2(): failed to reallocate memory");
  598.  
  599.  
  600.   return ptr_new;
  601.  
  602. }
  603.  
  604.  
  605.  
  606.  
  607.  
  608. memory::Wrapper::Wrapper(size_t size){
  609.   ptr = memory::alloc(size);
  610.   if(ptr == nullptr)
  611.     THROW_ERROR("memory::Wrapper::Wrapper() failed to allocate memory");
  612.  
  613. }
  614.  
  615.  
  616.  
  617.  
  618. memory::WrapperSIMD::WrapperSIMD(size_t size){
  619.   ptr = memory::allocSIMD(size);
  620.   if(ptr == nullptr)
  621.     THROW_ERROR("memory::WrapperSIMD::WrapperSIMD() failed to allocate memory");
  622.  
  623. }
  624.  
  625.  
  626.  
  627.  
  628.  
  629. }; /* namespace kit */
  630. /******************************************************************************/
  631. /******************************************************************************/
  632. //"2024-11-21\src\kit_sdl2\kit_Mutex.cpp":
  633. #include "_kit_common.hpp"
  634.  
  635. #define KIT_MUTEX_NULLPTR "internal mutex = nullptr"
  636. #define KIT_MUTEX_TIMEDOUT "mutex timed out"
  637.  
  638. #define MUTEX_PTR ((SDL_mutex*)_mutex_p)
  639.  
  640.  
  641. using namespace kit;
  642.  
  643.  
  644.  
  645.  
  646.  
  647. Mutex::Mutex(){
  648.   if(_valid) return;
  649.   _type = KIT_CLASSTYPE_MUTEX;
  650.  
  651.  
  652.   _mutex_p = SDL_CreateMutex(); //can't use MUTEX_PTR here
  653.  
  654.   if(MUTEX_PTR == nullptr)
  655.     THROW_ERRORF("Mutex::Mutex(): \"%s\"", SDL_GetError());
  656.  
  657.   ++numAllocations;
  658.  
  659.  
  660.   _valid = true;
  661.   _constructing = false;
  662.  
  663. }
  664.  
  665.  
  666.  
  667.  
  668.  
  669. Mutex::~Mutex(){
  670.   if(!_valid) return;
  671.   _valid = false;
  672.  
  673.   //(destroying a locked mutex will result in undefined behavior!)
  674.   if(MUTEX_PTR != nullptr) SDL_DestroyMutex(MUTEX_PTR);
  675.  
  676.   _mutex_p = nullptr; //can't use MUTEX_PTR here
  677.  
  678.   --numAllocations;
  679.  
  680. }
  681.  
  682.  
  683.  
  684.  
  685.  
  686. void Mutex::lock(bool locked){
  687.   if(MUTEX_PTR == nullptr)
  688.     THROW_ERROR("Mutex::lock(): " KIT_MUTEX_NULLPTR);
  689.  
  690.  
  691.   int result;
  692.   if(locked) result = SDL_LockMutex  (MUTEX_PTR);
  693.   else       result = SDL_UnlockMutex(MUTEX_PTR);
  694.  
  695.  
  696.   if(result < 0){
  697.     THROW_ERRORF("Mutex::lock(): \"%s\"", SDL_GetError());
  698.  
  699.   } else if(result == SDL_MUTEX_TIMEDOUT){
  700.     THROW_ERROR("Mutex::lock(): " KIT_MUTEX_TIMEDOUT);
  701.  
  702.   }
  703.  
  704.  
  705. }
  706.  
  707.  
  708.  
  709.  
  710.  
  711. bool Mutex::tryLock(){
  712.   if(MUTEX_PTR == nullptr)
  713.     THROW_ERROR("Mutex::tryLock(): " KIT_MUTEX_NULLPTR);
  714.  
  715.   int result = SDL_TryLockMutex(MUTEX_PTR);
  716.  
  717.   if(result < 0) THROW_ERRORF("Mutex::tryLock(): \"%s\"", SDL_GetError());
  718.  
  719.   return result == 0;
  720.  
  721. }
  722. /******************************************************************************/
  723. /******************************************************************************/
  724. //"2024-11-21\src\kit_sdl2\kit_SoundEngine.cpp":
  725. #include "_kit_common.hpp"
  726.  
  727. #define SNDENGINE_IS_INVALID (!_valid  ||  _tracks == nullptr)
  728. #define SNDENGINE_IS_TRACK_OOB (track >= _tracks_len)
  729. #define SNDENGINE_IS_MUTEX_NULLPTR (_lock == nullptr)
  730.  
  731.  
  732. #define CHECK_INVALID(_func_name) \
  733.   if(SNDENGINE_IS_INVALID){ THROW_ERROR(_func_name ": invalid SoundEngine"); }
  734.  
  735. #define CHECK_TRACK_OOB(_func_name) \
  736.   if(SNDENGINE_IS_TRACK_OOB){ THROW_ERROR(_func_name ": track is out of bounds"); }
  737.  
  738. #define CHECK_MUTEX(_func_name) \
  739.   if(SNDENGINE_IS_MUTEX_NULLPTR){ THROW_ERROR(_func_name ": _lock = nullptr"); }
  740.  
  741.  
  742. #define CHECK_INVALID_AND_OOB(_func_name) \
  743.   CHECK_INVALID(_func_name)               \
  744.   CHECK_TRACK_OOB(_func_name)
  745.  
  746. #define CHECK_INVALID_AND_MUTEX(_func_name) \
  747.   CHECK_INVALID(_func_name)                 \
  748.   CHECK_MUTEX(_func_name)
  749.  
  750. #define CHECK_ALL(_func_name) \
  751.   CHECK_INVALID(_func_name)   \
  752.   CHECK_TRACK_OOB(_func_name) \
  753.   CHECK_MUTEX(_func_name)
  754.  
  755.  
  756. #define MUTEX_PTR ((SDL_mutex*)_lock)
  757.  
  758. #define LOCK_MUTEX                                              \
  759.   bool locked = false;                                          \
  760.   if(MUTEX_PTR != nullptr){ locked = !SDL_LockMutex(MUTEX_PTR); }
  761.  
  762. #define UNLOCK_MUTEX                      { \
  763.   if(locked){ SDL_UnlockMutex(MUTEX_PTR); } }
  764.  
  765.  
  766. namespace kit {
  767.  
  768.  
  769.  
  770.  
  771.  
  772. #define GOTO_SET_ERROR(_text) { errTxt = _text; goto _err; }
  773.  
  774. SoundEngine::SoundEngine(u16 numTracks, f32 _sampleRate){
  775.   if(_valid) return;
  776.   _type = KIT_CLASSTYPE_SOUNDENGINE;
  777.  
  778.   const char* errTxt = "?";
  779.   if(0) _err: THROW_ERRORF("SoundEngine::SoundEngine(): %s", errTxt);
  780.  
  781.  
  782.  
  783.   if(numTracks < 1)
  784.     GOTO_SET_ERROR("numTracks < 1");
  785.  
  786.   _tracks_len = numTracks;
  787.  
  788.  
  789.  
  790.   size_t _tracks_size = sizeof(_SoundEngineTrack)*_tracks_len;
  791.  
  792.   _tracks = (_SoundEngineTrack*)memory::alloc(_tracks_size);
  793.  
  794.   if(_tracks == nullptr)
  795.     GOTO_SET_ERROR("failed to allocate memory for _tracks");
  796.  
  797.   memory::set(_tracks, 0, _tracks_size);
  798.  
  799.  
  800.  
  801.   _lock = SDL_CreateMutex();
  802.  
  803.   if(_lock == nullptr){
  804.     memory::free(&_tracks);
  805.     GOTO_SET_ERROR("failed to create mutex object");
  806.  
  807.   }
  808.  
  809.  
  810.  
  811.   sampleRate = _sampleRate;
  812.  
  813.  
  814.  
  815.   _valid = true;
  816.   _constructing = false;
  817.  
  818. }
  819.  
  820.  
  821.  
  822.  
  823.  
  824. SoundEngine::~SoundEngine(){
  825.   if(!_valid) return;
  826.   _valid = false;
  827.  
  828.   LOCK_MUTEX;
  829.  
  830.  
  831.   if(_tracks != nullptr){
  832.     for(u16 t=0; t<_tracks_len; ++t)
  833.       _tracks[t].audio = nullptr; //maybe redundant
  834.  
  835.   }
  836.  
  837.   _tracks_len = 0;
  838.  
  839.   memory::free(&_tracks);
  840.  
  841.  
  842.   UNLOCK_MUTEX;
  843.  
  844.   if(MUTEX_PTR != nullptr) SDL_DestroyMutex(MUTEX_PTR);
  845.  
  846.   _lock = nullptr;
  847.  
  848. }
  849.  
  850.  
  851.  
  852.  
  853.  
  854. bool SoundEngine::isTrackPlaying(u16 track){
  855.   CHECK_INVALID_AND_OOB("SoundEngine::isTrackPlaying()");
  856.  
  857.   return _tracks[track].audio != nullptr;
  858.  
  859. }
  860.  
  861.  
  862.  
  863.  
  864.  
  865. u16 SoundEngine::getActiveTracks(){
  866.   CHECK_INVALID("SoundEngine::getActiveTracks()");
  867.  
  868.   u16 activeTracks = 0;
  869.  
  870.   _SoundEngineTrack* tracks = _tracks;
  871.  
  872.   LOCK_MUTEX;
  873.  
  874.   for(u16 t=0; t<_tracks_len; ++t){
  875.     if(tracks[t].audio != nullptr) ++activeTracks;
  876.   }
  877.  
  878.   UNLOCK_MUTEX;
  879.  
  880.   return activeTracks;
  881.  
  882. }
  883.  
  884.  
  885.  
  886.  
  887.  
  888. void SoundEngine::setVolume(f32 volumeL, f32 volumeR,
  889.                             u16 track, bool forced)
  890. {
  891.   CHECK_INVALID_AND_MUTEX("SoundEngine::setVolume()");
  892.  
  893.   //normally, anything at or below 0 will cause the clip
  894.    //to stop immediately, but this check couldn't hurt
  895.   Stereo_f32 volumeNew(MAX(volumeL, 0.0f), MAX(volumeR, 0.0f));
  896.  
  897.  
  898.  
  899.   if(track != 0xFFFF){
  900.     CHECK_TRACK_OOB("SoundEngine::setVolume()");
  901.  
  902.     _SoundEngineTrack& _track = _tracks[track];
  903.     if(_track.audio == nullptr) return; //track is empty; exit early
  904.  
  905.     LOCK_MUTEX;
  906.  
  907.     if(forced) _track.vol_old = volumeNew;
  908.     _track.vol_new = volumeNew;
  909.  
  910.     UNLOCK_MUTEX;
  911.  
  912.  
  913.  
  914.   } else {
  915.     _SoundEngineTrack* tracks = _tracks;
  916.  
  917.     LOCK_MUTEX;
  918.  
  919.     if(!forced){
  920.       for(u16 t=0; t<_tracks_len; ++t)
  921.         tracks[t].vol_new = volumeNew;
  922.  
  923.     } else {
  924.       for(u16 t=0; t<_tracks_len; ++t){
  925.         tracks[t].vol_old = volumeNew;
  926.         tracks[t].vol_new = volumeNew;
  927.       }
  928.  
  929.     }
  930.  
  931.     UNLOCK_MUTEX;
  932.  
  933.  
  934.  
  935.   }
  936.  
  937. }
  938.  
  939.  
  940.  
  941.  
  942.  
  943. //used to modify speed values to account for different sample rates
  944. //(volume doesn't need this modifier, since it operates
  945.  //on the destination buffer, NOT the source buffer!)
  946. #define SMPRATE_MOD_RAW(_src_samplerate) \
  947.   (  (f64)(_src_samplerate)/sampleRate  )
  948.  
  949. //(this one assumes .audio != nullptr, so just be aware of that)
  950. #define SMPRATE_MOD(_track_lvalue) \
  951.   SMPRATE_MOD_RAW(_track_lvalue.audio->sampleRate)
  952.  
  953. void SoundEngine::setSpeed(f64 speedNew,
  954.                            u16 track, bool forced)
  955. {
  956.   CHECK_INVALID_AND_MUTEX("SoundEngine::setSpeed()");
  957.  
  958.   //normally, anything at or below 0 will cause the clip
  959.    //to stop immediately, but this check couldn't hurt
  960.   if(speedNew < 0.0) speedNew = 0.0;
  961.  
  962.  
  963.  
  964.   if(track != 0xFFFF){
  965.     CHECK_TRACK_OOB("SoundEngine::setSpeed()");
  966.  
  967.     _SoundEngineTrack& _track = _tracks[track];
  968.     if(_track.audio == nullptr) return; //track is empty; exit early
  969.  
  970.     LOCK_MUTEX;
  971.  
  972.     speedNew *= SMPRATE_MOD(_track);
  973.  
  974.     if(forced) _track.spd_old = speedNew;
  975.     _track.spd_new = speedNew;
  976.  
  977.     UNLOCK_MUTEX;
  978.  
  979.  
  980.  
  981.   } else {
  982.     _SoundEngineTrack* tracks = _tracks;
  983.  
  984.     LOCK_MUTEX;
  985.  
  986.     if(!forced){
  987.       for(u16 t=0; t<_tracks_len; ++t){
  988.         if(tracks[t].audio == nullptr) continue; //track is empty; next iteration
  989.         tracks[t].spd_new = speedNew*SMPRATE_MOD(tracks[t]);
  990.       }
  991.  
  992.     } else {
  993.       for(u16 t=0; t<_tracks_len; ++t){
  994.         if(tracks[t].audio == nullptr) continue; //track is empty; next iteration
  995.         f64 _speedNew = speedNew*SMPRATE_MOD(tracks[t]);
  996.         tracks[t].spd_old = _speedNew;
  997.         tracks[t].spd_new = _speedNew;
  998.       }
  999.  
  1000.     }
  1001.  
  1002.     UNLOCK_MUTEX;
  1003.  
  1004.  
  1005.  
  1006.   }
  1007.  
  1008. }
  1009.  
  1010.  
  1011.  
  1012.  
  1013.  
  1014. void SoundEngine::setVolumeDelta(f32 deltaSecondsL, f32 deltaSecondsR,
  1015.                                  u16 track)
  1016. {
  1017.   CHECK_INVALID("SoundEngine::setVolumeDelta()");
  1018.  
  1019.   //calculate delta, with a divide-by zero check for deltaSeconds
  1020.    //(sampleRate doesn't need it, since mixTracks just exits early in that case)
  1021.   Stereo_f32 delta((1.0f/deltaSecondsL) / sampleRate,
  1022.                    (1.0f/deltaSecondsR) / sampleRate);
  1023.  
  1024.   if(!deltaSecondsL) delta.l = 0.0f;
  1025.   if(!deltaSecondsR) delta.r = 0.0f;
  1026.  
  1027.  
  1028.  
  1029.   if(track != 0xFFFF){
  1030.     CHECK_TRACK_OOB("SoundEngine::setVolumeDelta()");
  1031.  
  1032.     _tracks[track].volDelta = delta;
  1033.  
  1034.  
  1035.  
  1036.   } else {
  1037.     _SoundEngineTrack* tracks = _tracks;
  1038.  
  1039.     for(u16 t=0; t<_tracks_len; ++t)
  1040.       tracks[t].volDelta = delta;
  1041.  
  1042.  
  1043.  
  1044.   }
  1045.  
  1046. }
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052. void SoundEngine::setSpeedDelta(f64 deltaSeconds,
  1053.                                 u16 track)
  1054. {
  1055.   CHECK_INVALID("SoundEngine::setSpeedDelta()");
  1056.  
  1057.   //calculate delta, with a divide-by zero check for deltaSeconds
  1058.    //(sampleRate doesn't need it, since mixTracks just exits early in that case)
  1059.   f64 delta = (deltaSeconds != 0)  ?  ((1.0/deltaSeconds) / sampleRate)  :  0.0;
  1060.  
  1061.  
  1062.  
  1063.   if(track != 0xFFFF){
  1064.     CHECK_TRACK_OOB("SoundEngine::setSpeedDelta()");
  1065.  
  1066.     _SoundEngineTrack& _track = _tracks[track];
  1067.     if(_track.audio == nullptr) return; //track is empty; exit early
  1068.  
  1069.     _track.spdDelta = delta*SMPRATE_MOD(_track);
  1070.  
  1071.  
  1072.  
  1073.   } else {
  1074.     _SoundEngineTrack* tracks = _tracks;
  1075.  
  1076.     for(u16 t=0; t<_tracks_len; ++t){
  1077.       if(tracks[t].audio == nullptr) continue; //track is empty; next iteration
  1078.       tracks[t].spdDelta = delta*SMPRATE_MOD(tracks[t]);
  1079.  
  1080.     }
  1081.  
  1082.  
  1083.  
  1084.   }
  1085.  
  1086. }
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092. #define PLAY_ASSERT(_success, _err_msg) \
  1093.   if(!(_success)){ THROW_ERROR("SoundEngine::play(): " _err_msg); }
  1094.  
  1095. u16 SoundEngine::play(const AudioData& audio,
  1096.                       f32 volumeL, f32 volumeR, f64 speed)
  1097. {
  1098.   CHECK_INVALID_AND_MUTEX("SoundEngine::play()");
  1099.   PLAY_ASSERT(audio.hdr, "audio.hdr = nullptr");
  1100.   PLAY_ASSERT(audio.hdr->format == SMPFMT_F32, "audio.hdr->format != SMPFMT_F32");
  1101.   PLAY_ASSERT(audio.hdr->channels == 1  ||  audio.hdr->channels == 2,
  1102.               "audio.hdr->channels is neither mono nor stereo")
  1103.  
  1104.  
  1105.   u64 timestamp = time::getMS();
  1106.  
  1107.  
  1108.   //will remain and return as 0xFFFF if no available track was found
  1109.   u16 queuedTrackNum = 0xFFFF;
  1110.  
  1111.   _SoundEngineTrack* tracks = _tracks;
  1112.  
  1113.  
  1114.  
  1115.   //(is locking actually necessary here?)
  1116.   LOCK_MUTEX; //tbd: if timing problems start to occur, remove the lock
  1117.  
  1118.   for(u16 t=0; t<_tracks_len; ++t){
  1119.     _SoundEngineTrack& track = tracks[t];
  1120.  
  1121.  
  1122.     if(track.audio == nullptr){
  1123.       track.timestamp = timestamp;
  1124.  
  1125.     //track.position  = <set inside callback>;
  1126.  
  1127.       track.spd_old   = MAX(speed*SMPRATE_MOD_RAW(audio.hdr->sampleRate), 0.0);
  1128.       track.spd_new   = track.spd_old;
  1129.       track.spdDelta  = 0.0;
  1130.  
  1131.       track.vol_old   = Stereo_f32(volumeL, volumeR);
  1132.       track.vol_new   = Stereo_f32(volumeL, volumeR);
  1133.       track.volDelta  = Stereo_f32(   0.0f,    0.0f);
  1134.       track.volMaster = audio.volume;
  1135.  
  1136.       track.loops     = audio.hdr->loopCount;
  1137.       track.stopping  = false;
  1138.  
  1139.       //set last to make sure that all relevant members
  1140.        //of the track are set before beginning
  1141.       track.audio     = audio.hdr;
  1142.  
  1143.       queuedTrackNum = t; break;
  1144.  
  1145.     }
  1146.  
  1147.   }
  1148.  
  1149.   UNLOCK_MUTEX;
  1150.  
  1151.   return queuedTrackNum;
  1152.  
  1153. }
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159. void SoundEngine::stop(u16 track, bool forced){
  1160.   CHECK_INVALID("SoundEngine::stop()");
  1161.  
  1162.   //if !forced, 'stop' the track by setting a fade-out of 10ms,
  1163.    //whereupon the track will *actually* stop automatically
  1164.   Stereo_f32 fadeoutDelta((1.0f/-0.010f) / sampleRate);
  1165.  
  1166.  
  1167.  
  1168.   if(track != 0xFFFF){
  1169.     CHECK_TRACK_OOB("SoundEngine::stop()");
  1170.  
  1171.     _SoundEngineTrack& _track = _tracks[track];
  1172.     if(_track.audio == nullptr) return; //track is empty; exit early
  1173.  
  1174.     if(!forced) _track.volDelta = fadeoutDelta;
  1175.     else        _track.audio    = nullptr;
  1176.  
  1177.  
  1178.  
  1179.   } else {
  1180.     _SoundEngineTrack* tracks = _tracks;
  1181.  
  1182.     if(!forced){
  1183.       for(u16 t=0; t<_tracks_len; ++t)
  1184.         tracks[t].volDelta = fadeoutDelta;
  1185.  
  1186.     } else {
  1187.       for(u16 t=0; t<_tracks_len; ++t)
  1188.         tracks[t].audio = nullptr;
  1189.  
  1190.     }
  1191.  
  1192.  
  1193.  
  1194.   }
  1195.  
  1196. }
  1197.  
  1198.  
  1199.  
  1200.  
  1201.  
  1202. //returns false if timeout is reached, true otherwise
  1203. static inline bool _waitForTrack(const AudioDataHeader*& audio,
  1204.                                  u64 timestampMS, u64 timeoutMS)
  1205. {
  1206.   while(audio != nullptr){
  1207.     time::sleep(5);
  1208.     if((time::getMS()-timestampMS) > timeoutMS) return false;
  1209.   }
  1210.  
  1211.   return true;
  1212.  
  1213. }
  1214.  
  1215.  
  1216.  
  1217. bool SoundEngine::waitForTrack(u64 timeoutMS, u16 track){
  1218.   CHECK_INVALID("SoundEngine::waitForTrack()");
  1219.  
  1220.   u64 timestampMS = time::getMS();
  1221.  
  1222.   if(timeoutMS == 0) timeoutMS = KIT_U64_MAX; //effectively an infinite timeout
  1223.  
  1224.  
  1225.  
  1226.   if(track != 0xFFFF){
  1227.     CHECK_TRACK_OOB("SoundEngine::waitForTrack()");
  1228.  
  1229.     if(!_waitForTrack(_tracks[track].audio,
  1230.                       timestampMS, timeoutMS))
  1231.     {
  1232.       return false;
  1233.     }
  1234.  
  1235.  
  1236.  
  1237.   } else {
  1238.     _SoundEngineTrack* tracks = _tracks;
  1239.  
  1240.     for(u16 t=0; t<_tracks_len; ++t){
  1241.       if(!_waitForTrack(tracks[t].audio,
  1242.                         timestampMS, timeoutMS))
  1243.       {
  1244.         return false;
  1245.       }
  1246.  
  1247.     }
  1248.  
  1249.     /*
  1250.     //(alternate method)
  1251.     while(getActiveTracks() > 0){
  1252.       time::sleep(10);
  1253.       if((time::getMS()-timestampMS) > timeoutMS) return false;
  1254.     }
  1255.     */
  1256.  
  1257.  
  1258.  
  1259.   }
  1260.  
  1261.  
  1262.  
  1263.   return true; //will return true only if track(s) finished before timeout
  1264.  
  1265. }
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271. //SoundEngine::mixTracks() is located in "kit_SoundEngine_mixTracks.cpp"
  1272.  
  1273.  
  1274.  
  1275.  
  1276.  
  1277. }; /* namespace kit */
  1278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement