Advertisement
Kitomas

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

Nov 22nd, 2024
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 37.11 KB | None | 0 0
  1. /******************************************************************************/
  2. /******************************************************************************/
  3. //"2024-11-21\src\kit_sdl2\kit_audio_func.cpp":
  4. #include "_kit_common.hpp"
  5.  
  6. #define AUDIO_UNINIT_CHECK(_funcname) \
  7.   if(!_gl.init.audio){ THROW_ERROR(_funcname ": audio subsystem is uninitialized"); }
  8.  
  9. namespace kit {
  10.  
  11.  
  12.  
  13.  
  14.  
  15. static AudioDeviceInfo _AudioSpecToDevInfo(SDL_AudioSpec& spec, bool isInput){
  16.   AudioDeviceInfo info;
  17.   info.sampleRate      = spec.freq; //(hopefully freq is never negative!)
  18.   info.sampleFrames    = spec.samples;
  19.   info.sampleFormat    = spec.format;
  20.   info.sampleFrameSize = KIT_AUDIO_BYTESIZE(spec.format)*spec.channels;
  21.   info.numChannels     = spec.channels;
  22.   info.isInput         = isInput;
  23.  
  24.   return info;
  25.  
  26. }
  27.  
  28.  
  29.  
  30.  
  31.  
  32. AudioDeviceInfo audiofunc::getDefaultDevInfo(char** name_p, bool isInput){
  33.   AUDIO_UNINIT_CHECK("audiofunc::getDefaultDevInfo()");
  34.  
  35.   SDL_AudioSpec spec;
  36.   if(SDL_GetDefaultAudioInfo(name_p, &spec, isInput) != 0)
  37.     THROW_ERRORF("audiofunc::getDefaultDevInfo(): \"%s\"", SDL_GetError());
  38.  
  39.   if(name_p != nullptr)
  40.     ++numAllocations; //memory has been allocated; increment # of allocations
  41.  
  42.   return _AudioSpecToDevInfo(spec, isInput);
  43.  
  44. }
  45.  
  46.  
  47.  
  48.  
  49.  
  50. AudioDeviceInfo audiofunc::getDeviceInfo(s32 index, bool isInput){
  51.   AUDIO_UNINIT_CHECK("audiofunc::getDeviceInfo()");
  52.  
  53.   SDL_AudioSpec spec;
  54.   if(SDL_GetAudioDeviceSpec(index, isInput, &spec) != 0)
  55.     THROW_ERRORF("audiofunc::getDeviceInfo(): \"%s\"", SDL_GetError());
  56.  
  57.   return _AudioSpecToDevInfo(spec, isInput);
  58.  
  59. }
  60.  
  61.  
  62.  
  63.  
  64.  
  65. s32 audiofunc::getNumDevices(bool isInput){
  66.   AUDIO_UNINIT_CHECK("audiofunc::getNumDevices()");
  67.  
  68.   return SDL_GetNumAudioDevices(isInput);
  69.  
  70. }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. const char* audiofunc::getDeviceName(u32 index, bool isInput){
  77.   AUDIO_UNINIT_CHECK("audiofunc::getDeviceName()");
  78.  
  79.   if(index > KIT_S32_MAX)
  80.     THROW_ERROR("audiofunc::getDeviceName(): index > KIT_S32_MAX");
  81.  
  82.   const char* name = SDL_GetAudioDeviceName((s32)index, isInput);
  83.   if(name == nullptr)
  84.     THROW_ERRORF("audiofunc::getDeviceName(): \"%s\"", SDL_GetError());
  85.  
  86.   return name;
  87.  
  88. }
  89.  
  90.  
  91.  
  92.  
  93.  
  94. void audiofunc::printAudioDeviceInfo(const AudioDeviceInfo& info){
  95.   kit_LogInfo("info of device \"%s\": {", audiofunc::getDeviceName(info.deviceID, info.isInput));
  96. #ifdef _DEBUG
  97.   kit_LogInfoS("  .timeStartTicks  = %llu", info.timeStartTicks);
  98.   kit_LogInfoS("  .timeStartMS     = %llu", info.timeStartMS   );
  99.   kit_LogInfo("  .deviceID        = %u", info.deviceID);
  100.   kit_LogInfo("  .sampleRate      = %u", info.sampleRate);
  101.   kit_LogInfo("  .sampleFrames    = %u", info.sampleFrames);
  102.   const char* smpfmt;
  103.   switch(info.sampleFormat){
  104.     case SMPFMT_U8 : smpfmt = "U8"     ; break;
  105.     case SMPFMT_S8 : smpfmt = "S8"     ; break;
  106.     case SMPFMT_U16: smpfmt = "U16"    ; break;
  107.     case SMPFMT_S16: smpfmt = "S16"    ; break;
  108.     case SMPFMT_S32: smpfmt = "S32"    ; break;
  109.     case SMPFMT_F32: smpfmt = "F32"    ; break;
  110.     default        : smpfmt = "UNKNOWN";
  111.   }
  112.   kit_LogInfo("  .sampleFormat    = SMPFMT_%s (0x%04X)", smpfmt, info.sampleFormat);
  113.   kit_LogInfo("  .sampleFrameSize = %u", info.sampleFrameSize);
  114.   kit_LogInfo("  .numChannels     = %u", info.numChannels);
  115.   kit_LogInfo("  .isInput         = %s", BOOLSTR(info.isInput));
  116.   kit_LogInfo("  .zeroBuffer      = %s", BOOLSTR(info.zeroBuffer));
  117.   kit_LogInfo("  .callback        = %p", info.callback);
  118.   kit_LogInfo("  .userdata        = %p", info.userdata);
  119.   kit_LogInfo("}");
  120.  
  121. #else
  122.   kit_LogInfo("  (audiofunc::printAudioDeviceInfo() is not available in release build!)\nINFO: }");
  123.  
  124. #endif /* _DEBUG */
  125.  
  126. }
  127.  
  128.  
  129.  
  130.  
  131.  
  132. }; /* namespace kit */
  133. /******************************************************************************/
  134. /******************************************************************************/
  135. //"2024-11-21\src\kit_sdl2\kit_BFont_default.cpp":
  136. #include "_kit_common.hpp"
  137.  
  138.  
  139. namespace kit {
  140.  
  141.  
  142.  
  143.  
  144.  
  145. //each bit is a pixel (1296 bytes total), LSb -> MSb; left -> right, top -> bottom
  146. static u8 _BFont_default[] = { //an 8x8, monospaced, 128-char, public domain font
  147.   0x53, 0x7c, 0x98, 0x01, 0xe0, 0x87, 0xc7, 0x80, 0x31, 0x71, 0x6c, 0xc4, 0x00, 0x10, 0x27, 0x8e, 0x87, 0x24,
  148.   0x55, 0x82, 0x98, 0xf9, 0xf7, 0x0f, 0xc3, 0x81, 0x3b, 0x52, 0xfe, 0x48, 0x71, 0x23, 0x41, 0xca, 0x09, 0x1f,
  149.   0x65, 0xaa, 0x98, 0xf9, 0x77, 0x0e, 0x83, 0x13, 0x1f, 0x32, 0xfe, 0x48, 0xd9, 0x21, 0x43, 0xc6, 0x00, 0x11,
  150.   0x00, 0x82, 0x98, 0x01, 0x30, 0x8c, 0x07, 0x0f, 0x1f, 0x52, 0xfe, 0x48, 0x01, 0x20, 0x41, 0xca, 0x80, 0x31,
  151.   0x11, 0xba, 0x98, 0x01, 0x30, 0xcc, 0x0b, 0x06, 0x1f, 0x74, 0x7c, 0x50, 0x71, 0x43, 0x81, 0xca, 0x10, 0x11,
  152.   0x11, 0x82, 0x98, 0xf9, 0x77, 0xce, 0x0f, 0x0a, 0x1f, 0x00, 0x38, 0x00, 0xd8, 0x01, 0x00, 0xc0, 0x19, 0x1f,
  153.   0x11, 0x7c, 0x98, 0xf9, 0xf7, 0x8f, 0x07, 0x11, 0x0e, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x24,
  154.   0x77, 0x00, 0x98, 0x01, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  155.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  156.   0xff, 0xfe, 0xed, 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x4a, 0x95, 0x08, 0x00,
  157.   0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0x5b, 0xb7, 0x6e, 0x55, 0x88, 0x10, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00,
  158.   0xff, 0xdc, 0xb9, 0x73, 0xa7, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x0a, 0x11, 0x22, 0x44,
  159.   0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0xdb, 0x9d, 0x2a, 0x55, 0xaa, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  160.   0xff, 0xfe, 0xed, 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x4a, 0x95, 0x08, 0x00,
  161.   0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0x5b, 0xb7, 0x6e, 0x55, 0x88, 0x10, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00,
  162.   0xff, 0xdc, 0xb9, 0x73, 0xa7, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x0a, 0x11, 0x22, 0x44,
  163.   0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0xdb, 0x9d, 0x2a, 0x55, 0xaa, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  164.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  165.   0x00, 0x30, 0xd8, 0xb0, 0xc1, 0x00, 0x00, 0x07, 0x03, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
  166.   0x00, 0x78, 0xd8, 0xb0, 0xe1, 0x63, 0x8c, 0x0d, 0x03, 0x0c, 0x18, 0x98, 0x61, 0x00, 0x00, 0x00, 0x00, 0x18,
  167.   0x00, 0x78, 0x00, 0xf8, 0x33, 0x60, 0x06, 0x87, 0x01, 0x06, 0x30, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c,
  168.   0x00, 0x30, 0x00, 0xb0, 0xe1, 0x01, 0x83, 0x1b, 0x00, 0x06, 0x30, 0xfc, 0xfb, 0x01, 0xe0, 0x07, 0x00, 0x06,
  169.   0x00, 0x30, 0x00, 0xf8, 0x03, 0x83, 0xc1, 0x0e, 0x00, 0x06, 0x30, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x03,
  170.   0x00, 0x00, 0x00, 0xb0, 0xf1, 0xc1, 0xcc, 0x0c, 0x00, 0x0c, 0x18, 0x98, 0x61, 0xc0, 0x00, 0x00, 0x83, 0x01,
  171.   0x00, 0x30, 0x00, 0xb0, 0xc1, 0x60, 0x8c, 0x1b, 0x00, 0x18, 0x0c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x83, 0x00,
  172.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
  173.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  174.   0x3e, 0x18, 0x78, 0xf0, 0x80, 0xe3, 0x07, 0x87, 0x1f, 0x1e, 0x3c, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x0f,
  175.   0x63, 0x1c, 0xcc, 0x98, 0xc1, 0x63, 0x80, 0x81, 0x19, 0x33, 0x66, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x83, 0x19,
  176.   0x73, 0x18, 0xc0, 0x80, 0x61, 0xe3, 0xc3, 0x00, 0x18, 0x33, 0x66, 0x30, 0x60, 0x60, 0xe0, 0x07, 0x06, 0x18,
  177.   0x7b, 0x18, 0x70, 0xe0, 0x30, 0x03, 0xc6, 0x07, 0x0c, 0x1e, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x0c,
  178.   0x6f, 0x18, 0x18, 0x80, 0xf1, 0x07, 0xc6, 0x0c, 0x06, 0x33, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x06,
  179.   0x67, 0x18, 0xcc, 0x98, 0x01, 0x63, 0xc6, 0x0c, 0x06, 0x33, 0x30, 0x30, 0x60, 0xc0, 0xe0, 0x07, 0x03, 0x00,
  180.   0x3e, 0x7e, 0xfc, 0xf0, 0x80, 0xc7, 0x83, 0x07, 0x06, 0x1e, 0x1c, 0x30, 0x60, 0x80, 0x01, 0x80, 0x01, 0x06,
  181.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
  182.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  183.   0x3e, 0x18, 0xfc, 0xe0, 0xf1, 0xe1, 0xcf, 0x1f, 0x1e, 0x33, 0x3c, 0xe0, 0x39, 0xf3, 0x60, 0xcc, 0x18, 0x0e,
  184.   0x63, 0x3c, 0x98, 0x31, 0x63, 0xc3, 0x88, 0x11, 0x33, 0x33, 0x18, 0xc0, 0x30, 0x63, 0xe0, 0xce, 0x19, 0x1b,
  185.   0x7b, 0x66, 0x98, 0x19, 0x60, 0xc6, 0x82, 0x85, 0x01, 0x33, 0x18, 0xc0, 0xb0, 0x61, 0xe0, 0xcf, 0x9b, 0x31,
  186.   0x7b, 0x66, 0xf8, 0x18, 0x60, 0xc6, 0x83, 0x87, 0x01, 0x3f, 0x18, 0xc0, 0xf0, 0x60, 0xe0, 0xcf, 0x9e, 0x31,
  187.   0x7b, 0x7e, 0x98, 0x19, 0x60, 0xc6, 0x82, 0x85, 0x39, 0x33, 0x18, 0xcc, 0xb0, 0x61, 0x64, 0xcd, 0x9c, 0x31,
  188.   0x03, 0x66, 0x98, 0x31, 0x63, 0xc3, 0x88, 0x01, 0x33, 0x33, 0x18, 0xcc, 0x30, 0x63, 0x66, 0xcc, 0x18, 0x1b,
  189.   0x1e, 0x66, 0xfc, 0xe0, 0xf1, 0xe1, 0xcf, 0x03, 0x3e, 0x33, 0x3c, 0x78, 0x38, 0xf3, 0x67, 0xcc, 0x18, 0x0e,
  190.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  191.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  192.   0x3f, 0x3c, 0xfc, 0xf0, 0xf0, 0x63, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0xfc, 0xf1, 0x30, 0xc0, 0x03, 0x02, 0x00,
  193.   0x66, 0x66, 0x98, 0x99, 0xd1, 0x62, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0x8c, 0x31, 0x60, 0x00, 0x03, 0x07, 0x00,
  194.   0x66, 0x66, 0x98, 0x39, 0xc0, 0x60, 0xc6, 0x8c, 0x31, 0x36, 0x66, 0xc4, 0x30, 0xc0, 0x00, 0x83, 0x0d, 0x00,
  195.   0x3e, 0x66, 0xf8, 0x70, 0xc0, 0x60, 0xc6, 0x8c, 0x35, 0x1c, 0x3c, 0x60, 0x30, 0x80, 0x01, 0xc3, 0x18, 0x00,
  196.   0x06, 0x76, 0xd8, 0xc0, 0xc1, 0x60, 0xc6, 0x8c, 0x3f, 0x1c, 0x18, 0x30, 0x31, 0x00, 0x03, 0x03, 0x00, 0x00,
  197.   0x06, 0x3c, 0x98, 0x99, 0xc1, 0x60, 0x86, 0x87, 0x3b, 0x36, 0x18, 0x98, 0x31, 0x00, 0x06, 0x03, 0x00, 0x00,
  198.   0x0f, 0x70, 0x9c, 0xf1, 0xe0, 0xe1, 0x07, 0x83, 0x31, 0x63, 0x3c, 0xfc, 0xf1, 0x00, 0xc4, 0x03, 0x00, 0x00,
  199.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f,
  200.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  201.   0x0c, 0x00, 0x1c, 0x00, 0x80, 0x03, 0x00, 0x07, 0x00, 0x07, 0x18, 0xc0, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00,
  202.   0x0c, 0x00, 0x18, 0x00, 0x00, 0x03, 0x80, 0x0d, 0x00, 0x06, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
  203.   0x18, 0x3c, 0x18, 0xf0, 0x00, 0xc3, 0x83, 0x01, 0x37, 0x36, 0x1c, 0xc0, 0x30, 0xc3, 0x60, 0xc6, 0x07, 0x0f,
  204.   0x00, 0x60, 0xf8, 0x98, 0xe1, 0x63, 0xc6, 0x83, 0x19, 0x6e, 0x18, 0xc0, 0xb0, 0xc1, 0xe0, 0xcf, 0x8c, 0x19,
  205.   0x00, 0x7c, 0x98, 0x19, 0x30, 0xe3, 0x87, 0x81, 0x19, 0x66, 0x18, 0xc0, 0xf0, 0xc0, 0xe0, 0xcf, 0x8c, 0x19,
  206.   0x00, 0x66, 0x98, 0x99, 0x31, 0x63, 0x80, 0x01, 0x1f, 0x66, 0x18, 0xcc, 0xb0, 0xc1, 0x60, 0xcd, 0x8c, 0x19,
  207.   0x00, 0xdc, 0xec, 0xf0, 0xe0, 0xc6, 0xc3, 0x03, 0x18, 0x67, 0x3c, 0xcc, 0x38, 0xe3, 0x61, 0xcc, 0x0c, 0x0f,
  208.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  209.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  210.   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x81, 0xe1, 0x80, 0x1b, 0x00,
  211.   0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x81, 0xc1, 0x0e, 0x00,
  212.   0x3b, 0xdc, 0xec, 0xf0, 0xe1, 0x63, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0xfc, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
  213.   0x66, 0x66, 0xb8, 0x19, 0xc0, 0x60, 0xc6, 0x8c, 0x35, 0x36, 0x66, 0x64, 0x38, 0x00, 0x00, 0x07, 0x00, 0x00,
  214.   0x66, 0x66, 0x98, 0xf1, 0xc0, 0x60, 0xc6, 0x8c, 0x3f, 0x1c, 0x66, 0x30, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
  215.   0x3e, 0x7c, 0x18, 0x80, 0xc1, 0x62, 0x86, 0x87, 0x3f, 0x36, 0x7c, 0x98, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
  216.   0x06, 0x60, 0x3c, 0xf8, 0x80, 0xc1, 0x0d, 0x03, 0x1b, 0x63, 0x60, 0xfc, 0xc0, 0x81, 0xe1, 0x00, 0x00, 0x00,
  217.   0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  218.   0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
  219. };
  220.  
  221.  
  222.  
  223.  
  224.  
  225. SDL_Surface* _BFont_default_create(){
  226.   SDL_Surface* surf = SDL_CreateRGBSurfaceWithFormat(0, 144, 144, 32, SDL_PIXELFORMAT_ABGR8888);
  227.   if(surf == nullptr) return nullptr;
  228.  
  229.  
  230.   //the bottom half of the font atlas will be left untouched,
  231.    //since the default font only uses the first 128 chars
  232.  
  233.   u32* pixels = (u32*)surf->pixels;
  234.  
  235.   for(u32 i=0; i<sizeof(_BFont_default); ++i){
  236.     u8 byte = _BFont_default[i];
  237.  
  238.     for(unsigned b=0; b<8; ++b){
  239.       if(byte&1) *(pixels++) = 0xFFFFFFFF;
  240.       else       *(pixels++) = 0x00000000;
  241.       byte >>= 1;
  242.     }
  243.  
  244.   }
  245.  
  246.  
  247.   if(SDL_SetColorKey(surf, SDL_TRUE, 0x00000000)<0){
  248.     SDL_FreeSurface(surf);
  249.     return nullptr;
  250.  
  251.   }
  252.  
  253.   return surf;
  254.  
  255. }
  256.  
  257.  
  258.  
  259.  
  260.  
  261. }; /* namespace kit */
  262. /******************************************************************************/
  263. /******************************************************************************/
  264. //"2024-11-21\src\kit_sdl2\kit_BFont_Surface.cpp":
  265. #include "_kit_common.hpp"
  266. #include "../stb_sprintf/stb_sprintf.hpp"
  267.  
  268. #define SURF_SRC ((SDL_Surface*)_surf_src)
  269. #define SURF_DST ((SDL_Surface*)_surf_dst)
  270.  
  271.  
  272. namespace kit {
  273.  
  274. #define logrect(r) kit_LogInfo(#r ": {%i, %i, %i, %i}", r.x, r.y, r.w, r.h);
  275. #define logpoint(p) kit_LogInfo(#p ": {%i, %i}", p.x, p.y);
  276.  
  277. SDL_Surface* _invoke_surface_loader(const char* filePath,
  278.                                     SurfaceLoaderCallback callback,
  279.                                     const char* funcName);
  280.  
  281. SDL_Surface* _BFont_default_create();
  282.  
  283.  
  284.  
  285.  
  286.  
  287. #define FREE_SURFACE(_surf_p) /* (safe to use on nullptr SDL_Surfaces) */ \
  288.   if((_surf_p) != nullptr){                                               \
  289.     SDL_FreeSurface((SDL_Surface*)(_surf_p));                             \
  290.     (_surf_p) = nullptr;                                                  \
  291.     --numAllocations;                                                     \
  292.   }
  293.  
  294. #define GOTO_SET_ERROR(_text) { errTxt = _text; goto _err; }
  295.  
  296. #define BF_S_COPY "BFont_Surface::BFont_Surface(copy)"
  297.  
  298. void BFont_Surface::_constructor(GenOpqPtr surf_opq, colors::ABGR txt_fg,
  299.                                  u31 fmtBuffer_len, const char* funcName)
  300. {
  301.   if(_valid) return;
  302.   _type = KIT_CLASSTYPE_BFONT_SURFACE;
  303.  
  304.   bool surf_in_is_external = funcName == nullptr;
  305.  
  306.   SDL_Surface* surf_abgr = nullptr;
  307.   SDL_Surface* surf_in   = (SDL_Surface*)surf_opq;
  308.  
  309.   //if surf_opq points to an instance of Surface instead of
  310.    //an SDL_Surface created by the 'from file' constructor,
  311.    //don't free it, as it's an external reference handled separately
  312.   if(surf_in_is_external){
  313.     surf_in = (SDL_Surface*)KIT_GET_CLASS_OPAQUE(surf_opq);
  314.     funcName = BF_S_COPY;
  315.   }
  316.  
  317.  
  318.  
  319.   const char* errTxt = "?";
  320.   if(0){ _err:
  321.     FREE_SURFACE(_surf_src);
  322.     FREE_SURFACE(surf_abgr);
  323.     if(!surf_in_is_external) FREE_SURFACE(surf_in);
  324.     //freeing _fmtBuffer is redundant as long as it's the last thing created
  325.     //memory::free(&_fmtBuffer);
  326.     THROW_ERRORF("%s: %s", funcName, errTxt);
  327.  
  328.   }
  329.  
  330.  
  331.  
  332.   if(!fmtBuffer_len.v) GOTO_SET_ERROR("fmtBuffer_len = 0");
  333.   if( fmtBuffer_len.s) GOTO_SET_ERROR("fmtBuffer_len > KIT_S32_MAX");
  334.  
  335.   _fmtBuffer_len = fmtBuffer_len;
  336.  
  337.  
  338.  
  339.   //convert input to abgr, before freeing input (unless input surf is external)
  340.   surf_abgr = SDL_ConvertSurfaceFormat(surf_in, SDL_PIXELFORMAT_ABGR8888, 0);
  341.   if(!surf_in_is_external) FREE_SURFACE(surf_in);
  342.   if(surf_abgr == nullptr) GOTO_SET_ERROR(SDL_GetError());
  343.   ++numAllocations; //here, a new surface counts as an allocation
  344.  
  345.   //create an indexed surface with the same properties as surf_abgr,
  346.    //so they can be used as the destination and source surface respectively
  347.   //(indexed color is used so the text color can be changed easily and quickly)
  348.   _surf_src = SDL_ConvertSurfaceFormat(surf_abgr, SDL_PIXELFORMAT_ABGR8888, 0);
  349.   if(_surf_src == nullptr) GOTO_SET_ERROR(SDL_GetError());
  350.   ++numAllocations;
  351.  
  352.  
  353.  
  354.   //convert pixel data to either the text color or pure black (transparency)
  355.   u32* pixels_in  = (u32*)surf_abgr->pixels;
  356.   u32* pixels_out = (u32*)SURF_SRC->pixels;
  357.   u32  pixels_len = SURF_SRC->w * SURF_SRC->h;
  358.  
  359.   txt_fg.a = 255; //opaque
  360.   //since pure black is treated as transparent, the text color must be
  361.    //ever so slightly *not* black (hopefully this doesn't mess anything up)
  362.   if(txt_fg.v == 0xFF000000) txt_fg.v = 0xFF010101;
  363.   _txt_fg = txt_fg;
  364.  
  365.   for(u32 i=0; i<pixels_len; ++i)
  366.     pixels_out[i] = (pixels_in[i]&0xFFFFFF) ? txt_fg.v : 0xFF000000;
  367.  
  368.   FREE_SURFACE(surf_abgr); //free intermediate abgr surface
  369.  
  370.   if(SDL_SetColorKey(SURF_SRC, SDL_TRUE, 0xFF000000)<0) //make black transparent
  371.     GOTO_SET_ERROR(SDL_GetError());
  372.  
  373.  
  374.  
  375.   //make sure the surface's dimensions are correct
  376.   if(SURF_SRC->w<32) GOTO_SET_ERROR("surface width < 32");
  377.   if(SURF_SRC->h<32) GOTO_SET_ERROR("surface height < 32");
  378.   if(SURF_SRC->w%16) GOTO_SET_ERROR("surface width % 16  !=  0");
  379.   if(SURF_SRC->h%16) GOTO_SET_ERROR("surface height % 16  !=  0");
  380.  
  381.   _glyphSize.x = (SURF_SRC->w/16)-1;
  382.   _glyphSize.y = (SURF_SRC->h/16)-1;
  383.  
  384.  
  385.  
  386.   //allocate memory for string buffer used in formatting text
  387.   _fmtBuffer = (u8*)memory::alloc(_fmtBuffer_len.n);
  388.  
  389.   if(_fmtBuffer == nullptr)
  390.     GOTO_SET_ERROR("failed to allocate memory for _fmtBuffer");
  391.  
  392.   memory::set(_fmtBuffer, 0, _fmtBuffer_len.n);
  393.  
  394.  
  395.  
  396.   _valid = true;
  397.   _constructing = false;
  398.  
  399. }
  400.  
  401.  
  402.  
  403.  
  404.  
  405. #define BF_S_FILE "BFont_Surface::BFont_Surface(file)"
  406.  
  407. BFont_Surface::BFont_Surface(const char* img_filePath,
  408.                              SurfaceLoaderCallback img_callback,
  409.                              colors::ABGR txt_fg, u31 fmtBuffer_len)
  410. {
  411.   if(_valid) return;
  412. //_type = KIT_CLASSTYPE_BFONT_SURFACE;
  413.  
  414.  
  415.   SDL_Surface* surf_out = nullptr;
  416.  
  417.   if(img_filePath != nullptr){
  418.     surf_out = _invoke_surface_loader(img_filePath, img_callback, BF_S_FILE);
  419.     SDL_SetColorKey(surf_out, SDL_TRUE, 0xFF000000);
  420.  
  421.   } else {
  422.     surf_out = _BFont_default_create();
  423.     if(surf_out == nullptr)
  424.       THROW_ERRORF("%s: \"%s\"", BF_S_FILE, SDL_GetError());
  425.  
  426.   }
  427.  
  428.  
  429.   ++numAllocations; //here, a new surface counts as an allocation
  430.   _constructor(surf_out, txt_fg, fmtBuffer_len, BF_S_FILE);
  431.  
  432. //_valid = true;
  433. //_constructing = false;
  434.  
  435. }
  436.  
  437.  
  438.  
  439.  
  440.  
  441. BFont_Surface::~BFont_Surface(){
  442.   if(!_valid) return;
  443.   _valid = false;
  444.  
  445.   FREE_SURFACE(_surf_src);
  446.   memory::free(&_fmtBuffer);
  447.  
  448. }
  449.  
  450.  
  451.  
  452.  
  453.  
  454. /******************************************************************************/
  455.  
  456.  
  457.  
  458.  
  459.  
  460. //refined for every function
  461. #define FUNC_NAME "?"
  462.  
  463.  
  464.  
  465.  
  466.  
  467. #define GET_WIN_SURF                                               \
  468.   SDL_Window* win = (SDL_Window*)KIT_GET_CLASS_OPAQUE(dst_surf_p); \
  469.                                                                    \
  470.   if(!SDL_HasWindowSurface(win))                                   \
  471.     THROW_ERROR(FUNC_NAME ": Window has no surface");              \
  472.                                                                    \
  473.   _surf_dst = KIT_GET_CLASS_OPAQUE2(dst_surf_p);
  474.  
  475.  
  476.  
  477. #define DST_PTR                                     \
  478.   &dst_surf;                                        \
  479.   if(!KIT_GET_CLASS_VALID(dst_surf_p))              \
  480.     THROW_ERROR(FUNC_NAME ": dst_surf is invalid");
  481.  
  482. #define FMT(_last_named_var)                                      \
  483.   va_list va;                                                     \
  484.   va_start(va, _last_named_var);                                  \
  485.   _format_buffer(_fmtBuffer, _fmtBuffer_len, fmt, va, FUNC_NAME);
  486.  
  487. #define DST_PTR_AND_FMT(_last_named_var) \
  488.   DST_PTR;                               \
  489.   FMT(_last_named_var);
  490.  
  491. static void _format_buffer(u8* _fmtBuffer, u31 _fmtBuffer_len,
  492.                            const char* fmt, va_list va,
  493.                            const char* funcName)
  494. {
  495.   if(_fmtBuffer == nullptr){
  496.     SDL_SetError("_fmtBuffer = nullptr");
  497.     _err: va_end(va); //end va always, including on error
  498.     THROW_ERRORF("%s: %s", funcName, SDL_GetError());
  499.   }
  500.  
  501.   if(fmt == nullptr){
  502.     SDL_SetError("fmt = nullptr");
  503.     goto _err;
  504.   }
  505.  
  506.   if(stbsp_vsnprintf((char*)_fmtBuffer, _fmtBuffer_len.n, fmt, va)<0){
  507.     SDL_SetError("vsnprintf failed");
  508.     goto _err;
  509.   }
  510.  
  511.   va_end(va); //automatically end va
  512.  
  513. }
  514.  
  515.  
  516.  
  517.  
  518.  
  519. /******************************************************************************/
  520.  
  521.  
  522.  
  523.  
  524.  
  525. #define ERR_POINT {-1,-1}
  526. #define ERR_RECT {0,0,-1,-1}
  527. #define IF_ERR_POINT(_thing) if((_thing).y == -1)
  528. #define IF_ERR_RECT(_thing) if((_thing).h == -1)
  529.  
  530.  
  531.  
  532.  
  533.  
  534. //calculates size based on what is already in _fmtBuffer
  535. shape::point BFont_Surface::_getTextSize(bool bordered){
  536.   if(_fmtBuffer == nullptr){
  537.     SDL_SetError("_fmtBuffer = nullptr");
  538.     _lastBounds = ERR_RECT;
  539.     return ERR_POINT;
  540.   }
  541.  
  542.   u8 chr;
  543.   const u8* text = _fmtBuffer;
  544.   s32 maxWidth = 0;
  545.  
  546.   shape::point glyphSizeScaled = getGlyphSizeScaled();
  547.   shape::point size = {0, glyphSizeScaled.y*(text[0]!=0)};
  548.  
  549.  
  550.  
  551.   while( (chr=*(text++)) )
  552.   if(chr != '\n'){
  553.     size.x += glyphSizeScaled.x;
  554.  
  555.   } else {
  556.     if(maxWidth < size.x) maxWidth = size.x;
  557.     size.x  = 0;
  558.     size.y += glyphSizeScaled.y;
  559.  
  560.   }
  561.  
  562.   if(size.x < maxWidth) size.x = maxWidth;
  563.  
  564.  
  565.  
  566.   if(bordered){
  567.     size.x += (s32)((3.0f+box_padded)*scale.x);
  568.     size.y += (s32)((3.0f+box_padded)*scale.y);
  569.   }
  570.  
  571.  
  572.  
  573.   return size;
  574.  
  575. }
  576.  
  577.  
  578.  
  579.  
  580.  
  581. //calculates size AND position based on what is already in _fmtBuffer
  582. shape::rect BFont_Surface::_getRect(s32 x, s32 y, bool bordered){
  583.   shape::point textSize = _getTextSize(bordered);
  584.   IF_ERR_POINT(textSize) return ERR_RECT;
  585.  
  586.   if(_surf_dst == nullptr){
  587.     SDL_SetError("_surf_dst = nullptr");
  588.     _lastBounds = ERR_RECT;
  589.     return ERR_RECT;
  590.   }
  591.  
  592.  
  593.   _lastBounds.w = textSize.x;
  594.   _lastBounds.h = textSize.y;
  595.  
  596.  
  597.   if(neg_pos_margin){
  598.     if(x >= 0)                    _lastBounds.x = x;
  599.     else if(x != KIT_CENTER_TEXT) _lastBounds.x = SURF_DST->w   - textSize.x + x + 1;
  600.     else                          _lastBounds.x = SURF_DST->w/2 - textSize.x/2;
  601.  
  602.     if(y >= 0)                    _lastBounds.y = y;
  603.     else if(y != KIT_CENTER_TEXT) _lastBounds.y = SURF_DST->h   - textSize.y + y + 1;
  604.     else                          _lastBounds.y = SURF_DST->h/2 - textSize.y/2;
  605.  
  606.   } else {
  607.     _lastBounds.x = x;
  608.     _lastBounds.y = y;
  609.  
  610.   }
  611.  
  612.  
  613.   return _lastBounds;
  614.  
  615. }
  616.  
  617.  
  618.  
  619.  
  620.  
  621. //returns box shift
  622. shape::point BFont_Surface::_drawBoxNoText(shape::rect dst_rect){
  623.   if(_surf_dst == nullptr){
  624.     SDL_SetError("_surf_dst = nullptr");
  625.     _err: _lastBounds = ERR_RECT;
  626.     return ERR_POINT;
  627.   }
  628.  
  629.   _lastBounds = dst_rect;
  630.  
  631.  
  632.  
  633.   u32 color_border = SDL_MapRGBA(SURF_DST->format, txt_bd.r, txt_bd.g,
  634.                                                    txt_bd.b,      255);
  635.  
  636.   if(SDL_FillRect(SURF_DST, (SDL_Rect*)&dst_rect, color_border)<0) goto _err;
  637.  
  638.  
  639.  
  640.   shape::point box_shift = { MAX((s32)scale.x,1), MAX((s32)scale.y,1) };
  641.  
  642.   dst_rect.x += box_shift.x;
  643.   dst_rect.y += box_shift.y;
  644.  
  645.   box_shift.x *= 2; //size of border + size of inner space
  646.   box_shift.y *= 2;  //(which are equal, so *2 is appropriate here)
  647.   dst_rect.w -= box_shift.x;
  648.   dst_rect.h -= box_shift.y;
  649.  
  650.   if(dst_rect.w < 1  ||  dst_rect.h < 1) return box_shift;
  651.  
  652.   u32 color_background = SDL_MapRGBA(SURF_DST->format, txt_bg.r, txt_bg.g,
  653.                                                        txt_bg.b,      255);
  654.  
  655.   if(SDL_FillRect(SURF_DST, (SDL_Rect*)&dst_rect, color_background)<0) goto _err;
  656.  
  657.  
  658.  
  659.   return box_shift;
  660.  
  661. }
  662.  
  663.  
  664.  
  665.  
  666.  
  667. //define a function pointer type, so i can use function pointers for blitting
  668. typedef int (SDLCALL * BlitFunc)(SDL_Surface* src, const SDL_Rect* src_rect,
  669.                                  SDL_Surface* dst,       SDL_Rect* dst_rect);
  670.  
  671.  
  672.  
  673. //draws whatever is already in _fmtBuffer to the destination surface
  674. shape::rect BFont_Surface::_draw(s32 x, s32 y, u31 maxLen){
  675.   //calculate bounding box, unless this was called by _drawBox (maxLen.s = 1)
  676.   if(!maxLen.s){
  677.     _getRect(x, y, false);
  678.     x = _lastBounds.x,  y = _lastBounds.y;
  679.     IF_ERR_RECT(_lastBounds) return ERR_RECT;
  680.   }
  681.  
  682.   if(_surf_src == nullptr){
  683.     SDL_SetError("_surf_src = nullptr");
  684.     _lastBounds = ERR_RECT;
  685.     return ERR_RECT;
  686.   }
  687.  
  688.  
  689.  
  690.   BlitFunc blit;
  691.   if(scale.x == 1.0f  &&  scale.y == 1.0f) blit = SDL_BlitSurface;
  692.   else                                     blit = SDL_BlitScaled;
  693.  
  694.   u8 chr;
  695.   const u8* text = _fmtBuffer;
  696.  
  697.   shape::point glyphSizeScaled = getGlyphSizeScaled();
  698.  
  699.   shape::rect src_rect = {0, 0,      _glyphSize.x,      _glyphSize.y};
  700.   shape::rect dst_rect = {x, y, glyphSizeScaled.x, glyphSizeScaled.y};
  701.  
  702.   shape::point src_stride = {_glyphSize.x+1, _glyphSize.y+1};
  703.  
  704.  
  705.  
  706.   maxLen.s = 0; //maxLen.s is used as a flag, but is unused past this point
  707.   if(!maxLen.v) --maxLen.v; //effectively uncaps the length
  708.  
  709.   while( (chr=*(text++)) && (maxLen.v--) )
  710.   if(chr != '\n'){
  711.     src_rect.x = ( chr    &15)*src_stride.x;
  712.     src_rect.y = ((chr>>4)&15)*src_stride.y;
  713.  
  714.     //copy, since BlitFunc's dst_rect parameter is not a const*
  715.     shape::rect _dst_rect = dst_rect;
  716.  
  717.     if(blit(SURF_SRC, (SDL_Rect*)& src_rect,
  718.             SURF_DST, (SDL_Rect*)&_dst_rect)<0)
  719.     {
  720.       _lastBounds = ERR_RECT;
  721.       return ERR_RECT;
  722.     }
  723.  
  724.     dst_rect.x += dst_rect.w;
  725.  
  726.  
  727.   } else { //chr = '\n'
  728.     dst_rect.x  = x;
  729.     dst_rect.y += dst_rect.h;
  730.  
  731.  
  732.   }
  733.  
  734.  
  735.  
  736.   return _lastBounds;
  737.  
  738. }
  739.  
  740.  
  741.  
  742.  
  743.  
  744. //draws whatever is already in _fmtBuffer to the destination surface
  745. shape::rect BFont_Surface::_drawBox(s32 x, s32 y, u31 maxLen){
  746.   shape::rect dst_rect = _getRect(x, y, true);
  747.   IF_ERR_RECT(dst_rect) return ERR_RECT;
  748.  
  749.   shape::point box_shift = _drawBoxNoText(dst_rect);
  750.   IF_ERR_POINT(box_shift) return ERR_RECT;
  751.  
  752.  
  753.   shape::rect box_rect = dst_rect; //dst_rect's state before shifting
  754.  
  755.   dst_rect.x += box_shift.x;
  756.   dst_rect.y += box_shift.y;
  757.  
  758.   maxLen.s = 1; //to indicate that _draw is being called by _drawBox
  759.  
  760.   IF_ERR_RECT(_draw(dst_rect.x, dst_rect.y, maxLen)) return ERR_RECT;
  761.  
  762.   return box_rect;
  763.  
  764. }
  765.  
  766.  
  767.  
  768.  
  769.  
  770. /******************************************************************************/
  771.  
  772.  
  773.  
  774.  
  775.  
  776. #undef FUNC_NAME
  777. #define FUNC_NAME "BFont_Surface::getTextSize()"
  778.  
  779. shape::point BFont_Surface::getTextSize(const char* fmt, bool bordered, ...){
  780.   FMT(bordered);
  781.  
  782.   shape::point result = _getTextSize(bordered);
  783.  
  784.   IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  785.  
  786.   return result;
  787.  
  788. }
  789.  
  790.  
  791.  
  792.  
  793.  
  794. #undef FUNC_NAME
  795. #define FUNC_NAME "BFont_Surface::getRect(Surface&, fmt)"
  796.  
  797. shape::rect BFont_Surface::getRect(Surface& dst_surf, s32 x, s32 y,
  798.                                    const char* fmt, bool bordered, ...)
  799. {
  800.   void* dst_surf_p = DST_PTR_AND_FMT(bordered);
  801.  
  802.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  803.  
  804.   shape::rect result = _getRect(x, y, bordered);
  805.   _surf_dst = nullptr;
  806.  
  807.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  808.  
  809.   return result;
  810.  
  811. }
  812.  
  813.  
  814.  
  815.  
  816.  
  817. #undef FUNC_NAME
  818. #define FUNC_NAME "BFont_Surface::getRect(Window&, fmt)"
  819.  
  820. shape::rect BFont_Surface::getRect(Window& dst_surf, s32 x, s32 y,
  821.                                    const char* fmt, bool bordered, ...)
  822. {
  823.   void* dst_surf_p = DST_PTR_AND_FMT(bordered);
  824.  
  825.   GET_WIN_SURF;
  826.  
  827.   shape::rect result = _getRect(x, y, bordered);
  828.   _surf_dst = nullptr;
  829.  
  830.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  831.  
  832.   return result;
  833.  
  834. }
  835.  
  836.  
  837.  
  838.  
  839.  
  840. #undef FUNC_NAME
  841. #define FUNC_NAME "BFont_Surface::getRect(Surface&)"
  842.  
  843. shape::rect BFont_Surface::getRect(Surface& dst_surf, s32 x, s32 y,
  844.                                    bool bordered)
  845. {
  846.   void* dst_surf_p = DST_PTR;
  847.  
  848.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  849.  
  850.   shape::rect result = _getRect(x, y, bordered);
  851.   _surf_dst = nullptr;
  852.  
  853.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  854.  
  855.   return result;
  856.  
  857. }
  858.  
  859.  
  860.  
  861.  
  862.  
  863. #undef FUNC_NAME
  864. #define FUNC_NAME "BFont_Surface::getRect(Window&)"
  865.  
  866. shape::rect BFont_Surface::getRect(Window& dst_surf, s32 x, s32 y,
  867.                                    bool bordered)
  868. {
  869.   void* dst_surf_p = DST_PTR;
  870.  
  871.   GET_WIN_SURF;
  872.  
  873.   shape::rect result = _getRect(x, y, bordered);
  874.   _surf_dst = nullptr;
  875.  
  876.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  877.  
  878.   return result;
  879.  
  880. }
  881.  
  882.  
  883.  
  884.  
  885.  
  886. #undef FUNC_NAME
  887. #define FUNC_NAME "BFont_Surface::draw(Surface&, fmt)"
  888.  
  889. shape::rect BFont_Surface::draw(Surface& dst_surf, s32 x, s32 y,
  890.                                 const char* fmt, u31 maxLen, ...)
  891. {
  892.   void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
  893.  
  894.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  895.  
  896.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  897.  
  898.   shape::rect result = _draw(x, y, maxLen);
  899.   _surf_dst = nullptr;
  900.  
  901.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  902.  
  903.   return result;
  904.  
  905. }
  906.  
  907.  
  908.  
  909.  
  910.  
  911. #undef FUNC_NAME
  912. #define FUNC_NAME "BFont_Surface::draw(Window&, fmt)"
  913.  
  914. shape::rect BFont_Surface::draw(Window& dst_surf, s32 x, s32 y,
  915.                                 const char* fmt, u31 maxLen, ...)
  916. {
  917.   void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
  918.  
  919.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  920.  
  921.   GET_WIN_SURF;
  922.  
  923.   shape::rect result = _draw(x, y, maxLen);
  924.   _surf_dst = nullptr;
  925.  
  926.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  927.  
  928.   return result;
  929.  
  930. }
  931.  
  932.  
  933.  
  934.  
  935.  
  936. #undef FUNC_NAME
  937. #define FUNC_NAME "BFont_Surface::draw(Surface&)"
  938.  
  939. shape::rect BFont_Surface::draw(Surface& dst_surf, s32 x, s32 y, u31 maxLen){
  940.   void* dst_surf_p = DST_PTR;
  941.  
  942.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  943.  
  944.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  945.  
  946.   shape::rect result = _draw(x, y, maxLen);
  947.   _surf_dst = nullptr;
  948.  
  949.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  950.  
  951.   return result;
  952.  
  953. }
  954.  
  955.  
  956.  
  957.  
  958.  
  959. #undef FUNC_NAME
  960. #define FUNC_NAME "BFont_Surface::draw(Window&)"
  961.  
  962. shape::rect BFont_Surface::draw(Window& dst_surf, s32 x, s32 y, u31 maxLen){
  963.   void* dst_surf_p = DST_PTR;
  964.  
  965.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  966.  
  967.   GET_WIN_SURF;
  968.  
  969.   shape::rect result = _draw(x, y, maxLen);
  970.   _surf_dst = nullptr;
  971.  
  972.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  973.  
  974.   return result;
  975.  
  976. }
  977.  
  978.  
  979.  
  980.  
  981.  
  982. #undef FUNC_NAME
  983. #define FUNC_NAME "BFont_Surface::drawBox(Surface&, fmt)"
  984.  
  985. shape::rect BFont_Surface::drawBox(Surface& dst_surf, s32 x, s32 y,
  986.                                    const char* fmt, u31 maxLen, ...)
  987. {
  988.   void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
  989.  
  990.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  991.  
  992.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  993.  
  994.   shape::rect result = _drawBox(x, y, maxLen);
  995.   _surf_dst = nullptr;
  996.  
  997.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  998.  
  999.   return result;
  1000.  
  1001. }
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007. #undef FUNC_NAME
  1008. #define FUNC_NAME "BFont_Surface::drawBox(Window&, fmt)"
  1009.  
  1010. shape::rect BFont_Surface::drawBox(Window& dst_surf, s32 x, s32 y,
  1011.                                    const char* fmt, u31 maxLen, ...)
  1012. {
  1013.   void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
  1014.  
  1015.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  1016.  
  1017.   GET_WIN_SURF;
  1018.  
  1019.   shape::rect result = _drawBox(x, y, maxLen);
  1020.   _surf_dst = nullptr;
  1021.  
  1022.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1023.  
  1024.   return result;
  1025.  
  1026. }
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032. #undef FUNC_NAME
  1033. #define FUNC_NAME "BFont_Surface::drawBox(Surface&)"
  1034.  
  1035. shape::rect BFont_Surface::drawBox(Surface& dst_surf, s32 x, s32 y, u31 maxLen){
  1036.   void* dst_surf_p = DST_PTR;
  1037.  
  1038.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  1039.  
  1040.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  1041.  
  1042.   shape::rect result = _drawBox(x, y, maxLen);
  1043.   _surf_dst = nullptr;
  1044.  
  1045.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1046.  
  1047.   return result;
  1048.  
  1049. }
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055. #undef FUNC_NAME
  1056. #define FUNC_NAME "BFont_Surface::drawBox(Window&)"
  1057.  
  1058. shape::rect BFont_Surface::drawBox(Window& dst_surf, s32 x, s32 y, u31 maxLen){
  1059.   void* dst_surf_p = DST_PTR;
  1060.  
  1061.   if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
  1062.  
  1063.   GET_WIN_SURF;
  1064.  
  1065.   shape::rect result = _drawBox(x, y, maxLen);
  1066.   _surf_dst = nullptr;
  1067.  
  1068.   IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1069.  
  1070.   return result;
  1071.  
  1072. }
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078. #undef FUNC_NAME
  1079. #define FUNC_NAME "BFont_Surface::drawBoxNoText(Surface&)"
  1080.  
  1081. shape::point BFont_Surface::drawBoxNoText(Surface& dst_surf,
  1082.                                           s32 x, s32 y, u31 w, u31 h)
  1083. {
  1084.   void* dst_surf_p = DST_PTR;
  1085.  
  1086.   if(w.s) THROW_ERROR(FUNC_NAME ": w > KIT_S32_MAX");
  1087.   if(h.s) THROW_ERROR(FUNC_NAME ": h > KIT_S32_MAX");
  1088.  
  1089.   shape::rect dst_rect = {x, y, (s32)w.n, (s32)h.n};
  1090.  
  1091.   _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
  1092.  
  1093.   shape::point result = _drawBoxNoText(dst_rect);
  1094.   _surf_dst = nullptr;
  1095.  
  1096.   IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1097.  
  1098.   return result;
  1099.  
  1100. }
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106. #undef FUNC_NAME
  1107. #define FUNC_NAME "BFont_Surface::drawBoxNoText(Window&)"
  1108.  
  1109. shape::point BFont_Surface::drawBoxNoText(Window& dst_surf,
  1110.                                           s32 x, s32 y, u31 w, u31 h)
  1111. {
  1112.   void* dst_surf_p = DST_PTR;
  1113.  
  1114.   if(w.s) THROW_ERROR(FUNC_NAME ": w > KIT_S32_MAX");
  1115.   if(h.s) THROW_ERROR(FUNC_NAME ": h > KIT_S32_MAX");
  1116.  
  1117.   shape::rect dst_rect = {x, y, (s32)w.n, (s32)h.n};
  1118.  
  1119.   GET_WIN_SURF;
  1120.  
  1121.   shape::point result = _drawBoxNoText(dst_rect);
  1122.   _surf_dst = nullptr;
  1123.  
  1124.   IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1125.  
  1126.   return result;
  1127.  
  1128. }
  1129.  
  1130.  
  1131.  
  1132.  
  1133.  
  1134. #undef FUNC_NAME
  1135. #define FUNC_NAME "BFont_Surface::drawChar(Surface&)"
  1136.  
  1137. //some things are reimplemented inside the function itself,
  1138.  //to hopefully speed things up a bit
  1139. shape::rect BFont_Surface::drawChar(Surface& dst_surf, u8 chr, s32 x, s32 y){
  1140.   void* dst_surf_p = DST_PTR;
  1141.  
  1142.   SDL_Surface* surf_dst = (SDL_Surface*)KIT_GET_CLASS_OPAQUE(dst_surf_p);
  1143.  
  1144.  
  1145.  
  1146.   //calculate char dimensions and determine which blit function to use
  1147.   shape::rect src_rect, dst_rect;
  1148.   BlitFunc blit;
  1149.  
  1150.   src_rect.w = _glyphSize.x;
  1151.   src_rect.h = _glyphSize.y;
  1152.  
  1153.   if(scale.x != 1.0f  ||  scale.y != 1.0f){
  1154.     dst_rect.w = MAX((s32)(src_rect.w*scale.x), 1);
  1155.     dst_rect.h = MAX((s32)(src_rect.h*scale.y), 1);
  1156.     blit = SDL_BlitScaled;
  1157.  
  1158.   } else {
  1159.     dst_rect.w = src_rect.w;
  1160.     dst_rect.h = src_rect.h;
  1161.     blit = SDL_BlitSurface;
  1162.  
  1163.   }
  1164.  
  1165.  
  1166.  
  1167.   //calculate destination position
  1168.   if(neg_pos_margin){
  1169.     if(x >= 0)                    dst_rect.x = x;
  1170.     else if(x != KIT_CENTER_TEXT) dst_rect.x = surf_dst->w   - dst_rect.w + x + 1;
  1171.     else                          dst_rect.x = surf_dst->w/2 - dst_rect.w/2;
  1172.  
  1173.     if(y >= 0)                    dst_rect.y = y;
  1174.     else if(y != KIT_CENTER_TEXT) dst_rect.y = surf_dst->h   - dst_rect.h + y + 1;
  1175.     else                          dst_rect.y = surf_dst->h/2 - dst_rect.h/2;
  1176.  
  1177.   } else {
  1178.     dst_rect.x = x;
  1179.     dst_rect.y = y;
  1180.  
  1181.   }
  1182.  
  1183.  
  1184.  
  1185.   //dst_rect before blit gets the chance to clobber it
  1186.   shape::rect _dst_rect = dst_rect;
  1187.  
  1188.   src_rect.x = ( chr    &15)*(src_rect.w+1);
  1189.   src_rect.y = ((chr>>4)&15)*(src_rect.h+1);
  1190.  
  1191.   if(blit(SURF_SRC, (SDL_Rect*)&src_rect,
  1192.           surf_dst, (SDL_Rect*)&dst_rect)<0)
  1193.   {
  1194.     THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1195.   }
  1196.  
  1197.   return _dst_rect;
  1198.  
  1199. }
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205. #undef FUNC_NAME
  1206. #define FUNC_NAME "BFont_Surface::drawChar(Window&)"
  1207.  
  1208. //some things are reimplemented inside the function itself,
  1209.  //to hopefully speed things up a bit
  1210. shape::rect BFont_Surface::drawChar(Window& dst_surf, u8 chr, s32 x, s32 y){
  1211.   void* dst_surf_p = DST_PTR;
  1212.   SDL_Window* win = (SDL_Window*)KIT_GET_CLASS_OPAQUE(dst_surf_p);
  1213.  
  1214.   if(!SDL_HasWindowSurface(win))
  1215.     THROW_ERROR(FUNC_NAME ": Window has no surface");
  1216.  
  1217.   SDL_Surface* surf_dst = (SDL_Surface*)KIT_GET_CLASS_OPAQUE2(dst_surf_p);
  1218.  
  1219.  
  1220.  
  1221.   //calculate char dimensions and determine which blit function to use
  1222.   shape::rect src_rect, dst_rect;
  1223.   BlitFunc blit;
  1224.  
  1225.   src_rect.w = _glyphSize.x;
  1226.   src_rect.h = _glyphSize.y;
  1227.  
  1228.   if(scale.x != 1.0f  ||  scale.y != 1.0f){
  1229.     dst_rect.w = MAX((s32)(src_rect.w*scale.x), 1);
  1230.     dst_rect.h = MAX((s32)(src_rect.h*scale.y), 1);
  1231.     blit = SDL_BlitScaled;
  1232.  
  1233.   } else {
  1234.     dst_rect.w = src_rect.w;
  1235.     dst_rect.h = src_rect.h;
  1236.     blit = SDL_BlitSurface;
  1237.  
  1238.   }
  1239.  
  1240.  
  1241.  
  1242.   //calculate destination position
  1243.   if(neg_pos_margin){
  1244.     if(x >= 0)                    dst_rect.x = x;
  1245.     else if(x != KIT_CENTER_TEXT) dst_rect.x = surf_dst->w   - dst_rect.w + x + 1;
  1246.     else                          dst_rect.x = surf_dst->w/2 - dst_rect.w/2;
  1247.  
  1248.     if(y >= 0)                    dst_rect.y = y;
  1249.     else if(y != KIT_CENTER_TEXT) dst_rect.y = surf_dst->h   - dst_rect.h + y + 1;
  1250.     else                          dst_rect.y = surf_dst->h/2 - dst_rect.h/2;
  1251.  
  1252.   } else {
  1253.     dst_rect.x = x;
  1254.     dst_rect.y = y;
  1255.  
  1256.   }
  1257.  
  1258.  
  1259.  
  1260.   //dst_rect before blit gets the chance to clobber it
  1261.   shape::rect _dst_rect = dst_rect;
  1262.  
  1263.   src_rect.x = ( chr    &15)*(src_rect.w+1);
  1264.   src_rect.y = ((chr>>4)&15)*(src_rect.h+1);
  1265.  
  1266.   if(blit(SURF_SRC, (SDL_Rect*)&src_rect,
  1267.           surf_dst, (SDL_Rect*)&dst_rect)<0)
  1268.   {
  1269.     THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
  1270.   }
  1271.  
  1272.   return _dst_rect;
  1273.  
  1274. }
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280. #undef FUNC_NAME
  1281. #define FUNC_NAME "BFont_Surface::format()"
  1282.  
  1283. u8* BFont_Surface::format(const char* fmt, ...){
  1284.   FMT(fmt);
  1285.   return _fmtBuffer;
  1286.  
  1287. }
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293. }; /* namespace kit */
  1294.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement