about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/include/sdl2rwops.h1
-rwxr-xr-xsrc/libtools/sdl2rwops.c38
-rwxr-xr-xsrc/wrapped/wrappedsdl2image.c18
3 files changed, 43 insertions, 14 deletions
diff --git a/src/include/sdl2rwops.h b/src/include/sdl2rwops.h
index a049f80b..f03f17c2 100755
--- a/src/include/sdl2rwops.h
+++ b/src/include/sdl2rwops.h
@@ -22,6 +22,7 @@ typedef struct SDL2RWSave_s {
 SDL2_RWops_t* AddNativeRW2(x64emu_t* emu, SDL2_RWops_t* ops);
 SDL2_RWops_t* RWNativeStart2(x64emu_t* emu, SDL2_RWops_t* ops); // put native RW functions, wrapping the emulated (callback style) ones if needed
 void RWNativeEnd2(SDL2_RWops_t* ops);                           // put emulated function back in place
+int isRWops(SDL2_RWops_t* ops); // 1 if ops seems to be a valid RWops, 0 if not
 
 int64_t RWNativeSeek2(SDL2_RWops_t *ops, int64_t offset, int32_t whence);
 uint32_t RWNativeRead2(SDL2_RWops_t* ops, void* ptr, uint32_t size, uint32_t maxnum);
diff --git a/src/libtools/sdl2rwops.c b/src/libtools/sdl2rwops.c
index bbe28414..f57dc567 100755
--- a/src/libtools/sdl2rwops.c
+++ b/src/libtools/sdl2rwops.c
@@ -53,6 +53,13 @@ typedef struct SDL2_RWops_s {
     } hidden;
 } SDL2_RWops_t;
 
+#define SUPER()         \
+    GO(size, IFp)       \
+    GO(seek, IFpIi)     \
+    GO(read, iFppii)    \
+    GO(write, iFppii)   \
+    GO(close, iFp)
+
 EXPORT int64_t my2_native_size(SDL2_RWops_t *context)
 {
     return context->hidden.my.orig->size(context->hidden.my.orig);
@@ -118,11 +125,7 @@ SDL2_RWops_t* AddNativeRW2(x64emu_t* emu, SDL2_RWops_t* ops)
     fnc = AddCheckBridge(system, W, my2_native_##A, 0, NULL); \
     newrw->A = (sdl2_##A)fnc;
 
-    GO(size, IFp)
-    GO(seek, IFpIi)
-    GO(read, iFppii)
-    GO(write, iFppii)
-    GO(close, iFp)
+    SUPER()
 
     #undef GO
 
@@ -149,11 +152,7 @@ SDL2_RWops_t* RWNativeStart2(x64emu_t* emu, SDL2_RWops_t* ops)
     #define GO(A, W) \
     newrw->A = my2_emulated_##A;
 
-    GO(size, IFp)
-    GO(seek, IFpIi)
-    GO(read, iFppii)
-    GO(write, iFppii)
-    GO(close, iFp)
+    SUPER()
 
     #undef GO
 
@@ -169,6 +168,25 @@ void RWNativeEnd2(SDL2_RWops_t* ops)
     ops->hidden.my.custom_free(ops);
 }
 
+int isRWops(SDL2_RWops_t* ops)
+{
+    if(!ops)
+        return 0;
+    #define GO(A, W)      \
+    if(!ops->A || (uintptr_t)ops->A < 0x1000) return 0;
+
+    SUPER()
+
+    #undef GO
+    // check if all then hidden content is just full of 0
+    if(ops->hidden.mem.base==NULL && ops->hidden.mem.here==NULL && ops->hidden.mem.stop==NULL)
+        return 0;
+    // check the type (not sure it's a good check here)
+    if (ops->type>5 && ops->type!=BOX64RW)
+        return 0;
+    return 1;
+}
+
 int64_t RWNativeSeek2(SDL2_RWops_t *ops, int64_t offset, int32_t whence)
 {
     return ops->seek(ops, offset, whence);
diff --git a/src/wrapped/wrappedsdl2image.c b/src/wrapped/wrappedsdl2image.c
index 5b531167..eae0c159 100755
--- a/src/wrapped/wrappedsdl2image.c
+++ b/src/wrapped/wrappedsdl2image.c
@@ -119,12 +119,22 @@ EXPORT void *my2_IMG_Load_RW(x64emu_t* emu, void* a, int32_t b)
         RWNativeEnd2(rw);
     return r;
 }
-EXPORT int32_t my2_IMG_SavePNG_RW(x64emu_t* emu, void* a, void* surf, int32_t compression)
+EXPORT int32_t my2_IMG_SavePNG_RW(x64emu_t* emu, void* s, void* a, int32_t b)
 {
     sdl2image_my_t *my = (sdl2image_my_t *)my_lib->priv.w.p2;
-    SDL2_RWops_t *rw = RWNativeStart2(emu, (SDL2_RWops_t*)a);
-    int32_t r = my->IMG_SavePNG_RW(rw, surf, compression);
-    RWNativeEnd2(rw);
+    // some old? fuction signature use IMG_SavePNG_RW(dst, surf, compression) instead of the IMG_SavePNG_RW(surf, dst, freedst)
+    // need to try detect if s is in fact a RWops
+    int32_t r;
+    if(isRWops((SDL2_RWops_t*)s) && !isRWops((SDL2_RWops_t*)a)) {
+        SDL2_RWops_t *rw = RWNativeStart2(emu, (SDL2_RWops_t*)s);
+        r = my->IMG_SavePNG_RW(a, rw, 0);
+        RWNativeEnd2(rw);
+    } else {
+        SDL2_RWops_t *rw = RWNativeStart2(emu, (SDL2_RWops_t*)a);
+        r = my->IMG_SavePNG_RW(s, rw, b);
+        if(b==0)
+            RWNativeEnd2(rw);
+    }
     return r;
 }