test/testscale.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 28 Nov 2014 04:51:33 -0800
changeset 9246 a761913e5e91
parent 8149 681eb46b8ac4
child 9278 8900afb78a19
permissions -rw-r--r--
Fixed bug 2786 - "UCS-2-INTERNAL" iconv encoding is not supported everywhere, use UTF-16LE instead

Jonas Kulla

src/main/windows/SDL_windows_main.c:137:
cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));

I'm trying to compile an SDL2 application for windows using the mingw-w64 32bit toolchain provided by my distro (Fedora 19). However, even the simplest test program that does nothing at all fails to startup with a "Fatal error - out of memory" message because the mingw iconv library provided by my distro does not support the "UCS-2-INTERNAL" encoding and the conversion returns null.

From my little bit of research, it turns out that even though this encoding is supported by the external GNU libiconv library, some glibc versions (?) don't support it with their internal iconv routines, and will instead provide the native endian encoding when "UCS-2" is specified.

Nonetheless, I wonder why the native endianness is considered in the first place when Windows doesn't even run on any big endian archs (to my knowledge). And true enough, 'WIN_StringToUTF8' from core/windows/SDL_windows.h is used everywhere else in the windows backend, which is just a macro to iconv with "UTF-16LE" as source. Therefore it would IMO make sense to use this macro here as well, which would solve my problem (patch attached).
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@5240
    12
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@5240
    13
slouken@5240
    14
#include <stdlib.h>
slouken@5240
    15
#include <stdio.h>
slouken@5240
    16
#include <time.h>
slouken@5240
    17
slouken@6785
    18
#include "SDL_test_common.h"
slouken@5240
    19
slouken@5240
    20
#define WINDOW_WIDTH    640
slouken@5240
    21
#define WINDOW_HEIGHT   480
slouken@5240
    22
slouken@6785
    23
static SDLTest_CommonState *state;
slouken@5240
    24
slouken@5240
    25
typedef struct {
slouken@5240
    26
    SDL_Window *window;
slouken@5240
    27
    SDL_Renderer *renderer;
slouken@5240
    28
    SDL_Texture *background;
slouken@5240
    29
    SDL_Texture *sprite;
slouken@5240
    30
    SDL_Rect sprite_rect;
slouken@5240
    31
    int scale_direction;
slouken@5240
    32
} DrawState;
slouken@5240
    33
slouken@5240
    34
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@5240
    35
static void
slouken@5240
    36
quit(int rc)
slouken@5240
    37
{
slouken@6785
    38
    SDLTest_CommonQuit(state);
slouken@5240
    39
    exit(rc);
slouken@5240
    40
}
slouken@5240
    41
slouken@5240
    42
SDL_Texture *
slouken@5240
    43
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
slouken@5240
    44
{
slouken@5240
    45
    SDL_Surface *temp;
slouken@5240
    46
    SDL_Texture *texture;
slouken@5240
    47
slouken@5240
    48
    /* Load the sprite image */
slouken@5240
    49
    temp = SDL_LoadBMP(file);
slouken@5240
    50
    if (temp == NULL) {
aschiffler@7639
    51
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
slouken@5240
    52
        return NULL;
slouken@5240
    53
    }
slouken@5240
    54
slouken@5240
    55
    /* Set transparent pixel as the pixel at (0,0) */
slouken@5240
    56
    if (transparent) {
slouken@5240
    57
        if (temp->format->palette) {
slouken@5240
    58
            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
slouken@5240
    59
        } else {
slouken@5240
    60
            switch (temp->format->BitsPerPixel) {
slouken@5240
    61
            case 15:
slouken@5240
    62
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@5240
    63
                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
slouken@5240
    64
                break;
slouken@5240
    65
            case 16:
slouken@5240
    66
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
slouken@5240
    67
                break;
slouken@5240
    68
            case 24:
slouken@5240
    69
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@5240
    70
                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
slouken@5240
    71
                break;
slouken@5240
    72
            case 32:
slouken@5240
    73
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
slouken@5240
    74
                break;
slouken@5240
    75
            }
slouken@5240
    76
        }
slouken@5240
    77
    }
slouken@5240
    78
slouken@5240
    79
    /* Create textures from the image */
slouken@5240
    80
    texture = SDL_CreateTextureFromSurface(renderer, temp);
slouken@5240
    81
    if (!texture) {
aschiffler@7639
    82
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
slouken@5240
    83
        SDL_FreeSurface(temp);
slouken@5240
    84
        return NULL;
slouken@5240
    85
    }
slouken@5240
    86
    SDL_FreeSurface(temp);
slouken@5240
    87
slouken@5240
    88
    /* We're ready to roll. :) */
slouken@5240
    89
    return texture;
slouken@5240
    90
}
slouken@5240
    91
slouken@5240
    92
void
slouken@5240
    93
Draw(DrawState *s)
slouken@5240
    94
{
slouken@5297
    95
    SDL_Rect viewport;
slouken@5240
    96
slouken@5297
    97
    SDL_RenderGetViewport(s->renderer, &viewport);
slouken@5240
    98
slouken@5240
    99
    /* Draw the background */
slouken@5240
   100
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
slouken@5240
   101
slouken@5240
   102
    /* Scale and draw the sprite */
slouken@5240
   103
    s->sprite_rect.w += s->scale_direction;
slouken@5240
   104
    s->sprite_rect.h += s->scale_direction;
slouken@5240
   105
    if (s->scale_direction > 0) {
slouken@5297
   106
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
slouken@5240
   107
            s->scale_direction = -1;
slouken@5240
   108
        }
slouken@5240
   109
    } else {
slouken@5240
   110
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
slouken@5240
   111
            s->scale_direction = 1;
slouken@5240
   112
        }
slouken@5240
   113
    }
slouken@5297
   114
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
slouken@5297
   115
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
slouken@5240
   116
slouken@5240
   117
    SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
slouken@5240
   118
slouken@5240
   119
    /* Update the screen! */
slouken@5240
   120
    SDL_RenderPresent(s->renderer);
slouken@5240
   121
}
slouken@5240
   122
slouken@5240
   123
int
slouken@5240
   124
main(int argc, char *argv[])
slouken@5240
   125
{
slouken@5240
   126
    DrawState *drawstates;
slouken@5240
   127
    int i, done;
slouken@5240
   128
    SDL_Event event;
slouken@5240
   129
    int frames;
slouken@5240
   130
    Uint32 then, now;
slouken@5240
   131
aschiffler@7639
   132
    /* Enable standard application logging */
aschiffler@7639
   133
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   134
slouken@5240
   135
    /* Initialize test framework */
slouken@6785
   136
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@5240
   137
    if (!state) {
slouken@5240
   138
        return 1;
slouken@5240
   139
    }
slouken@5240
   140
    for (i = 1; i < argc;) {
slouken@5240
   141
        int consumed;
slouken@5240
   142
slouken@6785
   143
        consumed = SDLTest_CommonArg(state, i);
slouken@5240
   144
        if (consumed == 0) {
aschiffler@7639
   145
            SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
slouken@5240
   146
            return 1;
slouken@5240
   147
        }
slouken@5240
   148
        i += consumed;
slouken@5240
   149
    }
slouken@6785
   150
    if (!SDLTest_CommonInit(state)) {
slouken@5240
   151
        quit(2);
slouken@5240
   152
    }
slouken@5240
   153
slouken@5240
   154
    drawstates = SDL_stack_alloc(DrawState, state->num_windows);
slouken@5240
   155
    for (i = 0; i < state->num_windows; ++i) {
slouken@5240
   156
        DrawState *drawstate = &drawstates[i];
slouken@5240
   157
slouken@5240
   158
        drawstate->window = state->windows[i];
slouken@5240
   159
        drawstate->renderer = state->renderers[i];
slouken@5240
   160
        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
slouken@5240
   161
        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
slouken@5240
   162
        if (!drawstate->sprite || !drawstate->background) {
slouken@5240
   163
            quit(2);
slouken@5240
   164
        }
slouken@5240
   165
        SDL_QueryTexture(drawstate->sprite, NULL, NULL,
slouken@5240
   166
                         &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
slouken@5240
   167
        drawstate->scale_direction = 1;
slouken@5240
   168
    }
slouken@5240
   169
slouken@5240
   170
    /* Main render loop */
slouken@5240
   171
    frames = 0;
slouken@5240
   172
    then = SDL_GetTicks();
slouken@5240
   173
    done = 0;
slouken@5240
   174
    while (!done) {
slouken@5240
   175
        /* Check for events */
slouken@5240
   176
        ++frames;
slouken@5240
   177
        while (SDL_PollEvent(&event)) {
slouken@6785
   178
            SDLTest_CommonEvent(state, &event, &done);
slouken@5240
   179
        }
slouken@5240
   180
        for (i = 0; i < state->num_windows; ++i) {
slouken@7787
   181
            if (state->windows[i] == NULL)
slouken@7787
   182
                continue;
slouken@5240
   183
            Draw(&drawstates[i]);
slouken@5240
   184
        }
slouken@5240
   185
    }
slouken@5240
   186
slouken@5240
   187
    /* Print out some timing information */
slouken@5240
   188
    now = SDL_GetTicks();
slouken@5240
   189
    if (now > then) {
slouken@5240
   190
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   191
        SDL_Log("%2.2f frames per second\n", fps);
slouken@5240
   192
    }
slouken@5240
   193
slouken@5295
   194
    SDL_stack_free(drawstates);
slouken@5240
   195
slouken@5240
   196
    quit(0);
slouken@5240
   197
    return 0;
slouken@5240
   198
}
slouken@5240
   199
slouken@5240
   200
/* vi: set ts=4 sw=4 expandtab: */