Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\src\kit_sdl2\kit_audio_func.cpp":
- #include "_kit_common.hpp"
- #define AUDIO_UNINIT_CHECK(_funcname) \
- if(!_gl.init.audio){ THROW_ERROR(_funcname ": audio subsystem is uninitialized"); }
- namespace kit {
- static AudioDeviceInfo _AudioSpecToDevInfo(SDL_AudioSpec& spec, bool isInput){
- AudioDeviceInfo info;
- info.sampleRate = spec.freq; //(hopefully freq is never negative!)
- info.sampleFrames = spec.samples;
- info.sampleFormat = spec.format;
- info.sampleFrameSize = KIT_AUDIO_BYTESIZE(spec.format)*spec.channels;
- info.numChannels = spec.channels;
- info.isInput = isInput;
- return info;
- }
- AudioDeviceInfo audiofunc::getDefaultDevInfo(char** name_p, bool isInput){
- AUDIO_UNINIT_CHECK("audiofunc::getDefaultDevInfo()");
- SDL_AudioSpec spec;
- if(SDL_GetDefaultAudioInfo(name_p, &spec, isInput) != 0)
- THROW_ERRORF("audiofunc::getDefaultDevInfo(): \"%s\"", SDL_GetError());
- if(name_p != nullptr)
- ++numAllocations; //memory has been allocated; increment # of allocations
- return _AudioSpecToDevInfo(spec, isInput);
- }
- AudioDeviceInfo audiofunc::getDeviceInfo(s32 index, bool isInput){
- AUDIO_UNINIT_CHECK("audiofunc::getDeviceInfo()");
- SDL_AudioSpec spec;
- if(SDL_GetAudioDeviceSpec(index, isInput, &spec) != 0)
- THROW_ERRORF("audiofunc::getDeviceInfo(): \"%s\"", SDL_GetError());
- return _AudioSpecToDevInfo(spec, isInput);
- }
- s32 audiofunc::getNumDevices(bool isInput){
- AUDIO_UNINIT_CHECK("audiofunc::getNumDevices()");
- return SDL_GetNumAudioDevices(isInput);
- }
- const char* audiofunc::getDeviceName(u32 index, bool isInput){
- AUDIO_UNINIT_CHECK("audiofunc::getDeviceName()");
- if(index > KIT_S32_MAX)
- THROW_ERROR("audiofunc::getDeviceName(): index > KIT_S32_MAX");
- const char* name = SDL_GetAudioDeviceName((s32)index, isInput);
- if(name == nullptr)
- THROW_ERRORF("audiofunc::getDeviceName(): \"%s\"", SDL_GetError());
- return name;
- }
- void audiofunc::printAudioDeviceInfo(const AudioDeviceInfo& info){
- kit_LogInfo("info of device \"%s\": {", audiofunc::getDeviceName(info.deviceID, info.isInput));
- #ifdef _DEBUG
- kit_LogInfoS(" .timeStartTicks = %llu", info.timeStartTicks);
- kit_LogInfoS(" .timeStartMS = %llu", info.timeStartMS );
- kit_LogInfo(" .deviceID = %u", info.deviceID);
- kit_LogInfo(" .sampleRate = %u", info.sampleRate);
- kit_LogInfo(" .sampleFrames = %u", info.sampleFrames);
- const char* smpfmt;
- switch(info.sampleFormat){
- case SMPFMT_U8 : smpfmt = "U8" ; break;
- case SMPFMT_S8 : smpfmt = "S8" ; break;
- case SMPFMT_U16: smpfmt = "U16" ; break;
- case SMPFMT_S16: smpfmt = "S16" ; break;
- case SMPFMT_S32: smpfmt = "S32" ; break;
- case SMPFMT_F32: smpfmt = "F32" ; break;
- default : smpfmt = "UNKNOWN";
- }
- kit_LogInfo(" .sampleFormat = SMPFMT_%s (0x%04X)", smpfmt, info.sampleFormat);
- kit_LogInfo(" .sampleFrameSize = %u", info.sampleFrameSize);
- kit_LogInfo(" .numChannels = %u", info.numChannels);
- kit_LogInfo(" .isInput = %s", BOOLSTR(info.isInput));
- kit_LogInfo(" .zeroBuffer = %s", BOOLSTR(info.zeroBuffer));
- kit_LogInfo(" .callback = %p", info.callback);
- kit_LogInfo(" .userdata = %p", info.userdata);
- kit_LogInfo("}");
- #else
- kit_LogInfo(" (audiofunc::printAudioDeviceInfo() is not available in release build!)\nINFO: }");
- #endif /* _DEBUG */
- }
- }; /* namespace kit */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\src\kit_sdl2\kit_BFont_default.cpp":
- #include "_kit_common.hpp"
- namespace kit {
- //each bit is a pixel (1296 bytes total), LSb -> MSb; left -> right, top -> bottom
- static u8 _BFont_default[] = { //an 8x8, monospaced, 128-char, public domain font
- 0x53, 0x7c, 0x98, 0x01, 0xe0, 0x87, 0xc7, 0x80, 0x31, 0x71, 0x6c, 0xc4, 0x00, 0x10, 0x27, 0x8e, 0x87, 0x24,
- 0x55, 0x82, 0x98, 0xf9, 0xf7, 0x0f, 0xc3, 0x81, 0x3b, 0x52, 0xfe, 0x48, 0x71, 0x23, 0x41, 0xca, 0x09, 0x1f,
- 0x65, 0xaa, 0x98, 0xf9, 0x77, 0x0e, 0x83, 0x13, 0x1f, 0x32, 0xfe, 0x48, 0xd9, 0x21, 0x43, 0xc6, 0x00, 0x11,
- 0x00, 0x82, 0x98, 0x01, 0x30, 0x8c, 0x07, 0x0f, 0x1f, 0x52, 0xfe, 0x48, 0x01, 0x20, 0x41, 0xca, 0x80, 0x31,
- 0x11, 0xba, 0x98, 0x01, 0x30, 0xcc, 0x0b, 0x06, 0x1f, 0x74, 0x7c, 0x50, 0x71, 0x43, 0x81, 0xca, 0x10, 0x11,
- 0x11, 0x82, 0x98, 0xf9, 0x77, 0xce, 0x0f, 0x0a, 0x1f, 0x00, 0x38, 0x00, 0xd8, 0x01, 0x00, 0xc0, 0x19, 0x1f,
- 0x11, 0x7c, 0x98, 0xf9, 0xf7, 0x8f, 0x07, 0x11, 0x0e, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x24,
- 0x77, 0x00, 0x98, 0x01, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0xff, 0xfe, 0xed, 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x4a, 0x95, 0x08, 0x00,
- 0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0x5b, 0xb7, 0x6e, 0x55, 0x88, 0x10, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xdc, 0xb9, 0x73, 0xa7, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x0a, 0x11, 0x22, 0x44,
- 0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0xdb, 0x9d, 0x2a, 0x55, 0xaa, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xfe, 0xed, 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x4a, 0x95, 0x08, 0x00,
- 0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0x5b, 0xb7, 0x6e, 0x55, 0x88, 0x10, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xdc, 0xb9, 0x73, 0xa7, 0x4a, 0x95, 0x2a, 0x55, 0xaa, 0x54, 0xa9, 0x52, 0xa5, 0x0a, 0x11, 0x22, 0x44,
- 0xff, 0xfe, 0xfd, 0xfb, 0xf7, 0xaf, 0xdb, 0x9d, 0x2a, 0x55, 0xaa, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x00, 0x30, 0xd8, 0xb0, 0xc1, 0x00, 0x00, 0x07, 0x03, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
- 0x00, 0x78, 0xd8, 0xb0, 0xe1, 0x63, 0x8c, 0x0d, 0x03, 0x0c, 0x18, 0x98, 0x61, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x78, 0x00, 0xf8, 0x33, 0x60, 0x06, 0x87, 0x01, 0x06, 0x30, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0x00, 0x30, 0x00, 0xb0, 0xe1, 0x01, 0x83, 0x1b, 0x00, 0x06, 0x30, 0xfc, 0xfb, 0x01, 0xe0, 0x07, 0x00, 0x06,
- 0x00, 0x30, 0x00, 0xf8, 0x03, 0x83, 0xc1, 0x0e, 0x00, 0x06, 0x30, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x00, 0x00, 0x00, 0xb0, 0xf1, 0xc1, 0xcc, 0x0c, 0x00, 0x0c, 0x18, 0x98, 0x61, 0xc0, 0x00, 0x00, 0x83, 0x01,
- 0x00, 0x30, 0x00, 0xb0, 0xc1, 0x60, 0x8c, 0x1b, 0x00, 0x18, 0x0c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x83, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x3e, 0x18, 0x78, 0xf0, 0x80, 0xe3, 0x07, 0x87, 0x1f, 0x1e, 0x3c, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x0f,
- 0x63, 0x1c, 0xcc, 0x98, 0xc1, 0x63, 0x80, 0x81, 0x19, 0x33, 0x66, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x83, 0x19,
- 0x73, 0x18, 0xc0, 0x80, 0x61, 0xe3, 0xc3, 0x00, 0x18, 0x33, 0x66, 0x30, 0x60, 0x60, 0xe0, 0x07, 0x06, 0x18,
- 0x7b, 0x18, 0x70, 0xe0, 0x30, 0x03, 0xc6, 0x07, 0x0c, 0x1e, 0x7c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x0c,
- 0x6f, 0x18, 0x18, 0x80, 0xf1, 0x07, 0xc6, 0x0c, 0x06, 0x33, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x06,
- 0x67, 0x18, 0xcc, 0x98, 0x01, 0x63, 0xc6, 0x0c, 0x06, 0x33, 0x30, 0x30, 0x60, 0xc0, 0xe0, 0x07, 0x03, 0x00,
- 0x3e, 0x7e, 0xfc, 0xf0, 0x80, 0xc7, 0x83, 0x07, 0x06, 0x1e, 0x1c, 0x30, 0x60, 0x80, 0x01, 0x80, 0x01, 0x06,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x3e, 0x18, 0xfc, 0xe0, 0xf1, 0xe1, 0xcf, 0x1f, 0x1e, 0x33, 0x3c, 0xe0, 0x39, 0xf3, 0x60, 0xcc, 0x18, 0x0e,
- 0x63, 0x3c, 0x98, 0x31, 0x63, 0xc3, 0x88, 0x11, 0x33, 0x33, 0x18, 0xc0, 0x30, 0x63, 0xe0, 0xce, 0x19, 0x1b,
- 0x7b, 0x66, 0x98, 0x19, 0x60, 0xc6, 0x82, 0x85, 0x01, 0x33, 0x18, 0xc0, 0xb0, 0x61, 0xe0, 0xcf, 0x9b, 0x31,
- 0x7b, 0x66, 0xf8, 0x18, 0x60, 0xc6, 0x83, 0x87, 0x01, 0x3f, 0x18, 0xc0, 0xf0, 0x60, 0xe0, 0xcf, 0x9e, 0x31,
- 0x7b, 0x7e, 0x98, 0x19, 0x60, 0xc6, 0x82, 0x85, 0x39, 0x33, 0x18, 0xcc, 0xb0, 0x61, 0x64, 0xcd, 0x9c, 0x31,
- 0x03, 0x66, 0x98, 0x31, 0x63, 0xc3, 0x88, 0x01, 0x33, 0x33, 0x18, 0xcc, 0x30, 0x63, 0x66, 0xcc, 0x18, 0x1b,
- 0x1e, 0x66, 0xfc, 0xe0, 0xf1, 0xe1, 0xcf, 0x03, 0x3e, 0x33, 0x3c, 0x78, 0x38, 0xf3, 0x67, 0xcc, 0x18, 0x0e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x3f, 0x3c, 0xfc, 0xf0, 0xf0, 0x63, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0xfc, 0xf1, 0x30, 0xc0, 0x03, 0x02, 0x00,
- 0x66, 0x66, 0x98, 0x99, 0xd1, 0x62, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0x8c, 0x31, 0x60, 0x00, 0x03, 0x07, 0x00,
- 0x66, 0x66, 0x98, 0x39, 0xc0, 0x60, 0xc6, 0x8c, 0x31, 0x36, 0x66, 0xc4, 0x30, 0xc0, 0x00, 0x83, 0x0d, 0x00,
- 0x3e, 0x66, 0xf8, 0x70, 0xc0, 0x60, 0xc6, 0x8c, 0x35, 0x1c, 0x3c, 0x60, 0x30, 0x80, 0x01, 0xc3, 0x18, 0x00,
- 0x06, 0x76, 0xd8, 0xc0, 0xc1, 0x60, 0xc6, 0x8c, 0x3f, 0x1c, 0x18, 0x30, 0x31, 0x00, 0x03, 0x03, 0x00, 0x00,
- 0x06, 0x3c, 0x98, 0x99, 0xc1, 0x60, 0x86, 0x87, 0x3b, 0x36, 0x18, 0x98, 0x31, 0x00, 0x06, 0x03, 0x00, 0x00,
- 0x0f, 0x70, 0x9c, 0xf1, 0xe0, 0xe1, 0x07, 0x83, 0x31, 0x63, 0x3c, 0xfc, 0xf1, 0x00, 0xc4, 0x03, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x0c, 0x00, 0x1c, 0x00, 0x80, 0x03, 0x00, 0x07, 0x00, 0x07, 0x18, 0xc0, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x00, 0x18, 0x00, 0x00, 0x03, 0x80, 0x0d, 0x00, 0x06, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x18, 0xf0, 0x00, 0xc3, 0x83, 0x01, 0x37, 0x36, 0x1c, 0xc0, 0x30, 0xc3, 0x60, 0xc6, 0x07, 0x0f,
- 0x00, 0x60, 0xf8, 0x98, 0xe1, 0x63, 0xc6, 0x83, 0x19, 0x6e, 0x18, 0xc0, 0xb0, 0xc1, 0xe0, 0xcf, 0x8c, 0x19,
- 0x00, 0x7c, 0x98, 0x19, 0x30, 0xe3, 0x87, 0x81, 0x19, 0x66, 0x18, 0xc0, 0xf0, 0xc0, 0xe0, 0xcf, 0x8c, 0x19,
- 0x00, 0x66, 0x98, 0x99, 0x31, 0x63, 0x80, 0x01, 0x1f, 0x66, 0x18, 0xcc, 0xb0, 0xc1, 0x60, 0xcd, 0x8c, 0x19,
- 0x00, 0xdc, 0xec, 0xf0, 0xe0, 0xc6, 0xc3, 0x03, 0x18, 0x67, 0x3c, 0xcc, 0x38, 0xe3, 0x61, 0xcc, 0x0c, 0x0f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x81, 0xe1, 0x80, 0x1b, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x81, 0xc1, 0x0e, 0x00,
- 0x3b, 0xdc, 0xec, 0xf0, 0xe1, 0x63, 0xc6, 0x8c, 0x31, 0x63, 0x66, 0xfc, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
- 0x66, 0x66, 0xb8, 0x19, 0xc0, 0x60, 0xc6, 0x8c, 0x35, 0x36, 0x66, 0x64, 0x38, 0x00, 0x00, 0x07, 0x00, 0x00,
- 0x66, 0x66, 0x98, 0xf1, 0xc0, 0x60, 0xc6, 0x8c, 0x3f, 0x1c, 0x66, 0x30, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
- 0x3e, 0x7c, 0x18, 0x80, 0xc1, 0x62, 0x86, 0x87, 0x3f, 0x36, 0x7c, 0x98, 0x60, 0x80, 0x81, 0x01, 0x00, 0x00,
- 0x06, 0x60, 0x3c, 0xf8, 0x80, 0xc1, 0x0d, 0x03, 0x1b, 0x63, 0x60, 0xfc, 0xc0, 0x81, 0xe1, 0x00, 0x00, 0x00,
- 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- };
- SDL_Surface* _BFont_default_create(){
- SDL_Surface* surf = SDL_CreateRGBSurfaceWithFormat(0, 144, 144, 32, SDL_PIXELFORMAT_ABGR8888);
- if(surf == nullptr) return nullptr;
- //the bottom half of the font atlas will be left untouched,
- //since the default font only uses the first 128 chars
- u32* pixels = (u32*)surf->pixels;
- for(u32 i=0; i<sizeof(_BFont_default); ++i){
- u8 byte = _BFont_default[i];
- for(unsigned b=0; b<8; ++b){
- if(byte&1) *(pixels++) = 0xFFFFFFFF;
- else *(pixels++) = 0x00000000;
- byte >>= 1;
- }
- }
- if(SDL_SetColorKey(surf, SDL_TRUE, 0x00000000)<0){
- SDL_FreeSurface(surf);
- return nullptr;
- }
- return surf;
- }
- }; /* namespace kit */
- /******************************************************************************/
- /******************************************************************************/
- //"2024-11-21\src\kit_sdl2\kit_BFont_Surface.cpp":
- #include "_kit_common.hpp"
- #include "../stb_sprintf/stb_sprintf.hpp"
- #define SURF_SRC ((SDL_Surface*)_surf_src)
- #define SURF_DST ((SDL_Surface*)_surf_dst)
- namespace kit {
- #define logrect(r) kit_LogInfo(#r ": {%i, %i, %i, %i}", r.x, r.y, r.w, r.h);
- #define logpoint(p) kit_LogInfo(#p ": {%i, %i}", p.x, p.y);
- SDL_Surface* _invoke_surface_loader(const char* filePath,
- SurfaceLoaderCallback callback,
- const char* funcName);
- SDL_Surface* _BFont_default_create();
- #define FREE_SURFACE(_surf_p) /* (safe to use on nullptr SDL_Surfaces) */ \
- if((_surf_p) != nullptr){ \
- SDL_FreeSurface((SDL_Surface*)(_surf_p)); \
- (_surf_p) = nullptr; \
- --numAllocations; \
- }
- #define GOTO_SET_ERROR(_text) { errTxt = _text; goto _err; }
- #define BF_S_COPY "BFont_Surface::BFont_Surface(copy)"
- void BFont_Surface::_constructor(GenOpqPtr surf_opq, colors::ABGR txt_fg,
- u31 fmtBuffer_len, const char* funcName)
- {
- if(_valid) return;
- _type = KIT_CLASSTYPE_BFONT_SURFACE;
- bool surf_in_is_external = funcName == nullptr;
- SDL_Surface* surf_abgr = nullptr;
- SDL_Surface* surf_in = (SDL_Surface*)surf_opq;
- //if surf_opq points to an instance of Surface instead of
- //an SDL_Surface created by the 'from file' constructor,
- //don't free it, as it's an external reference handled separately
- if(surf_in_is_external){
- surf_in = (SDL_Surface*)KIT_GET_CLASS_OPAQUE(surf_opq);
- funcName = BF_S_COPY;
- }
- const char* errTxt = "?";
- if(0){ _err:
- FREE_SURFACE(_surf_src);
- FREE_SURFACE(surf_abgr);
- if(!surf_in_is_external) FREE_SURFACE(surf_in);
- //freeing _fmtBuffer is redundant as long as it's the last thing created
- //memory::free(&_fmtBuffer);
- THROW_ERRORF("%s: %s", funcName, errTxt);
- }
- if(!fmtBuffer_len.v) GOTO_SET_ERROR("fmtBuffer_len = 0");
- if( fmtBuffer_len.s) GOTO_SET_ERROR("fmtBuffer_len > KIT_S32_MAX");
- _fmtBuffer_len = fmtBuffer_len;
- //convert input to abgr, before freeing input (unless input surf is external)
- surf_abgr = SDL_ConvertSurfaceFormat(surf_in, SDL_PIXELFORMAT_ABGR8888, 0);
- if(!surf_in_is_external) FREE_SURFACE(surf_in);
- if(surf_abgr == nullptr) GOTO_SET_ERROR(SDL_GetError());
- ++numAllocations; //here, a new surface counts as an allocation
- //create an indexed surface with the same properties as surf_abgr,
- //so they can be used as the destination and source surface respectively
- //(indexed color is used so the text color can be changed easily and quickly)
- _surf_src = SDL_ConvertSurfaceFormat(surf_abgr, SDL_PIXELFORMAT_ABGR8888, 0);
- if(_surf_src == nullptr) GOTO_SET_ERROR(SDL_GetError());
- ++numAllocations;
- //convert pixel data to either the text color or pure black (transparency)
- u32* pixels_in = (u32*)surf_abgr->pixels;
- u32* pixels_out = (u32*)SURF_SRC->pixels;
- u32 pixels_len = SURF_SRC->w * SURF_SRC->h;
- txt_fg.a = 255; //opaque
- //since pure black is treated as transparent, the text color must be
- //ever so slightly *not* black (hopefully this doesn't mess anything up)
- if(txt_fg.v == 0xFF000000) txt_fg.v = 0xFF010101;
- _txt_fg = txt_fg;
- for(u32 i=0; i<pixels_len; ++i)
- pixels_out[i] = (pixels_in[i]&0xFFFFFF) ? txt_fg.v : 0xFF000000;
- FREE_SURFACE(surf_abgr); //free intermediate abgr surface
- if(SDL_SetColorKey(SURF_SRC, SDL_TRUE, 0xFF000000)<0) //make black transparent
- GOTO_SET_ERROR(SDL_GetError());
- //make sure the surface's dimensions are correct
- if(SURF_SRC->w<32) GOTO_SET_ERROR("surface width < 32");
- if(SURF_SRC->h<32) GOTO_SET_ERROR("surface height < 32");
- if(SURF_SRC->w%16) GOTO_SET_ERROR("surface width % 16 != 0");
- if(SURF_SRC->h%16) GOTO_SET_ERROR("surface height % 16 != 0");
- _glyphSize.x = (SURF_SRC->w/16)-1;
- _glyphSize.y = (SURF_SRC->h/16)-1;
- //allocate memory for string buffer used in formatting text
- _fmtBuffer = (u8*)memory::alloc(_fmtBuffer_len.n);
- if(_fmtBuffer == nullptr)
- GOTO_SET_ERROR("failed to allocate memory for _fmtBuffer");
- memory::set(_fmtBuffer, 0, _fmtBuffer_len.n);
- _valid = true;
- _constructing = false;
- }
- #define BF_S_FILE "BFont_Surface::BFont_Surface(file)"
- BFont_Surface::BFont_Surface(const char* img_filePath,
- SurfaceLoaderCallback img_callback,
- colors::ABGR txt_fg, u31 fmtBuffer_len)
- {
- if(_valid) return;
- //_type = KIT_CLASSTYPE_BFONT_SURFACE;
- SDL_Surface* surf_out = nullptr;
- if(img_filePath != nullptr){
- surf_out = _invoke_surface_loader(img_filePath, img_callback, BF_S_FILE);
- SDL_SetColorKey(surf_out, SDL_TRUE, 0xFF000000);
- } else {
- surf_out = _BFont_default_create();
- if(surf_out == nullptr)
- THROW_ERRORF("%s: \"%s\"", BF_S_FILE, SDL_GetError());
- }
- ++numAllocations; //here, a new surface counts as an allocation
- _constructor(surf_out, txt_fg, fmtBuffer_len, BF_S_FILE);
- //_valid = true;
- //_constructing = false;
- }
- BFont_Surface::~BFont_Surface(){
- if(!_valid) return;
- _valid = false;
- FREE_SURFACE(_surf_src);
- memory::free(&_fmtBuffer);
- }
- /******************************************************************************/
- //refined for every function
- #define FUNC_NAME "?"
- #define GET_WIN_SURF \
- SDL_Window* win = (SDL_Window*)KIT_GET_CLASS_OPAQUE(dst_surf_p); \
- \
- if(!SDL_HasWindowSurface(win)) \
- THROW_ERROR(FUNC_NAME ": Window has no surface"); \
- \
- _surf_dst = KIT_GET_CLASS_OPAQUE2(dst_surf_p);
- #define DST_PTR \
- &dst_surf; \
- if(!KIT_GET_CLASS_VALID(dst_surf_p)) \
- THROW_ERROR(FUNC_NAME ": dst_surf is invalid");
- #define FMT(_last_named_var) \
- va_list va; \
- va_start(va, _last_named_var); \
- _format_buffer(_fmtBuffer, _fmtBuffer_len, fmt, va, FUNC_NAME);
- #define DST_PTR_AND_FMT(_last_named_var) \
- DST_PTR; \
- FMT(_last_named_var);
- static void _format_buffer(u8* _fmtBuffer, u31 _fmtBuffer_len,
- const char* fmt, va_list va,
- const char* funcName)
- {
- if(_fmtBuffer == nullptr){
- SDL_SetError("_fmtBuffer = nullptr");
- _err: va_end(va); //end va always, including on error
- THROW_ERRORF("%s: %s", funcName, SDL_GetError());
- }
- if(fmt == nullptr){
- SDL_SetError("fmt = nullptr");
- goto _err;
- }
- if(stbsp_vsnprintf((char*)_fmtBuffer, _fmtBuffer_len.n, fmt, va)<0){
- SDL_SetError("vsnprintf failed");
- goto _err;
- }
- va_end(va); //automatically end va
- }
- /******************************************************************************/
- #define ERR_POINT {-1,-1}
- #define ERR_RECT {0,0,-1,-1}
- #define IF_ERR_POINT(_thing) if((_thing).y == -1)
- #define IF_ERR_RECT(_thing) if((_thing).h == -1)
- //calculates size based on what is already in _fmtBuffer
- shape::point BFont_Surface::_getTextSize(bool bordered){
- if(_fmtBuffer == nullptr){
- SDL_SetError("_fmtBuffer = nullptr");
- _lastBounds = ERR_RECT;
- return ERR_POINT;
- }
- u8 chr;
- const u8* text = _fmtBuffer;
- s32 maxWidth = 0;
- shape::point glyphSizeScaled = getGlyphSizeScaled();
- shape::point size = {0, glyphSizeScaled.y*(text[0]!=0)};
- while( (chr=*(text++)) )
- if(chr != '\n'){
- size.x += glyphSizeScaled.x;
- } else {
- if(maxWidth < size.x) maxWidth = size.x;
- size.x = 0;
- size.y += glyphSizeScaled.y;
- }
- if(size.x < maxWidth) size.x = maxWidth;
- if(bordered){
- size.x += (s32)((3.0f+box_padded)*scale.x);
- size.y += (s32)((3.0f+box_padded)*scale.y);
- }
- return size;
- }
- //calculates size AND position based on what is already in _fmtBuffer
- shape::rect BFont_Surface::_getRect(s32 x, s32 y, bool bordered){
- shape::point textSize = _getTextSize(bordered);
- IF_ERR_POINT(textSize) return ERR_RECT;
- if(_surf_dst == nullptr){
- SDL_SetError("_surf_dst = nullptr");
- _lastBounds = ERR_RECT;
- return ERR_RECT;
- }
- _lastBounds.w = textSize.x;
- _lastBounds.h = textSize.y;
- if(neg_pos_margin){
- if(x >= 0) _lastBounds.x = x;
- else if(x != KIT_CENTER_TEXT) _lastBounds.x = SURF_DST->w - textSize.x + x + 1;
- else _lastBounds.x = SURF_DST->w/2 - textSize.x/2;
- if(y >= 0) _lastBounds.y = y;
- else if(y != KIT_CENTER_TEXT) _lastBounds.y = SURF_DST->h - textSize.y + y + 1;
- else _lastBounds.y = SURF_DST->h/2 - textSize.y/2;
- } else {
- _lastBounds.x = x;
- _lastBounds.y = y;
- }
- return _lastBounds;
- }
- //returns box shift
- shape::point BFont_Surface::_drawBoxNoText(shape::rect dst_rect){
- if(_surf_dst == nullptr){
- SDL_SetError("_surf_dst = nullptr");
- _err: _lastBounds = ERR_RECT;
- return ERR_POINT;
- }
- _lastBounds = dst_rect;
- u32 color_border = SDL_MapRGBA(SURF_DST->format, txt_bd.r, txt_bd.g,
- txt_bd.b, 255);
- if(SDL_FillRect(SURF_DST, (SDL_Rect*)&dst_rect, color_border)<0) goto _err;
- shape::point box_shift = { MAX((s32)scale.x,1), MAX((s32)scale.y,1) };
- dst_rect.x += box_shift.x;
- dst_rect.y += box_shift.y;
- box_shift.x *= 2; //size of border + size of inner space
- box_shift.y *= 2; //(which are equal, so *2 is appropriate here)
- dst_rect.w -= box_shift.x;
- dst_rect.h -= box_shift.y;
- if(dst_rect.w < 1 || dst_rect.h < 1) return box_shift;
- u32 color_background = SDL_MapRGBA(SURF_DST->format, txt_bg.r, txt_bg.g,
- txt_bg.b, 255);
- if(SDL_FillRect(SURF_DST, (SDL_Rect*)&dst_rect, color_background)<0) goto _err;
- return box_shift;
- }
- //define a function pointer type, so i can use function pointers for blitting
- typedef int (SDLCALL * BlitFunc)(SDL_Surface* src, const SDL_Rect* src_rect,
- SDL_Surface* dst, SDL_Rect* dst_rect);
- //draws whatever is already in _fmtBuffer to the destination surface
- shape::rect BFont_Surface::_draw(s32 x, s32 y, u31 maxLen){
- //calculate bounding box, unless this was called by _drawBox (maxLen.s = 1)
- if(!maxLen.s){
- _getRect(x, y, false);
- x = _lastBounds.x, y = _lastBounds.y;
- IF_ERR_RECT(_lastBounds) return ERR_RECT;
- }
- if(_surf_src == nullptr){
- SDL_SetError("_surf_src = nullptr");
- _lastBounds = ERR_RECT;
- return ERR_RECT;
- }
- BlitFunc blit;
- if(scale.x == 1.0f && scale.y == 1.0f) blit = SDL_BlitSurface;
- else blit = SDL_BlitScaled;
- u8 chr;
- const u8* text = _fmtBuffer;
- shape::point glyphSizeScaled = getGlyphSizeScaled();
- shape::rect src_rect = {0, 0, _glyphSize.x, _glyphSize.y};
- shape::rect dst_rect = {x, y, glyphSizeScaled.x, glyphSizeScaled.y};
- shape::point src_stride = {_glyphSize.x+1, _glyphSize.y+1};
- maxLen.s = 0; //maxLen.s is used as a flag, but is unused past this point
- if(!maxLen.v) --maxLen.v; //effectively uncaps the length
- while( (chr=*(text++)) && (maxLen.v--) )
- if(chr != '\n'){
- src_rect.x = ( chr &15)*src_stride.x;
- src_rect.y = ((chr>>4)&15)*src_stride.y;
- //copy, since BlitFunc's dst_rect parameter is not a const*
- shape::rect _dst_rect = dst_rect;
- if(blit(SURF_SRC, (SDL_Rect*)& src_rect,
- SURF_DST, (SDL_Rect*)&_dst_rect)<0)
- {
- _lastBounds = ERR_RECT;
- return ERR_RECT;
- }
- dst_rect.x += dst_rect.w;
- } else { //chr = '\n'
- dst_rect.x = x;
- dst_rect.y += dst_rect.h;
- }
- return _lastBounds;
- }
- //draws whatever is already in _fmtBuffer to the destination surface
- shape::rect BFont_Surface::_drawBox(s32 x, s32 y, u31 maxLen){
- shape::rect dst_rect = _getRect(x, y, true);
- IF_ERR_RECT(dst_rect) return ERR_RECT;
- shape::point box_shift = _drawBoxNoText(dst_rect);
- IF_ERR_POINT(box_shift) return ERR_RECT;
- shape::rect box_rect = dst_rect; //dst_rect's state before shifting
- dst_rect.x += box_shift.x;
- dst_rect.y += box_shift.y;
- maxLen.s = 1; //to indicate that _draw is being called by _drawBox
- IF_ERR_RECT(_draw(dst_rect.x, dst_rect.y, maxLen)) return ERR_RECT;
- return box_rect;
- }
- /******************************************************************************/
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::getTextSize()"
- shape::point BFont_Surface::getTextSize(const char* fmt, bool bordered, ...){
- FMT(bordered);
- shape::point result = _getTextSize(bordered);
- IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::getRect(Surface&, fmt)"
- shape::rect BFont_Surface::getRect(Surface& dst_surf, s32 x, s32 y,
- const char* fmt, bool bordered, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(bordered);
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _getRect(x, y, bordered);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::getRect(Window&, fmt)"
- shape::rect BFont_Surface::getRect(Window& dst_surf, s32 x, s32 y,
- const char* fmt, bool bordered, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(bordered);
- GET_WIN_SURF;
- shape::rect result = _getRect(x, y, bordered);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::getRect(Surface&)"
- shape::rect BFont_Surface::getRect(Surface& dst_surf, s32 x, s32 y,
- bool bordered)
- {
- void* dst_surf_p = DST_PTR;
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _getRect(x, y, bordered);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::getRect(Window&)"
- shape::rect BFont_Surface::getRect(Window& dst_surf, s32 x, s32 y,
- bool bordered)
- {
- void* dst_surf_p = DST_PTR;
- GET_WIN_SURF;
- shape::rect result = _getRect(x, y, bordered);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::draw(Surface&, fmt)"
- shape::rect BFont_Surface::draw(Surface& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _draw(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::draw(Window&, fmt)"
- shape::rect BFont_Surface::draw(Window& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- GET_WIN_SURF;
- shape::rect result = _draw(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::draw(Surface&)"
- shape::rect BFont_Surface::draw(Surface& dst_surf, s32 x, s32 y, u31 maxLen){
- void* dst_surf_p = DST_PTR;
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _draw(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::draw(Window&)"
- shape::rect BFont_Surface::draw(Window& dst_surf, s32 x, s32 y, u31 maxLen){
- void* dst_surf_p = DST_PTR;
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- GET_WIN_SURF;
- shape::rect result = _draw(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBox(Surface&, fmt)"
- shape::rect BFont_Surface::drawBox(Surface& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _drawBox(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBox(Window&, fmt)"
- shape::rect BFont_Surface::drawBox(Window& dst_surf, s32 x, s32 y,
- const char* fmt, u31 maxLen, ...)
- {
- void* dst_surf_p = DST_PTR_AND_FMT(maxLen);
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- GET_WIN_SURF;
- shape::rect result = _drawBox(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBox(Surface&)"
- shape::rect BFont_Surface::drawBox(Surface& dst_surf, s32 x, s32 y, u31 maxLen){
- void* dst_surf_p = DST_PTR;
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::rect result = _drawBox(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBox(Window&)"
- shape::rect BFont_Surface::drawBox(Window& dst_surf, s32 x, s32 y, u31 maxLen){
- void* dst_surf_p = DST_PTR;
- if(maxLen.s) THROW_ERROR(FUNC_NAME ": maxLen > KIT_S32_MAX");
- GET_WIN_SURF;
- shape::rect result = _drawBox(x, y, maxLen);
- _surf_dst = nullptr;
- IF_ERR_RECT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBoxNoText(Surface&)"
- shape::point BFont_Surface::drawBoxNoText(Surface& dst_surf,
- s32 x, s32 y, u31 w, u31 h)
- {
- void* dst_surf_p = DST_PTR;
- if(w.s) THROW_ERROR(FUNC_NAME ": w > KIT_S32_MAX");
- if(h.s) THROW_ERROR(FUNC_NAME ": h > KIT_S32_MAX");
- shape::rect dst_rect = {x, y, (s32)w.n, (s32)h.n};
- _surf_dst = KIT_GET_CLASS_OPAQUE(dst_surf_p);
- shape::point result = _drawBoxNoText(dst_rect);
- _surf_dst = nullptr;
- IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawBoxNoText(Window&)"
- shape::point BFont_Surface::drawBoxNoText(Window& dst_surf,
- s32 x, s32 y, u31 w, u31 h)
- {
- void* dst_surf_p = DST_PTR;
- if(w.s) THROW_ERROR(FUNC_NAME ": w > KIT_S32_MAX");
- if(h.s) THROW_ERROR(FUNC_NAME ": h > KIT_S32_MAX");
- shape::rect dst_rect = {x, y, (s32)w.n, (s32)h.n};
- GET_WIN_SURF;
- shape::point result = _drawBoxNoText(dst_rect);
- _surf_dst = nullptr;
- IF_ERR_POINT(result) THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- return result;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawChar(Surface&)"
- //some things are reimplemented inside the function itself,
- //to hopefully speed things up a bit
- shape::rect BFont_Surface::drawChar(Surface& dst_surf, u8 chr, s32 x, s32 y){
- void* dst_surf_p = DST_PTR;
- SDL_Surface* surf_dst = (SDL_Surface*)KIT_GET_CLASS_OPAQUE(dst_surf_p);
- //calculate char dimensions and determine which blit function to use
- shape::rect src_rect, dst_rect;
- BlitFunc blit;
- src_rect.w = _glyphSize.x;
- src_rect.h = _glyphSize.y;
- if(scale.x != 1.0f || scale.y != 1.0f){
- dst_rect.w = MAX((s32)(src_rect.w*scale.x), 1);
- dst_rect.h = MAX((s32)(src_rect.h*scale.y), 1);
- blit = SDL_BlitScaled;
- } else {
- dst_rect.w = src_rect.w;
- dst_rect.h = src_rect.h;
- blit = SDL_BlitSurface;
- }
- //calculate destination position
- if(neg_pos_margin){
- if(x >= 0) dst_rect.x = x;
- else if(x != KIT_CENTER_TEXT) dst_rect.x = surf_dst->w - dst_rect.w + x + 1;
- else dst_rect.x = surf_dst->w/2 - dst_rect.w/2;
- if(y >= 0) dst_rect.y = y;
- else if(y != KIT_CENTER_TEXT) dst_rect.y = surf_dst->h - dst_rect.h + y + 1;
- else dst_rect.y = surf_dst->h/2 - dst_rect.h/2;
- } else {
- dst_rect.x = x;
- dst_rect.y = y;
- }
- //dst_rect before blit gets the chance to clobber it
- shape::rect _dst_rect = dst_rect;
- src_rect.x = ( chr &15)*(src_rect.w+1);
- src_rect.y = ((chr>>4)&15)*(src_rect.h+1);
- if(blit(SURF_SRC, (SDL_Rect*)&src_rect,
- surf_dst, (SDL_Rect*)&dst_rect)<0)
- {
- THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- }
- return _dst_rect;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::drawChar(Window&)"
- //some things are reimplemented inside the function itself,
- //to hopefully speed things up a bit
- shape::rect BFont_Surface::drawChar(Window& dst_surf, u8 chr, s32 x, s32 y){
- void* dst_surf_p = DST_PTR;
- SDL_Window* win = (SDL_Window*)KIT_GET_CLASS_OPAQUE(dst_surf_p);
- if(!SDL_HasWindowSurface(win))
- THROW_ERROR(FUNC_NAME ": Window has no surface");
- SDL_Surface* surf_dst = (SDL_Surface*)KIT_GET_CLASS_OPAQUE2(dst_surf_p);
- //calculate char dimensions and determine which blit function to use
- shape::rect src_rect, dst_rect;
- BlitFunc blit;
- src_rect.w = _glyphSize.x;
- src_rect.h = _glyphSize.y;
- if(scale.x != 1.0f || scale.y != 1.0f){
- dst_rect.w = MAX((s32)(src_rect.w*scale.x), 1);
- dst_rect.h = MAX((s32)(src_rect.h*scale.y), 1);
- blit = SDL_BlitScaled;
- } else {
- dst_rect.w = src_rect.w;
- dst_rect.h = src_rect.h;
- blit = SDL_BlitSurface;
- }
- //calculate destination position
- if(neg_pos_margin){
- if(x >= 0) dst_rect.x = x;
- else if(x != KIT_CENTER_TEXT) dst_rect.x = surf_dst->w - dst_rect.w + x + 1;
- else dst_rect.x = surf_dst->w/2 - dst_rect.w/2;
- if(y >= 0) dst_rect.y = y;
- else if(y != KIT_CENTER_TEXT) dst_rect.y = surf_dst->h - dst_rect.h + y + 1;
- else dst_rect.y = surf_dst->h/2 - dst_rect.h/2;
- } else {
- dst_rect.x = x;
- dst_rect.y = y;
- }
- //dst_rect before blit gets the chance to clobber it
- shape::rect _dst_rect = dst_rect;
- src_rect.x = ( chr &15)*(src_rect.w+1);
- src_rect.y = ((chr>>4)&15)*(src_rect.h+1);
- if(blit(SURF_SRC, (SDL_Rect*)&src_rect,
- surf_dst, (SDL_Rect*)&dst_rect)<0)
- {
- THROW_ERRORF("%s: %s", FUNC_NAME, SDL_GetError());
- }
- return _dst_rect;
- }
- #undef FUNC_NAME
- #define FUNC_NAME "BFont_Surface::format()"
- u8* BFont_Surface::format(const char* fmt, ...){
- FMT(fmt);
- return _fmtBuffer;
- }
- }; /* namespace kit */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement