Forráskód Böngészése

Enable texture wrapping for SDL_RenderGeometry()

Currently wrapping is based on whether texture coordinates are outside of [0,1], but the code is structured so it's easy to add an API to set it and add additional wrapping modes if we want.

Fixes https://github.com/libsdl-org/SDL/issues/9238
Closes https://github.com/libsdl-org/SDL/pull/5369
Sam Lantinga 9 hónapja
szülő
commit
03bb2c17ed

+ 17 - 10
src/render/SDL_render.c

@@ -576,6 +576,7 @@ static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_Ren
             cmd->data.draw.color = *color;
             cmd->data.draw.blend = blendMode;
             cmd->data.draw.texture = texture;
+            cmd->data.draw.texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
         }
     }
     return cmd;
@@ -715,12 +716,14 @@ static int QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture,
                             const float *uv, int uv_stride,
                             int num_vertices,
                             const void *indices, int num_indices, int size_indices,
-                            float scale_x, float scale_y)
+                            float scale_x, float scale_y, SDL_TextureAddressMode texture_address_mode)
 {
     SDL_RenderCommand *cmd;
     int retval = -1;
     cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture);
     if (cmd) {
+        cmd->data.draw.texture_address_mode = texture_address_mode;
+
         retval = renderer->QueueGeometry(renderer, cmd, texture,
                                          xy, xy_stride,
                                          color, color_stride, uv, uv_stride,
@@ -3602,7 +3605,7 @@ int SDL_RenderLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
             retval = QueueCmdGeometry(renderer, NULL,
                                       xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0,
                                       num_vertices, indices, num_indices, size_indices,
-                                      1.0f, 1.0f);
+                                      1.0f, 1.0f, SDL_TEXTURE_ADDRESS_CLAMP);
         }
 
         SDL_small_free(xy, isstack1);
@@ -3818,7 +3821,7 @@ int SDL_RenderTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_FR
                                   num_vertices,
                                   indices, num_indices, size_indices,
                                   renderer->view->scale.x,
-                                  renderer->view->scale.y);
+                                  renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
     } else {
 
         real_dstrect.x *= renderer->view->scale.x;
@@ -3976,7 +3979,7 @@ int SDL_RenderTextureRotated(SDL_Renderer *renderer, SDL_Texture *texture,
                                   num_vertices,
                                   indices, num_indices, size_indices,
                                   renderer->view->scale.x,
-                                  renderer->view->scale.y);
+                                  renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
     } else {
 
         retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip,
@@ -4340,7 +4343,7 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
                                           xy, xy_stride, color, color_stride, uv, uv_stride,
                                           num_vertices, prev, 3, 4,
                                           renderer->view->scale.x,
-                                          renderer->view->scale.y);
+                                          renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
                 if (retval < 0) {
                     goto end;
                 }
@@ -4361,7 +4364,7 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
                                   xy, xy_stride, color, color_stride, uv, uv_stride,
                                   num_vertices, prev, 3, 4,
                                   renderer->view->scale.x,
-                                  renderer->view->scale.y);
+                                  renderer->view->scale.y, SDL_TEXTURE_ADDRESS_CLAMP);
         if (retval < 0) {
             goto end;
         }
@@ -4386,6 +4389,7 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
 {
     int i;
     int count = indices ? num_indices : num_vertices;
+    SDL_TextureAddressMode texture_address_mode;
 
     CHECK_RENDERER_MAGIC(renderer, -1);
 
@@ -4440,13 +4444,16 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
         texture = texture->native;
     }
 
-    if (texture) {
+    texture_address_mode = renderer->texture_address_mode;
+    if (texture_address_mode == SDL_TEXTURE_ADDRESS_AUTO && texture) {
+        texture_address_mode = SDL_TEXTURE_ADDRESS_CLAMP;
         for (i = 0; i < num_vertices; ++i) {
             const float *uv_ = (const float *)((const char *)uv + i * uv_stride);
             float u = uv_[0];
             float v = uv_[1];
             if (u < 0.0f || v < 0.0f || u > 1.0f || v > 1.0f) {
-                return SDL_SetError("Values of 'uv' out of bounds %f %f at %d/%d", u, v, i, num_vertices);
+                texture_address_mode = SDL_TEXTURE_ADDRESS_WRAP;
+                break;
             }
         }
     }
@@ -4473,7 +4480,7 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
 
     /* For the software renderer, try to reinterpret triangles as SDL_Rect */
 #if SDL_VIDEO_RENDER_SW
-    if (renderer->software) {
+    if (renderer->software && texture_address_mode == SDL_TEXTURE_ADDRESS_CLAMP) {
         return SDL_SW_RenderGeometryRaw(renderer, texture,
                                         xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices,
                                         indices, num_indices, size_indices);
@@ -4485,7 +4492,7 @@ int SDL_RenderGeometryRaw(SDL_Renderer *renderer,
                               num_vertices,
                               indices, num_indices, size_indices,
                               renderer->view->scale.x,
-                              renderer->view->scale.y);
+                              renderer->view->scale.y, texture_address_mode);
 }
 
 SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)

+ 9 - 0
src/render/SDL_sysrender.h

@@ -30,6 +30,13 @@
 extern "C" {
 #endif
 
+typedef enum SDL_TextureAddressMode
+{
+    SDL_TEXTURE_ADDRESS_AUTO,
+    SDL_TEXTURE_ADDRESS_CLAMP,
+    SDL_TEXTURE_ADDRESS_WRAP,
+} SDL_TextureAddressMode;
+
 /**
  * A rectangle, with the origin at the upper left (double precision).
  */
@@ -132,6 +139,7 @@ typedef struct SDL_RenderCommand
             SDL_FColor color;
             SDL_BlendMode blend;
             SDL_Texture *texture;
+            SDL_TextureAddressMode texture_address_mode;
         } draw;
         struct
         {
@@ -262,6 +270,7 @@ struct SDL_Renderer
     float color_scale;
     SDL_FColor color;        /**< Color for drawing operations values */
     SDL_BlendMode blendMode; /**< The drawing blend mode */
+    SDL_TextureAddressMode texture_address_mode;
 
     SDL_RenderCommand *render_commands;
     SDL_RenderCommand *render_commands_tail;

+ 31 - 11
src/render/direct3d/SDL_render_d3d.c

@@ -62,7 +62,8 @@ typedef struct
     SDL_bool updateSize;
     SDL_bool beginScene;
     SDL_bool enableSeparateAlphaBlend;
-    D3DTEXTUREFILTERTYPE scaleMode[8];
+    D3DTEXTUREFILTERTYPE scaleMode[3];
+    SDL_TextureAddressMode addressMode[3];
     IDirect3DSurface9 *defaultRenderTarget;
     IDirect3DSurface9 *currentRenderTarget;
     void *d3dxDLL;
@@ -277,6 +278,9 @@ static void D3D_InitRenderState(D3D_RenderData *data)
     /* Reset our current scale mode */
     SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
 
+    /* Reset our current address mode */
+    SDL_zeroa(data->addressMode);
+
     /* Start the render with beginScene */
     data->beginScene = SDL_TRUE;
 }
@@ -927,19 +931,32 @@ static int BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWO
 static void UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsigned index)
 {
     if (texturedata->scaleMode != data->scaleMode[index]) {
-        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER,
-                                         texturedata->scaleMode);
-        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MAGFILTER,
-                                         texturedata->scaleMode);
-        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU,
-                                         D3DTADDRESS_CLAMP);
-        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV,
-                                         D3DTADDRESS_CLAMP);
+        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER, texturedata->scaleMode);
+        IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MAGFILTER, texturedata->scaleMode);
         data->scaleMode[index] = texturedata->scaleMode;
     }
 }
 
-static int SetupTextureState(D3D_RenderData *data, SDL_Texture *texture, D3D9_Shader *shader, const float **shader_params)
+static void UpdateTextureAddressMode(D3D_RenderData *data, SDL_TextureAddressMode addressMode, unsigned index)
+{
+    if (addressMode != data->addressMode[index]) {
+        switch (addressMode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+            IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
+            IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
+            break;
+        default:
+            break;
+        }
+        data->addressMode[index] = addressMode;
+    }
+}
+
+static int SetupTextureState(D3D_RenderData *data, SDL_Texture *texture, SDL_TextureAddressMode addressMode, D3D9_Shader *shader, const float **shader_params)
 {
     D3D_TextureData *texturedata = (D3D_TextureData *)texture->internal;
 
@@ -948,6 +965,7 @@ static int SetupTextureState(D3D_RenderData *data, SDL_Texture *texture, D3D9_Sh
     }
 
     UpdateTextureScaleMode(data, texturedata, 0);
+    UpdateTextureAddressMode(data, addressMode, 0);
 
     *shader = texturedata->shader;
     *shader_params = texturedata->shader_params;
@@ -959,6 +977,8 @@ static int SetupTextureState(D3D_RenderData *data, SDL_Texture *texture, D3D9_Sh
     if (texturedata->yuv) {
         UpdateTextureScaleMode(data, texturedata, 1);
         UpdateTextureScaleMode(data, texturedata, 2);
+        UpdateTextureAddressMode(data, addressMode, 1);
+        UpdateTextureAddressMode(data, addressMode, 2);
 
         if (BindTextureRep(data->device, &texturedata->utexture, 1) < 0) {
             return -1;
@@ -994,7 +1014,7 @@ static int SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
             IDirect3DDevice9_SetTexture(data->device, 2, NULL);
         }
 #endif
-        if (texture && SetupTextureState(data, texture, &shader, &shader_params) < 0) {
+        if (texture && SetupTextureState(data, texture, cmd->data.draw.texture_address_mode, &shader, &shader_params) < 0) {
             return -1;
         }
 

+ 56 - 24
src/render/direct3d11/SDL_render_d3d11.c

@@ -68,6 +68,16 @@ extern ISwapChainBackgroundPanelNative *WINRT_GlobalSwapChainBackgroundPanelNati
 /* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
    !!! FIXME:  textures are needed. */
 
+/* Sampler types */
+typedef enum
+{
+    SDL_D3D11_SAMPLER_NEAREST_CLAMP,
+    SDL_D3D11_SAMPLER_NEAREST_WRAP,
+    SDL_D3D11_SAMPLER_LINEAR_CLAMP,
+    SDL_D3D11_SAMPLER_LINEAR_WRAP,
+    SDL_NUM_D3D11_SAMPLERS
+} SDL_D3D11_sampler_type;
+
 /* Vertex shader, common values */
 typedef struct
 {
@@ -181,8 +191,7 @@ typedef struct
     ID3D11PixelShader *pixelShaders[NUM_SHADERS];
     int blendModesCount;
     D3D11_BlendMode *blendModes;
-    ID3D11SamplerState *nearestPixelSampler;
-    ID3D11SamplerState *linearSampler;
+    ID3D11SamplerState *samplers[SDL_NUM_D3D11_SAMPLERS];
     D3D_FEATURE_LEVEL featureLevel;
     SDL_bool pixelSizeChanged;
 
@@ -346,8 +355,9 @@ static void D3D11_ReleaseAll(SDL_Renderer *renderer)
         SAFE_RELEASE(data->vertexShaderConstants);
         SAFE_RELEASE(data->clippedRasterizer);
         SAFE_RELEASE(data->mainRasterizer);
-        SAFE_RELEASE(data->linearSampler);
-        SAFE_RELEASE(data->nearestPixelSampler);
+        for (i = 0; i < SDL_arraysize(data->samplers); ++i) {
+            SAFE_RELEASE(data->samplers[i]);
+        }
 
         if (data->blendModesCount > 0) {
             for (i = 0; i < data->blendModesCount; ++i) {
@@ -734,31 +744,35 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer)
     }
 
     /* Create samplers to use when drawing textures: */
+    static struct 
+    {
+        D3D11_FILTER filter;
+        D3D11_TEXTURE_ADDRESS_MODE address;
+    } samplerParams[] = {
+        { D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_CLAMP },
+        { D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_WRAP },
+        { D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_CLAMP },
+        { D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_WRAP },
+    };
+    SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_NUM_D3D11_SAMPLERS);
     SDL_zero(samplerDesc);
-    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
-    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
-    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
     samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
     samplerDesc.MipLODBias = 0.0f;
     samplerDesc.MaxAnisotropy = 1;
     samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
     samplerDesc.MinLOD = 0.0f;
     samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
-    result = ID3D11Device_CreateSamplerState(data->d3dDevice,
-                                             &samplerDesc,
-                                             &data->nearestPixelSampler);
-    if (FAILED(result)) {
-        WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result);
-        goto done;
-    }
-
-    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
-    result = ID3D11Device_CreateSamplerState(data->d3dDevice,
-                                             &samplerDesc,
-                                             &data->linearSampler);
-    if (FAILED(result)) {
-        WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [linear filter]"), result);
-        goto done;
+    for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
+        samplerDesc.Filter = samplerParams[i].filter;
+        samplerDesc.AddressU = samplerParams[i].address;
+        samplerDesc.AddressV = samplerParams[i].address;
+        result = ID3D11Device_CreateSamplerState(data->d3dDevice,
+                                                 &samplerDesc,
+                                                 &data->samplers[i]);
+        if (FAILED(result)) {
+            WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result);
+            goto done;
+        }
     }
 
     /* Setup Direct3D rasterizer states */
@@ -2426,10 +2440,28 @@ static int D3D11_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *c
 
     switch (textureData->scaleMode) {
     case D3D11_FILTER_MIN_MAG_MIP_POINT:
-        textureSampler = rendererData->nearestPixelSampler;
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = rendererData->samplers[SDL_D3D11_SAMPLER_NEAREST_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = rendererData->samplers[SDL_D3D11_SAMPLER_NEAREST_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
-        textureSampler = rendererData->linearSampler;
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = rendererData->samplers[SDL_D3D11_SAMPLER_LINEAR_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = rendererData->samplers[SDL_D3D11_SAMPLER_LINEAR_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     default:
         return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);

+ 51 - 14
src/render/direct3d12/SDL_render_d3d12.c

@@ -134,6 +134,16 @@ extern "C" {
 /* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
    !!! FIXME:  textures are needed. */
 
+/* Sampler types */
+typedef enum
+{
+    SDL_D3D12_SAMPLER_NEAREST_CLAMP,
+    SDL_D3D12_SAMPLER_NEAREST_WRAP,
+    SDL_D3D12_SAMPLER_LINEAR_CLAMP,
+    SDL_D3D12_SAMPLER_LINEAR_WRAP,
+    SDL_D3D12_NUM_SAMPLERS
+} SDL_D3D12_sampler_type;
+
 /* Vertex shader, common values */
 typedef struct
 {
@@ -294,8 +304,7 @@ typedef struct
     D3D12_PipelineState *currentPipelineState;
 
     D3D12_VertexBuffer vertexBuffers[SDL_D3D12_NUM_VERTEX_BUFFERS];
-    D3D12_CPU_DESCRIPTOR_HANDLE nearestPixelSampler;
-    D3D12_CPU_DESCRIPTOR_HANDLE linearSampler;
+    D3D12_CPU_DESCRIPTOR_HANDLE samplers[SDL_D3D12_NUM_SAMPLERS];
 
     /* Data for staging/allocating textures */
     ID3D12Resource *uploadBuffers[SDL_D3D12_NUM_UPLOAD_BUFFERS];
@@ -1057,7 +1066,7 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
     data->srvDescriptorSize = D3D_CALL(d3dDevice, GetDescriptorHandleIncrementSize, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
 
     SDL_zero(descriptorHeapDesc);
-    descriptorHeapDesc.NumDescriptors = 2;
+    descriptorHeapDesc.NumDescriptors = 4;
     descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
     descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
     result = D3D_CALL(data->d3dDevice, CreateDescriptorHeap,
@@ -1165,22 +1174,32 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer)
     }
 
     /* Create samplers to use when drawing textures: */
+    static struct
+    {
+        D3D12_FILTER filter;
+        D3D12_TEXTURE_ADDRESS_MODE address;
+    } samplerParams[] = {
+        { D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_CLAMP },
+        { D3D12_FILTER_MIN_MAG_MIP_POINT, D3D12_TEXTURE_ADDRESS_MODE_WRAP },
+        { D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_CLAMP },
+        { D3D12_FILTER_MIN_MAG_MIP_LINEAR, D3D12_TEXTURE_ADDRESS_MODE_WRAP },
+    };
+    SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_D3D12_NUM_SAMPLERS);
     SDL_zero(samplerDesc);
-    samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
-    samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
-    samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
     samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
     samplerDesc.MipLODBias = 0.0f;
     samplerDesc.MaxAnisotropy = 1;
     samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
     samplerDesc.MinLOD = 0.0f;
     samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
-    D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->samplerDescriptorHeap, &data->nearestPixelSampler);
-    D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->nearestPixelSampler);
-
-    samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
-    data->linearSampler.ptr = data->nearestPixelSampler.ptr + data->samplerDescriptorSize;
-    D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->linearSampler);
+    D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->samplerDescriptorHeap, &data->samplers[0]);
+    for (i = 0; i < SDL_arraysize(samplerParams); ++i) {
+        samplerDesc.Filter = samplerParams[i].filter;
+        samplerDesc.AddressU = samplerParams[i].address;
+        samplerDesc.AddressV = samplerParams[i].address;
+        data->samplers[i].ptr = data->samplers[0].ptr + i * data->samplerDescriptorSize;
+        D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->samplers[i]);
+    }
 
     /* Initialize the pool allocator for SRVs */
     for (i = 0; i < SDL_D3D12_MAX_NUM_TEXTURES; ++i) {
@@ -2797,10 +2816,28 @@ static int D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *c
 
     switch (textureData->scaleMode) {
     case D3D12_FILTER_MIN_MAG_MIP_POINT:
-        textureSampler = &rendererData->nearestPixelSampler;
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = &rendererData->samplers[SDL_D3D12_SAMPLER_NEAREST_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = &rendererData->samplers[SDL_D3D12_SAMPLER_NEAREST_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     case D3D12_FILTER_MIN_MAG_MIP_LINEAR:
-        textureSampler = &rendererData->linearSampler;
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = &rendererData->samplers[SDL_D3D12_SAMPLER_LINEAR_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = &rendererData->samplers[SDL_D3D12_SAMPLER_LINEAR_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     default:
         return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);

+ 56 - 35
src/render/metal/SDL_render_metal.m

@@ -80,6 +80,16 @@ static const size_t CONSTANTS_OFFSET_DECODE_BT2020_LIMITED = ALIGN_CONSTANTS(16,
 static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4);
 static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4;
 
+/* Sampler types */
+typedef enum
+{
+    SDL_METAL_SAMPLER_NEAREST_CLAMP,
+    SDL_METAL_SAMPLER_NEAREST_WRAP,
+    SDL_METAL_SAMPLER_LINEAR_CLAMP,
+    SDL_METAL_SAMPLER_LINEAR_WRAP,
+    SDL_NUM_METAL_SAMPLERS
+} SDL_METAL_sampler_type;
+
 typedef enum SDL_MetalVertexFunction
 {
     SDL_METAL_VERTEX_SOLID,
@@ -130,8 +140,7 @@ typedef struct METAL_ShaderPipelines
 @property(nonatomic, retain) id<MTLRenderCommandEncoder> mtlcmdencoder;
 @property(nonatomic, retain) id<MTLLibrary> mtllibrary;
 @property(nonatomic, retain) id<CAMetalDrawable> mtlbackbuffer;
-@property(nonatomic, retain) id<MTLSamplerState> mtlsamplernearest;
-@property(nonatomic, retain) id<MTLSamplerState> mtlsamplerlinear;
+@property(nonatomic, retain) NSMutableArray<id<MTLSamplerState>> *mtlsamplers;
 @property(nonatomic, retain) id<MTLBuffer> mtlbufconstants;
 @property(nonatomic, retain) id<MTLBuffer> mtlbufquadindices;
 @property(nonatomic, assign) SDL_MetalView mtlview;
@@ -148,7 +157,6 @@ typedef struct METAL_ShaderPipelines
 @interface METAL_TextureData : NSObject
 @property(nonatomic, retain) id<MTLTexture> mtltexture;
 @property(nonatomic, retain) id<MTLTexture> mtltextureUv;
-@property(nonatomic, retain) id<MTLSamplerState> mtlsampler;
 @property(nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction;
 #if SDL_HAVE_YUV
 @property(nonatomic, assign) BOOL yuv;
@@ -739,11 +747,6 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
         }
 #endif /* SDL_HAVE_YUV */
         texturedata = [[METAL_TextureData alloc] init];
-        if (texture->scaleMode == SDL_SCALEMODE_NEAREST) {
-            texturedata.mtlsampler = data.mtlsamplernearest;
-        } else {
-            texturedata.mtlsampler = data.mtlsamplerlinear;
-        }
         if (SDL_COLORSPACETRANSFER(texture->colorspace) == SDL_TRANSFER_CHARACTERISTICS_SRGB) {
             texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY;
 #if SDL_HAVE_YUV
@@ -1094,16 +1097,6 @@ static void METAL_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
 
 static void METAL_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
 {
-    @autoreleasepool {
-        METAL_RenderData *data = (__bridge METAL_RenderData *)renderer->internal;
-        METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->internal;
-
-        if (scaleMode == SDL_SCALEMODE_NEAREST) {
-            texturedata.mtlsampler = data.mtlsamplernearest;
-        } else {
-            texturedata.mtlsampler = data.mtlsamplerlinear;
-        }
-    }
 }
 
 static int METAL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
@@ -1503,13 +1496,32 @@ static SDL_bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cm
     }
 
     if (texture != statecache->texture) {
-        METAL_TextureData *oldtexturedata = NULL;
-        if (statecache->texture) {
-            oldtexturedata = (__bridge METAL_TextureData *)statecache->texture->internal;
-        }
-        if (!oldtexturedata || (texturedata.mtlsampler != oldtexturedata.mtlsampler)) {
-            [data.mtlcmdencoder setFragmentSamplerState:texturedata.mtlsampler atIndex:0];
+        id<MTLSamplerState> mtlsampler;
+
+        if (texture->scaleMode == SDL_SCALEMODE_NEAREST) {
+            switch (cmd->data.draw.texture_address_mode) {
+            case SDL_TEXTURE_ADDRESS_CLAMP:
+                mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_CLAMP];
+                break;
+            case SDL_TEXTURE_ADDRESS_WRAP:
+                mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_NEAREST_WRAP];
+                break;
+            default:
+                return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+            }
+        } else {
+            switch (cmd->data.draw.texture_address_mode) {
+            case SDL_TEXTURE_ADDRESS_CLAMP:
+                mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_CLAMP];
+                break;
+            case SDL_TEXTURE_ADDRESS_WRAP:
+                mtlsampler = data.mtlsamplers[SDL_METAL_SAMPLER_LINEAR_WRAP];
+                break;
+            default:
+                return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+            }
         }
+        [data.mtlcmdencoder setFragmentSamplerState:mtlsampler atIndex:0];
 
         [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
 #if SDL_HAVE_YUV
@@ -1904,7 +1916,6 @@ static int METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_
         MTLSamplerDescriptor *samplerdesc;
         id<MTLCommandQueue> mtlcmdqueue;
         id<MTLLibrary> mtllibrary;
-        id<MTLSamplerState> mtlsamplernearest, mtlsamplerlinear;
         id<MTLBuffer> mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices;
         id<MTLCommandBuffer> cmdbuffer;
         id<MTLBlitCommandEncoder> blitcmd;
@@ -2066,17 +2077,27 @@ static int METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_
         data.allpipelines = NULL;
         ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm);
 
-        samplerdesc = [[MTLSamplerDescriptor alloc] init];
-
-        samplerdesc.minFilter = MTLSamplerMinMagFilterNearest;
-        samplerdesc.magFilter = MTLSamplerMinMagFilterNearest;
-        mtlsamplernearest = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc];
-        data.mtlsamplernearest = mtlsamplernearest;
+        static struct
+        {
+            MTLSamplerMinMagFilter filter;
+            MTLSamplerAddressMode address;
+        } samplerParams[] = {
+            { MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeClampToEdge },
+            { MTLSamplerMinMagFilterNearest, MTLSamplerAddressModeRepeat },
+            { MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeClampToEdge },
+            { MTLSamplerMinMagFilterLinear, MTLSamplerAddressModeRepeat },
+        };
+        SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_NUM_METAL_SAMPLERS);
 
-        samplerdesc.minFilter = MTLSamplerMinMagFilterLinear;
-        samplerdesc.magFilter = MTLSamplerMinMagFilterLinear;
-        mtlsamplerlinear = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc];
-        data.mtlsamplerlinear = mtlsamplerlinear;
+        data.mtlsamplers = [[NSMutableArray<id<MTLSamplerState>> alloc] init];
+        samplerdesc = [[MTLSamplerDescriptor alloc] init];
+        for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
+            samplerdesc.minFilter = samplerParams[i].filter;
+            samplerdesc.magFilter = samplerParams[i].filter;
+            samplerdesc.sAddressMode = samplerParams[i].address;
+            samplerdesc.tAddressMode = samplerParams[i].address;
+            [data.mtlsamplers addObject:[data.mtldevice newSamplerStateWithDescriptor:samplerdesc]];
+        }
 
         mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
 

+ 33 - 21
src/render/opengl/SDL_render_gl.c

@@ -541,15 +541,6 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
     renderdata->glBindTexture(textype, data->texture);
     renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, scaleMode);
     renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, scaleMode);
-    /* According to the spec, CLAMP_TO_EDGE is the default for TEXTURE_RECTANGLE
-       and setting it causes an INVALID_ENUM error in the latest NVidia drivers.
-    */
-    if (textype != GL_TEXTURE_RECTANGLE_ARB) {
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_S,
-                                    GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T,
-                                    GL_CLAMP_TO_EDGE);
-    }
 #ifdef SDL_PLATFORM_MACOS
 #ifndef GL_TEXTURE_STORAGE_HINT_APPLE
 #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
@@ -609,10 +600,6 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
                                     scaleMode);
         renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
                                     scaleMode);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_S,
-                                    GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T,
-                                    GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
                                  (texture_h + 1) / 2, 0, format, type, NULL);
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_U_NUMBER, data->utexture);
@@ -622,10 +609,6 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
                                     scaleMode);
         renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
                                     scaleMode);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_S,
-                                    GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T,
-                                    GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2,
                                  (texture_h + 1) / 2, 0, format, type, NULL);
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_V_NUMBER, data->vtexture);
@@ -646,10 +629,6 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
                                     scaleMode);
         renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER,
                                     scaleMode);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_S,
-                                    GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T,
-                                    GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w + 1) / 2,
                                  (texture_h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
         SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_OPENGL_TEXTURE_UV_NUMBER, data->utexture);
@@ -1141,6 +1120,23 @@ static int SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const
     return 0;
 }
 
+static int SetTextureAddressMode(GL_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
+{
+    switch (addressMode) {
+    case SDL_TEXTURE_ADDRESS_CLAMP:
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        break;
+    case SDL_TEXTURE_ADDRESS_WRAP:
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        break;
+    default:
+        return SDL_SetError("Unknown texture address mode: %d\n", addressMode);
+    }
+    return 0;
+}
+
 static int SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
 {
     SDL_Texture *texture = cmd->data.draw.texture;
@@ -1157,16 +1153,28 @@ static int SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
             }
             data->glBindTexture(textype, texturedata->vtexture);
 
+            if (SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
+
             if (data->GL_ARB_multitexture_supported) {
                 data->glActiveTextureARB(GL_TEXTURE1_ARB);
             }
             data->glBindTexture(textype, texturedata->utexture);
+
+            if (SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
         }
         if (texturedata->nv12) {
             if (data->GL_ARB_multitexture_supported) {
                 data->glActiveTextureARB(GL_TEXTURE1_ARB);
             }
             data->glBindTexture(textype, texturedata->utexture);
+
+            if (SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
         }
 #endif
         if (data->GL_ARB_multitexture_supported) {
@@ -1174,6 +1182,10 @@ static int SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
         }
         data->glBindTexture(textype, texturedata->texture);
 
+        if (SetTextureAddressMode(data, textype, cmd->data.draw.texture_address_mode) < 0) {
+            return -1;
+        }
+
         data->drawstate.texture = texture;
     }
 

+ 34 - 8
src/render/opengles2/SDL_render_gles2.c

@@ -1030,6 +1030,23 @@ static int SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, co
     return 0;
 }
 
+static int SetTextureAddressMode(GLES2_RenderData *data, GLenum textype, SDL_TextureAddressMode addressMode)
+{
+    switch (addressMode) {
+    case SDL_TEXTURE_ADDRESS_CLAMP:
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        break;
+    case SDL_TEXTURE_ADDRESS_WRAP:
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_S, GL_REPEAT);
+        data->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_REPEAT);
+        break;
+    default:
+        return SDL_SetError("Unknown texture address mode: %d\n", addressMode);
+    }
+    return 0;
+}
+
 static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
 {
     GLES2_RenderData *data = (GLES2_RenderData *)renderer->internal;
@@ -1162,18 +1179,35 @@ static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, vo
             data->glActiveTexture(GL_TEXTURE2);
             data->glBindTexture(tdata->texture_type, tdata->texture_v);
 
+            if (SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
+
             data->glActiveTexture(GL_TEXTURE1);
             data->glBindTexture(tdata->texture_type, tdata->texture_u);
 
+            if (SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
+
             data->glActiveTexture(GL_TEXTURE0);
         } else if (tdata->nv12) {
             data->glActiveTexture(GL_TEXTURE1);
             data->glBindTexture(tdata->texture_type, tdata->texture_u);
 
+            if (SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode) < 0) {
+                return -1;
+            }
+
             data->glActiveTexture(GL_TEXTURE0);
         }
 #endif
         data->glBindTexture(tdata->texture_type, tdata->texture);
+
+        if (SetTextureAddressMode(data, tdata->texture_type, cmd->data.draw.texture_address_mode) < 0) {
+            return -1;
+        }
+
         data->drawstate.texture = texture;
     }
 
@@ -1552,8 +1586,6 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
         renderdata->glBindTexture(data->texture_type, data->texture_v);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
         SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_V_NUMBER, data->texture_v);
 
@@ -1570,8 +1602,6 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
         renderdata->glBindTexture(data->texture_type, data->texture_u);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL);
         if (GL_CheckError("glTexImage2D()", renderer) < 0) {
             return -1;
@@ -1595,8 +1625,6 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
         renderdata->glBindTexture(data->texture_type, data->texture_u);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
         renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
         if (GL_CheckError("glTexImage2D()", renderer) < 0) {
             return -1;
@@ -1623,8 +1651,6 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
     renderdata->glBindTexture(data->texture_type, data->texture);
     renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
     renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
-    renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     if (texture->format != SDL_PIXELFORMAT_EXTERNAL_OES) {
         renderdata->glTexImage2D(data->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
         if (GL_CheckError("glTexImage2D()", renderer) < 0) {

+ 2 - 1
src/render/software/SDL_render_sw.c

@@ -928,7 +928,8 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
                         &(ptr[0].src), &(ptr[1].src), &(ptr[2].src),
                         surface,
                         &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst),
-                        ptr[0].color, ptr[1].color, ptr[2].color);
+                        ptr[0].color, ptr[1].color, ptr[2].color,
+                        cmd->data.draw.texture_address_mode);
                 }
             } else {
                 GeometryFillData *ptr = (GeometryFillData *)verts;

+ 23 - 20
src/render/software/SDL_triangle.c

@@ -42,7 +42,7 @@ static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
                                   SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
                                   int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
                                   int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
-                                  SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform);
+                                  SDL_Color c0, SDL_Color c1, SDL_Color c2, SDL_bool is_uniform, SDL_TextureAddressMode texture_address_mode);
 
 #if 0
 int SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3])
@@ -183,7 +183,17 @@ static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Poin
 /* Use 64 bits precision to prevent overflow when interpolating color / texture with wide triangles */
 #define TRIANGLE_GET_TEXTCOORD                                                          \
     int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \
-    int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area);
+    int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \
+    if (texture_address_mode == SDL_TEXTURE_ADDRESS_WRAP) {                             \
+        srcx %= src_surface->w;                                                         \
+        if (srcx < 0) {                                                                 \
+            srcx += (src_surface->w - 1);                                               \
+        }                                                                               \
+        srcy %= src_surface->h;                                                         \
+        if (srcy < 0) {                                                                 \
+            srcy += (src_surface->h - 1);                                               \
+        }                                                                               \
+    }
 
 #define TRIANGLE_GET_MAPPED_COLOR                                                      \
     Uint8 r = (Uint8)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \
@@ -231,7 +241,7 @@ int SDL_SW_FillTriangle(SDL_Surface *dst, SDL_Point *d0, SDL_Point *d1, SDL_Poin
     Sint64 w0_row, w1_row, w2_row;
     int bias_w0, bias_w1, bias_w2;
 
-    int is_uniform;
+    SDL_bool is_uniform;
 
     SDL_Surface *tmp = NULL;
 
@@ -454,8 +464,10 @@ int SDL_SW_BlitTriangle(
     SDL_Point *s0, SDL_Point *s1, SDL_Point *s2,
     SDL_Surface *dst,
     SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
-    SDL_Color c0, SDL_Color c1, SDL_Color c2)
+    SDL_Color c0, SDL_Color c1, SDL_Color c2,
+    SDL_TextureAddressMode texture_address_mode)
 {
+    SDL_Surface *src_surface = src;
     int ret = 0;
     int src_locked = 0;
     int dst_locked = 0;
@@ -482,9 +494,9 @@ int SDL_SW_BlitTriangle(
     Sint64 w0_row, w1_row, w2_row;
     int bias_w0, bias_w1, bias_w2;
 
-    int is_uniform;
+    SDL_bool is_uniform;
 
-    int has_modulation;
+    SDL_bool has_modulation;
 
     if (!SDL_SurfaceValid(src)) {
         return SDL_InvalidParamError("src");
@@ -527,7 +539,7 @@ int SDL_SW_BlitTriangle(
     SDL_GetSurfaceBlendMode(src, &blend);
 
     /* TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1 */
-    {
+    if (texture_address_mode == SDL_TEXTURE_ADDRESS_CLAMP) {
         SDL_Rect srcrect;
         int maxx, maxy;
         bounding_rect(s0, s1, s2, &srcrect);
@@ -564,17 +576,6 @@ int SDL_SW_BlitTriangle(
         has_modulation = SDL_TRUE;
     }
 
-    {
-        /* Clip triangle rect with surface rect */
-        SDL_Rect rect;
-        rect.x = 0;
-        rect.y = 0;
-        rect.w = dst->w;
-        rect.h = dst->h;
-
-        SDL_GetRectIntersection(&dstrect, &rect, &dstrect);
-    }
-
     {
         /* Clip triangle with surface clip rect */
         SDL_Rect rect;
@@ -695,6 +696,7 @@ int SDL_SW_BlitTriangle(
         tmp_info.colorkey = info->colorkey;
 
         /* src */
+        tmp_info.src_surface = src_surface;
         tmp_info.src = (Uint8 *)src_ptr;
         tmp_info.src_pitch = src_pitch;
 
@@ -714,7 +716,7 @@ int SDL_SW_BlitTriangle(
         SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, (int)area, bias_w0, bias_w1, bias_w2,
                               d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x,
                               s2s0_x, s2s1_x, s2s0_y, s2s1_y, (int)w0_row, (int)w1_row, (int)w2_row,
-                              c0, c1, c2, is_uniform);
+                              c0, c1, c2, is_uniform, texture_address_mode);
 
         goto end;
     }
@@ -786,8 +788,9 @@ static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
                                   SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
                                   int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
                                   int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
-                                  SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform)
+                                  SDL_Color c0, SDL_Color c1, SDL_Color c2, SDL_bool is_uniform, SDL_TextureAddressMode texture_address_mode)
 {
+    SDL_Surface *src_surface = info->src_surface;
     const int flags = info->flags;
     Uint32 modulateR = info->r;
     Uint32 modulateG = info->g;

+ 4 - 1
src/render/software/SDL_triangle.h

@@ -24,6 +24,8 @@
 
 #include "SDL_internal.h"
 
+#include "../SDL_sysrender.h"   // For SDL_TextureAddressMode
+
 extern int SDL_SW_FillTriangle(SDL_Surface *dst,
                                SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
                                SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2);
@@ -33,7 +35,8 @@ extern int SDL_SW_BlitTriangle(
     SDL_Point *s0, SDL_Point *s1, SDL_Point *s2,
     SDL_Surface *dst,
     SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
-    SDL_Color c0, SDL_Color c1, SDL_Color c2);
+    SDL_Color c0, SDL_Color c1, SDL_Color c2,
+    SDL_TextureAddressMode texture_address_mode);
 
 extern void trianglepoint_2_fixedpoint(SDL_Point *a);
 

+ 59 - 26
src/render/vulkan/SDL_render_vulkan.c

@@ -158,9 +158,12 @@ typedef enum {
 } SDL_vulkan_renderpass_type;
 
 /* Sampler types */
-typedef enum {
-    SDL_VULKAN_SAMPLER_NEAREST = 0,
-    SDL_VULKAN_SAMPLER_LINEAR = 1,
+typedef enum
+{
+    SDL_VULKAN_SAMPLER_NEAREST_CLAMP,
+    SDL_VULKAN_SAMPLER_NEAREST_WRAP,
+    SDL_VULKAN_SAMPLER_LINEAR_CLAMP,
+    SDL_VULKAN_SAMPLER_LINEAR_WRAP,
     SDL_VULKAN_NUM_SAMPLERS
 } SDL_vulkan_sampler_type;
 
@@ -181,6 +184,15 @@ static const float INPUTTYPE_SRGB = 1;
 static const float INPUTTYPE_SCRGB = 2;
 static const float INPUTTYPE_HDR10 = 3;
 
+typedef enum
+{
+    SAMPLER_POINT_CLAMP,
+    SAMPLER_POINT_WRAP,
+    SAMPLER_LINEAR_CLAMP,
+    SAMPLER_LINEAR_WRAP,
+    NUM_SAMPLERS
+} Sampler;
+
 /* Pixel shader constants, common values */
 typedef struct
 {
@@ -1904,34 +1916,37 @@ static VkResult VULKAN_CreateDeviceResources(SDL_Renderer *renderer, SDL_Propert
 
     /* Create samplers */
     {
+        static struct
+        {
+            VkFilter filter;
+            VkSamplerAddressMode address;
+        } samplerParams[] = {
+            { VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
+            { VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_REPEAT },
+            { VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE },
+            { VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT },
+        };
+        SDL_COMPILE_TIME_ASSERT(samplerParams_SIZE, SDL_arraysize(samplerParams) == SDL_VULKAN_NUM_SAMPLERS);
         VkSamplerCreateInfo samplerCreateInfo = { 0 };
         samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
-        samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
-        samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
         samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
-        samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
-        samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
         samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
         samplerCreateInfo.mipLodBias = 0.0f;
         samplerCreateInfo.anisotropyEnable = VK_FALSE;
         samplerCreateInfo.maxAnisotropy = 1.0f;
         samplerCreateInfo.minLod = 0.0f;
         samplerCreateInfo.maxLod = 1000.0f;
-        result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST]);
-        if (result != VK_SUCCESS) {
-            VULKAN_DestroyAll(renderer);
-            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSampler(): %s\n", SDL_Vulkan_GetResultString(result));
-            return result;
-        }
-
-        samplerCreateInfo.magFilter = VK_FILTER_LINEAR;
-        samplerCreateInfo.minFilter = VK_FILTER_LINEAR;
-        samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
-        result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR]);
-        if (result != VK_SUCCESS) {
-            VULKAN_DestroyAll(renderer);
-            SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSampler(): %s\n", SDL_Vulkan_GetResultString(result));
-            return result;
+        for (int i = 0; i < SDL_arraysize(samplerParams); ++i) {
+            samplerCreateInfo.magFilter = samplerParams[i].filter;
+            samplerCreateInfo.minFilter = samplerParams[i].filter;
+            samplerCreateInfo.addressModeU = samplerParams[i].address;
+            samplerCreateInfo.addressModeV = samplerParams[i].address;
+            result = vkCreateSampler(rendererData->device, &samplerCreateInfo, NULL, &rendererData->samplers[i]);
+            if (result != VK_SUCCESS) {
+                VULKAN_DestroyAll(renderer);
+                SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateSampler(): %s\n", SDL_Vulkan_GetResultString(result));
+                return result;
+            }
         }
     }
 
@@ -2602,8 +2617,8 @@ static int VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
         samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
         samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
         samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
-        samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
-        samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+        samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
+        samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
         samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
         samplerCreateInfo.mipLodBias = 0.0f;
         samplerCreateInfo.anisotropyEnable = VK_FALSE;
@@ -3627,10 +3642,28 @@ static SDL_bool VULKAN_SetCopyState(SDL_Renderer *renderer, const SDL_RenderComm
 
     switch (textureData->scaleMode) {
     case VK_FILTER_NEAREST:
-        textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST];
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_NEAREST_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     case VK_FILTER_LINEAR:
-        textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR];
+        switch (cmd->data.draw.texture_address_mode) {
+        case SDL_TEXTURE_ADDRESS_CLAMP:
+            textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR_CLAMP];
+            break;
+        case SDL_TEXTURE_ADDRESS_WRAP:
+            textureSampler = rendererData->samplers[SDL_VULKAN_SAMPLER_LINEAR_WRAP];
+            break;
+        default:
+            return SDL_SetError("Unknown texture address mode: %d\n", cmd->data.draw.texture_address_mode);
+        }
         break;
     default:
         return SDL_SetError("Unknown scale mode: %d", textureData->scaleMode);

+ 708 - 240
test/testautomation_images.c

@@ -1725,158 +1725,158 @@ static const SDLTest_SurfaceImage_t SDLTest_imageRainbowBackground = {
         32,
         32,
         4,
-        "\000\016\377\377\000\031\377\377\000\045\377\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377"
-        "\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250"
-        "\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000"
-        "\374\377\377\000\377\356\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\216\377\000\377\167\377"
-        "\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\000\031\377\377\000\045\377"
-        "\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\170"
-        "\377\377\000\204\377\377\000\220\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000"
-        "\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\373\377\377\000\377\357\377\000\377\326\377"
-        "\000\377\276\377\000\377\247\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\110\377\000\377\060"
-        "\377\000\377\030\377\003\377\003\377\027\377\000\377\000\045\377\377\000\061\377\377\000\075\377\377\000\111"
-        "\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000"
-        "\235\377\377\000\251\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377"
-        "\000\360\377\377\000\374\377\377\000\377\357\377\000\377\325\377\000\377\276\377\000\377\246\377\000\377\216"
-        "\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\002\377\002\377\030\377"
-        "\000\377\060\377\000\377\000\061\377\377\000\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000"
-        "\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377"
-        "\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357"
-        "\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377"
-        "\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\061\377\000\377\110\377\000\377\000"
-        "\075\377\377\000\111\377\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377"
-        "\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377"
-        "\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377"
-        "\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003"
-        "\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\000\111\377\377\000\125\377\377"
-        "\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377"
-        "\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374"
-        "\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000"
-        "\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377"
-        "\107\377\000\377\140\377\000\377\167\377\000\377\000\125\377\377\000\141\377\377\000\155\377\377\000\171\377"
-        "\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314"
-        "\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000"
-        "\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377"
-        "\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\137\377\000\377\170\377\000"
-        "\377\217\377\000\377\000\141\377\377\000\155\377\377\000\171\377\377\000\205\377\377\000\221\377\377\000\234"
-        "\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000"
-        "\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377"
-        "\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000"
-        "\377\060\377\000\377\110\377\000\377\140\377\000\377\167\377\000\377\220\377\000\377\247\377\000\377\000\155"
-        "\377\377\000\170\377\377\000\205\377\377\000\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000"
-        "\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377"
-        "\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107"
-        "\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377"
-        "\000\377\170\377\000\377\217\377\000\377\250\377\000\377\277\377\000\377\000\171\377\377\000\204\377\377\000"
-        "\221\377\377\000\234\377\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377"
-        "\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246"
-        "\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377"
-        "\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247"
-        "\377\000\377\300\377\000\377\327\377\000\377\000\205\377\377\000\220\377\377\000\235\377\377\000\250\377\377"
-        "\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377"
-        "\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377"
-        "\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110"
-        "\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377"
-        "\357\377\000\377\000\221\377\377\000\234\377\377\000\251\377\377\000\264\377\377\000\300\377\377\000\314\377"
-        "\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377"
-        "\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000"
-        "\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377"
-        "\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\000\234\377"
-        "\377\000\250\377\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360"
-        "\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000"
-        "\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377"
-        "\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000"
-        "\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\000\250\377\377\000\264\377\377\000\300"
-        "\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000"
-        "\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377"
-        "\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000"
-        "\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367"
-        "\000\377\377\337\000\377\377\307\000\377\000\264\377\377\000\300\377\377\000\314\377\377\000\330\377\377\000"
-        "\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377"
-        "\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003"
-        "\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377"
-        "\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\340\000\377\377\307\000\377\377"
-        "\260\000\377\000\300\377\377\000\314\377\377\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377"
-        "\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137"
-        "\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377"
-        "\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360"
-        "\377\000\377\377\367\000\377\377\337\000\377\377\310\000\377\377\257\000\377\377\230\000\377\000\314\377\377"
-        "\000\330\377\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276"
-        "\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377"
-        "\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217"
-        "\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377"
-        "\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\000\330\377\377\000\344\377\377\000\360\377"
-        "\377\000\374\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377"
-        "\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060"
-        "\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377"
-        "\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000"
-        "\377\377\200\000\377\377\151\000\377\000\344\377\377\000\360\377\377\000\374\377\377\000\377\357\377\000\377"
-        "\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000"
-        "\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377"
-        "\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000"
-        "\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\201\000\377\377\150\000\377\377\121"
-        "\000\377\000\360\377\377\000\373\377\377\000\377\357\377\000\377\326\377\000\377\276\377\000\377\246\377\000"
-        "\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377"
-        "\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000"
-        "\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260"
-        "\000\377\377\230\000\377\377\200\000\377\377\151\000\377\377\120\000\377\377\071\000\377\000\374\377\377\000"
-        "\377\357\377\000\377\325\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377"
-        "\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000"
-        "\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377"
-        "\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377"
-        "\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\000\377\356\377\000\377\326\377\000\377\276\377"
-        "\000\377\246\377\000\377\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027"
-        "\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377"
-        "\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377"
-        "\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377"
-        "\377\041\000\377\377\012\000\377\000\377\326\377\000\377\276\377\000\377\246\377\000\377\217\377\000\377\167"
-        "\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377"
-        "\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327"
-        "\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377"
-        "\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015"
-        "\377\000\377\276\377\000\377\247\377\000\377\216\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377"
-        "\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170"
-        "\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377"
-        "\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000"
-        "\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\016\377\377\000\046\377\000\377\246\377\000\377"
-        "\217\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027"
-        "\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377"
-        "\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000"
-        "\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011"
-        "\000\377\377\000\015\377\377\000\047\377\377\000\076\377\000\377\216\377\000\377\167\377\000\377\137\377\000"
-        "\377\107\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377"
-        "\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000"
-        "\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150"
-        "\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377"
-        "\000\076\377\377\000\126\377\000\377\167\377\000\377\137\377\000\377\107\377\000\377\060\377\000\377\027\377"
-        "\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000"
-        "\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307"
-        "\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377"
-        "\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126\377\377\000\155\377"
-        "\000\377\137\377\000\377\110\377\000\377\060\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000"
-        "\377\110\377\000\377\140\377\000\377\170\377\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377"
-        "\000\377\360\377\000\377\377\367\000\377\377\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377"
-        "\200\000\377\377\150\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377"
-        "\377\000\046\377\377\000\076\377\377\000\125\377\377\000\156\377\377\000\205\377\000\377\107\377\000\377\060"
-        "\377\000\377\027\377\003\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\170\377"
-        "\000\377\217\377\000\377\247\377\000\377\277\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377"
-        "\337\000\377\377\307\000\377\377\260\000\377\377\230\000\377\377\200\000\377\377\150\000\377\377\121\000\377"
-        "\377\071\000\377\377\041\000\377\377\011\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126"
-        "\377\377\000\155\377\377\000\206\377\377\000\235\377\000\377\060\377\000\377\030\377\002\377\002\377\027\377"
-        "\000\377\060\377\000\377\107\377\000\377\137\377\000\377\167\377\000\377\217\377\000\377\247\377\000\377\277"
-        "\377\000\377\327\377\000\377\360\377\000\377\377\367\000\377\377\340\000\377\377\310\000\377\377\260\000\377"
-        "\377\230\000\377\377\201\000\377\377\151\000\377\377\121\000\377\377\071\000\377\377\041\000\377\377\011\000"
-        "\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\125\377\377\000\155\377\377\000\205\377\377\000"
-        "\235\377\377\000\264\377\000\377\027\377\003\377\003\377\030\377\000\377\061\377\000\377\110\377\000\377\140"
-        "\377\000\377\170\377\000\377\220\377\000\377\250\377\000\377\300\377\000\377\327\377\000\377\360\377\000\377"
-        "\377\367\000\377\377\337\000\377\377\307\000\377\377\257\000\377\377\230\000\377\377\200\000\377\377\150\000"
-        "\377\377\120\000\377\377\071\000\377\377\041\000\377\377\011\000\377\377\000\016\377\377\000\047\377\377\000"
-        "\076\377\377\000\126\377\377\000\156\377\377\000\206\377\377\000\235\377\377\000\266\377\377\000\315\377\003"
-        "\377\003\377\027\377\000\377\060\377\000\377\110\377\000\377\140\377\000\377\167\377\000\377\217\377\000\377"
-        "\247\377\000\377\277\377\000\377\327\377\000\377\357\377\000\377\377\367\000\377\377\337\000\377\377\307\000"
-        "\377\377\260\000\377\377\230\000\377\377\200\000\377\377\151\000\377\377\121\000\377\377\071\000\377\377\041"
-        "\000\377\377\012\000\377\377\000\015\377\377\000\046\377\377\000\076\377\377\000\126\377\377\000\155\377\377"
-        "\000\205\377\377\000\235\377\377\000\264\377\377\000\315\377\377\000\344\377"
+        "\0\016\377\377\0\031\377\377\0\045\377\377\0\061\377\377\0\075\377\377\0\111\377\377\0\125\377"
+        "\377\0\141\377\377\0\155\377\377\0\171\377\377\0\205\377\377\0\221\377\377\0\234\377\377\0\250"
+        "\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0"
+        "\374\377\377\0\377\356\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\216\377\0\377\167\377"
+        "\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\0\031\377\377\0\045\377"
+        "\377\0\061\377\377\0\075\377\377\0\111\377\377\0\125\377\377\0\141\377\377\0\155\377\377\0\170"
+        "\377\377\0\204\377\377\0\220\377\377\0\234\377\377\0\250\377\377\0\264\377\377\0\300\377\377\0"
+        "\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\373\377\377\0\377\357\377\0\377\326\377"
+        "\0\377\276\377\0\377\247\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\110\377\0\377\060"
+        "\377\0\377\030\377\003\377\003\377\027\377\0\377\0\045\377\377\0\061\377\377\0\075\377\377\0\111"
+        "\377\377\0\125\377\377\0\141\377\377\0\155\377\377\0\171\377\377\0\205\377\377\0\221\377\377\0"
+        "\235\377\377\0\251\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377"
+        "\0\360\377\377\0\374\377\377\0\377\357\377\0\377\325\377\0\377\276\377\0\377\246\377\0\377\216"
+        "\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\002\377\002\377\030\377"
+        "\0\377\060\377\0\377\0\061\377\377\0\075\377\377\0\111\377\377\0\125\377\377\0\141\377\377\0"
+        "\155\377\377\0\171\377\377\0\205\377\377\0\221\377\377\0\234\377\377\0\250\377\377\0\264\377\377"
+        "\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357"
+        "\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377"
+        "\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\061\377\0\377\110\377\0\377\0"
+        "\075\377\377\0\111\377\377\0\125\377\377\0\141\377\377\0\155\377\377\0\171\377\377\0\205\377\377"
+        "\0\221\377\377\0\234\377\377\0\250\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377"
+        "\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377"
+        "\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003"
+        "\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\0\111\377\377\0\125\377\377"
+        "\0\141\377\377\0\155\377\377\0\171\377\377\0\205\377\377\0\221\377\377\0\234\377\377\0\250\377"
+        "\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374"
+        "\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0"
+        "\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377"
+        "\107\377\0\377\140\377\0\377\167\377\0\377\0\125\377\377\0\141\377\377\0\155\377\377\0\171\377"
+        "\377\0\205\377\377\0\221\377\377\0\234\377\377\0\250\377\377\0\264\377\377\0\300\377\377\0\314"
+        "\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0"
+        "\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377"
+        "\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\137\377\0\377\170\377\0"
+        "\377\217\377\0\377\0\141\377\377\0\155\377\377\0\171\377\377\0\205\377\377\0\221\377\377\0\234"
+        "\377\377\0\250\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0"
+        "\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377"
+        "\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0"
+        "\377\060\377\0\377\110\377\0\377\140\377\0\377\167\377\0\377\220\377\0\377\247\377\0\377\0\155"
+        "\377\377\0\170\377\377\0\205\377\377\0\221\377\377\0\234\377\377\0\250\377\377\0\264\377\377\0"
+        "\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377"
+        "\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107"
+        "\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377"
+        "\0\377\170\377\0\377\217\377\0\377\250\377\0\377\277\377\0\377\0\171\377\377\0\204\377\377\0"
+        "\221\377\377\0\234\377\377\0\250\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377"
+        "\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246"
+        "\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377"
+        "\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247"
+        "\377\0\377\300\377\0\377\327\377\0\377\0\205\377\377\0\220\377\377\0\235\377\377\0\250\377\377"
+        "\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377"
+        "\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377"
+        "\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110"
+        "\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377"
+        "\357\377\0\377\0\221\377\377\0\234\377\377\0\251\377\377\0\264\377\377\0\300\377\377\0\314\377"
+        "\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377"
+        "\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0"
+        "\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377"
+        "\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\0\234\377"
+        "\377\0\250\377\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360"
+        "\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0"
+        "\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377"
+        "\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0"
+        "\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\0\250\377\377\0\264\377\377\0\300"
+        "\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0"
+        "\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377"
+        "\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0"
+        "\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367"
+        "\0\377\377\337\0\377\377\307\0\377\0\264\377\377\0\300\377\377\0\314\377\377\0\330\377\377\0"
+        "\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377"
+        "\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003"
+        "\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377"
+        "\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\340\0\377\377\307\0\377\377"
+        "\260\0\377\0\300\377\377\0\314\377\377\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377"
+        "\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137"
+        "\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377"
+        "\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360"
+        "\377\0\377\377\367\0\377\377\337\0\377\377\310\0\377\377\257\0\377\377\230\0\377\0\314\377\377"
+        "\0\330\377\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276"
+        "\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377"
+        "\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217"
+        "\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377"
+        "\377\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\0\330\377\377\0\344\377\377\0\360\377"
+        "\377\0\374\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377"
+        "\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060"
+        "\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377"
+        "\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0"
+        "\377\377\200\0\377\377\151\0\377\0\344\377\377\0\360\377\377\0\374\377\377\0\377\357\377\0\377"
+        "\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0"
+        "\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377"
+        "\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0"
+        "\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377\201\0\377\377\150\0\377\377\121"
+        "\0\377\0\360\377\377\0\373\377\377\0\377\357\377\0\377\326\377\0\377\276\377\0\377\246\377\0"
+        "\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377"
+        "\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0"
+        "\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260"
+        "\0\377\377\230\0\377\377\200\0\377\377\151\0\377\377\120\0\377\377\071\0\377\0\374\377\377\0"
+        "\377\357\377\0\377\325\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377"
+        "\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0"
+        "\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377"
+        "\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377"
+        "\150\0\377\377\121\0\377\377\071\0\377\377\041\0\377\0\377\356\377\0\377\326\377\0\377\276\377"
+        "\0\377\246\377\0\377\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027"
+        "\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377"
+        "\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377"
+        "\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377\150\0\377\377\121\0\377\377\071\0\377"
+        "\377\041\0\377\377\012\0\377\0\377\326\377\0\377\276\377\0\377\246\377\0\377\217\377\0\377\167"
+        "\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377"
+        "\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327"
+        "\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377"
+        "\377\200\0\377\377\150\0\377\377\121\0\377\377\071\0\377\377\041\0\377\377\011\0\377\377\0\015"
+        "\377\0\377\276\377\0\377\247\377\0\377\216\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377"
+        "\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170"
+        "\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377"
+        "\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377\150\0\377\377\121\0"
+        "\377\377\071\0\377\377\041\0\377\377\011\0\377\377\0\016\377\377\0\046\377\0\377\246\377\0\377"
+        "\217\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027"
+        "\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377"
+        "\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0"
+        "\377\377\230\0\377\377\200\0\377\377\150\0\377\377\121\0\377\377\071\0\377\377\041\0\377\377\011"
+        "\0\377\377\0\015\377\377\0\047\377\377\0\076\377\0\377\216\377\0\377\167\377\0\377\137\377\0"
+        "\377\107\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377"
+        "\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0"
+        "\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377\150"
+        "\0\377\377\121\0\377\377\071\0\377\377\041\0\377\377\011\0\377\377\0\015\377\377\0\046\377\377"
+        "\0\076\377\377\0\126\377\0\377\167\377\0\377\137\377\0\377\107\377\0\377\060\377\0\377\027\377"
+        "\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0"
+        "\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307"
+        "\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377\150\0\377\377\121\0\377\377\071\0\377\377"
+        "\041\0\377\377\011\0\377\377\0\015\377\377\0\046\377\377\0\076\377\377\0\126\377\377\0\155\377"
+        "\0\377\137\377\0\377\110\377\0\377\060\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0"
+        "\377\110\377\0\377\140\377\0\377\170\377\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377"
+        "\0\377\360\377\0\377\377\367\0\377\377\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377"
+        "\200\0\377\377\150\0\377\377\121\0\377\377\071\0\377\377\041\0\377\377\011\0\377\377\0\015\377"
+        "\377\0\046\377\377\0\076\377\377\0\125\377\377\0\156\377\377\0\205\377\0\377\107\377\0\377\060"
+        "\377\0\377\027\377\003\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\170\377"
+        "\0\377\217\377\0\377\247\377\0\377\277\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377"
+        "\337\0\377\377\307\0\377\377\260\0\377\377\230\0\377\377\200\0\377\377\150\0\377\377\121\0\377"
+        "\377\071\0\377\377\041\0\377\377\011\0\377\377\0\015\377\377\0\046\377\377\0\076\377\377\0\126"
+        "\377\377\0\155\377\377\0\206\377\377\0\235\377\0\377\060\377\0\377\030\377\002\377\002\377\027\377"
+        "\0\377\060\377\0\377\107\377\0\377\137\377\0\377\167\377\0\377\217\377\0\377\247\377\0\377\277"
+        "\377\0\377\327\377\0\377\360\377\0\377\377\367\0\377\377\340\0\377\377\310\0\377\377\260\0\377"
+        "\377\230\0\377\377\201\0\377\377\151\0\377\377\121\0\377\377\071\0\377\377\041\0\377\377\011\0"
+        "\377\377\0\015\377\377\0\046\377\377\0\076\377\377\0\125\377\377\0\155\377\377\0\205\377\377\0"
+        "\235\377\377\0\264\377\0\377\027\377\003\377\003\377\030\377\0\377\061\377\0\377\110\377\0\377\140"
+        "\377\0\377\170\377\0\377\220\377\0\377\250\377\0\377\300\377\0\377\327\377\0\377\360\377\0\377"
+        "\377\367\0\377\377\337\0\377\377\307\0\377\377\257\0\377\377\230\0\377\377\200\0\377\377\150\0"
+        "\377\377\120\0\377\377\071\0\377\377\041\0\377\377\011\0\377\377\0\016\377\377\0\047\377\377\0"
+        "\076\377\377\0\126\377\377\0\156\377\377\0\206\377\377\0\235\377\377\0\266\377\377\0\315\377\003"
+        "\377\003\377\027\377\0\377\060\377\0\377\110\377\0\377\140\377\0\377\167\377\0\377\217\377\0\377"
+        "\247\377\0\377\277\377\0\377\327\377\0\377\357\377\0\377\377\367\0\377\377\337\0\377\377\307\0"
+        "\377\377\260\0\377\377\230\0\377\377\200\0\377\377\151\0\377\377\121\0\377\377\071\0\377\377\041"
+        "\0\377\377\012\0\377\377\0\015\377\377\0\046\377\377\0\076\377\377\0\126\377\377\0\155\377\377"
+        "\0\205\377\377\0\235\377\377\0\264\377\377\0\315\377\377\0\344\377"
 };
 
 /**
@@ -1899,59 +1899,59 @@ static const SDLTest_SurfaceImage_t SDLTest_imageTransparentSprite = {
         32,
         32,
         4,
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\101\205\101\000\143\152\143\000\143\151\143\003\145\151\145\034\146\150\146\111\146\150\146\132\145\150"
-        "\146\014\146\150\146\000\146\150\146\000\147\147\147\000\145\150\145\042\146\147\146\137\146\150\146\111\145"
-        "\151\145\056\144\152\144\017\151\145\151\000\067\215\076\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\125\166\126\000\177\120"
-        "\176\000\147\147\147\117\147\147\147\230\147\147\147\242\147\147\147\233\147\147\147\111\377\000\377\000\143"
-        "\152\143\000\143\152\143\005\146\147\146\120\147\147\147\155\147\147\147\144\147\147\147\135\144\151\144\057"
-        "\176\126\174\000\110\200\113\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\126\164\127\000\205\115\204\000\146\147\146\154\147"
-        "\147\147\260\147\147\147\243\147\147\147\234\147\147\147\211\146\150\146\047\335\017\335\000\146\150\146\052"
-        "\147\147\147\160\147\147\147\154\147\147\147\144\147\147\147\135\146\150\146\064\203\123\201\000\132\161\134"
-        "\000\135\156\136\000\146\151\145\000\150\146\150\000\135\155\135\000\144\151\144\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\152\144\000\126\165\131\000\147\147\147\000\146"
-        "\147\146\000\143\152\143\000\204\120\203\000\156\142\156\000\146\147\146\135\147\147\147\256\147\147\147\243"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\101\205\101\0\143\152\143\0\143\151\143\003\145\151\145\034\146\150\146\111\146\150\146\132\145\150"
+        "\146\014\146\150\146\0\146\150\146\0\147\147\147\0\145\150\145\042\146\147\146\137\146\150\146\111\145"
+        "\151\145\056\144\152\144\017\151\145\151\0\067\215\076\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\125\166\126\0\177\120"
+        "\176\0\147\147\147\117\147\147\147\230\147\147\147\242\147\147\147\233\147\147\147\111\377\0\377\0\143"
+        "\152\143\0\143\152\143\005\146\147\146\120\147\147\147\155\147\147\147\144\147\147\147\135\144\151\144\057"
+        "\176\126\174\0\110\200\113\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\126\164\127\0\205\115\204\0\146\147\146\154\147"
+        "\147\147\260\147\147\147\243\147\147\147\234\147\147\147\211\146\150\146\047\335\017\335\0\146\150\146\052"
+        "\147\147\147\160\147\147\147\154\147\147\147\144\147\147\147\135\146\150\146\064\203\123\201\0\132\161\134"
+        "\0\135\156\136\0\146\151\145\0\150\146\150\0\135\155\135\0\144\151\144\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\144\152\144\0\126\165\131\0\147\147\147\0\146"
+        "\147\146\0\143\152\143\0\204\120\203\0\156\142\156\0\146\147\146\135\147\147\147\256\147\147\147\243"
         "\147\147\147\233\147\147\147\224\147\147\147\171\146\150\146\134\147\147\147\155\147\147\147\164\147\147\147"
-        "\154\147\147\147\144\147\147\147\135\146\150\146\065\161\140\161\000\143\152\143\000\120\165\123\001\143\153"
-        "\143\014\143\152\143\013\152\146\153\000\145\147\145\000\146\146\146\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\133\161\133\000\101\207\104\000\150\146\150\000\146\150\146\045\146\150\146\046\141\154\141\003"
-        "\147\147\147\000\150\146\150\000\146\150\146\126\147\147\147\256\147\147\147\243\147\147\147\233\147\147\147"
+        "\154\147\147\147\144\147\147\147\135\146\150\146\065\161\140\161\0\143\152\143\0\120\165\123\001\143\153"
+        "\143\014\143\152\143\013\152\146\153\0\145\147\145\0\146\146\146\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\133\161\133\0\101\207\104\0\150\146\150\0\146\150\146\045\146\150\146\046\141\154\141\003"
+        "\147\147\147\0\150\146\150\0\146\150\146\126\147\147\147\256\147\147\147\243\147\147\147\233\147\147\147"
         "\223\147\147\147\214\147\147\147\206\147\147\147\174\147\147\147\163\147\147\147\154\147\147\147\144\147\147"
         "\147\135\146\150\146\101\142\153\142\014\143\152\143\013\145\150\145\043\147\150\147\060\147\147\147\050\147"
-        "\147\147\013\147\152\147\000\143\150\143\000\133\161\134\000\000\000\000\000\000\000\000\000\150\146\150\000"
-        "\147\147\147\000\147\147\147\046\147\147\147\264\147\147\147\301\147\147\147\202\146\150\146\072\146\150\146"
+        "\147\147\013\147\152\147\0\143\150\143\0\133\161\134\0\0\0\0\0\0\0\0\0\150\146\150\0"
+        "\147\147\147\0\147\147\147\046\147\147\147\264\147\147\147\301\147\147\147\202\146\150\146\072\146\150\146"
         "\071\147\147\147\222\147\147\147\255\147\147\147\243\147\147\147\234\147\147\147\225\147\147\147\216\147\147"
         "\147\206\147\147\147\176\147\147\147\165\147\147\147\155\147\147\147\144\147\147\147\134\147\147\147\123\146"
         "\150\146\103\146\147\146\074\147\147\147\074\147\147\147\064\147\147\147\054\147\147\147\040\146\150\146\011"
-        "\152\145\152\000\132\162\133\000\000\000\000\000\000\000\000\000\147\147\147\000\146\150\146\024\147\147\147"
+        "\152\145\152\0\132\162\133\0\0\0\0\0\0\0\0\0\147\147\147\0\146\150\146\024\147\147\147"
         "\243\147\147\147\336\147\147\147\325\147\147\147\316\147\147\147\275\147\147\147\264\147\147\147\265\147\147"
         "\147\254\147\147\147\246\147\147\147\227\147\147\147\174\147\147\147\137\146\150\146\120\146\150\146\113\146"
         "\147\146\117\146\147\146\132\147\147\147\141\147\147\147\135\147\147\147\124\147\147\147\114\147\146\147\104"
-        "\147\147\147\074\147\147\147\064\147\147\147\054\147\147\147\044\145\151\145\015\154\144\153\000\125\166\130"
-        "\000\000\000\000\000\000\000\000\000\147\147\147\000\146\150\146\057\147\147\147\320\147\147\147\335\147\147"
+        "\147\147\147\074\147\147\147\064\147\147\147\054\147\147\147\044\145\151\145\015\154\144\153\0\125\166\130"
+        "\0\0\0\0\0\0\0\0\0\147\147\147\0\146\150\146\057\147\147\147\320\147\147\147\335\147\147"
         "\147\323\147\147\147\313\147\147\147\304\147\147\147\274\147\147\147\265\147\147\147\250\147\147\147\163\146"
-        "\150\146\061\144\151\145\016\137\155\140\002\170\133\212\000\170\127\213\000\134\160\134\002\143\152\143\012"
+        "\150\146\061\144\151\145\016\137\155\140\002\170\133\212\0\170\127\213\0\134\160\134\002\143\152\143\012"
         "\145\150\146\037\146\150\146\100\147\147\147\122\147\147\147\114\147\147\147\104\147\147\147\074\147\147\147"
-        "\064\147\147\147\054\146\150\146\035\141\154\141\003\142\152\142\000\134\161\135\000\000\000\000\000\000\000"
-        "\000\000\146\150\146\000\144\152\144\001\147\147\147\151\147\147\147\330\147\147\147\324\147\147\147\313\147"
-        "\147\147\303\147\147\147\275\147\147\147\244\147\147\146\110\143\150\133\006\163\162\231\000\202\204\275\000"
-        "\236\240\375\000\140\144\231\002\144\145\237\003\245\252\377\000\166\167\255\000\152\152\174\000\141\154\141"
+        "\064\147\147\147\054\146\150\146\035\141\154\141\003\142\152\142\0\134\161\135\0\0\0\0\0\0\0"
+        "\0\0\146\150\146\0\144\152\144\001\147\147\147\151\147\147\147\330\147\147\147\324\147\147\147\313\147"
+        "\147\147\303\147\147\147\275\147\147\147\244\147\147\146\110\143\150\133\006\163\162\231\0\202\204\275\0"
+        "\236\240\375\0\140\144\231\002\144\145\237\003\245\252\377\0\166\167\255\0\152\152\174\0\141\154\141"
         "\004\146\150\146\042\147\147\147\105\147\147\147\104\147\147\147\074\147\147\147\064\147\147\147\052\144\151"
-        "\144\014\150\146\147\000\162\130\162\000\000\000\000\000\000\000\000\000\000\000\000\000\146\150\146\000\146"
-        "\147\146\000\146\150\146\012\147\147\147\215\147\147\147\325\147\147\147\313\147\147\147\305\147\147\147\253"
-        "\146\150\146\071\161\152\222\000\162\162\274\011\174\173\311\053\177\176\314\110\201\201\321\115\202\202\322"
-        "\127\202\202\322\126\173\172\307\101\167\167\300\041\170\167\302\010\213\217\320\000\157\143\213\000\146\147"
-        "\146\026\147\147\147\075\147\147\147\074\147\147\147\064\147\150\147\050\142\153\142\006\150\147\150\000\146"
-        "\150\146\000\144\151\144\000\135\151\135\000\150\145\147\000\133\160\133\000\142\153\142\000\147\147\147\000"
-        "\146\147\146\130\147\147\147\323\147\147\147\314\147\147\147\277\147\147\147\117\166\161\240\000\163\161\271"
+        "\144\014\150\146\147\0\162\130\162\0\0\0\0\0\0\0\0\0\0\0\0\0\146\150\146\0\146"
+        "\147\146\0\146\150\146\012\147\147\147\215\147\147\147\325\147\147\147\313\147\147\147\305\147\147\147\253"
+        "\146\150\146\071\161\152\222\0\162\162\274\011\174\173\311\053\177\176\314\110\201\201\321\115\202\202\322"
+        "\127\202\202\322\126\173\172\307\101\167\167\300\041\170\167\302\010\213\217\320\0\157\143\213\0\146\147"
+        "\146\026\147\147\147\075\147\147\147\074\147\147\147\064\147\150\147\050\142\153\142\006\150\147\150\0\146"
+        "\150\146\0\144\151\144\0\135\151\135\0\150\145\147\0\133\160\133\0\142\153\142\0\147\147\147\0"
+        "\146\147\146\130\147\147\147\323\147\147\147\314\147\147\147\277\147\147\147\117\166\161\240\0\163\161\271"
         "\032\202\201\321\163\176\176\314\216\200\200\320\217\204\204\326\214\201\201\321\203\177\177\316\173\203\203"
-        "\324\165\200\200\320\150\175\175\312\120\175\174\313\054\147\144\245\007\164\155\237\000\145\150\145\033\147"
+        "\324\165\200\200\320\150\175\175\312\120\175\174\313\054\147\144\245\007\164\155\237\0\145\150\145\033\147"
         "\147\147\072\147\147\147\064\147\147\147\054\145\151\145\031\143\152\144\014\142\152\142\010\134\157\134\004"
-        "\131\154\131\001\150\146\150\000\155\143\155\000\143\152\143\006\145\150\145\033\147\147\147\237\147\147\147"
+        "\131\154\131\001\150\146\150\0\155\143\155\0\143\152\143\006\145\150\145\033\147\147\147\237\147\147\147"
         "\326\147\147\147\316\147\147\147\212\137\143\116\007\165\163\276\032\174\173\310\173\206\206\331\243\176\176"
         "\314\222\177\177\315\214\203\203\324\210\201\201\321\200\205\205\330\173\202\202\323\163\176\176\313\154\176"
         "\176\314\144\177\177\315\134\172\171\304\073\172\167\306\011\130\150\106\002\146\150\146\051\147\147\147\065"
@@ -1974,83 +1974,83 @@ static const SDLTest_SurfaceImage_t SDLTest_imageTransparentSprite = {
         "\147\147\146\176\171\172\305\015\203\203\325\227\202\202\323\260\210\210\334\250\202\202\323\231\205\205\327"
         "\234\204\204\327\223\204\204\325\212\204\204\326\201\203\203\323\173\200\200\317\164\177\177\316\153\201\201"
         "\320\143\205\205\327\134\205\205\327\124\176\176\313\115\174\173\310\063\142\146\237\002\146\150\145\037\147"
-        "\147\147\055\147\147\147\044\147\150\147\032\144\152\144\014\140\152\140\002\036\233\036\000\146\150\146\054"
+        "\147\147\055\147\147\147\044\147\150\147\032\144\152\144\014\140\152\140\002\036\233\036\0\146\150\146\054"
         "\147\147\147\150\147\147\147\254\147\147\147\331\147\147\147\334\147\147\147\327\147\147\147\177\150\156\255"
         "\003\201\201\321\176\177\177\315\261\206\206\330\251\203\203\323\234\202\202\323\233\203\203\324\223\205\205"
         "\330\213\203\203\325\203\206\206\331\174\200\200\316\163\177\177\316\153\203\203\324\144\200\200\316\134\201"
         "\201\321\124\200\200\316\114\202\202\323\067\153\154\254\004\145\150\145\037\147\147\147\055\147\147\147\044"
-        "\145\152\145\025\067\212\073\000\136\155\136\000\105\177\105\000\147\147\146\000\151\146\150\000\144\151\145"
+        "\145\152\145\025\067\212\073\0\136\155\136\0\105\177\105\0\147\147\146\0\151\146\150\0\144\151\145"
         "\010\147\147\147\171\147\147\147\335\147\147\147\326\147\147\147\221\104\124\011\003\177\176\315\103\206\206"
         "\332\244\206\206\331\254\202\202\323\234\206\206\331\230\202\202\323\223\205\205\327\213\202\202\323\202\203"
         "\203\324\171\205\205\327\163\201\201\320\154\176\176\314\144\201\201\320\134\205\205\330\124\201\201\320\115"
         "\202\201\322\053\072\132\047\001\145\151\145\044\147\147\147\055\147\147\147\044\146\152\146\026\134\160\135"
-        "\002\145\154\144\000\072\203\072\000\136\157\137\000\154\143\153\000\147\147\147\000\146\147\146\103\147\147"
-        "\147\327\147\147\147\325\147\147\147\256\145\150\145\025\143\170\000\000\177\176\315\057\203\203\324\231\205"
+        "\002\145\154\144\0\072\203\072\0\136\157\137\0\154\143\153\0\147\147\147\0\146\147\146\103\147\147"
+        "\147\327\147\147\147\325\147\147\147\256\145\150\145\025\143\170\0\0\177\176\315\057\203\203\324\231\205"
         "\205\327\240\176\176\313\217\201\201\321\220\174\174\310\211\174\174\311\201\200\200\320\170\176\176\314\162"
         "\200\200\317\153\207\207\333\143\202\202\323\134\176\176\314\124\174\174\310\103\173\173\310\020\134\151\124"
         "\005\146\150\146\054\147\147\147\054\147\147\147\044\150\150\150\034\144\147\144\017\140\151\140\003\227\076"
-        "\227\000\147\147\147\000\146\147\146\000\143\151\144\003\147\147\147\155\147\147\147\332\147\147\147\324\147"
-        "\147\147\307\147\147\147\103\150\147\161\000\137\133\225\003\174\173\307\163\202\202\322\246\203\203\324\227"
+        "\227\0\147\147\147\0\146\147\146\0\143\151\144\003\147\147\147\155\147\147\147\332\147\147\147\324\147"
+        "\147\147\307\147\147\147\103\150\147\161\0\137\133\225\003\174\173\307\163\202\202\322\246\203\203\324\227"
         "\202\202\322\220\202\202\322\210\177\177\316\202\177\177\316\172\200\200\317\163\205\205\327\153\177\177\316"
-        "\142\201\201\320\134\175\174\311\120\162\160\266\036\166\166\233\000\144\151\144\023\147\147\147\063\147\147"
-        "\147\054\147\147\147\044\150\150\150\034\146\146\146\024\144\147\144\013\142\153\142\002\146\147\146\000\146"
+        "\142\201\201\320\134\175\174\311\120\162\160\266\036\166\166\233\0\144\151\144\023\147\147\147\063\147\147"
+        "\147\054\147\147\147\044\150\150\150\034\146\146\146\024\144\147\144\013\142\153\142\002\146\147\146\0\146"
         "\150\146\007\147\147\147\160\147\147\147\332\147\147\147\334\147\147\147\323\147\147\147\316\147\147\147\216"
-        "\145\150\145\012\155\155\223\000\163\162\271\045\203\202\323\202\204\204\326\201\205\205\330\152\211\211\336"
+        "\145\150\145\012\155\155\223\0\163\162\271\045\203\202\323\202\204\204\326\201\205\205\330\152\211\211\336"
         "\212\203\203\324\203\200\200\316\173\203\203\324\163\201\201\320\154\200\200\316\144\176\176\314\134\172\171"
         "\304\060\126\111\235\001\140\154\134\003\146\150\146\052\147\147\147\065\147\147\147\054\147\147\147\044\150"
-        "\150\150\034\146\146\146\024\146\146\146\014\142\150\142\003\222\076\212\000\147\147\147\157\147\147\147\346"
+        "\150\150\034\146\146\146\024\146\146\146\014\142\150\142\003\222\076\212\0\147\147\147\157\147\147\147\346"
         "\147\147\147\344\147\147\147\333\147\147\147\323\147\147\147\314\147\147\147\300\147\147\147\124\155\143\156"
-        "\000\202\204\302\000\172\167\304\020\165\163\275\017\166\164\277\013\203\203\324\123\204\203\325\172\205\205"
-        "\327\175\200\200\317\164\176\176\314\155\166\166\276\142\164\164\273\074\152\151\254\006\170\145\246\000\145"
+        "\0\202\204\302\0\172\167\304\020\165\163\275\017\166\164\277\013\203\203\324\123\204\203\325\172\205\205"
+        "\327\175\200\200\317\164\176\176\314\155\166\166\276\142\164\164\273\074\152\151\254\006\170\145\246\0\145"
         "\150\145\035\147\147\147\073\147\147\147\064\147\147\147\054\147\147\147\044\150\150\150\034\147\146\147\024"
-        "\145\146\145\013\135\152\135\001\151\145\151\000\147\147\147\162\147\147\147\354\147\147\147\343\147\147\147"
-        "\334\147\147\147\325\147\147\147\314\147\147\147\304\147\147\147\255\146\150\147\076\155\142\155\000\161\161"
-        "\233\000\167\165\301\000\173\171\306\000\142\140\233\004\173\172\307\041\203\203\324\104\200\177\317\110\201"
-        "\200\320\102\176\175\313\046\170\164\306\005\172\147\252\000\143\151\144\031\146\147\146\076\147\147\147\074"
+        "\145\146\145\013\135\152\135\001\151\145\151\0\147\147\147\162\147\147\147\354\147\147\147\343\147\147\147"
+        "\334\147\147\147\325\147\147\147\314\147\147\147\304\147\147\147\255\146\150\147\076\155\142\155\0\161\161"
+        "\233\0\167\165\301\0\173\171\306\0\142\140\233\004\173\172\307\041\203\203\324\104\200\177\317\110\201"
+        "\200\320\102\176\175\313\046\170\164\306\005\172\147\252\0\143\151\144\031\146\147\146\076\147\147\147\074"
         "\147\147\147\064\146\150\146\047\145\151\146\031\146\151\146\026\145\147\145\021\144\151\145\010\074\205\103"
-        "\000\147\147\147\000\147\147\147\034\147\147\147\304\147\147\147\347\147\147\147\323\147\147\147\271\147\147"
-        "\147\274\147\147\147\305\147\147\147\275\147\147\147\246\147\147\147\115\144\151\145\011\150\147\150\000\145"
-        "\150\145\000\146\152\212\000\200\200\315\000\257\261\377\000\000\000\011\000\257\306\304\000\167\166\237\000"
+        "\0\147\147\147\0\147\147\147\034\147\147\147\304\147\147\147\347\147\147\147\323\147\147\147\271\147\147"
+        "\147\274\147\147\147\305\147\147\147\275\147\147\147\246\147\147\147\115\144\151\145\011\150\147\150\0\145"
+        "\150\145\0\146\152\212\0\200\200\315\0\257\261\377\0\0\0\011\0\257\306\304\0\167\166\237\0"
         "\140\152\131\004\146\151\146\045\147\147\147\106\147\147\147\104\147\147\147\074\147\147\147\060\144\152\144"
-        "\015\056\226\063\000\132\163\132\001\134\160\134\002\137\156\137\001\150\143\150\000\141\154\141\000\151\144"
-        "\151\000\147\147\147\111\147\147\147\147\146\147\146\072\146\150\146\031\147\147\147\074\147\147\147\254\147"
+        "\015\056\226\063\0\132\163\132\001\134\160\134\002\137\156\137\001\150\143\150\0\141\154\141\0\151\144"
+        "\151\0\147\147\147\111\147\147\147\147\146\147\146\072\146\150\146\031\147\147\147\074\147\147\147\254\147"
         "\147\147\274\147\147\147\264\147\147\147\251\147\147\147\170\146\150\146\066\145\150\145\021\141\154\141\004"
-        "\036\243\037\000\017\276\022\000\137\156\137\003\144\152\144\014\145\150\145\043\146\150\146\102\147\147\147"
-        "\122\147\147\147\114\147\147\147\104\147\147\147\074\146\150\146\053\140\154\140\004\136\155\137\000\131\164"
-        "\131\000\134\160\134\000\137\155\137\000\153\141\153\000\145\151\145\000\144\152\144\000\151\145\151\000\150"
-        "\146\150\000\147\147\147\000\146\150\146\000\147\147\147\000\147\150\146\130\147\147\147\274\147\147\147\263"
+        "\036\243\037\0\017\276\022\0\137\156\137\003\144\152\144\014\145\150\145\043\146\150\146\102\147\147\147"
+        "\122\147\147\147\114\147\147\147\104\147\147\147\074\146\150\146\053\140\154\140\004\136\155\137\0\131\164"
+        "\131\0\134\160\134\0\137\155\137\0\153\141\153\0\145\151\145\0\144\152\144\0\151\145\151\0\150"
+        "\146\150\0\147\147\147\0\146\150\146\0\147\147\147\0\147\150\146\130\147\147\147\274\147\147\147\263"
         "\147\147\147\254\147\147\147\245\147\147\147\231\147\147\147\177\147\147\146\145\147\147\147\122\147\147\147"
         "\115\146\147\146\123\147\147\147\135\147\147\147\142\147\147\147\135\147\147\147\124\147\147\147\114\147\147"
-        "\147\104\147\147\147\074\147\147\147\062\145\151\145\015\146\147\146\000\137\153\140\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\134\160\135\000\133\161\134\000\127\163\130\000\131\162\132\000"
-        "\075\206\100\000\152\145\152\000\147\147\147\141\147\147\147\276\147\147\147\263\147\147\147\253\147\147\147"
+        "\147\104\147\147\147\074\147\147\147\062\145\151\145\015\146\147\146\0\137\153\140\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\134\160\135\0\133\161\134\0\127\163\130\0\131\162\132\0"
+        "\075\206\100\0\152\145\152\0\147\147\147\141\147\147\147\276\147\147\147\263\147\147\147\253\147\147\147"
         "\243\147\147\147\234\147\147\147\225\147\147\147\216\147\147\147\206\147\147\147\176\147\147\147\165\147\147"
         "\147\154\147\147\147\144\147\147\147\135\147\147\147\125\147\147\147\114\146\146\146\104\147\147\147\074\147"
-        "\147\147\064\145\150\146\034\106\176\114\000\134\156\135\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\144\151\144\000\144\151\144"
+        "\147\147\064\145\150\146\034\106\176\114\0\134\156\135\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\144\151\144\0\144\151\144"
         "\006\147\147\147\214\147\147\147\276\147\147\147\263\147\147\147\254\147\147\147\243\147\147\147\221\147\147"
         "\147\220\147\147\147\214\147\147\147\203\147\147\147\173\147\147\147\164\147\147\147\154\147\147\147\137\146"
         "\150\146\100\146\150\146\057\146\147\146\104\147\147\147\105\147\147\147\074\147\147\147\065\145\150\146\042"
-        "\135\155\136\002\136\155\137\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\146\150\146\000\146\150\146\027\147\147\147\251\147\147"
+        "\135\155\136\002\136\155\137\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\146\150\146\0\146\150\146\027\147\147\147\251\147\147"
         "\147\277\147\147\147\264\147\147\147\254\147\147\147\152\145\151\145\037\146\150\146\054\147\147\147\145\147"
-        "\147\147\205\147\147\147\173\147\147\147\164\147\147\147\155\146\150\146\070\132\160\134\002\172\130\171\000"
-        "\145\150\145\023\146\147\146\067\147\147\147\074\146\150\146\046\143\152\144\011\175\141\167\000\133\155\136"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\146\150\146\000\145\150\146\007\147\147\147\116\147\147\147\234\147\147\147\263\147"
-        "\147\147\160\145\151\145\015\146\150\146\000\147\147\147\000\146\150\146\052\147\147\147\200\147\147\147\174"
-        "\147\147\147\164\147\147\147\152\145\150\145\040\146\150\146\000\134\160\134\000\147\146\147\000\143\152\143"
-        "\013\144\152\144\031\142\154\142\005\145\150\146\000\067\200\077\000\131\156\135\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\146"
-        "\150\146\000\146\150\146\000\152\145\152\000\146\150\146\030\147\147\147\103\145\150\145\017\146\147\146\000"
-        "\150\146\150\000\144\151\145\000\144\151\144\015\147\147\147\155\147\147\147\175\147\147\147\165\147\147\147"
-        "\143\144\151\144\021\144\151\145\000\131\162\131\000\375\000\374\000\146\147\146\000\155\142\154\000\143\152"
-        "\144\000\150\147\150\000\116\176\116\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\142\153\142\000"
-        "\124\166\124\000\147\150\147\000\150\146\150\000\146\147\146\000\150\146\150\000\120\170\120\000\136\156\136"
-        "\000\115\167\115\000\146\150\146\115\146\147\146\170\146\147\146\151\146\150\146\110\143\152\143\005\142\152"
-        "\143\000\000\000\000\000\072\212\100\000\073\213\077\000\073\213\076\000\076\220\070\000\000\000\000\000\000"
-        "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
+        "\147\147\205\147\147\147\173\147\147\147\164\147\147\147\155\146\150\146\070\132\160\134\002\172\130\171\0"
+        "\145\150\145\023\146\147\146\067\147\147\147\074\146\150\146\046\143\152\144\011\175\141\167\0\133\155\136"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\146\150\146\0\145\150\146\007\147\147\147\116\147\147\147\234\147\147\147\263\147"
+        "\147\147\160\145\151\145\015\146\150\146\0\147\147\147\0\146\150\146\052\147\147\147\200\147\147\147\174"
+        "\147\147\147\164\147\147\147\152\145\150\145\040\146\150\146\0\134\160\134\0\147\146\147\0\143\152\143"
+        "\013\144\152\144\031\142\154\142\005\145\150\146\0\067\200\077\0\131\156\135\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\146"
+        "\150\146\0\146\150\146\0\152\145\152\0\146\150\146\030\147\147\147\103\145\150\145\017\146\147\146\0"
+        "\150\146\150\0\144\151\145\0\144\151\144\015\147\147\147\155\147\147\147\175\147\147\147\165\147\147\147"
+        "\143\144\151\144\021\144\151\145\0\131\162\131\0\375\0\374\0\146\147\146\0\155\142\154\0\143\152"
+        "\144\0\150\147\150\0\116\176\116\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\142\153\142\0"
+        "\124\166\124\0\147\150\147\0\150\146\150\0\146\147\146\0\150\146\150\0\120\170\120\0\136\156\136"
+        "\0\115\167\115\0\146\150\146\115\146\147\146\170\146\147\146\151\146\150\146\110\143\152\143\005\142\152"
+        "\143\0\0\0\0\0\072\212\100\0\073\213\077\0\073\213\076\0\076\220\070\0\0\0\0\0\0"
+        "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 };
 
 /**
@@ -2066,3 +2066,471 @@ SDL_Surface *SDLTest_ImageBlendingSprite(void)
             SDLTest_imageTransparentSprite.width * SDLTest_imageTransparentSprite.bytes_per_pixel);
     return surface;
 }
+
+static const SDLTest_SurfaceImage_t SDLTest_imageWrappingSprite = {
+    80,
+    60,
+    3,
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0"
+  "\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0"
+  "\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0"
+  "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377"
+  "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377"
+  "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377"
+  "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377"
+  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+  "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
+  "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
+};
+
+/**
+ * \brief Returns the blending rendering sprite test image as an SDL_Surface.
+ */
+SDL_Surface *SDLTest_ImageWrappingSprite(void)
+{
+    SDL_Surface *surface = SDL_CreateSurfaceFrom(
+            SDLTest_imageWrappingSprite.width,
+            SDLTest_imageWrappingSprite.height,
+            SDL_PIXELFORMAT_RGB24,
+            (void *)SDLTest_imageWrappingSprite.pixel_data,
+            SDLTest_imageWrappingSprite.width * SDLTest_imageWrappingSprite.bytes_per_pixel);
+    return surface;
+}
+

+ 7 - 6
test/testautomation_images.h

@@ -23,9 +23,10 @@ typedef struct SDLTest_SurfaceImage_s {
 } SDLTest_SurfaceImage_t;
 
 /* Test images */
-SDL_Surface *SDLTest_ImageBlit(void);
-SDL_Surface *SDLTest_ImageBlitColor(void);
-SDL_Surface *SDLTest_ImageFace(void);
-SDL_Surface *SDLTest_ImagePrimitives(void);
-SDL_Surface *SDLTest_ImageBlendingBackground(void);
-SDL_Surface *SDLTest_ImageBlendingSprite(void);
+extern SDL_Surface *SDLTest_ImageBlit(void);
+extern SDL_Surface *SDLTest_ImageBlitColor(void);
+extern SDL_Surface *SDLTest_ImageFace(void);
+extern SDL_Surface *SDLTest_ImagePrimitives(void);
+extern SDL_Surface *SDLTest_ImageBlendingBackground(void);
+extern SDL_Surface *SDLTest_ImageBlendingSprite(void);
+extern SDL_Surface *SDLTest_ImageWrappingSprite(void);

+ 108 - 1
test/testautomation_render.c

@@ -1076,6 +1076,109 @@ clearScreen(void)
     return 0;
 }
 
+/**
+ * Tests geometry UV wrapping
+ */
+static int render_testUVWrapping(void *arg)
+{
+    SDL_Vertex vertices[6];
+    SDL_Vertex *verts = vertices;
+    SDL_FColor color = { 1.0f, 1.0f, 1.0f, 1.0f };
+    float tw, th;
+    SDL_FRect rect;
+    float min_U = -0.5f;
+    float max_U = 1.5f;
+    float min_V = -0.5f;
+    float max_V = 1.5f;
+    SDL_Texture *tface;
+    SDL_Surface *referenceSurface = NULL;
+
+    /* Clear surface. */
+    clearScreen();
+
+    /* Create face surface. */
+    tface = loadTestFace();
+    SDLTest_AssertCheck(tface != NULL, "Verify loadTestFace() result");
+    if (tface == NULL) {
+        return TEST_ABORTED;
+    }
+
+    CHECK_FUNC(SDL_GetTextureSize, (tface, &tw, &th))
+    rect.w = tw * 2;
+    rect.h = th * 2;
+    rect.x = (TESTRENDER_SCREEN_W - rect.w) / 2;
+    rect.y = (TESTRENDER_SCREEN_H - rect.h) / 2;
+
+    /*
+     *   0--1
+     *   | /|
+     *   |/ |
+     *   3--2
+     *
+     *  Draw sprite2 as triangles that can be recombined as rect by software renderer
+     */
+
+    /* 0 */
+    verts->position.x = rect.x;
+    verts->position.y = rect.y;
+    verts->color = color;
+    verts->tex_coord.x = min_U;
+    verts->tex_coord.y = min_V;
+    verts++;
+    /* 1 */
+    verts->position.x = rect.x + rect.w;
+    verts->position.y = rect.y;
+    verts->color = color;
+    verts->tex_coord.x = max_U;
+    verts->tex_coord.y = min_V;
+    verts++;
+    /* 2 */
+    verts->position.x = rect.x + rect.w;
+    verts->position.y = rect.y + rect.h;
+    verts->color = color;
+    verts->tex_coord.x = max_U;
+    verts->tex_coord.y = max_V;
+    verts++;
+    /* 0 */
+    verts->position.x = rect.x;
+    verts->position.y = rect.y;
+    verts->color = color;
+    verts->tex_coord.x = min_U;
+    verts->tex_coord.y = min_V;
+    verts++;
+    /* 2 */
+    verts->position.x = rect.x + rect.w;
+    verts->position.y = rect.y + rect.h;
+    verts->color = color;
+    verts->tex_coord.x = max_U;
+    verts->tex_coord.y = max_V;
+    verts++;
+    /* 3 */
+    verts->position.x = rect.x;
+    verts->position.y = rect.y + rect.h;
+    verts->color = color;
+    verts->tex_coord.x = min_U;
+    verts->tex_coord.y = max_V;
+    verts++;
+
+    /* Blit sprites as triangles onto the screen */
+    SDL_RenderGeometry(renderer, tface, vertices, 6, NULL, 0);
+
+    /* See if it's the same */
+    referenceSurface = SDLTest_ImageWrappingSprite();
+    compare(referenceSurface, ALLOWABLE_ERROR_OPAQUE);
+
+    /* Make current */
+    SDL_RenderPresent(renderer);
+
+    /* Clean up. */
+    SDL_DestroyTexture(tface);
+    SDL_DestroySurface(referenceSurface);
+    referenceSurface = NULL;
+
+    return TEST_COMPLETED;
+}
+
 /* ================= Test References ================== */
 
 /* Render test cases */
@@ -1115,11 +1218,15 @@ static const SDLTest_TestCaseReference renderTest9 = {
     (SDLTest_TestCaseFp)render_testLogicalSize, "render_testLogicalSize", "Tests logical size", TEST_ENABLED
 };
 
+static const SDLTest_TestCaseReference renderTestUVWrapping = {
+    (SDLTest_TestCaseFp)render_testUVWrapping, "render_testUVWrapping", "Tests geometry UV wrapping", TEST_ENABLED
+};
+
 /* Sequence of Render test cases */
 static const SDLTest_TestCaseReference *renderTests[] = {
     &renderTest1, &renderTest2, &renderTest3, &renderTest4,
     &renderTest5, &renderTest6, &renderTest7, &renderTest8,
-    &renderTest9, NULL
+    &renderTest9, &renderTestUVWrapping, NULL
 };
 
 /* Render test suite (global) */