mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 08:04:40 +00:00
Somebody broke SDL when they updated it. The new version depends on AudioToolbox, so added that as dependency in torque3d.cmake
This commit is contained in:
parent
0c6174b045
commit
de53ac86c7
82 changed files with 2082 additions and 1035 deletions
|
|
@ -13,7 +13,10 @@ TARGETS = \
|
|||
loopwavequeue$(EXE) \
|
||||
testatomic$(EXE) \
|
||||
testaudioinfo$(EXE) \
|
||||
testaudiocapture$(EXE) \
|
||||
testautomation$(EXE) \
|
||||
testbounds$(EXE) \
|
||||
testcustomcursor$(EXE) \
|
||||
testdraw2$(EXE) \
|
||||
testdrawchessboard$(EXE) \
|
||||
testdropfile$(EXE) \
|
||||
|
|
@ -61,6 +64,7 @@ TARGETS = \
|
|||
testrendercopyex$(EXE) \
|
||||
testmessage$(EXE) \
|
||||
testdisplayinfo$(EXE) \
|
||||
testqsort$(EXE) \
|
||||
controllermap$(EXE) \
|
||||
|
||||
all: Makefile $(TARGETS)
|
||||
|
|
@ -110,6 +114,9 @@ testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c
|
|||
testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testaudiocapture$(EXE): $(srcdir)/testaudiocapture.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testatomic$(EXE): $(srcdir)/testatomic.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
|
@ -270,6 +277,15 @@ testmessage$(EXE): $(srcdir)/testmessage.c
|
|||
testdisplayinfo$(EXE): $(srcdir)/testdisplayinfo.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testqsort$(EXE): $(srcdir)/testqsort.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testbounds$(EXE): $(srcdir)/testbounds.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
testcustomcursor$(EXE): $(srcdir)/testcustomcursor.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
controllermap$(EXE): $(srcdir)/controllermap.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
|
||||
|
||||
|
|
|
|||
0
Engine/lib/sdl/test/autogen.sh
Normal file → Executable file
0
Engine/lib/sdl/test/autogen.sh
Normal file → Executable file
0
Engine/lib/sdl/test/configure
vendored
Normal file → Executable file
0
Engine/lib/sdl/test/configure
vendored
Normal file → Executable file
|
|
@ -26,12 +26,9 @@
|
|||
#define SCREEN_HEIGHT 480
|
||||
#else
|
||||
#define SCREEN_WIDTH 512
|
||||
#define SCREEN_HEIGHT 317
|
||||
#define SCREEN_HEIGHT 320
|
||||
#endif
|
||||
|
||||
#define MAP_WIDTH 512
|
||||
#define MAP_HEIGHT 317
|
||||
|
||||
#define MARKER_BUTTON 1
|
||||
#define MARKER_AXIS 2
|
||||
|
||||
|
|
@ -47,7 +44,7 @@ typedef struct MappingStep
|
|||
|
||||
|
||||
SDL_Texture *
|
||||
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
|
||||
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
|
||||
{
|
||||
SDL_Surface *temp;
|
||||
SDL_Texture *texture;
|
||||
|
|
@ -226,7 +223,7 @@ WatchJoystick(SDL_Joystick * joystick)
|
|||
SDL_RenderCopy(screen, background, NULL, NULL);
|
||||
SDL_SetTextureAlphaMod(marker, alpha);
|
||||
SDL_SetTextureColorMod(marker, 10, 255, 21);
|
||||
SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, 0);
|
||||
SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, SDL_FLIP_NONE);
|
||||
SDL_RenderPresent(screen);
|
||||
|
||||
if (SDL_PollEvent(&event)) {
|
||||
|
|
|
|||
0
Engine/lib/sdl/test/gcc-fat.sh
Normal file → Executable file
0
Engine/lib/sdl/test/gcc-fat.sh
Normal file → Executable file
|
|
@ -284,7 +284,7 @@ typedef struct
|
|||
char cache_pad4[SDL_CACHELINE_SIZE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)];
|
||||
#endif
|
||||
|
||||
volatile SDL_bool active;
|
||||
SDL_atomic_t active;
|
||||
|
||||
/* Only needed for the mutex test */
|
||||
SDL_mutex *mutex;
|
||||
|
|
@ -305,7 +305,7 @@ static void InitEventQueue(SDL_EventQueue *queue)
|
|||
SDL_AtomicSet(&queue->rwcount, 0);
|
||||
SDL_AtomicSet(&queue->watcher, 0);
|
||||
#endif
|
||||
queue->active = SDL_TRUE;
|
||||
SDL_AtomicSet(&queue->active, 1);
|
||||
}
|
||||
|
||||
static SDL_bool EnqueueEvent_LockFree(SDL_EventQueue *queue, const SDL_Event *event)
|
||||
|
|
@ -538,7 +538,7 @@ static int FIFO_Reader(void* _data)
|
|||
if (DequeueEvent_LockFree(queue, &event)) {
|
||||
WriterData *writer = (WriterData*)event.user.data1;
|
||||
++data->counters[writer->index];
|
||||
} else if (queue->active) {
|
||||
} else if (SDL_AtomicGet(&queue->active)) {
|
||||
++data->waits;
|
||||
SDL_Delay(0);
|
||||
} else {
|
||||
|
|
@ -551,7 +551,7 @@ static int FIFO_Reader(void* _data)
|
|||
if (DequeueEvent_Mutex(queue, &event)) {
|
||||
WriterData *writer = (WriterData*)event.user.data1;
|
||||
++data->counters[writer->index];
|
||||
} else if (queue->active) {
|
||||
} else if (SDL_AtomicGet(&queue->active)) {
|
||||
++data->waits;
|
||||
SDL_Delay(0);
|
||||
} else {
|
||||
|
|
@ -571,7 +571,7 @@ static int FIFO_Watcher(void* _data)
|
|||
{
|
||||
SDL_EventQueue *queue = (SDL_EventQueue *)_data;
|
||||
|
||||
while (queue->active) {
|
||||
while (SDL_AtomicGet(&queue->active)) {
|
||||
SDL_AtomicLock(&queue->lock);
|
||||
SDL_AtomicIncRef(&queue->watcher);
|
||||
while (SDL_AtomicGet(&queue->rwcount) > 0) {
|
||||
|
|
@ -652,7 +652,7 @@ static void RunFIFOTest(SDL_bool lock_free)
|
|||
}
|
||||
|
||||
/* Shut down the queue so readers exit */
|
||||
queue.active = SDL_FALSE;
|
||||
SDL_AtomicSet(&queue.active, 0);
|
||||
|
||||
/* Wait for the readers */
|
||||
while (SDL_AtomicGet(&readersRunning) > 0) {
|
||||
|
|
|
|||
165
Engine/lib/sdl/test/testaudiocapture.c
Normal file
165
Engine/lib/sdl/test/testaudiocapture.c
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
#include "SDL.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
static SDL_Window *window = NULL;
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_AudioSpec spec;
|
||||
static SDL_AudioDeviceID devid_in = 0;
|
||||
static SDL_AudioDeviceID devid_out = 0;
|
||||
|
||||
static void
|
||||
loop()
|
||||
{
|
||||
SDL_bool please_quit = SDL_FALSE;
|
||||
SDL_Event e;
|
||||
|
||||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
please_quit = SDL_TRUE;
|
||||
} else if (e.type == SDL_KEYDOWN) {
|
||||
if (e.key.keysym.sym == SDLK_ESCAPE) {
|
||||
please_quit = SDL_TRUE;
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEBUTTONDOWN) {
|
||||
if (e.button.button == 1) {
|
||||
SDL_PauseAudioDevice(devid_out, SDL_TRUE);
|
||||
SDL_PauseAudioDevice(devid_in, SDL_FALSE);
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEBUTTONUP) {
|
||||
if (e.button.button == 1) {
|
||||
SDL_PauseAudioDevice(devid_in, SDL_TRUE);
|
||||
SDL_PauseAudioDevice(devid_out, SDL_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) {
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||
} else {
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
|
||||
}
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
if (please_quit) {
|
||||
/* stop playing back, quit. */
|
||||
SDL_Log("Shutting down.\n");
|
||||
SDL_PauseAudioDevice(devid_in, 1);
|
||||
SDL_CloseAudioDevice(devid_in);
|
||||
SDL_PauseAudioDevice(devid_out, 1);
|
||||
SDL_CloseAudioDevice(devid_out);
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_cancel_main_loop();
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Note that it would be easier to just have a one-line function that
|
||||
calls SDL_QueueAudio() as a capture device callback, but we're
|
||||
trying to test the API, so we use SDL_DequeueAudio() here. */
|
||||
while (SDL_TRUE) {
|
||||
Uint8 buf[1024];
|
||||
const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof (buf));
|
||||
SDL_QueueAudio(devid_out, buf, br);
|
||||
if (br < sizeof (buf)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
/* (argv[1] == NULL means "open default device.") */
|
||||
const char *devname = argv[1];
|
||||
SDL_AudioSpec wanted;
|
||||
int devcount;
|
||||
int i;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
/* Load the SDL library */
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
return (1);
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow("testaudiocapture", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0);
|
||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
|
||||
|
||||
devcount = SDL_GetNumAudioDevices(SDL_TRUE);
|
||||
for (i = 0; i < devcount; i++) {
|
||||
SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE));
|
||||
}
|
||||
|
||||
SDL_zero(wanted);
|
||||
wanted.freq = 44100;
|
||||
wanted.format = AUDIO_F32SYS;
|
||||
wanted.channels = 1;
|
||||
wanted.samples = 4096;
|
||||
wanted.callback = NULL;
|
||||
|
||||
SDL_zero(spec);
|
||||
|
||||
/* DirectSound can fail in some instances if you open the same hardware
|
||||
for both capture and output and didn't open the output end first,
|
||||
according to the docs, so if you're doing something like this, always
|
||||
open your capture devices second in case you land in those bizarre
|
||||
circumstances. */
|
||||
|
||||
SDL_Log("Opening default playback device...\n");
|
||||
devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
if (!devid_out) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_Log("Opening capture device %s%s%s...\n",
|
||||
devname ? "'" : "",
|
||||
devname ? devname : "[[default]]",
|
||||
devname ? "'" : "");
|
||||
|
||||
devid_in = SDL_OpenAudioDevice(argv[1], SDL_TRUE, &spec, &spec, 0);
|
||||
if (!devid_in) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SDL_Log("Ready! Hold down mouse or finger to record!\n");
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(loop, 0, 1);
|
||||
#else
|
||||
while (1) { loop(); SDL_Delay(16); }
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +74,12 @@ poked(int sig)
|
|||
done = 1;
|
||||
}
|
||||
|
||||
static const char*
|
||||
devtypestr(int iscapture)
|
||||
{
|
||||
return iscapture ? "capture" : "output";
|
||||
}
|
||||
|
||||
static void
|
||||
iteration()
|
||||
{
|
||||
|
|
@ -82,10 +88,21 @@ iteration()
|
|||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) {
|
||||
done = 1;
|
||||
} else if (e.type == SDL_KEYUP) {
|
||||
if (e.key.keysym.sym == SDLK_ESCAPE)
|
||||
done = 1;
|
||||
} else if (e.type == SDL_AUDIODEVICEADDED) {
|
||||
const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0);
|
||||
SDL_Log("New %s audio device: %s\n", e.adevice.iscapture ? "capture" : "output", name);
|
||||
if (!e.adevice.iscapture) {
|
||||
int index = e.adevice.which;
|
||||
int iscapture = e.adevice.iscapture;
|
||||
const char *name = SDL_GetAudioDeviceName(index, iscapture);
|
||||
if (name != NULL)
|
||||
SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name);
|
||||
else {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n",
|
||||
devtypestr(iscapture), (unsigned int) index, SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
if (!iscapture) {
|
||||
positions[posindex] = 0;
|
||||
spec.userdata = &positions[posindex++];
|
||||
spec.callback = fillerup;
|
||||
|
|
@ -99,7 +116,7 @@ iteration()
|
|||
}
|
||||
} else if (e.type == SDL_AUDIODEVICEREMOVED) {
|
||||
dev = (SDL_AudioDeviceID) e.adevice.which;
|
||||
SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int) dev);
|
||||
SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev);
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
}
|
||||
|
|
@ -163,6 +180,7 @@ main(int argc, char *argv[])
|
|||
SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
|
||||
}
|
||||
|
||||
SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n");
|
||||
SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
@ -175,6 +193,8 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/* Clean up on signal */
|
||||
/* Quit audio first, then free WAV. This prevents access violations in the audio threads. */
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
SDL_FreeWAV(sound);
|
||||
SDL_Quit();
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ print_devices(int iscapture)
|
|||
const char *typestr = ((iscapture) ? "capture" : "output");
|
||||
int n = SDL_GetNumAudioDevices(iscapture);
|
||||
|
||||
SDL_Log("%s devices:\n", typestr);
|
||||
SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : "");
|
||||
|
||||
if (n == -1)
|
||||
SDL_Log(" Driver can't detect specific %s devices.\n\n", typestr);
|
||||
|
|
@ -27,7 +27,11 @@ print_devices(int iscapture)
|
|||
else {
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
SDL_Log(" %s\n", SDL_GetAudioDeviceName(i, iscapture));
|
||||
const char *name = SDL_GetAudioDeviceName(i, iscapture);
|
||||
if (name != NULL)
|
||||
SDL_Log(" %d: %s\n", i, name);
|
||||
else
|
||||
SDL_Log(" %d Error: %s\n", i, SDL_GetError());
|
||||
}
|
||||
SDL_Log("\n");
|
||||
}
|
||||
|
|
@ -55,9 +59,9 @@ main(int argc, char **argv)
|
|||
int i;
|
||||
SDL_Log("Built-in audio drivers:\n");
|
||||
for (i = 0; i < n; ++i) {
|
||||
SDL_Log(" %s\n", SDL_GetAudioDriver(i));
|
||||
SDL_Log(" %d: %s\n", i, SDL_GetAudioDriver(i));
|
||||
}
|
||||
SDL_Log("\n");
|
||||
SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n");
|
||||
}
|
||||
|
||||
SDL_Log("Using audio driver: %s\n\n", SDL_GetCurrentAudioDriver());
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ events_addDelEventWatch(void *arg)
|
|||
|
||||
/* Create user event */
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = SDLTest_RandomSint32();;
|
||||
event.user.code = SDLTest_RandomSint32();
|
||||
event.user.data1 = (void *)&_userdataValue1;
|
||||
event.user.data2 = (void *)&_userdataValue2;
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ events_addDelEventWatchWithUserdata(void *arg)
|
|||
|
||||
/* Create user event */
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = SDLTest_RandomSint32();;
|
||||
event.user.code = SDLTest_RandomSint32();
|
||||
event.user.data1 = (void *)&_userdataValue1;
|
||||
event.user.data2 = (void *)&_userdataValue2;
|
||||
|
||||
|
|
|
|||
|
|
@ -401,8 +401,8 @@ keyboard_setTextInputRect(void *arg)
|
|||
SDL_Rect refRect;
|
||||
|
||||
/* Normal visible refRect, origin inside */
|
||||
refRect.x = SDLTest_RandomIntegerInRange(1, 50);;
|
||||
refRect.y = SDLTest_RandomIntegerInRange(1, 50);;
|
||||
refRect.x = SDLTest_RandomIntegerInRange(1, 50);
|
||||
refRect.y = SDLTest_RandomIntegerInRange(1, 50);
|
||||
refRect.w = SDLTest_RandomIntegerInRange(10, 50);
|
||||
refRect.h = SDLTest_RandomIntegerInRange(10, 50);
|
||||
_testSetTextInputRect(refRect);
|
||||
|
|
@ -415,8 +415,8 @@ keyboard_setTextInputRect(void *arg)
|
|||
_testSetTextInputRect(refRect);
|
||||
|
||||
/* 1Pixel refRect */
|
||||
refRect.x = SDLTest_RandomIntegerInRange(10, 50);;
|
||||
refRect.y = SDLTest_RandomIntegerInRange(10, 50);;
|
||||
refRect.x = SDLTest_RandomIntegerInRange(10, 50);
|
||||
refRect.y = SDLTest_RandomIntegerInRange(10, 50);
|
||||
refRect.w = 1;
|
||||
refRect.h = 1;
|
||||
_testSetTextInputRect(refRect);
|
||||
|
|
@ -450,15 +450,15 @@ keyboard_setTextInputRect(void *arg)
|
|||
_testSetTextInputRect(refRect);
|
||||
|
||||
/* negative refRect */
|
||||
refRect.x = SDLTest_RandomIntegerInRange(-200, -100);;
|
||||
refRect.y = SDLTest_RandomIntegerInRange(-200, -100);;
|
||||
refRect.x = SDLTest_RandomIntegerInRange(-200, -100);
|
||||
refRect.y = SDLTest_RandomIntegerInRange(-200, -100);
|
||||
refRect.w = 50;
|
||||
refRect.h = 50;
|
||||
_testSetTextInputRect(refRect);
|
||||
|
||||
/* oversized refRect */
|
||||
refRect.x = SDLTest_RandomIntegerInRange(1, 50);;
|
||||
refRect.y = SDLTest_RandomIntegerInRange(1, 50);;
|
||||
refRect.x = SDLTest_RandomIntegerInRange(1, 50);
|
||||
refRect.y = SDLTest_RandomIntegerInRange(1, 50);
|
||||
refRect.w = 5000;
|
||||
refRect.h = 5000;
|
||||
_testSetTextInputRect(refRect);
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ static const SDLTest_TestCaseReference mainTest3 =
|
|||
static const SDLTest_TestCaseReference mainTest4 =
|
||||
{ (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED};
|
||||
|
||||
/* Sequence of Platform test cases */
|
||||
/* Sequence of Main test cases */
|
||||
static const SDLTest_TestCaseReference *mainTests[] = {
|
||||
&mainTest1,
|
||||
&mainTest2,
|
||||
|
|
@ -146,7 +146,7 @@ static const SDLTest_TestCaseReference *mainTests[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
/* Platform test suite (global) */
|
||||
/* Main test suite (global) */
|
||||
SDLTest_TestSuiteReference mainTestSuite = {
|
||||
"Main",
|
||||
NULL,
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ sdltest_randomIntegerInRange(void *arg)
|
|||
SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result);
|
||||
|
||||
/* Range with max at integer limit */
|
||||
min = long_min - (Sint32)SDLTest_RandomSint16();;
|
||||
min = long_min - (Sint32)SDLTest_RandomSint16();
|
||||
max = long_max;
|
||||
result = SDLTest_RandomIntegerInRange(min, max);
|
||||
SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(...,SINT32_MAX)");
|
||||
|
|
|
|||
|
|
@ -253,6 +253,43 @@ stdlib_getsetenv(void *arg)
|
|||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to SDL_sscanf
|
||||
*/
|
||||
#undef SDL_sscanf
|
||||
int
|
||||
stdlib_sscanf(void *arg)
|
||||
{
|
||||
int output;
|
||||
int result;
|
||||
int expected_output;
|
||||
int expected_result;
|
||||
|
||||
expected_output = output = 123;
|
||||
expected_result = -1;
|
||||
result = SDL_sscanf("", "%i", &output);
|
||||
SDLTest_AssertPass("Call to SDL_sscanf(\"\", \"%%i\", &output)");
|
||||
SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output);
|
||||
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||
|
||||
expected_output = output = 123;
|
||||
expected_result = 0;
|
||||
result = SDL_sscanf("a", "%i", &output);
|
||||
SDLTest_AssertPass("Call to SDL_sscanf(\"a\", \"%%i\", &output)");
|
||||
SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output);
|
||||
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||
|
||||
output = 123;
|
||||
expected_output = 2;
|
||||
expected_result = 1;
|
||||
result = SDL_sscanf("2", "%i", &output);
|
||||
SDLTest_AssertPass("Call to SDL_sscanf(\"2\", \"%%i\", &output)");
|
||||
SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output);
|
||||
SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result);
|
||||
|
||||
return TEST_COMPLETED;
|
||||
}
|
||||
|
||||
/* ================= Test References ================== */
|
||||
|
||||
/* Standard C routine test cases */
|
||||
|
|
@ -265,12 +302,15 @@ static const SDLTest_TestCaseReference stdlibTest2 =
|
|||
static const SDLTest_TestCaseReference stdlibTest3 =
|
||||
{ (SDLTest_TestCaseFp)stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED };
|
||||
|
||||
static const SDLTest_TestCaseReference stdlibTest4 =
|
||||
{ (SDLTest_TestCaseFp)stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED };
|
||||
|
||||
/* Sequence of Standard C routine test cases */
|
||||
static const SDLTest_TestCaseReference *stdlibTests[] = {
|
||||
&stdlibTest1, &stdlibTest2, &stdlibTest3, NULL
|
||||
&stdlibTest1, &stdlibTest2, &stdlibTest3, &stdlibTest4, NULL
|
||||
};
|
||||
|
||||
/* Timer test suite (global) */
|
||||
/* Standard C routine test suite (global) */
|
||||
SDLTest_TestSuiteReference stdlibTestSuite = {
|
||||
"Stdlib",
|
||||
NULL,
|
||||
|
|
|
|||
40
Engine/lib/sdl/test/testbounds.c
Normal file
40
Engine/lib/sdl/test/testbounds.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int total, i;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
SDL_Log("SDL_Init(SDL_INIT_VIDEO) failed: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
total = SDL_GetNumVideoDisplays();
|
||||
for (i = 0; i < total; i++) {
|
||||
SDL_Rect bounds = { -1,-1,-1,-1 }, usable = { -1,-1,-1,-1 };
|
||||
SDL_GetDisplayBounds(i, &bounds);
|
||||
SDL_GetDisplayUsableBounds(i, &usable);
|
||||
SDL_Log("Display #%d ('%s'): bounds={(%d,%d),%dx%d}, usable={(%d,%d),%dx%d}",
|
||||
i, SDL_GetDisplayName(i),
|
||||
bounds.x, bounds.y, bounds.w, bounds.h,
|
||||
usable.x, usable.y, usable.w, usable.h);
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
216
Engine/lib/sdl/test/testcustomcursor.c
Normal file
216
Engine/lib/sdl/test/testcustomcursor.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_test_common.h"
|
||||
|
||||
/* Stolen from the mailing list */
|
||||
/* Creates a new mouse cursor from an XPM */
|
||||
|
||||
|
||||
/* XPM */
|
||||
static const char *arrow[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 3 1",
|
||||
/* colors */
|
||||
"X c #000000",
|
||||
". c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
"X ",
|
||||
"XX ",
|
||||
"X.X ",
|
||||
"X..X ",
|
||||
"X...X ",
|
||||
"X....X ",
|
||||
"X.....X ",
|
||||
"X......X ",
|
||||
"X.......X ",
|
||||
"X........X ",
|
||||
"X.....XXXXX ",
|
||||
"X..X..X ",
|
||||
"X.X X..X ",
|
||||
"XX X..X ",
|
||||
"X X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
"0,0"
|
||||
};
|
||||
|
||||
static SDL_Cursor*
|
||||
init_color_cursor(const char *file)
|
||||
{
|
||||
SDL_Cursor *cursor = NULL;
|
||||
SDL_Surface *surface = SDL_LoadBMP(file);
|
||||
if (surface) {
|
||||
cursor = SDL_CreateColorCursor(surface, 0, 0);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
init_system_cursor(const char *image[])
|
||||
{
|
||||
int i, row, col;
|
||||
Uint8 data[4*32];
|
||||
Uint8 mask[4*32];
|
||||
int hot_x, hot_y;
|
||||
|
||||
i = -1;
|
||||
for (row=0; row<32; ++row) {
|
||||
for (col=0; col<32; ++col) {
|
||||
if (col % 8) {
|
||||
data[i] <<= 1;
|
||||
mask[i] <<= 1;
|
||||
} else {
|
||||
++i;
|
||||
data[i] = mask[i] = 0;
|
||||
}
|
||||
switch (image[4+row][col]) {
|
||||
case 'X':
|
||||
data[i] |= 0x01;
|
||||
mask[i] |= 0x01;
|
||||
break;
|
||||
case '.':
|
||||
mask[i] |= 0x01;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
|
||||
return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
|
||||
}
|
||||
|
||||
static SDLTest_CommonState *state;
|
||||
int done;
|
||||
SDL_Cursor *cursor = NULL;
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
quit(int rc)
|
||||
{
|
||||
SDLTest_CommonQuit(state);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
void
|
||||
loop()
|
||||
{
|
||||
int i;
|
||||
SDL_Event event;
|
||||
/* Check for events */
|
||||
while (SDL_PollEvent(&event)) {
|
||||
SDLTest_CommonEvent(state, &event, &done);
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (done) {
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
const char *color_cursor = NULL;
|
||||
|
||||
/* Enable standard application logging */
|
||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
|
||||
if (!state) {
|
||||
return 1;
|
||||
}
|
||||
for (i = 1; i < argc;) {
|
||||
int consumed;
|
||||
|
||||
consumed = SDLTest_CommonArg(state, i);
|
||||
if (consumed == 0) {
|
||||
color_cursor = argv[i];
|
||||
break;
|
||||
}
|
||||
if (consumed < 0) {
|
||||
SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
|
||||
quit(1);
|
||||
}
|
||||
i += consumed;
|
||||
}
|
||||
|
||||
if (!SDLTest_CommonInit(state)) {
|
||||
quit(2);
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
}
|
||||
|
||||
if (color_cursor) {
|
||||
cursor = init_color_cursor(color_cursor);
|
||||
} else {
|
||||
cursor = init_system_cursor(arrow);
|
||||
}
|
||||
if (!cursor) {
|
||||
SDL_Log("Error, couldn't create cursor\n");
|
||||
quit(2);
|
||||
}
|
||||
SDL_SetCursor(cursor);
|
||||
|
||||
/* Main render loop */
|
||||
done = 0;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(loop, 0, 1);
|
||||
#else
|
||||
while (!done) {
|
||||
loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_FreeCursor(cursor);
|
||||
quit(0);
|
||||
|
||||
/* keep the compiler happy ... */
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -51,11 +51,18 @@ main(int argc, char *argv[])
|
|||
for (dpy = 0; dpy < num_displays; dpy++) {
|
||||
const int num_modes = SDL_GetNumDisplayModes(dpy);
|
||||
SDL_Rect rect = { 0, 0, 0, 0 };
|
||||
float ddpi, hdpi, vdpi;
|
||||
int m;
|
||||
|
||||
SDL_GetDisplayBounds(dpy, &rect);
|
||||
SDL_Log("%d: \"%s\" (%dx%d, (%d, %d)), %d modes.\n", dpy, SDL_GetDisplayName(dpy), rect.w, rect.h, rect.x, rect.y, num_modes);
|
||||
|
||||
if (SDL_GetDisplayDPI(dpy, &ddpi, &hdpi, &vdpi) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DPI: failed to query (%s)\n", SDL_GetError());
|
||||
} else {
|
||||
SDL_Log(" DPI: ddpi=%f; hdpi=%f; vdpi=%f\n", ddpi, hdpi, vdpi);
|
||||
}
|
||||
|
||||
if (SDL_GetCurrentDisplayMode(dpy, &mode) == -1) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " CURRENT: failed to query (%s)\n", SDL_GetError());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ main(int argc, char *argv[])
|
|||
|
||||
|
||||
/* Create window and renderer for given surface */
|
||||
window = SDL_CreateWindow("Chess Board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
|
||||
window = SDL_CreateWindow("Chess Board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
|
||||
if(!window)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n",SDL_GetError());
|
||||
|
|
|
|||
|
|
@ -77,9 +77,14 @@ main(int argc, char *argv[])
|
|||
while (SDL_PollEvent(&event)) {
|
||||
SDLTest_CommonEvent(state, &event, &done);
|
||||
|
||||
if (event.type == SDL_DROPFILE) {
|
||||
if (event.type == SDL_DROPBEGIN) {
|
||||
SDL_Log("Drop beginning on window %u", (unsigned int) event.drop.windowID);
|
||||
} else if (event.type == SDL_DROPCOMPLETE) {
|
||||
SDL_Log("Drop complete on window %u", (unsigned int) event.drop.windowID);
|
||||
} else if ((event.type == SDL_DROPFILE) || (event.type == SDL_DROPTEXT)) {
|
||||
const char *typestr = (event.type == SDL_DROPFILE) ? "File" : "Text";
|
||||
char *dropped_filedir = event.drop.file;
|
||||
SDL_Log("File dropped on window: %s", dropped_filedir);
|
||||
SDL_Log("%s dropped on window %u: %s", typestr, (unsigned int) event.drop.windowID, dropped_filedir);
|
||||
SDL_free(dropped_filedir);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,8 @@ main(int argc, char *argv[])
|
|||
if(base_path == NULL){
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find base path: %s\n",
|
||||
SDL_GetError());
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_Log("base path: '%s'\n", base_path);
|
||||
SDL_free(base_path);
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ main(int argc, char *argv[])
|
|||
if(pref_path == NULL){
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path: %s\n",
|
||||
SDL_GetError());
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
SDL_Log("pref path: '%s'\n", pref_path);
|
||||
SDL_free(pref_path);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#define SCREEN_HEIGHT 320
|
||||
#else
|
||||
#define SCREEN_WIDTH 512
|
||||
#define SCREEN_HEIGHT 317
|
||||
#define SCREEN_HEIGHT 320
|
||||
#endif
|
||||
|
||||
/* This is indexed by SDL_GameControllerButton. */
|
||||
|
|
@ -67,7 +67,7 @@ SDL_bool done = SDL_FALSE;
|
|||
SDL_Texture *background, *button, *axis;
|
||||
|
||||
static SDL_Texture *
|
||||
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
|
||||
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
|
||||
{
|
||||
SDL_Surface *temp = NULL;
|
||||
SDL_Texture *texture = NULL;
|
||||
|
|
@ -129,7 +129,7 @@ loop(void *arg)
|
|||
for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) {
|
||||
if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) {
|
||||
const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 };
|
||||
SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, 0);
|
||||
SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,11 +139,11 @@ loop(void *arg)
|
|||
if (value < -deadzone) {
|
||||
const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
|
||||
const double angle = axis_positions[i].angle;
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0);
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
|
||||
} else if (value > deadzone) {
|
||||
const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 };
|
||||
const double angle = axis_positions[i].angle + 180.0;
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0);
|
||||
SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +181,8 @@ WatchGameController(SDL_GameController * gamecontroller)
|
|||
window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT, 0);
|
||||
SDL_free(title);
|
||||
title = NULL;
|
||||
if (window == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
|
||||
return SDL_FALSE;
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ main(int argc, char *argv[])
|
|||
quit(2);
|
||||
}
|
||||
|
||||
context = SDL_calloc(state->num_windows, sizeof(context));
|
||||
context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context));
|
||||
if (context == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
|
||||
quit(2);
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
context = SDL_calloc(state->num_windows, sizeof(context));
|
||||
context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context));
|
||||
if (context == NULL) {
|
||||
SDL_Log("Out of memory!\n");
|
||||
quit(2);
|
||||
|
|
@ -640,7 +640,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
datas = SDL_calloc(state->num_windows, sizeof(shader_data));
|
||||
datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data));
|
||||
|
||||
/* Set rendering settings for each context */
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
/* A simple program to test the Input Method support in the SDL library (2.0+) */
|
||||
/* A simple program to test the Input Method support in the SDL library (2.0+)
|
||||
If you build without SDL_ttf, you can use the GNU Unifont hex file instead.
|
||||
Download at http://unifoundry.com/unifont.html */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -22,19 +24,342 @@
|
|||
|
||||
#include "SDL_test_common.h"
|
||||
|
||||
#define DEFAULT_PTSIZE 30
|
||||
#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
|
||||
#define DEFAULT_PTSIZE 30
|
||||
#ifdef HAVE_SDL_TTF
|
||||
#ifdef __MACOSX__
|
||||
#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf"
|
||||
#elif __WIN32__
|
||||
/* Some japanese font present on at least Windows 8.1. */
|
||||
#define DEFAULT_FONT "C:\\Windows\\Fonts\\yugothic.ttf"
|
||||
#else
|
||||
#define DEFAULT_FONT "NoDefaultFont.ttf"
|
||||
#endif
|
||||
#else
|
||||
#define DEFAULT_FONT "unifont-9.0.02.hex"
|
||||
#endif
|
||||
#define MAX_TEXT_LENGTH 256
|
||||
|
||||
static SDLTest_CommonState *state;
|
||||
static SDL_Rect textRect, markedRect;
|
||||
static SDL_Color lineColor = {0,0,0,0};
|
||||
static SDL_Color backColor = {255,255,255,0};
|
||||
static SDL_Color textColor = {0,0,0,0};
|
||||
static SDL_Color lineColor = {0,0,0,255};
|
||||
static SDL_Color backColor = {255,255,255,255};
|
||||
static SDL_Color textColor = {0,0,0,255};
|
||||
static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
|
||||
static int cursor = 0;
|
||||
#ifdef HAVE_SDL_TTF
|
||||
static TTF_Font *font;
|
||||
#else
|
||||
#define UNIFONT_MAX_CODEPOINT 0x1ffff
|
||||
#define UNIFONT_NUM_GLYPHS 0x20000
|
||||
/* Using 512x512 textures that are supported everywhere. */
|
||||
#define UNIFONT_TEXTURE_WIDTH 512
|
||||
#define UNIFONT_GLYPHS_IN_ROW (UNIFONT_TEXTURE_WIDTH / 16)
|
||||
#define UNIFONT_GLYPHS_IN_TEXTURE (UNIFONT_GLYPHS_IN_ROW * UNIFONT_GLYPHS_IN_ROW)
|
||||
#define UNIFONT_NUM_TEXTURES ((UNIFONT_NUM_GLYPHS + UNIFONT_GLYPHS_IN_TEXTURE - 1) / UNIFONT_GLYPHS_IN_TEXTURE)
|
||||
#define UNIFONT_TEXTURE_SIZE (UNIFONT_TEXTURE_WIDTH * UNIFONT_TEXTURE_WIDTH * 4)
|
||||
#define UNIFONT_TEXTURE_PITCH (UNIFONT_TEXTURE_WIDTH * 4)
|
||||
#define UNIFONT_DRAW_SCALE 2
|
||||
struct UnifontGlyph {
|
||||
Uint8 width;
|
||||
Uint8 data[32];
|
||||
} *unifontGlyph;
|
||||
static SDL_Texture **unifontTexture;
|
||||
static Uint8 unifontTextureLoaded[UNIFONT_NUM_TEXTURES] = {0};
|
||||
|
||||
/* Unifont loading code start */
|
||||
|
||||
static Uint8 dehex(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return 255;
|
||||
}
|
||||
|
||||
static Uint8 dehex2(char c1, char c2)
|
||||
{
|
||||
return (dehex(c1) << 4) | dehex(c2);
|
||||
}
|
||||
|
||||
static Uint8 validate_hex(const char *cp, size_t len, Uint32 *np)
|
||||
{
|
||||
Uint32 n = 0;
|
||||
for (; len > 0; cp++, len--)
|
||||
{
|
||||
Uint8 c = dehex(*cp);
|
||||
if (c == 255)
|
||||
return 0;
|
||||
n = (n << 4) | c;
|
||||
}
|
||||
if (np != NULL)
|
||||
*np = n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void unifont_init(const char *fontname)
|
||||
{
|
||||
Uint8 hexBuffer[65];
|
||||
Uint32 numGlyphs = 0;
|
||||
int lineNumber = 1;
|
||||
size_t bytesRead;
|
||||
SDL_RWops *hexFile;
|
||||
const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph);
|
||||
const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *);
|
||||
|
||||
/* Allocate memory for the glyph data so the file can be closed after initialization. */
|
||||
unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize);
|
||||
if (unifontGlyph == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for glyph data.\n", (int)(unifontGlyphSize + 1023) / 1024);
|
||||
exit(-1);
|
||||
}
|
||||
SDL_memset(unifontGlyph, 0, unifontGlyphSize);
|
||||
|
||||
/* Allocate memory for texture pointers for all renderers. */
|
||||
unifontTexture = (SDL_Texture **)SDL_malloc(unifontTextureSize);
|
||||
if (unifontTexture == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for texture pointer data.\n", (int)(unifontTextureSize + 1023) / 1024);
|
||||
exit(-1);
|
||||
}
|
||||
SDL_memset(unifontTexture, 0, unifontTextureSize);
|
||||
|
||||
hexFile = SDL_RWFromFile(fontname, "rb");
|
||||
if (hexFile == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Read all the glyph data into memory to make it accessible later when textures are created. */
|
||||
do {
|
||||
int i, codepointHexSize;
|
||||
size_t bytesOverread;
|
||||
Uint8 glyphWidth;
|
||||
Uint32 codepoint;
|
||||
|
||||
bytesRead = SDL_RWread(hexFile, hexBuffer, 1, 9);
|
||||
if (numGlyphs > 0 && bytesRead == 0)
|
||||
break; /* EOF */
|
||||
if ((numGlyphs == 0 && bytesRead == 0) || (numGlyphs > 0 && bytesRead < 9))
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unfiont: Unexpected end of hex file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Looking for the colon that separates the codepoint and glyph data at position 2, 4, 6 and 8. */
|
||||
if (hexBuffer[2] == ':')
|
||||
codepointHexSize = 2;
|
||||
else if (hexBuffer[4] == ':')
|
||||
codepointHexSize = 4;
|
||||
else if (hexBuffer[6] == ':')
|
||||
codepointHexSize = 6;
|
||||
else if (hexBuffer[8] == ':')
|
||||
codepointHexSize = 8;
|
||||
else
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Could not find codepoint and glyph data separator symbol in hex file on line %d.\n", lineNumber);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!validate_hex((const char *)hexBuffer, codepointHexSize, &codepoint))
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal number in hex file on line %d.\n", lineNumber);
|
||||
exit(-1);
|
||||
}
|
||||
if (codepoint > UNIFONT_MAX_CODEPOINT)
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Codepoint on line %d exceeded limit of 0x%x.\n", lineNumber, UNIFONT_MAX_CODEPOINT);
|
||||
|
||||
/* If there was glyph data read in the last file read, move it to the front of the buffer. */
|
||||
bytesOverread = 8 - codepointHexSize;
|
||||
if (codepointHexSize < 8)
|
||||
SDL_memmove(hexBuffer, hexBuffer + codepointHexSize + 1, bytesOverread);
|
||||
bytesRead = SDL_RWread(hexFile, hexBuffer + bytesOverread, 1, 33 - bytesOverread);
|
||||
if (bytesRead < (33 - bytesOverread))
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (hexBuffer[32] == '\n')
|
||||
glyphWidth = 8;
|
||||
else
|
||||
{
|
||||
glyphWidth = 16;
|
||||
bytesRead = SDL_RWread(hexFile, hexBuffer + 33, 1, 32);
|
||||
if (bytesRead < 32)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!validate_hex((const char *)hexBuffer, glyphWidth * 4, NULL))
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal glyph data in hex file on line %d.\n", lineNumber);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (codepoint <= UNIFONT_MAX_CODEPOINT)
|
||||
{
|
||||
if (unifontGlyph[codepoint].width > 0)
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Ignoring duplicate codepoint 0x%08x in hex file on line %d.\n", codepoint, lineNumber);
|
||||
else
|
||||
{
|
||||
unifontGlyph[codepoint].width = glyphWidth;
|
||||
/* Pack the hex data into a more compact form. */
|
||||
for (i = 0; i < glyphWidth * 2; i++)
|
||||
unifontGlyph[codepoint].data[i] = dehex2(hexBuffer[i * 2], hexBuffer[i * 2 + 1]);
|
||||
numGlyphs++;
|
||||
}
|
||||
}
|
||||
|
||||
lineNumber++;
|
||||
} while (bytesRead > 0);
|
||||
|
||||
SDL_RWclose(hexFile);
|
||||
SDL_Log("unifont: Loaded %u glyphs.\n", numGlyphs);
|
||||
}
|
||||
|
||||
static void unifont_make_rgba(Uint8 *src, Uint8 *dst, Uint8 width)
|
||||
{
|
||||
int i, j;
|
||||
Uint8 *row = dst;
|
||||
|
||||
for (i = 0; i < width * 2; i++)
|
||||
{
|
||||
Uint8 data = src[i];
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (data & 0x80)
|
||||
{
|
||||
row[0] = textColor.r;
|
||||
row[1] = textColor.g;
|
||||
row[2] = textColor.b;
|
||||
row[3] = textColor.a;
|
||||
}
|
||||
else
|
||||
{
|
||||
row[0] = 0;
|
||||
row[1] = 0;
|
||||
row[2] = 0;
|
||||
row[3] = 0;
|
||||
}
|
||||
data <<= 1;
|
||||
row += 4;
|
||||
}
|
||||
|
||||
if (width == 8 || (width == 16 && i % 2 == 1))
|
||||
{
|
||||
dst += UNIFONT_TEXTURE_PITCH;
|
||||
row = dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void unifont_load_texture(Uint32 textureID)
|
||||
{
|
||||
int i;
|
||||
Uint8 * textureRGBA;
|
||||
|
||||
if (textureID >= UNIFONT_NUM_TEXTURES)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Tried to load out of range texture %u.\n", textureID);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
textureRGBA = (Uint8 *)SDL_malloc(UNIFONT_TEXTURE_SIZE);
|
||||
if (textureRGBA == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d MiB for a texture.\n", UNIFONT_TEXTURE_SIZE / 1024 / 1024);
|
||||
exit(-1);
|
||||
}
|
||||
SDL_memset(textureRGBA, 0, UNIFONT_TEXTURE_SIZE);
|
||||
|
||||
/* Copy the glyphs into memory in RGBA format. */
|
||||
for (i = 0; i < UNIFONT_GLYPHS_IN_TEXTURE; i++)
|
||||
{
|
||||
Uint32 codepoint = UNIFONT_GLYPHS_IN_TEXTURE * textureID + i;
|
||||
if (unifontGlyph[codepoint].width > 0)
|
||||
{
|
||||
const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE;
|
||||
const size_t offset = (cInTex / UNIFONT_GLYPHS_IN_ROW) * UNIFONT_TEXTURE_PITCH * 16 + (cInTex % UNIFONT_GLYPHS_IN_ROW) * 16 * 4;
|
||||
unifont_make_rgba(unifontGlyph[codepoint].data, textureRGBA + offset, unifontGlyph[codepoint].width);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create textures and upload the RGBA data from above. */
|
||||
for (i = 0; i < state->num_windows; ++i)
|
||||
{
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID];
|
||||
if (state->windows[i] == NULL || renderer == NULL || tex != NULL)
|
||||
continue;
|
||||
tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, UNIFONT_TEXTURE_WIDTH, UNIFONT_TEXTURE_WIDTH);
|
||||
if (tex == NULL)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to create texture %u for renderer %d.\n", textureID, i);
|
||||
exit(-1);
|
||||
}
|
||||
unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID] = tex;
|
||||
SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
|
||||
if (SDL_UpdateTexture(tex, NULL, textureRGBA, UNIFONT_TEXTURE_PITCH) != 0)
|
||||
{
|
||||
SDL_Log("unifont error: Failed to update texture %u data for renderer %d.\n", textureID, i);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(textureRGBA);
|
||||
unifontTextureLoaded[textureID] = 1;
|
||||
}
|
||||
|
||||
static Sint32 unifont_draw_glyph(Uint32 codepoint, int rendererID, SDL_Rect *dstrect)
|
||||
{
|
||||
SDL_Texture *texture;
|
||||
const Uint32 textureID = codepoint / UNIFONT_GLYPHS_IN_TEXTURE;
|
||||
SDL_Rect srcrect;
|
||||
srcrect.w = srcrect.h = 16;
|
||||
if (codepoint > UNIFONT_MAX_CODEPOINT)
|
||||
return 0;
|
||||
if (!unifontTextureLoaded[textureID])
|
||||
unifont_load_texture(textureID);
|
||||
texture = unifontTexture[UNIFONT_NUM_TEXTURES * rendererID + textureID];
|
||||
if (texture != NULL)
|
||||
{
|
||||
const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE;
|
||||
srcrect.x = cInTex % UNIFONT_GLYPHS_IN_ROW * 16;
|
||||
srcrect.y = cInTex / UNIFONT_GLYPHS_IN_ROW * 16;
|
||||
SDL_RenderCopy(state->renderers[rendererID], texture, &srcrect, dstrect);
|
||||
}
|
||||
return unifontGlyph[codepoint].width;
|
||||
}
|
||||
|
||||
static void unifont_cleanup()
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < state->num_windows; ++i)
|
||||
{
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
if (state->windows[i] == NULL || renderer == NULL)
|
||||
continue;
|
||||
for (j = 0; j < UNIFONT_NUM_TEXTURES; j++)
|
||||
{
|
||||
SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + j];
|
||||
if (tex != NULL)
|
||||
SDL_DestroyTexture(tex);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < UNIFONT_NUM_TEXTURES; j++)
|
||||
unifontTextureLoaded[j] = 0;
|
||||
|
||||
SDL_free(unifontTexture);
|
||||
SDL_free(unifontGlyph);
|
||||
}
|
||||
|
||||
/* Unifont code end */
|
||||
#endif
|
||||
|
||||
size_t utf8_length(unsigned char c)
|
||||
|
|
@ -78,6 +403,30 @@ char *utf8_advance(char *p, size_t distance)
|
|||
return p;
|
||||
}
|
||||
|
||||
Uint32 utf8_decode(char *p, size_t len)
|
||||
{
|
||||
Uint32 codepoint = 0;
|
||||
size_t i = 0;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
for (; i < len; ++i)
|
||||
{
|
||||
if (i == 0)
|
||||
codepoint = (0xff >> len) & *p;
|
||||
else
|
||||
{
|
||||
codepoint <<= 6;
|
||||
codepoint |= 0x3f & *p;
|
||||
}
|
||||
if (!*p)
|
||||
return 0;
|
||||
p++;
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
SDL_Log("usage: testime [--font fontfile]\n");
|
||||
|
|
@ -105,34 +454,61 @@ void CleanupVideo()
|
|||
#ifdef HAVE_SDL_TTF
|
||||
TTF_CloseFont(font);
|
||||
TTF_Quit();
|
||||
#else
|
||||
unifont_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
void _Redraw(int rendererID) {
|
||||
SDL_Renderer * renderer = state->renderers[rendererID];
|
||||
SDL_Rect drawnTextRect, cursorRect, underlineRect;
|
||||
drawnTextRect = textRect;
|
||||
drawnTextRect.w = 0;
|
||||
|
||||
void _Redraw(SDL_Renderer * renderer) {
|
||||
int w = 0, h = textRect.h;
|
||||
SDL_Rect cursorRect, underlineRect;
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
|
||||
SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a);
|
||||
SDL_RenderFillRect(renderer,&textRect);
|
||||
|
||||
#ifdef HAVE_SDL_TTF
|
||||
if (*text)
|
||||
{
|
||||
#ifdef HAVE_SDL_TTF
|
||||
SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor);
|
||||
SDL_Rect dest = {textRect.x, textRect.y, textSur->w, textSur->h };
|
||||
SDL_Texture *texture;
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
||||
/* Vertically center text */
|
||||
drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2;
|
||||
drawnTextRect.w = textSur->w;
|
||||
drawnTextRect.h = textSur->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
||||
SDL_FreeSurface(textSur);
|
||||
|
||||
SDL_RenderCopy(renderer,texture,NULL,&dest);
|
||||
SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect);
|
||||
SDL_DestroyTexture(texture);
|
||||
TTF_SizeUTF8(font, text, &w, &h);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
char *utext = text;
|
||||
Uint32 codepoint;
|
||||
size_t len;
|
||||
SDL_Rect dstrect;
|
||||
|
||||
markedRect.x = textRect.x + w;
|
||||
markedRect.w = textRect.w - w;
|
||||
dstrect.x = textRect.x;
|
||||
dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2;
|
||||
dstrect.w = 16 * UNIFONT_DRAW_SCALE;
|
||||
dstrect.h = 16 * UNIFONT_DRAW_SCALE;
|
||||
drawnTextRect.y = dstrect.y;
|
||||
drawnTextRect.h = dstrect.h;
|
||||
|
||||
while ((codepoint = utf8_decode(utext, len = utf8_length(*utext))))
|
||||
{
|
||||
Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE;
|
||||
dstrect.x += advance;
|
||||
drawnTextRect.w += advance;
|
||||
utext += len;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
markedRect.x = textRect.x + drawnTextRect.w;
|
||||
markedRect.w = textRect.w - drawnTextRect.w;
|
||||
if (markedRect.w < 0)
|
||||
{
|
||||
/* Stop text input because we cannot hold any more characters */
|
||||
|
|
@ -144,49 +520,88 @@ void _Redraw(SDL_Renderer * renderer) {
|
|||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
cursorRect = markedRect;
|
||||
cursorRect = drawnTextRect;
|
||||
cursorRect.x += cursorRect.w;
|
||||
cursorRect.w = 2;
|
||||
cursorRect.h = h;
|
||||
cursorRect.h = drawnTextRect.h;
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
|
||||
drawnTextRect.x += drawnTextRect.w;
|
||||
drawnTextRect.w = 0;
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a);
|
||||
SDL_RenderFillRect(renderer,&markedRect);
|
||||
|
||||
if (markedText[0])
|
||||
{
|
||||
#ifdef HAVE_SDL_TTF
|
||||
SDL_Surface *textSur;
|
||||
SDL_Texture *texture;
|
||||
if (cursor)
|
||||
{
|
||||
char *p = utf8_advance(markedText, cursor);
|
||||
char c = 0;
|
||||
if (!p)
|
||||
p = &markedText[strlen(markedText)];
|
||||
p = &markedText[SDL_strlen(markedText)];
|
||||
|
||||
c = *p;
|
||||
*p = 0;
|
||||
TTF_SizeUTF8(font, markedText, &w, 0);
|
||||
cursorRect.x += w;
|
||||
TTF_SizeUTF8(font, markedText, &drawnTextRect.w, NULL);
|
||||
cursorRect.x += drawnTextRect.w;
|
||||
*p = c;
|
||||
}
|
||||
SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, markedText, textColor);
|
||||
SDL_Rect dest = {markedRect.x, markedRect.y, textSur->w, textSur->h };
|
||||
TTF_SizeUTF8(font, markedText, &w, &h);
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
||||
textSur = TTF_RenderUTF8_Blended(font, markedText, textColor);
|
||||
/* Vertically center text */
|
||||
drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2;
|
||||
drawnTextRect.w = textSur->w;
|
||||
drawnTextRect.h = textSur->h;
|
||||
|
||||
texture = SDL_CreateTextureFromSurface(renderer,textSur);
|
||||
SDL_FreeSurface(textSur);
|
||||
|
||||
SDL_RenderCopy(renderer,texture,NULL,&dest);
|
||||
SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect);
|
||||
SDL_DestroyTexture(texture);
|
||||
#else
|
||||
int i = 0;
|
||||
char *utext = markedText;
|
||||
Uint32 codepoint;
|
||||
size_t len;
|
||||
SDL_Rect dstrect;
|
||||
|
||||
dstrect.x = drawnTextRect.x;
|
||||
dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2;
|
||||
dstrect.w = 16 * UNIFONT_DRAW_SCALE;
|
||||
dstrect.h = 16 * UNIFONT_DRAW_SCALE;
|
||||
drawnTextRect.y = dstrect.y;
|
||||
drawnTextRect.h = dstrect.h;
|
||||
|
||||
while ((codepoint = utf8_decode(utext, len = utf8_length(*utext))))
|
||||
{
|
||||
Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE;
|
||||
dstrect.x += advance;
|
||||
drawnTextRect.w += advance;
|
||||
if (i < cursor)
|
||||
cursorRect.x += advance;
|
||||
i++;
|
||||
utext += len;
|
||||
}
|
||||
#endif
|
||||
|
||||
underlineRect = markedRect;
|
||||
underlineRect.y += (h - 2);
|
||||
underlineRect.h = 2;
|
||||
underlineRect.w = w;
|
||||
if (cursor > 0)
|
||||
{
|
||||
cursorRect.y = drawnTextRect.y;
|
||||
cursorRect.h = drawnTextRect.h;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0,0,0,0);
|
||||
SDL_RenderFillRect(renderer,&markedRect);
|
||||
underlineRect = markedRect;
|
||||
underlineRect.y = drawnTextRect.y + drawnTextRect.h - 2;
|
||||
underlineRect.h = 2;
|
||||
underlineRect.w = drawnTextRect.w;
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a);
|
||||
SDL_RenderFillRect(renderer, &underlineRect);
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, 0,0,0,0);
|
||||
SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a);
|
||||
SDL_RenderFillRect(renderer,&cursorRect);
|
||||
|
||||
SDL_SetTextInputRect(&markedRect);
|
||||
|
|
@ -201,7 +616,8 @@ void Redraw() {
|
|||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
_Redraw(renderer);
|
||||
/* Sending in the window id to let the font renderers know which one we're working with. */
|
||||
_Redraw(i);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
|
@ -259,6 +675,8 @@ int main(int argc, char *argv[]) {
|
|||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to find font: %s\n", TTF_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
unifont_init(fontname);
|
||||
#endif
|
||||
|
||||
SDL_Log("Using font: %s\n", fontname);
|
||||
|
|
@ -288,6 +706,8 @@ int main(int argc, char *argv[]) {
|
|||
Redraw();
|
||||
break;
|
||||
case SDLK_BACKSPACE:
|
||||
/* Only delete text if not in editing mode. */
|
||||
if (!markedText[0])
|
||||
{
|
||||
size_t textlen = SDL_strlen(text);
|
||||
|
||||
|
|
@ -354,7 +774,7 @@ int main(int argc, char *argv[]) {
|
|||
SDL_Log("text editing \"%s\", selected range (%d, %d)\n",
|
||||
event.edit.text, event.edit.start, event.edit.length);
|
||||
|
||||
strcpy(markedText, event.edit.text);
|
||||
SDL_strlcpy(markedText, event.edit.text, SDL_TEXTEDITINGEVENT_TEXT_SIZE);
|
||||
cursor = event.edit.start;
|
||||
Redraw();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
static SDL_mutex *mutex = NULL;
|
||||
static SDL_threadID mainthread;
|
||||
static SDL_Thread *threads[6];
|
||||
static volatile int doterminate = 0;
|
||||
static SDL_atomic_t doterminate;
|
||||
|
||||
/*
|
||||
* SDL_Quit() shouldn't be used with atexit() directly because
|
||||
|
|
@ -45,7 +45,7 @@ void
|
|||
terminate(int sig)
|
||||
{
|
||||
signal(SIGINT, terminate);
|
||||
doterminate = 1;
|
||||
SDL_AtomicSet(&doterminate, 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -54,7 +54,7 @@ closemutex(int sig)
|
|||
SDL_threadID id = SDL_ThreadID();
|
||||
int i;
|
||||
SDL_Log("Process %lu: Cleaning up...\n", id == mainthread ? 0 : id);
|
||||
doterminate = 1;
|
||||
SDL_AtomicSet(&doterminate, 1);
|
||||
for (i = 0; i < 6; ++i)
|
||||
SDL_WaitThread(threads[i], NULL);
|
||||
SDL_DestroyMutex(mutex);
|
||||
|
|
@ -66,7 +66,7 @@ Run(void *data)
|
|||
{
|
||||
if (SDL_ThreadID() == mainthread)
|
||||
signal(SIGTERM, closemutex);
|
||||
while (!doterminate) {
|
||||
while (!SDL_AtomicGet(&doterminate)) {
|
||||
SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
|
||||
if (SDL_LockMutex(mutex) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
|
||||
|
|
@ -82,7 +82,7 @@ Run(void *data)
|
|||
/* If this sleep isn't done, then threads may starve */
|
||||
SDL_Delay(10);
|
||||
}
|
||||
if (SDL_ThreadID() == mainthread && doterminate) {
|
||||
if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) {
|
||||
SDL_Log("Process %lu: raising SIGTERM\n", SDL_ThreadID());
|
||||
raise(SIGTERM);
|
||||
}
|
||||
|
|
@ -105,6 +105,8 @@ main(int argc, char *argv[])
|
|||
}
|
||||
atexit(SDL_Quit_Wrapper);
|
||||
|
||||
SDL_AtomicSet(&doterminate, 0);
|
||||
|
||||
if ((mutex = SDL_CreateMutex()) == NULL) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ typedef struct
|
|||
{
|
||||
SDL_AudioDeviceID dev;
|
||||
int soundpos;
|
||||
volatile int done;
|
||||
SDL_atomic_t done;
|
||||
} callback_data;
|
||||
|
||||
callback_data cbd[64];
|
||||
|
|
@ -46,14 +46,14 @@ play_through_once(void *arg, Uint8 * stream, int len)
|
|||
if (len > 0) {
|
||||
stream += cpy;
|
||||
SDL_memset(stream, spec.silence, len);
|
||||
cbd->done++;
|
||||
SDL_AtomicSet(&cbd->done, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
loop()
|
||||
{
|
||||
if(cbd[0].done) {
|
||||
if (SDL_AtomicGet(&cbd[0].done)) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_cancel_main_loop();
|
||||
#endif
|
||||
|
|
@ -100,8 +100,7 @@ test_multi_audio(int devcount)
|
|||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_main_loop(loop, 0, 1);
|
||||
#else
|
||||
while (!cbd[0].done)
|
||||
{
|
||||
while (!SDL_AtomicGet(&cbd[0].done)) {
|
||||
#ifdef __ANDROID__
|
||||
/* Empty queue, some application events would prevent pause. */
|
||||
while (SDL_PollEvent(&event)){}
|
||||
|
|
@ -136,7 +135,7 @@ test_multi_audio(int devcount)
|
|||
while (keep_going) {
|
||||
keep_going = 0;
|
||||
for (i = 0; i < devcount; i++) {
|
||||
if ((cbd[i].dev) && (!cbd[i].done)) {
|
||||
if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) {
|
||||
keep_going = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
108
Engine/lib/sdl/test/testqsort.c
Normal file
108
Engine/lib/sdl/test/testqsort.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely.
|
||||
*/
|
||||
|
||||
#include "SDL_test.h"
|
||||
|
||||
static int
|
||||
num_compare(const void *_a, const void *_b)
|
||||
{
|
||||
const int a = *((const int *) _a);
|
||||
const int b = *((const int *) _b);
|
||||
return (a < b) ? -1 : ((a > b) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort(const char *desc, int *nums, const int arraylen)
|
||||
{
|
||||
int i;
|
||||
int prev;
|
||||
|
||||
SDL_Log("test: %s arraylen=%d", desc, arraylen);
|
||||
|
||||
SDL_qsort(nums, arraylen, sizeof (nums[0]), num_compare);
|
||||
|
||||
prev = nums[0];
|
||||
for (i = 1; i < arraylen; i++) {
|
||||
const int val = nums[i];
|
||||
if (val < prev) {
|
||||
SDL_Log("sort is broken!");
|
||||
return;
|
||||
}
|
||||
prev = val;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
static int nums[1024 * 100];
|
||||
static const int itervals[] = { SDL_arraysize(nums), 12 };
|
||||
int iteration;
|
||||
SDLTest_RandomContext rndctx;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
int success;
|
||||
Uint64 seed = 0;
|
||||
if (argv[1][0] == '0' && argv[1][1] == 'x')
|
||||
success = SDL_sscanf(argv[1] + 2, "%llx", &seed);
|
||||
else
|
||||
success = SDL_sscanf(argv[1], "%llu", &seed);
|
||||
if (!success)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid seed. Use a decimal or hexadecimal number.\n");
|
||||
return 1;
|
||||
}
|
||||
if (seed <= 0xffffffff)
|
||||
{
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Seed must be equal or greater than 0x100000000.\n");
|
||||
return 1;
|
||||
}
|
||||
SDLTest_RandomInit(&rndctx, (unsigned int)(seed >> 32), (unsigned int)(seed & 0xffffffff));
|
||||
}
|
||||
else
|
||||
{
|
||||
SDLTest_RandomInitTime(&rndctx);
|
||||
}
|
||||
SDL_Log("Using random seed 0x%08x%08x\n", rndctx.x, rndctx.c);
|
||||
|
||||
for (iteration = 0; iteration < SDL_arraysize(itervals); iteration++) {
|
||||
const int arraylen = itervals[iteration];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < arraylen; i++) {
|
||||
nums[i] = i;
|
||||
}
|
||||
test_sort("already sorted", nums, arraylen);
|
||||
|
||||
for (i = 0; i < arraylen; i++) {
|
||||
nums[i] = i;
|
||||
}
|
||||
nums[arraylen-1] = -1;
|
||||
test_sort("already sorted except last element", nums, arraylen);
|
||||
|
||||
for (i = 0; i < arraylen; i++) {
|
||||
nums[i] = (arraylen-1) - i;
|
||||
}
|
||||
test_sort("reverse sorted", nums, arraylen);
|
||||
|
||||
for (i = 0; i < arraylen; i++) {
|
||||
nums[i] = SDLTest_RandomInt(&rndctx);
|
||||
}
|
||||
test_sort("random sorted", nums, arraylen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ quit(int rc)
|
|||
}
|
||||
|
||||
SDL_Texture *
|
||||
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
|
||||
LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
|
||||
{
|
||||
SDL_Surface *temp;
|
||||
SDL_Texture *texture;
|
||||
|
|
@ -126,7 +126,7 @@ Draw(DrawState *s)
|
|||
s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
|
||||
s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
|
||||
|
||||
SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, s->scale_direction);
|
||||
SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction);
|
||||
|
||||
SDL_SetRenderTarget(s->renderer, NULL);
|
||||
SDL_RenderCopy(s->renderer, target, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ int main(int argc,char** argv)
|
|||
|
||||
num_pictures = argc - 1;
|
||||
pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures);
|
||||
if (!pictures) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory.");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0;i<num_pictures;i++)
|
||||
pictures[i].surface = NULL;
|
||||
for(i=0;i<num_pictures;i++) {
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ quit(int rc)
|
|||
void
|
||||
loop()
|
||||
{
|
||||
int i;
|
||||
SDL_Event event;
|
||||
/* Check for events */
|
||||
while (SDL_PollEvent(&event)) {
|
||||
|
|
@ -100,6 +101,12 @@ loop()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (done) {
|
||||
emscripten_cancel_main_loop();
|
||||
|
|
@ -122,7 +129,6 @@ main(int argc, char *argv[])
|
|||
if (!state) {
|
||||
return 1;
|
||||
}
|
||||
state->skip_renderer = SDL_TRUE;
|
||||
for (i = 1; i < argc;) {
|
||||
int consumed;
|
||||
|
||||
|
|
@ -140,6 +146,12 @@ main(int argc, char *argv[])
|
|||
quit(2);
|
||||
}
|
||||
|
||||
for (i = 0; i < state->num_windows; ++i) {
|
||||
SDL_Renderer *renderer = state->renderers[i];
|
||||
SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
|
||||
SDL_RenderClear(renderer);
|
||||
}
|
||||
|
||||
/* Main render loop */
|
||||
done = 0;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#define NUMTHREADS 10
|
||||
|
||||
static char volatile time_for_threads_to_die[NUMTHREADS];
|
||||
static SDL_atomic_t time_for_threads_to_die[NUMTHREADS];
|
||||
|
||||
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
||||
static void
|
||||
|
|
@ -58,7 +58,7 @@ ThreadFunc(void *data)
|
|||
}
|
||||
|
||||
SDL_Log("Thread '%d' waiting for signal\n", tid);
|
||||
while (time_for_threads_to_die[tid] != 1) {
|
||||
while (SDL_AtomicGet(&time_for_threads_to_die[tid]) != 1) {
|
||||
; /* do nothing */
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ main(int argc, char *argv[])
|
|||
for (i = 0; i < NUMTHREADS; i++) {
|
||||
char name[64];
|
||||
SDL_snprintf(name, sizeof (name), "Parent%d", i);
|
||||
time_for_threads_to_die[i] = 0;
|
||||
SDL_AtomicSet(&time_for_threads_to_die[i], 0);
|
||||
threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i);
|
||||
|
||||
if (threads[i] == NULL) {
|
||||
|
|
@ -102,7 +102,7 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
for (i = 0; i < NUMTHREADS; i++) {
|
||||
time_for_threads_to_die[i] = 1;
|
||||
SDL_AtomicSet(&time_for_threads_to_die[i], 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMTHREADS; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue