Ver código fonte

test: Add some common code to load test resources

As well as reducing duplication, this lets the tests load their resources
from the SDL_GetBasePath() on platforms that support it, which is useful
if the tests are compiled along with the rest of SDL and installed below
/usr as manual tests, similar to GNOME's installed-tests convention.

Thanks to Ozkan Sezer for the OS/2 build glue.

Co-authored-by: Ozkan Sezer <sezeroz@gmail.com>
Signed-off-by: Simon McVittie <smcv@collabora.com>
Simon McVittie 3 anos atrás
pai
commit
76a7b629bf

+ 1 - 0
VisualC/tests/controllermap/controllermap.vcxproj

@@ -271,6 +271,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\controllermap.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 2 - 1
VisualC/tests/loopwave/loopwave.vcxproj

@@ -203,6 +203,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\Test\loopwave.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\..\test\sample.wav">
@@ -227,4 +228,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 1 - 0
VisualC/tests/testgamecontroller/testgamecontroller.vcxproj

@@ -271,6 +271,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\testgamecontroller.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 1 - 0
VisualC/tests/testoverlay2/testoverlay2.vcxproj

@@ -217,6 +217,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\testoverlay2.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
     <ClCompile Include="..\..\..\test\testyuv_cvt.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 2 - 1
VisualC/tests/testrendertarget/testrendertarget.vcxproj

@@ -241,8 +241,9 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\testrendertarget.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 1
VisualC/tests/testscale/testscale.vcxproj

@@ -241,8 +241,9 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\testscale.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 1
VisualC/tests/testsprite2/testsprite2.vcxproj

@@ -223,8 +223,9 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\test\testsprite2.c" />
+    <ClCompile Include="..\..\..\test\testutils.c" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 22 - 20
test/CMakeLists.txt

@@ -49,8 +49,8 @@ endif()
 
 add_executable(checkkeys checkkeys.c)
 add_executable(checkkeysthreads checkkeysthreads.c)
-add_executable(loopwave loopwave.c)
-add_executable(loopwavequeue loopwavequeue.c)
+add_executable(loopwave loopwave.c testutils.c)
+add_executable(loopwavequeue loopwavequeue.c testutils.c)
 add_executable(testsurround testsurround.c)
 add_executable(testresample testresample.c)
 add_executable(testaudioinfo testaudioinfo.c)
@@ -58,8 +58,8 @@ add_executable(testaudioinfo testaudioinfo.c)
 file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c)
 add_executable(testautomation ${TESTAUTOMATION_SOURCE_FILES})
 
-add_executable(testmultiaudio testmultiaudio.c)
-add_executable(testaudiohotplug testaudiohotplug.c)
+add_executable(testmultiaudio testmultiaudio.c testutils.c)
+add_executable(testaudiohotplug testaudiohotplug.c testutils.c)
 add_executable(testaudiocapture testaudiocapture.c)
 add_executable(testatomic testatomic.c)
 add_executable(testintersections testintersections.c)
@@ -75,8 +75,8 @@ if(LINUX)
 endif()
 
 add_executable(testfile testfile.c)
-add_executable(testgamecontroller testgamecontroller.c)
-add_executable(testgeometry testgeometry.c)
+add_executable(testgamecontroller testgamecontroller.c testutils.c)
+add_executable(testgeometry testgeometry.c testutils.c)
 add_executable(testgesture testgesture.c)
 add_executable(testgl2 testgl2.c)
 add_executable(testgles testgles.c)
@@ -85,8 +85,8 @@ add_executable(testhaptic testhaptic.c)
 add_executable(testhotplug testhotplug.c)
 add_executable(testrumble testrumble.c)
 add_executable(testthread testthread.c)
-add_executable(testiconv testiconv.c)
-add_executable(testime testime.c)
+add_executable(testiconv testiconv.c testutils.c)
+add_executable(testime testime.c testutils.c)
 add_executable(testjoystick testjoystick.c)
 add_executable(testkeys testkeys.c)
 add_executable(testloadso testloadso.c)
@@ -97,40 +97,42 @@ add_executable(testmouse testmouse.c)
 if(APPLE)
     add_executable(testnative testnative.c
                               testnativecocoa.m
-                              testnativex11.c)
+                              testnativex11.c
+                              testutils.c)
 elseif(WINDOWS)
-    add_executable(testnative testnative.c testnativew32.c)
+    add_executable(testnative testnative.c testnativew32.c testutils.c)
 elseif(UNIX)
-    add_executable(testnative testnative.c testnativex11.c)
+    add_executable(testnative testnative.c testnativex11.c testutils.c)
+    target_link_libraries(testnative X11)
 endif()
 
-add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c)
+add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c testutils.c)
 add_executable(testplatform testplatform.c)
 add_executable(testpower testpower.c)
 add_executable(testfilesystem testfilesystem.c)
-add_executable(testrendertarget testrendertarget.c)
-add_executable(testscale testscale.c)
+add_executable(testrendertarget testrendertarget.c testutils.c)
+add_executable(testscale testscale.c testutils.c)
 add_executable(testsem testsem.c)
 add_executable(testsensor testsensor.c)
 add_executable(testshader testshader.c)
 add_executable(testshape testshape.c)
-add_executable(testsprite2 testsprite2.c)
-add_executable(testspriteminimal testspriteminimal.c)
-add_executable(teststreaming teststreaming.c)
+add_executable(testsprite2 testsprite2.c testutils.c)
+add_executable(testspriteminimal testspriteminimal.c testutils.c)
+add_executable(teststreaming teststreaming.c testutils.c)
 add_executable(testtimer testtimer.c)
 add_executable(testurl testurl.c)
 add_executable(testver testver.c)
-add_executable(testviewport testviewport.c)
+add_executable(testviewport testviewport.c testutils.c)
 add_executable(testwm2 testwm2.c)
 add_executable(testyuv testyuv.c testyuv_cvt.c)
 add_executable(torturethread torturethread.c)
-add_executable(testrendercopyex testrendercopyex.c)
+add_executable(testrendercopyex testrendercopyex.c testutils.c)
 add_executable(testmessage testmessage.c)
 add_executable(testdisplayinfo testdisplayinfo.c)
 add_executable(testqsort testqsort.c)
 add_executable(testbounds testbounds.c)
 add_executable(testcustomcursor testcustomcursor.c)
-add_executable(controllermap controllermap.c)
+add_executable(controllermap controllermap.c testutils.c)
 add_executable(testvulkan testvulkan.c)
 add_executable(testoffscreen testoffscreen.c)
 

+ 21 - 18
test/Makefile.in

@@ -90,10 +90,10 @@ checkkeys$(EXE): $(srcdir)/checkkeys.c
 checkkeysthreads$(EXE): $(srcdir)/checkkeysthreads.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-loopwave$(EXE): $(srcdir)/loopwave.c
+loopwave$(EXE): $(srcdir)/loopwave.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-loopwavequeue$(EXE): $(srcdir)/loopwavequeue.c
+loopwavequeue$(EXE): $(srcdir)/loopwavequeue.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testsurround$(EXE): $(srcdir)/testsurround.c
@@ -126,10 +126,10 @@ testautomation$(EXE): $(srcdir)/testautomation.c \
 		      $(srcdir)/testautomation_hints.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) 
 
-testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c
+testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c
+testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testaudiocapture$(EXE): $(srcdir)/testaudiocapture.c
@@ -165,10 +165,10 @@ testevdev$(EXE): $(srcdir)/testevdev.c
 testfile$(EXE): $(srcdir)/testfile.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c
+testgamecontroller$(EXE): $(srcdir)/testgamecontroller.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testgeometry$(EXE): $(srcdir)/testgeometry.c
+testgeometry$(EXE): $(srcdir)/testgeometry.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testgesture$(EXE): $(srcdir)/testgesture.c
@@ -183,7 +183,7 @@ testgles$(EXE): $(srcdir)/testgles.c
 testgles2$(EXE): $(srcdir)/testgles2.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
 
-testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c
+testgles2_sdf$(EXE): $(srcdir)/testgles2_sdf.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
 
 testhaptic$(EXE): $(srcdir)/testhaptic.c
@@ -198,10 +198,10 @@ testrumble$(EXE): $(srcdir)/testrumble.c
 testthread$(EXE): $(srcdir)/testthread.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testiconv$(EXE): $(srcdir)/testiconv.c
+testiconv$(EXE): $(srcdir)/testiconv.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testime$(EXE): $(srcdir)/testime.c
+testime$(EXE): $(srcdir)/testime.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @SDL_TTF_LIB@
 
 testjoystick$(EXE): $(srcdir)/testjoystick.c
@@ -219,18 +219,21 @@ testlock$(EXE): $(srcdir)/testlock.c
 ifeq (@ISMACOSX@,true)
 testnative$(EXE): $(srcdir)/testnative.c \
 			$(srcdir)/testnativecocoa.m \
+			$(srcdir)/testutils.c \
 			$(srcdir)/testnativex11.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -framework Cocoa @XLIB@
 endif
 
 ifeq (@ISWINDOWS@,true)
 testnative$(EXE): $(srcdir)/testnative.c \
+			$(srcdir)/testutils.c \
 			$(srcdir)/testnativew32.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 endif
 
 ifeq (@ISUNIX@,true)
 testnative$(EXE): $(srcdir)/testnative.c \
+			$(srcdir)/testutils.c \
 			$(srcdir)/testnativex11.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @XLIB@
 endif
@@ -252,7 +255,7 @@ endif
 endif
 endif
 
-testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c
+testoverlay2$(EXE): $(srcdir)/testoverlay2.c $(srcdir)/testyuv_cvt.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testplatform$(EXE): $(srcdir)/testplatform.c
@@ -264,10 +267,10 @@ testpower$(EXE): $(srcdir)/testpower.c
 testfilesystem$(EXE): $(srcdir)/testfilesystem.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testrendertarget$(EXE): $(srcdir)/testrendertarget.c
+testrendertarget$(EXE): $(srcdir)/testrendertarget.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testscale$(EXE): $(srcdir)/testscale.c
+testscale$(EXE): $(srcdir)/testscale.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testsem$(EXE): $(srcdir)/testsem.c
@@ -282,13 +285,13 @@ testshader$(EXE): $(srcdir)/testshader.c
 testshape$(EXE): $(srcdir)/testshape.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testsprite2$(EXE): $(srcdir)/testsprite2.c
+testsprite2$(EXE): $(srcdir)/testsprite2.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c
+testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
 
-teststreaming$(EXE): $(srcdir)/teststreaming.c
+teststreaming$(EXE): $(srcdir)/teststreaming.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
 
 testtimer$(EXE): $(srcdir)/testtimer.c
@@ -300,7 +303,7 @@ testurl$(EXE): $(srcdir)/testurl.c
 testver$(EXE): $(srcdir)/testver.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testviewport$(EXE): $(srcdir)/testviewport.c
+testviewport$(EXE): $(srcdir)/testviewport.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testwm2$(EXE): $(srcdir)/testwm2.c
@@ -312,7 +315,7 @@ testyuv$(EXE): $(srcdir)/testyuv.c $(srcdir)/testyuv_cvt.c
 torturethread$(EXE): $(srcdir)/torturethread.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c
+testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) @MATHLIB@
 
 testmessage$(EXE): $(srcdir)/testmessage.c
@@ -330,7 +333,7 @@ testbounds$(EXE): $(srcdir)/testbounds.c
 testcustomcursor$(EXE): $(srcdir)/testcustomcursor.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
-controllermap$(EXE): $(srcdir)/controllermap.c
+controllermap$(EXE): $(srcdir)/controllermap.c $(srcdir)/testutils.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 testvulkan$(EXE): $(srcdir)/testvulkan.c

+ 7 - 5
test/Makefile.os2

@@ -7,7 +7,7 @@ CFLAGS = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei
 CFLAGS+= -wx -wcd=303
 
 LIBPATH = ..
-LIBS    = SDL2.lib SDL2test.lib
+LIBS    = SDL2.lib SDL2test.lib testutils.lib
 
 #CFLAGS+= -DHAVE_SDL_TTF
 #TTFLIBS = SDL2ttf.lib
@@ -44,7 +44,7 @@ OBJS = $(TARGETS:.exe=.obj)
 COBJS = $(CSRCS:.c=.obj)
 TAOBJS = $(TASRCS:.c=.obj)
 
-all: $(TARGETS)
+all: testutils.lib $(TARGETS)
 
 .c: ../src/test
 
@@ -70,8 +70,10 @@ testyuv.exe: testyuv.obj testyuv_cvt.obj
 testime.exe: testime.obj
   wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS) $(TTFLIBS)} op q op el file {$<} name $@
 
+testutils.lib: testutils.obj
+  wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $<
+
 clean: .SYMBOLIC
-  @if exist *.obj rm *.obj
-  @if exist *.err rm *.err
+  rm -f *.obj *.err
 distclean: .SYMBOLIC clean
-  @if exist *.exe rm *.exe
+  rm -f *.exe *.lib

+ 5 - 37
test/controllermap.c

@@ -18,6 +18,7 @@
 #include <string.h>
 
 #include "SDL.h"
+#include "testutils.h"
 
 #ifndef SDL_JOYSTICK_DISABLED
 
@@ -169,39 +170,6 @@ static SDL_Renderer *screen;
 static SDL_bool done = SDL_FALSE;
 static SDL_bool bind_touchpad = SDL_FALSE;
 
-SDL_Texture *
-LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
-{
-    SDL_Surface *temp;
-    SDL_Texture *texture;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return NULL;
-    }
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (transparent) {
-        if (temp->format->palette) {
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-        }
-    }
-
-    /* Create textures from the image */
-    texture = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!texture) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return NULL;
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return texture;
-}
-
 static int
 StandardizeAxisValue(int nValue)
 {
@@ -392,10 +360,10 @@ WatchJoystick(SDL_Joystick * joystick)
     Uint32 alpha_ticks = 0;
     SDL_JoystickID nJoystickID;
 
-    background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE);
-    background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE);
-    button = LoadTexture(screen, "button.bmp", SDL_TRUE);
-    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE);
+    background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE, NULL, NULL);
+    background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE, NULL, NULL);
+    button = LoadTexture(screen, "button.bmp", SDL_TRUE, NULL, NULL);
+    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE, NULL, NULL);
     SDL_RaiseWindow(window);
 
     /* scale for platforms that don't give you the window size you asked for. */

+ 9 - 5
test/loopwave.c

@@ -25,6 +25,7 @@
 #endif
 
 #include "SDL.h"
+#include "testutils.h"
 
 static struct
 {
@@ -114,7 +115,7 @@ int
 main(int argc, char *argv[])
 {
     int i;
-    char filename[4096];
+    char *filename = NULL;
 
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -125,11 +126,13 @@ main(int argc, char *argv[])
         return (1);
     }
 
-    if (argc > 1) {
-        SDL_strlcpy(filename, argv[1], sizeof(filename));
-    } else {
-        SDL_strlcpy(filename, "sample.wav", sizeof(filename));
+    filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");
+
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
+        quit(1);
     }
+
     /* Load the wave file into memory */
     if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
@@ -172,6 +175,7 @@ main(int argc, char *argv[])
     /* Clean up on signal */
     close_audio();
     SDL_FreeWAV(wave.sound);
+    SDL_free(filename);
     SDL_Quit();
     return (0);
 }

+ 10 - 5
test/loopwavequeue.c

@@ -25,6 +25,8 @@
 #include <signal.h>
 #endif
 
+#include "testutils.h"
+
 static struct
 {
     SDL_AudioSpec spec;
@@ -74,7 +76,7 @@ loop()
 int
 main(int argc, char *argv[])
 {
-    char filename[4096];
+    char *filename = NULL;
 
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -85,11 +87,13 @@ main(int argc, char *argv[])
         return (1);
     }
 
-    if (argc > 1) {
-        SDL_strlcpy(filename, argv[1], sizeof(filename));
-    } else {
-        SDL_strlcpy(filename, "sample.wav", sizeof(filename));
+    filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");
+
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
+        quit(1);
     }
+
     /* Load the wave file into memory */
     if (SDL_LoadWAV(filename, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
@@ -142,6 +146,7 @@ main(int argc, char *argv[])
     /* Clean up on signal */
     SDL_CloseAudio();
     SDL_FreeWAV(wave.sound);
+    SDL_free(filename);
     SDL_Quit();
     return 0;
 }

+ 9 - 5
test/testaudiohotplug.c

@@ -26,6 +26,7 @@
 #endif
 
 #include "SDL.h"
+#include "testutils.h"
 
 static SDL_AudioSpec spec;
 static Uint8 *sound = NULL;     /* Pointer to wave data */
@@ -137,7 +138,7 @@ int
 main(int argc, char *argv[])
 {
     int i;
-    char filename[4096];
+    char *filename = NULL;
 
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -151,11 +152,13 @@ main(int argc, char *argv[])
     /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
     SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));
 
-    if (argc > 1) {
-        SDL_strlcpy(filename, argv[1], sizeof(filename));
-    } else {
-        SDL_strlcpy(filename, "sample.wav", sizeof(filename));
+    filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");
+
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
+        quit(1);
     }
+
     /* Load the wave file into memory */
     if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
@@ -196,6 +199,7 @@ main(int argc, char *argv[])
     /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */
     SDL_QuitSubSystem(SDL_INIT_AUDIO);
     SDL_FreeWAV(sound);
+    SDL_free(filename);
     SDL_Quit();
     return (0);
 }

+ 5 - 32
test/testgamecontroller.c

@@ -17,6 +17,7 @@
 #include <string.h>
 
 #include "SDL.h"
+#include "testutils.h"
 
 #ifdef __EMSCRIPTEN__
 #include <emscripten/emscripten.h>
@@ -217,34 +218,6 @@ static void DelController(SDL_JoystickID controller)
     UpdateWindowTitle();
 }
 
-static SDL_Texture *
-LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
-{
-    SDL_Surface *temp = NULL;
-    SDL_Texture *texture = NULL;
-
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-    } else {
-        /* Set transparent pixel as the pixel at (0,0) */
-        if (transparent) {
-            if (temp->format->BytesPerPixel == 1) {
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels);
-            }
-        }
-
-        texture = SDL_CreateTextureFromSurface(renderer, temp);
-        if (!texture) {
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        }
-    }
-    if (temp) {
-        SDL_FreeSurface(temp);
-    }
-    return texture;
-}
-
 static Uint16 ConvertAxisToRumble(Sint16 axisval)
 {
     /* Only start rumbling if the axis is past the halfway point */
@@ -638,10 +611,10 @@ main(int argc, char *argv[])
     /* scale for platforms that don't give you the window size you asked for. */
     SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT);
 
-    background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE);
-    background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE);
-    button = LoadTexture(screen, "button.bmp", SDL_TRUE);
-    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE);
+    background_front = LoadTexture(screen, "controllermap.bmp", SDL_FALSE, NULL, NULL);
+    background_back = LoadTexture(screen, "controllermap_back.bmp", SDL_FALSE, NULL, NULL);
+    button = LoadTexture(screen, "button.bmp", SDL_TRUE, NULL, NULL);
+    axis = LoadTexture(screen, "axis.bmp", SDL_TRUE, NULL, NULL);
 
     if (!background_front || !background_back || !button || !axis) {
         SDL_DestroyRenderer(screen);

+ 3 - 37
test/testgeometry.c

@@ -21,6 +21,7 @@
 #endif
 
 #include "SDL_test_common.h"
+#include "testutils.h"
 
 static SDLTest_CommonState *state;
 static SDL_bool use_texture = SDL_FALSE;
@@ -44,54 +45,19 @@ int
 LoadSprite(const char *file)
 {
     int i;
-    SDL_Surface *temp;
 
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return (-1);
-    }
-    sprite_w = temp->w;
-    sprite_h = temp->h;
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (temp->format->palette) {
-        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
-    } else {
-        switch (temp->format->BitsPerPixel) {
-        case 15:
-            SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF);
-            break;
-        case 16:
-            SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels);
-            break;
-        case 24:
-            SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-            break;
-        case 32:
-            SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels);
-            break;
-        }
-    }
-
-    /* Create textures from the image */
     for (i = 0; i < state->num_windows; ++i) {
-        SDL_Renderer *renderer = state->renderers[i];
-        sprites[i] = SDL_CreateTextureFromSurface(renderer, temp);
+        /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */
+        sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h);
         if (!sprites[i]) {
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-            SDL_FreeSurface(temp);
             return (-1);
         }
         if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) {
             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError());
-            SDL_FreeSurface(temp);
             SDL_DestroyTexture(sprites[i]);
             return (-1);
         }
     }
-    SDL_FreeSurface(temp);
 
     /* We're ready to roll. :) */
     return (0);

+ 15 - 3
test/testgles2_sdf.c

@@ -458,6 +458,7 @@ main(int argc, char *argv[])
     Uint32 then, now;
     int status;
     shader_data *data;
+    char *path = NULL;
 
     /* Initialize parameters */
     fsaa = 0;
@@ -561,14 +562,25 @@ main(int argc, char *argv[])
 
         /* Load SDF BMP image */
 #if 1
-        tmp = SDL_LoadBMP(f);
+        path = GetNearbyFilename(f);
+
+        if (path == NULL)
+            path = SDL_strdup(f);
+
+        if (path == NULL) {
+            SDL_Log("out of memory\n");
+            exit(-1);
+        }
+
+        tmp = SDL_LoadBMP(path);
         if  (tmp == NULL) {
-            SDL_Log("missing image file: %s", f);
+            SDL_Log("missing image file: %s", path);
             exit(-1);
         } else {
-            SDL_Log("Load image file: %s", f);
+            SDL_Log("Load image file: %s", path);
         }
 
+        SDL_free(path);
 #else
         /* Generate SDF image using SDL_ttf */
 

+ 4 - 2
test/testiconv.c

@@ -13,6 +13,7 @@
 #include <stdio.h>
 
 #include "SDL.h"
+#include "testutils.h"
 
 static size_t
 widelen(char *data)
@@ -43,7 +44,7 @@ main(int argc, char *argv[])
         "UCS-4",
     };
 
-    const char * fname;
+    char * fname;
     char buffer[BUFSIZ];
     char *ucs4;
     char *test[2];
@@ -54,12 +55,13 @@ main(int argc, char *argv[])
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
 
-    fname = (argc < 2) ? "utf8.txt" : argv[1];
+    fname = GetResourceFilename(argc > 1 ? argv[1] : NULL, "utf8.txt");
     file = fopen(fname, "rb");
     if (!file) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", fname);
         return (1);
     }
+    SDL_free(fname);
 
     while (fgets(buffer, sizeof(buffer), file)) {
         /* Convert to UCS-4 */

+ 9 - 1
test/testime.c

@@ -23,6 +23,7 @@
 #endif
 
 #include "SDL_test_common.h"
+#include "testutils.h"
 
 #define DEFAULT_PTSIZE 30
 #ifdef HAVE_SDL_TTF
@@ -108,6 +109,7 @@ static int unifont_init(const char *fontname)
     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 *);
+    char *filename;
 
     /* Allocate memory for the glyph data so the file can be closed after initialization. */
     unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize);
@@ -127,7 +129,13 @@ static int unifont_init(const char *fontname)
     }
     SDL_memset(unifontTexture, 0, unifontTextureSize);
 
-    hexFile = SDL_RWFromFile(fontname, "rb");
+    filename = GetResourceFilename(NULL, fontname);
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n");
+        return -1;
+    }
+    hexFile = SDL_RWFromFile(filename, "rb");
+    SDL_free(filename);
     if (hexFile == NULL)
     {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname);

+ 5 - 1
test/testmultiaudio.c

@@ -17,6 +17,8 @@
 #include <emscripten/emscripten.h>
 #endif
 
+#include "testutils.h"
+
 static SDL_AudioSpec spec;
 static Uint8 *sound = NULL;     /* Pointer to wave data */
 static Uint32 soundlen = 0;     /* Length of wave data */
@@ -180,7 +182,7 @@ main(int argc, char **argv)
     if (devcount < 1) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n");
     } else {
-        const char *file = (argc < 2) ? "sample.wav" : argv[1];
+        char *file = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");
 
         /* Load the wave file into memory */
         if (SDL_LoadWAV(file, &spec, &sound, &soundlen) == NULL) {
@@ -190,6 +192,8 @@ main(int argc, char **argv)
             test_multi_audio(devcount);
             SDL_FreeWAV(sound);
         }
+
+        SDL_free(file);
     }
 
     SDL_Quit();

+ 2 - 32
test/testnative.c

@@ -16,6 +16,7 @@
 #include <time.h> /* for time() */
 
 #include "testnative.h"
+#include "testutils.h"
 
 #define WINDOW_W    640
 #define WINDOW_H    480
@@ -52,37 +53,6 @@ quit(int rc)
     exit(rc);
 }
 
-SDL_Texture *
-LoadSprite(SDL_Renderer *renderer, const char *file)
-{
-    SDL_Surface *temp;
-    SDL_Texture *sprite;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return 0;
-    }
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (temp->format->palette) {
-        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
-    }
-
-    /* Create textures from the image */
-    sprite = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!sprite) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return 0;
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return sprite;
-}
-
 void
 MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
 {
@@ -180,7 +150,7 @@ main(int argc, char *argv[])
     SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
     SDL_RenderClear(renderer);
 
-    sprite = LoadSprite(renderer, "icon.bmp");
+    sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, NULL, NULL);
     if (!sprite) {
         quit(6);
     }

+ 9 - 1
test/testoverlay2.c

@@ -25,6 +25,7 @@
 #include "SDL.h"
 
 #include "testyuv_cvt.h"
+#include "testutils.h"
 
 #define MOOSEPIC_W 64
 #define MOOSEPIC_H 88
@@ -243,6 +244,7 @@ main(int argc, char **argv)
     int fps = 12;
     int nodelay = 0;
     int scale = 5;
+    char *filename = NULL;
 
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -315,7 +317,13 @@ main(int argc, char **argv)
     }
 
     /* load the trojan moose images */
-    handle = SDL_RWFromFile("moose.dat", "rb");
+    filename = GetResourceFilename(NULL, "moose.dat");
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n");
+        return -1;
+    }
+    handle = SDL_RWFromFile(filename, "rb");
+    SDL_free(filename);
     if (handle == NULL) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n");
         SDL_free(RawMooseData);

+ 3 - 53
test/testrendercopyex.c

@@ -20,7 +20,7 @@
 #endif
 
 #include "SDL_test_common.h"
-
+#include "testutils.h"
 
 static SDLTest_CommonState *state;
 
@@ -44,56 +44,6 @@ quit(int rc)
     exit(rc);
 }
 
-SDL_Texture *
-LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
-{
-    SDL_Surface *temp;
-    SDL_Texture *texture;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return NULL;
-    }
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (transparent) {
-        if (temp->format->palette) {
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-        } else {
-            switch (temp->format->BitsPerPixel) {
-            case 15:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
-                break;
-            case 16:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
-                break;
-            case 24:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-                break;
-            case 32:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
-                break;
-            }
-        }
-    }
-
-    /* Create textures from the image */
-    texture = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!texture) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return NULL;
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return texture;
-}
-
 void
 Draw(DrawState *s)
 {
@@ -186,8 +136,8 @@ main(int argc, char *argv[])
 
         drawstate->window = state->windows[i];
         drawstate->renderer = state->renderers[i];
-        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
-        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
+        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL);
+        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL);
         if (!drawstate->sprite || !drawstate->background) {
             quit(2);
         }

+ 4 - 54
test/testrendertarget.c

@@ -20,7 +20,7 @@
 #endif
 
 #include "SDL_test_common.h"
-
+#include "testutils.h"
 
 static SDLTest_CommonState *state;
 
@@ -45,56 +45,6 @@ quit(int rc)
     exit(rc);
 }
 
-SDL_Texture *
-LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
-{
-    SDL_Surface *temp;
-    SDL_Texture *texture;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return NULL;
-    }
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (transparent) {
-        if (temp->format->palette) {
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-        } else {
-            switch (temp->format->BitsPerPixel) {
-            case 15:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
-                break;
-            case 16:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
-                break;
-            case 24:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-                break;
-            case 32:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
-                break;
-            }
-        }
-    }
-
-    /* Create textures from the image */
-    texture = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!texture) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return NULL;
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return texture;
-}
-
 SDL_bool
 DrawComposite(DrawState *s)
 {
@@ -292,11 +242,11 @@ main(int argc, char *argv[])
         drawstate->window = state->windows[i];
         drawstate->renderer = state->renderers[i];
         if (test_composite) {
-            drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE);
+            drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE, NULL, NULL);
         } else {
-            drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
+            drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL);
         }
-        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
+        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL);
         if (!drawstate->sprite || !drawstate->background) {
             quit(2);
         }

+ 3 - 52
test/testscale.c

@@ -20,6 +20,7 @@
 #endif
 
 #include "SDL_test_common.h"
+#include "testutils.h"
 
 #define WINDOW_WIDTH    640
 #define WINDOW_HEIGHT   480
@@ -46,56 +47,6 @@ quit(int rc)
     exit(rc);
 }
 
-SDL_Texture *
-LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent)
-{
-    SDL_Surface *temp;
-    SDL_Texture *texture;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return NULL;
-    }
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (transparent) {
-        if (temp->format->palette) {
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-        } else {
-            switch (temp->format->BitsPerPixel) {
-            case 15:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
-                break;
-            case 16:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
-                break;
-            case 24:
-                SDL_SetColorKey(temp, SDL_TRUE,
-                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-                break;
-            case 32:
-                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
-                break;
-            }
-        }
-    }
-
-    /* Create textures from the image */
-    texture = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!texture) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return NULL;
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return texture;
-}
-
 void
 Draw(DrawState *s)
 {
@@ -176,8 +127,8 @@ main(int argc, char *argv[])
 
         drawstate->window = state->windows[i];
         drawstate->renderer = state->renderers[i];
-        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
-        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
+        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE, NULL, NULL);
+        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE, NULL, NULL);
         if (!drawstate->sprite || !drawstate->background) {
             quit(2);
         }

+ 3 - 37
test/testsprite2.c

@@ -21,6 +21,7 @@
 
 #include "SDL_test.h"
 #include "SDL_test_common.h"
+#include "testutils.h"
 
 #define NUM_SPRITES    100
 #define MAX_SPEED     1
@@ -62,54 +63,19 @@ int
 LoadSprite(const char *file)
 {
     int i;
-    SDL_Surface *temp;
 
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
-        return (-1);
-    }
-    sprite_w = temp->w;
-    sprite_h = temp->h;
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (temp->format->palette) {
-        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
-    } else {
-        switch (temp->format->BitsPerPixel) {
-        case 15:
-            SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF);
-            break;
-        case 16:
-            SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels);
-            break;
-        case 24:
-            SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-            break;
-        case 32:
-            SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels);
-            break;
-        }
-    }
-
-    /* Create textures from the image */
     for (i = 0; i < state->num_windows; ++i) {
-        SDL_Renderer *renderer = state->renderers[i];
-        sprites[i] = SDL_CreateTextureFromSurface(renderer, temp);
+        /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */
+        sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h);
         if (!sprites[i]) {
-            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-            SDL_FreeSurface(temp);
             return (-1);
         }
         if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) {
             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError());
-            SDL_FreeSurface(temp);
             SDL_DestroyTexture(sprites[i]);
             return (-1);
         }
     }
-    SDL_FreeSurface(temp);
 
     /* We're ready to roll. :) */
     return (0);

+ 4 - 50
test/testspriteminimal.c

@@ -20,6 +20,7 @@
 #endif
 
 #include "SDL.h"
+#include "testutils.h"
 
 #define WINDOW_WIDTH    640
 #define WINDOW_HEIGHT   480
@@ -42,55 +43,6 @@ quit(int rc)
     exit(rc);
 }
 
-int
-LoadSprite(const char *file)
-{
-    SDL_Surface *temp;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError());
-        return (-1);
-    }
-    sprite_w = temp->w;
-    sprite_h = temp->h;
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (temp->format->palette) {
-        SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-    } else {
-        switch (temp->format->BitsPerPixel) {
-        case 15:
-            SDL_SetColorKey(temp, SDL_TRUE,
-                            (*(Uint16 *) temp->pixels) & 0x00007FFF);
-            break;
-        case 16:
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
-            break;
-        case 24:
-            SDL_SetColorKey(temp, SDL_TRUE,
-                            (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-            break;
-        case 32:
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
-            break;
-        }
-    }
-
-    /* Create textures from the image */
-    sprite = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!sprite) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return (-1);
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return (0);
-}
-
 void
 MoveSprites()
 {
@@ -158,7 +110,9 @@ main(int argc, char *argv[])
         quit(2);
     }
 
-    if (LoadSprite("icon.bmp") < 0) {
+    sprite = LoadTexture(renderer, "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h);
+
+    if (sprite == NULL) {
         quit(2);
     }
 

+ 9 - 1
test/teststreaming.c

@@ -23,6 +23,7 @@
 #endif
 
 #include "SDL.h"
+#include "testutils.h"
 
 #define MOOSEPIC_W 64
 #define MOOSEPIC_H 88
@@ -128,6 +129,7 @@ main(int argc, char **argv)
 {
     SDL_Window *window;
     SDL_RWops *handle;
+    char *filename = NULL;
 
     /* Enable standard application logging */
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
@@ -138,7 +140,13 @@ main(int argc, char **argv)
     }
 
     /* load the moose images */
-    handle = SDL_RWFromFile("moose.dat", "rb");
+    filename = GetResourceFilename(NULL, "moose.dat");
+    if (filename == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory\n");
+        return -1;
+    }
+    handle = SDL_RWFromFile(filename, "rb");
+    SDL_free(filename);
     if (handle == NULL) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n");
         quit(2);

+ 149 - 0
test/testutils.c

@@ -0,0 +1,149 @@
+/*
+Copyright 1997-2022 Sam Lantinga
+Copyright 2022 Collabora Ltd.
+SPDX-License-Identifier: Zlib
+*/
+
+#include "testutils.h"
+
+#if defined(SDL_FILESYSTEM_OS2) || defined(SDL_FILESYSTEM_WINDOWS)
+static const char pathsep[] = "\\";
+#elif defined(SDL_FILESYSTEM_RISCOS)
+static const char pathsep[] = ".";
+#else
+static const char pathsep[] = "/";
+#endif
+
+/*
+ * Return the absolute path to def in the SDL_GetBasePath() if possible, or
+ * the relative path to def on platforms that don't have a working
+ * SDL_GetBasePath(). Free the result with SDL_free.
+ *
+ * Fails and returns NULL if out of memory.
+ */
+char *
+GetNearbyFilename(const char *file)
+{
+    char *base;
+    char *path;
+
+    base = SDL_GetBasePath();
+
+    if (base != NULL) {
+        size_t len = SDL_strlen(base) + SDL_strlen(pathsep) + SDL_strlen(file) + 1;
+
+        path = SDL_malloc(len);
+
+        if (path == NULL) {
+            SDL_OutOfMemory();
+            return NULL;
+        }
+
+        SDL_snprintf(path, len, "%s%s%s", base, pathsep, file);
+    }
+
+    if (base) {
+        SDL_free(base);
+    }
+
+    return path;
+}
+
+/*
+ * If user_specified is non-NULL, return a copy of it. Free with SDL_free.
+ *
+ * Otherwise, return the absolute path to def in the SDL_GetBasePath() if
+ * possible, or the relative path to def on platforms that don't have a
+ * working SDL_GetBasePath(). Free the result with SDL_free.
+ *
+ * Fails and returns NULL if out of memory.
+ */
+char *
+GetResourceFilename(const char *user_specified, const char *def)
+{
+    if (user_specified != NULL) {
+        char *ret = SDL_strdup(user_specified);
+
+        if (ret == NULL) {
+            SDL_OutOfMemory();
+        }
+
+        return ret;
+    } else {
+        return GetNearbyFilename(def);
+    }
+}
+
+/*
+ * Load the .bmp file whose name is file, from the SDL_GetBasePath() if
+ * possible or the current working directory if not.
+ *
+ * If transparent is true, set the transparent colour from the top left pixel.
+ *
+ * If width_out is non-NULL, set it to the texture width.
+ *
+ * If height_out is non-NULL, set it to the texture height.
+ */
+SDL_Texture *
+LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent,
+            int *width_out, int *height_out)
+{
+    SDL_Surface *temp = NULL;
+    SDL_Texture *texture = NULL;
+    char *path;
+
+    path = GetNearbyFilename(file);
+
+    if (path != NULL) {
+        file = path;
+    }
+
+    temp = SDL_LoadBMP(file);
+    if (temp == NULL) {
+        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
+    } else {
+        /* Set transparent pixel as the pixel at (0,0) */
+        if (transparent) {
+            if (temp->format->palette) {
+                SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels);
+            } else {
+                switch (temp->format->BitsPerPixel) {
+                case 15:
+                    SDL_SetColorKey(temp, SDL_TRUE,
+                                    (*(Uint16 *) temp->pixels) & 0x00007FFF);
+                    break;
+                case 16:
+                    SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
+                    break;
+                case 24:
+                    SDL_SetColorKey(temp, SDL_TRUE,
+                                    (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
+                    break;
+                case 32:
+                    SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
+                    break;
+                }
+            }
+        }
+
+        if (width_out != NULL) {
+            *width_out = temp->w;
+        }
+
+        if (height_out != NULL) {
+            *height_out = temp->h;
+        }
+
+        texture = SDL_CreateTextureFromSurface(renderer, temp);
+        if (!texture) {
+            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
+        }
+    }
+    if (temp) {
+        SDL_FreeSurface(temp);
+    }
+    if (path) {
+        SDL_free(path);
+    }
+    return texture;
+}

+ 17 - 0
test/testutils.h

@@ -0,0 +1,17 @@
+/*
+Copyright 1997-2022 Sam Lantinga
+Copyright 2022 Collabora Ltd.
+SPDX-License-Identifier: Zlib
+*/
+
+#ifndef TESTUTILS_H
+#define TESTUTILS_H
+
+#include "SDL.h"
+
+SDL_Texture *LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent,
+                         int *width_out, int *height_out);
+char *GetNearbyFilename(const char *file);
+char *GetResourceFilename(const char *user_specified, const char *def);
+
+#endif

+ 4 - 51
test/testviewport.c

@@ -21,7 +21,7 @@
 
 #include "SDL_test.h"
 #include "SDL_test_common.h"
-
+#include "testutils.h"
 
 static SDLTest_CommonState *state;
 
@@ -42,55 +42,6 @@ quit(int rc)
     exit(rc);
 }
 
-int
-LoadSprite(const char *file, SDL_Renderer *renderer)
-{
-    SDL_Surface *temp;
-
-    /* Load the sprite image */
-    temp = SDL_LoadBMP(file);
-    if (temp == NULL) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError());
-        return (-1);
-    }
-    sprite_w = temp->w;
-    sprite_h = temp->h;
-
-    /* Set transparent pixel as the pixel at (0,0) */
-    if (temp->format->palette) {
-        SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
-    } else {
-        switch (temp->format->BitsPerPixel) {
-        case 15:
-            SDL_SetColorKey(temp, SDL_TRUE,
-                            (*(Uint16 *) temp->pixels) & 0x00007FFF);
-            break;
-        case 16:
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
-            break;
-        case 24:
-            SDL_SetColorKey(temp, SDL_TRUE,
-                            (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
-            break;
-        case 32:
-            SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
-            break;
-        }
-    }
-
-    /* Create textures from the image */
-    sprite = SDL_CreateTextureFromSurface(renderer, temp);
-    if (!sprite) {
-        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
-        SDL_FreeSurface(temp);
-        return (-1);
-    }
-    SDL_FreeSurface(temp);
-
-    /* We're ready to roll. :) */
-    return (0);
-}
-
 void
 DrawOnViewport(SDL_Renderer * renderer)
 {    
@@ -229,7 +180,9 @@ main(int argc, char *argv[])
         quit(2);
     }
 
-    if (LoadSprite("icon.bmp", state->renderers[0]) < 0) {
+    sprite = LoadTexture(state->renderers[0], "icon.bmp", SDL_TRUE, &sprite_w, &sprite_h);
+
+    if (sprite == NULL) {
         quit(2);
     }