Ejemplo n.º 1
0
int
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
    HWND hwnd = (HWND) data;
    LPTSTR title;
    int titleLen;

    /* Query the title from the existing window */
    titleLen = GetWindowTextLength(hwnd);
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
    if (title) {
        titleLen = GetWindowText(hwnd, title, titleLen);
    } else {
        titleLen = 0;
    }
    if (titleLen > 0) {
        window->title = WIN_StringToUTF8(title);
    }
    if (title) {
        SDL_stack_free(title);
    }

    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
        return -1;
    }
    return 0;
}
Ejemplo n.º 2
0
static int
GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                     int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    int i;
    GLshort *vertices;

    GLES_SetBlendMode(data, renderer->blendMode, 1);

    data->glColor4f((GLfloat) renderer->r * inv255f,
                    (GLfloat) renderer->g * inv255f,
                    (GLfloat) renderer->b * inv255f,
                    (GLfloat) renderer->a * inv255f);

    vertices = SDL_stack_alloc(GLshort, count*2);
    for (i = 0; i < count; ++i) {
        vertices[2*i+0] = (GLshort)points[i].x;
        vertices[2*i+1] = (GLshort)points[i].y;
    }
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
    data->glEnableClientState(GL_VERTEX_ARRAY);
    if (count > 2 && 
        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
        /* GL_LINE_LOOP takes care of the final segment */
        --count;
        data->glDrawArrays(GL_LINE_LOOP, 0, count);
    } else {
        data->glDrawArrays(GL_LINE_STRIP, 0, count);
    }
    data->glDisableClientState(GL_VERTEX_ARRAY);
    SDL_stack_free(vertices);

    return 0;
}
Ejemplo n.º 3
0
static int
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                      int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    int i;
    GLshort *vertices;

    GLES_SetBlendMode(data, renderer->blendMode, 1);

    data->glColor4f((GLfloat) renderer->r * inv255f,
                    (GLfloat) renderer->g * inv255f,
                    (GLfloat) renderer->b * inv255f,
                    (GLfloat) renderer->a * inv255f);

    vertices = SDL_stack_alloc(GLshort, count*2);
    for (i = 0; i < count; ++i) {
        vertices[2*i+0] = (GLshort)points[i].x;
        vertices[2*i+1] = (GLshort)points[i].y;
    }
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
    data->glEnableClientState(GL_VERTEX_ARRAY);
    data->glDrawArrays(GL_POINTS, 0, count);
    data->glDisableClientState(GL_VERTEX_ARRAY);
    SDL_stack_free(vertices);

    return 0;
}
Ejemplo n.º 4
0
static int
GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                     int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    int i;
    GLshort *vertices;

    GLES_SetDrawingState(renderer);

    vertices = SDL_stack_alloc(GLshort, count*2);
    for (i = 0; i < count; ++i) {
        vertices[2*i+0] = (GLshort)points[i].x;
        vertices[2*i+1] = (GLshort)points[i].y;
    }
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
    if (count > 2 && 
        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
        /* GL_LINE_LOOP takes care of the final segment */
        --count;
        data->glDrawArrays(GL_LINE_LOOP, 0, count);
    } else {
        data->glDrawArrays(GL_LINE_STRIP, 0, count);
        /* We need to close the endpoint of the line */
        data->glDrawArrays(GL_POINTS, count-1, 1);
    }
    SDL_stack_free(vertices);

    return 0;
}
Ejemplo n.º 5
0
int
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
    HWND hwnd = (HWND) data;
    LPTSTR title;
    int titleLen;

    /* Query the title from the existing window */
    titleLen = GetWindowTextLength(hwnd);
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
    if (title) {
        titleLen = GetWindowText(hwnd, title, titleLen);
    } else {
        titleLen = 0;
    }
    if (titleLen > 0) {
        window->title = WIN_StringToUTF8(title);
    }
    if (title) {
        SDL_stack_free(title);
    }

    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
        return -1;
    }

    // Urho3D: if window will be used for OpenGL, choose pixel format
    if (window->flags & SDL_WINDOW_OPENGL) {
        if (WIN_GL_SetupWindow(_this, window) < 0) {
            return -1;
        }
    }

    return 0;
}
Ejemplo n.º 6
0
static int
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
                      int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    GLfloat *vertices;
    int idx;

    GLES_SetDrawingState(renderer);

    /* Emit the specified vertices as points */
    vertices = SDL_stack_alloc(GLfloat, count * 2);
    for (idx = 0; idx < count; ++idx) {
        GLfloat x = points[idx].x + 0.5f;
        GLfloat y = points[idx].y + 0.5f;

        vertices[idx * 2] = x;
        vertices[(idx * 2) + 1] = y;
    }

    data->glVertexPointer(2, GL_FLOAT, 0, vertices);
    data->glDrawArrays(GL_POINTS, 0, count);
    SDL_stack_free(vertices);
    return 0;
}
Ejemplo n.º 7
0
static int
GLES_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
                     int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    GLfloat *vertices;
    int idx;

    GLES_SetDrawingState(renderer);

    /* Emit a line strip including the specified vertices */
    vertices = SDL_stack_alloc(GLfloat, count * 2);
    for (idx = 0; idx < count; ++idx) {
        GLfloat x = points[idx].x + 0.5f;
        GLfloat y = points[idx].y + 0.5f;

        vertices[idx * 2] = x;
        vertices[(idx * 2) + 1] = y;
    }

    data->glVertexPointer(2, GL_FLOAT, 0, vertices);
    if (count > 2 &&
        points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
        /* GL_LINE_LOOP takes care of the final segment */
        --count;
        data->glDrawArrays(GL_LINE_LOOP, 0, count);
    } else {
        data->glDrawArrays(GL_LINE_STRIP, 0, count);
        /* We need to close the endpoint of the line */
        data->glDrawArrays(GL_POINTS, count-1, 1);
    }
    SDL_stack_free(vertices);

    return 0;
}
Ejemplo n.º 8
0
int
WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
    HWND hwnd = (HWND) data;
    LPTSTR title;
    int titleLen;

    /* Query the title from the existing window */
    titleLen = GetWindowTextLength(hwnd);
    title = SDL_stack_alloc(TCHAR, titleLen + 1);
    if (title) {
        titleLen = GetWindowText(hwnd, title, titleLen);
    } else {
        titleLen = 0;
    }
    if (titleLen > 0) {
        window->title = WIN_StringToUTF8(title);
    }
    if (title) {
        SDL_stack_free(title);
    }

    if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
        return -1;
    }

    // Urho3D: if window will be used for OpenGL, choose pixel format
    if (window->flags & SDL_WINDOW_OPENGL) {
        if (WIN_GL_SetupWindow(_this, window) < 0) {
            return -1;
        }
    }

#if SDL_VIDEO_OPENGL_WGL
    {
        const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT);
        if (hint) {
            // This hint is a pointer (in string form) of the address of
            // the window to share a pixel format with
            SDL_Window *otherWindow = NULL;
            SDL_sscanf(hint, "%p", (void**)&otherWindow);

            // Do some error checking on the pointer
            if (otherWindow != NULL && otherWindow->magic == &_this->window_magic)
            {
                // If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well
                if (otherWindow->flags & SDL_WINDOW_OPENGL)
                {
                    window->flags |= SDL_WINDOW_OPENGL;
                    if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
                        return -1;
                    }
                }
            }
        }
    }
#endif
    return 0;
}
Ejemplo n.º 9
0
static int
GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                    Uint32 pixel_format, void * pixels, int pitch)
{
    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    Uint32 temp_format = SDL_PIXELFORMAT_ARGB8888;
    void *temp_pixels;
    int temp_pitch;
    GLint internalFormat;
    GLenum format, type;
    Uint8 *src, *dst, *tmp;
    int w, h, length, rows;
    int status;

    GL_ActivateRenderer(renderer);

    temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
    temp_pixels = SDL_malloc(rect->h * temp_pitch);
    if (!temp_pixels) {
        SDL_OutOfMemory();
        return -1;
    }

    convert_format(data, temp_format, &internalFormat, &format, &type);

    SDL_GetWindowSize(window, &w, &h);

    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
    data->glPixelStorei(GL_PACK_ROW_LENGTH,
                        (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));

    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
                       format, type, temp_pixels);

    /* Flip the rows to be top-down */
    length = rect->w * SDL_BYTESPERPIXEL(temp_format);
    src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
    dst = (Uint8*)temp_pixels;
    tmp = SDL_stack_alloc(Uint8, length);
    rows = rect->h / 2;
    while (rows--) {
        SDL_memcpy(tmp, dst, length);
        SDL_memcpy(dst, src, length);
        SDL_memcpy(src, tmp, length);
        dst += temp_pitch;
        src -= temp_pitch;
    }
    SDL_stack_free(tmp);

    status = SDL_ConvertPixels(rect->w, rect->h,
                               temp_format, temp_pixels, temp_pitch,
                               pixel_format, pixels, pitch);
    SDL_free(temp_pixels);

    return status;
}
Ejemplo n.º 10
0
void
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
    HICON hicon = NULL;
    BYTE *icon_bmp;
    int icon_len;
    SDL_RWops *dst;
    SDL_Surface *surface;

    /* Create temporary bitmap buffer */
    icon_len = 40 + icon->h * icon->w * 4;
    icon_bmp = SDL_stack_alloc(BYTE, icon_len);
    dst = SDL_RWFromMem(icon_bmp, icon_len);
    if (!dst) {
        SDL_stack_free(icon_bmp);
        return;
    }

    /* Write the BITMAPINFO header */
    SDL_WriteLE32(dst, 40);
    SDL_WriteLE32(dst, icon->w);
    SDL_WriteLE32(dst, icon->h * 2);
    SDL_WriteLE16(dst, 1);
    SDL_WriteLE16(dst, 32);
    SDL_WriteLE32(dst, BI_RGB);
    SDL_WriteLE32(dst, icon->h * icon->w * 4);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);

    /* Convert the icon to a 32-bit surface with alpha channel */
    surface = SDL_ConvertSurfaceFormat(icon, SDL_PIXELFORMAT_ARGB8888, 0);
    if (surface) {
        /* Write the pixels upside down into the bitmap buffer */
        int y = surface->h;
        while (y--) {
            Uint8 *src = (Uint8 *) surface->pixels + y * surface->pitch;
            SDL_RWwrite(dst, src, surface->pitch, 1);
        }
        SDL_FreeSurface(surface);

/* TODO: create the icon in WinCE (CreateIconFromResource isn't available) */
#ifndef _WIN32_WCE
        hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
#endif
    }
    SDL_RWclose(dst);
    SDL_stack_free(icon_bmp);

    /* Set the icon for the window */
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);

    /* Set the icon in the task manager (should we do this?) */
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
}
Ejemplo n.º 11
0
static int
D3D_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                    int count)
{
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    DWORD color;
    Vertex *vertices;
    int i;
    HRESULT result;

    if (data->beginScene) {
        IDirect3DDevice9_BeginScene(data->device);
        data->beginScene = SDL_FALSE;
    }

    D3D_SetBlendMode(data, renderer->blendMode);

    result =
        IDirect3DDevice9_SetTexture(data->device, 0,
                                    (IDirect3DBaseTexture9 *) 0);
    if (FAILED(result)) {
        D3D_SetError("SetTexture()", result);
        return -1;
    }

    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);

    vertices = SDL_stack_alloc(Vertex, count);
    for (i = 0; i < count; ++i) {
        vertices[i].x = (float) points[i].x;
        vertices[i].y = (float) points[i].y;
        vertices[i].z = 0.0f;
        vertices[i].rhw = 1.0f;
        vertices[i].color = color;
        vertices[i].u = 0.0f;
        vertices[i].v = 0.0f;
    }
    result =
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1,
                                         vertices, sizeof(*vertices));

    /* DirectX 9 has the same line rasterization semantics as GDI,
       so we need to close the endpoint of the line */
    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
        vertices[0].x = (float) points[count-1].x;
        vertices[0].y = (float) points[count-1].y;
        result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices, sizeof(*vertices));
    }

    SDL_stack_free(vertices);
    if (FAILED(result)) {
        D3D_SetError("DrawPrimitiveUP()", result);
        return -1;
    }
    return 0;
}
Ejemplo n.º 12
0
static int
GDI_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                    int count)
{
    GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
    HPEN pen;
    BOOL status;

    if (data->makedirty) {
        /* Get the smallest rectangle that contains everything */
        SDL_Window *window = renderer->window;
        SDL_Rect clip, rect;

        clip.x = 0;
        clip.y = 0;
        clip.w = window->w;
        clip.h = window->h;
        SDL_EnclosePoints(points, count, NULL, &rect);
        if (!SDL_IntersectRect(&rect, &clip, &rect)) {
            /* Nothing to draw */
            return 0;
        }

        SDL_AddDirtyRect(&data->dirty, &rect);
    }

    /* Should we cache the pen? .. it looks like GDI does for us. :) */
    pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b));
    SelectObject(data->current_hdc, pen);
    {
        LPPOINT p = SDL_stack_alloc(POINT, count);
        int i;

        for (i = 0; i < count; ++i) {
            p[i].x = points[i].x;
            p[i].y = points[i].y;
        }
        status = Polyline(data->current_hdc, p, count);
        SDL_stack_free(p);
    }
    DeleteObject(pen);

    /* Need to close the endpoint of the line */
    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
        SetPixel(data->current_hdc, points[count-1].x, points[count-1].y,
                 RGB(renderer->r, renderer->g, renderer->b));
    }

    if (!status) {
        WIN_SetError("Polyline()");
        return -1;
    }
    return 0;
}
Ejemplo n.º 13
0
void
WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
    HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
    HICON hicon = NULL;
    BYTE *icon_bmp;
    int icon_len, mask_len, y;
    SDL_RWops *dst;

    /* Create temporary buffer for ICONIMAGE structure */
    mask_len = (icon->h * (icon->w + 7)/8);
    icon_len = 40 + icon->h * icon->w * sizeof(Uint32) + mask_len;
    icon_bmp = SDL_stack_alloc(BYTE, icon_len);
    dst = SDL_RWFromMem(icon_bmp, icon_len);
    if (!dst) {
        SDL_stack_free(icon_bmp);
        return;
    }

    /* Write the BITMAPINFO header */
    SDL_WriteLE32(dst, 40);
    SDL_WriteLE32(dst, icon->w);
    SDL_WriteLE32(dst, icon->h * 2);
    SDL_WriteLE16(dst, 1);
    SDL_WriteLE16(dst, 32);
    SDL_WriteLE32(dst, BI_RGB);
    SDL_WriteLE32(dst, icon->h * icon->w * sizeof(Uint32));
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);

    /* Write the pixels upside down into the bitmap buffer */
    SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888);
    y = icon->h;
    while (y--) {
        Uint8 *src = (Uint8 *) icon->pixels + y * icon->pitch;
        SDL_RWwrite(dst, src, icon->w * sizeof(Uint32), 1);
    }

    /* Write the mask */
    SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len);

    hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);

    SDL_RWclose(dst);
    SDL_stack_free(icon_bmp);

    /* Set the icon for the window */
    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) hicon);

    /* Set the icon in the task manager (should we do this?) */
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) hicon);
}
Ejemplo n.º 14
0
static int
GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                    Uint32 pixel_format, void * pixels, int pitch)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
    void *temp_pixels;
    int temp_pitch;
    Uint8 *src, *dst, *tmp;
    int w, h, length, rows;
    int status;

    GLES_ActivateRenderer(renderer);

    temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
    temp_pixels = SDL_malloc(rect->h * temp_pitch);
    if (!temp_pixels) {
        return SDL_OutOfMemory();
    }

    SDL_GetRendererOutputSize(renderer, &w, &h);

    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);

    data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
                       rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);

    /* Flip the rows to be top-down if necessary */
    if (!renderer->target) {
        length = rect->w * SDL_BYTESPERPIXEL(temp_format);
        src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
        dst = (Uint8*)temp_pixels;
        tmp = SDL_stack_alloc(Uint8, length);
        rows = rect->h / 2;
        while (rows--) {
            SDL_memcpy(tmp, dst, length);
            SDL_memcpy(dst, src, length);
            SDL_memcpy(src, tmp, length);
            dst += temp_pitch;
            src -= temp_pitch;
        }
        SDL_stack_free(tmp);
    }

    status = SDL_ConvertPixels(rect->w, rect->h,
                               temp_format, temp_pixels, temp_pitch,
                               pixel_format, pixels, pitch);
    SDL_free(temp_pixels);

    return status;
}
Ejemplo n.º 15
0
static int
X11_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                     int count)
{
    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    unsigned long foreground;
    XPoint *xpoints, *xpoint;
    int i, xcount;

    if (data->makedirty) {
        SDL_Rect rect;

        /* Get the smallest rectangle that contains everything */
        rect.x = 0;
        rect.y = 0;
        rect.w = window->w;
        rect.h = window->h;
        if (!SDL_EnclosePoints(points, count, &rect, &rect)) {
            /* Nothing to draw */
            return 0;
        }
        SDL_AddDirtyRect(&data->dirty, &rect);
    }

    foreground = renderdrawcolor(renderer, 1);
    XSetForeground(data->display, data->gc, foreground);

    xpoint = xpoints = SDL_stack_alloc(XPoint, count);
    xcount = 0;
    for (i = 0; i < count; ++i) {
        int x = points[i].x;
        int y = points[i].y;
        if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
            continue;
        }
        xpoint->x = (short)x;
        xpoint->y = (short)y;
        ++xpoint;
        ++xcount;
    }
    if (xcount > 0) {
        XDrawPoints(data->display, data->drawable, data->gc, xpoints, xcount,
                    CoordModeOrigin);
    }
    SDL_stack_free(xpoints);

    return 0;
}
Ejemplo n.º 16
0
static int
SW_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
{
    SDL_Surface *surface = SW_ActivateRenderer(renderer);
    SDL_Rect *final_rects;
    int i, status;

    if (!surface) {
        return -1;
    }

    final_rects = SDL_stack_alloc(SDL_Rect, count);
    if (!final_rects) {
        return SDL_OutOfMemory();
    }
    if (renderer->viewport.x || renderer->viewport.y) {
        int x = renderer->viewport.x;
        int y = renderer->viewport.y;

        for (i = 0; i < count; ++i) {
            final_rects[i].x = (int)(x + rects[i].x);
            final_rects[i].y = (int)(y + rects[i].y);
            final_rects[i].w = SDL_max((int)rects[i].w, 1);
            final_rects[i].h = SDL_max((int)rects[i].h, 1);
        }
    } else {
        for (i = 0; i < count; ++i) {
            final_rects[i].x = (int)rects[i].x;
            final_rects[i].y = (int)rects[i].y;
            final_rects[i].w = SDL_max((int)rects[i].w, 1);
            final_rects[i].h = SDL_max((int)rects[i].h, 1);
        }
    }

    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
        Uint32 color = SDL_MapRGBA(surface->format,
                                   renderer->r, renderer->g, renderer->b,
                                   renderer->a);
        status = SDL_FillRects(surface, final_rects, count, color);
    } else {
        status = SDL_BlendFillRects(surface, final_rects, count,
                                    renderer->blendMode,
                                    renderer->r, renderer->g, renderer->b,
                                    renderer->a);
    }
    SDL_stack_free(final_rects);

    return status;
}
Ejemplo n.º 17
0
static int
SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
                   int count)
{
    SDL_Surface *surface = SW_ActivateRenderer(renderer);
    SDL_Point *final_points;
    int i, status;

    if (!surface) {
        return -1;
    }

    final_points = SDL_stack_alloc(SDL_Point, count);
    if (!final_points) {
        return SDL_OutOfMemory();
    }
    if (renderer->viewport.x || renderer->viewport.y) {
        int x = renderer->viewport.x;
        int y = renderer->viewport.y;

        for (i = 0; i < count; ++i) {
            final_points[i].x = (int)(x + points[i].x);
            final_points[i].y = (int)(y + points[i].y);
        }
    } else {
        for (i = 0; i < count; ++i) {
            final_points[i].x = (int)points[i].x;
            final_points[i].y = (int)points[i].y;
        }
    }

    /* Draw the lines! */
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
        Uint32 color = SDL_MapRGBA(surface->format,
                                   renderer->r, renderer->g, renderer->b,
                                   renderer->a);

        status = SDL_DrawLines(surface, final_points, count, color);
    } else {
        status = SDL_BlendLines(surface, final_points, count,
                                renderer->blendMode,
                                renderer->r, renderer->g, renderer->b,
                                renderer->a);
    }
    SDL_stack_free(final_points);

    return status;
}
Ejemplo n.º 18
0
static int
D3D_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                     int count)
{
    D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
    DWORD color;
    Vertex *vertices;
    int i;
    HRESULT result;

    if (data->beginScene) {
        IDirect3DDevice9_BeginScene(data->device);
        data->beginScene = SDL_FALSE;
    }

    D3D_SetBlendMode(data, renderer->blendMode);

    result =
        IDirect3DDevice9_SetTexture(data->device, 0,
                                    (IDirect3DBaseTexture9 *) 0);
    if (FAILED(result)) {
        D3D_SetError("SetTexture()", result);
        return -1;
    }

    color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);

    vertices = SDL_stack_alloc(Vertex, count);
    for (i = 0; i < count; ++i) {
        vertices[i].x = (float) points[i].x;
        vertices[i].y = (float) points[i].y;
        vertices[i].z = 0.0f;
        vertices[i].rhw = 1.0f;
        vertices[i].color = color;
        vertices[i].u = 0.0f;
        vertices[i].v = 0.0f;
    }
    result =
        IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count,
                                         vertices, sizeof(*vertices));
    SDL_stack_free(vertices);
    if (FAILED(result)) {
        D3D_SetError("DrawPrimitiveUP()", result);
        return -1;
    }
    return 0;
}
Ejemplo n.º 19
0
static int
GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                    Uint32 pixel_format, void * pixels, int pitch)
{
    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    GLint internalFormat;
    GLenum format, type;
    Uint8 *src, *dst, *tmp;
    int w, h, length, rows;

    GL_ActivateRenderer(renderer);

    if (!convert_format(data, pixel_format, &internalFormat, &format, &type)) {
        /* FIXME: Do a temp copy to a format that is supported */
        SDL_SetError("Unsupported pixel format");
        return -1;
    }

    SDL_GetWindowSize(window, &w, &h);

    data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
    data->glPixelStorei(GL_PACK_ROW_LENGTH,
                        (pitch / SDL_BYTESPERPIXEL(pixel_format)));

    data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
                       format, type, pixels);

    /* Flip the rows to be top-down */
    length = rect->w * SDL_BYTESPERPIXEL(pixel_format);
    src = (Uint8*)pixels + (rect->h-1)*pitch;
    dst = (Uint8*)pixels;
    tmp = SDL_stack_alloc(Uint8, length);
    rows = rect->h / 2;
    while (rows--) {
        SDL_memcpy(tmp, dst, length);
        SDL_memcpy(dst, src, length);
        SDL_memcpy(src, tmp, length);
        dst += pitch;
        src -= pitch;
    }
    SDL_stack_free(tmp);

    return 0;
}
Ejemplo n.º 20
0
static int
X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
{
    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    SDL_Rect clip, rect;
    unsigned long foreground;
    XRectangle *xrects, *xrect;
    int i, xcount;

    clip.x = 0;
    clip.y = 0;
    clip.w = window->w;
    clip.h = window->h;

    foreground = renderdrawcolor(renderer, 1);
    XSetForeground(data->display, data->gc, foreground);

    xrect = xrects = SDL_stack_alloc(XRectangle, count);
    xcount = 0;
    for (i = 0; i < count; ++i) {
        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
            continue;
        }

        xrect->x = (short)rect.x;
        xrect->y = (short)rect.y;
        xrect->width = (unsigned short)rect.w;
        xrect->height = (unsigned short)rect.h;
        ++xrect;
        ++xcount;

        if (data->makedirty) {
            SDL_AddDirtyRect(&data->dirty, &rect);
        }
    }
    if (xcount > 0) {
        XFillRectangles(data->display, data->drawable, data->gc,
                        xrects, xcount);
    }
    SDL_stack_free(xpoints);

    return 0;
}
Ejemplo n.º 21
0
static int
SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                   int count)
{
    SDL_Surface *surface = SW_ActivateRenderer(renderer);
    SDL_Point *temp = NULL;
    int status;

    if (!surface) {
        return -1;
    }

    if (renderer->viewport.x || renderer->viewport.y) {
        int i;
        int x = renderer->viewport.x;
        int y = renderer->viewport.y;

        temp = SDL_stack_alloc(SDL_Point, count);
        for (i = 0; i < count; ++i) {
            temp[i].x = x + points[i].x;
            temp[i].y = y + points[i].y;
        }
        points = temp;
    }

    /* Draw the lines! */
    if (renderer->blendMode == SDL_BLENDMODE_NONE) {
        Uint32 color = SDL_MapRGBA(surface->format,
                                   renderer->r, renderer->g, renderer->b,
                                   renderer->a);

        status = SDL_DrawLines(surface, points, count, color);
    } else {
        status = SDL_BlendLines(surface, points, count,
                                renderer->blendMode,
                                renderer->r, renderer->g, renderer->b,
                                renderer->a);
    }

    if (temp) {
        SDL_stack_free(temp);
    }
    return status;
}
Ejemplo n.º 22
0
static int
GLES_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points,
                      int count)
{
    GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
    int i;
    GLshort *vertices;

    GLES_SetDrawingState(renderer);

    vertices = SDL_stack_alloc(GLshort, count*2);
    for (i = 0; i < count; ++i) {
        vertices[2*i+0] = (GLshort)points[i].x;
        vertices[2*i+1] = (GLshort)points[i].y;
    }
    data->glVertexPointer(2, GL_SHORT, 0, vertices);
    data->glDrawArrays(GL_POINTS, 0, count);
    SDL_stack_free(vertices);

    return 0;
}
Ejemplo n.º 23
0
/*
 * If there is an existing add event in the queue, it needs to be modified
 * to have the right value for which, because the number of controllers in
 * the system is now one less.
 */
static void UpdateEventsForDeviceRemoval()
{
    int i, num_events;
    SDL_Event *events;

    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
    if (num_events <= 0) {
        return;
    }

    events = SDL_stack_alloc(SDL_Event, num_events);
    if (!events) {
        return;
    }

    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
    for (i = 0; i < num_events; ++i) {
        --events[i].jdevice.which;
    }
    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);

    SDL_stack_free(events);
}
Ejemplo n.º 24
0
void
SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
{
    int i;

    if (screen == SDL_ShadowSurface) {
        for (i = 0; i < numrects; ++i) {
            SDL_LowerBlit(SDL_ShadowSurface, &rects[i], SDL_VideoSurface,
                          &rects[i]);
        }

        /* Fall through to video surface update */
        screen = SDL_VideoSurface;
    }
    if (screen == SDL_VideoSurface) {
        if (SDL_VideoViewport.x || SDL_VideoViewport.y) {
            SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects);
            SDL_Rect *stackrect;
            const SDL_Rect *rect;
            
            /* Offset all the rectangles before updating */
            for (i = 0; i < numrects; ++i) {
                rect = &rects[i];
                stackrect = &stackrects[i];
                stackrect->x = SDL_VideoViewport.x + rect->x;
                stackrect->y = SDL_VideoViewport.y + rect->y;
                stackrect->w = rect->w;
                stackrect->h = rect->h;
            }
            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, stackrects, numrects);
            SDL_stack_free(stackrects);
        } else {
            SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, rects, numrects);
        }
    }
}
static int ANDROID_LockHWSurface(_THIS, SDL_Surface *surface)
{
	if( !SDL_ANDROID_InsideVideoThread() )
	{
		__android_log_print(ANDROID_LOG_INFO, "libSDL", "Error: calling %s not from the main thread!", __PRETTY_FUNCTION__);
		return -1;
	}

	if( surface == SDL_CurrentVideoSurface )
	{
		// Copy pixels from pixelbuffer to video surface - this is slow!
		Uint16 * row = NULL;
		int fakeH = SDL_ANDROID_sFakeWindowHeight, fakeW = SDL_ANDROID_sFakeWindowWidth;
		int realH = SDL_ANDROID_sWindowHeight, realW = SDL_ANDROID_sWindowWidth;
		int x, y;
		if( ! SDL_CurrentVideoSurface->pixels )
		{
			glPixelStorei(GL_PACK_ALIGNMENT, 1);
			SDL_CurrentVideoSurface->pixels = SDL_malloc(SDL_ANDROID_sFakeWindowWidth * SDL_ANDROID_sFakeWindowHeight * SDL_ANDROID_BYTESPERPIXEL);
			if ( ! SDL_CurrentVideoSurface->pixels ) {
				__android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate buffer for SDL_CurrentVideoSurface");
				SDL_SetError("Couldn't allocate buffer for SDL_CurrentVideoSurface");
				return(-1);
			}
		}
		if( ! SDL_CurrentVideoSurface->hwdata )
		{
			SDL_CurrentVideoSurface->hwdata = (struct private_hwdata *)SDL_CreateTexture(PixelFormatEnum, SDL_TEXTUREACCESS_STATIC, SDL_ANDROID_sFakeWindowWidth, SDL_ANDROID_sFakeWindowHeight);
			if( !SDL_CurrentVideoSurface->hwdata ) {
				__android_log_print(ANDROID_LOG_INFO, "libSDL", "Couldn't allocate texture for SDL_CurrentVideoSurface");
				SDL_OutOfMemory();
				return(-1);
			}
			if( SDL_ANDROID_SmoothVideo )
				SDL_SetTextureScaleMode((SDL_Texture *)SDL_CurrentVideoSurface->hwdata, SDL_SCALEMODE_SLOW);
			// Register main video texture to be recreated when needed
			HwSurfaceCount++;
			HwSurfaceList = SDL_realloc( HwSurfaceList, HwSurfaceCount * sizeof(SDL_Surface *) );
			HwSurfaceList[HwSurfaceCount-1] = SDL_CurrentVideoSurface;
			DEBUGOUT("ANDROID_SetVideoMode() HwSurfaceCount %d HwSurfaceList %p", HwSurfaceCount, HwSurfaceList);
		}

		row = SDL_stack_alloc(Uint16, SDL_ANDROID_sWindowWidth);

		for(y=0; y<fakeH; y++)
		{
			// TODO: support 24bpp and 32bpp
			glReadPixels(0, realH - 1 - (realH * y / fakeH),
							realW, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, row);
			for(x=0; x<fakeW; x++)
				((Uint16 *)SDL_CurrentVideoSurface->pixels)[ fakeW * y + x ] = row[ x * fakeW / realW ];
		}
		
		SDL_stack_free(row);
	}

	if( !surface->hwdata )
		return(-1);

	// Extra check not necessary
	/*
	if( SDL_CurrentVideoSurface->format->BitsPerPixel == surface->format->BitsPerPixel &&
		SDL_CurrentVideoSurface->format->Rmask == surface->format->Rmask &&
		SDL_CurrentVideoSurface->format->Gmask == surface->format->Gmask &&
		SDL_CurrentVideoSurface->format->Bmask == surface->format->Bmask &&
		SDL_CurrentVideoSurface->format->Amask == surface->format->Amask )
		return(0);

	if( this->displayformatalphapixel->BitsPerPixel == surface->format->BitsPerPixel &&
		this->displayformatalphapixel->Rmask == surface->format->Rmask &&
		this->displayformatalphapixel->Gmask == surface->format->Gmask &&
		this->displayformatalphapixel->Bmask == surface->format->Bmask &&
		this->displayformatalphapixel->Amask == surface->format->Amask )
		return(0);
	return(-1);
	*/
	
	return(0);
}
Ejemplo n.º 26
0
static int
X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                    int count)
{
    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    SDL_Rect clip, rect;
    unsigned long foreground;
    XPoint *xpoints, *xpoint;
    int i, xcount;
    int minx, miny;
    int maxx, maxy;

    clip.x = 0;
    clip.y = 0;
    clip.w = window->w;
    clip.h = window->h;

    foreground = renderdrawcolor(renderer, 1);
    XSetForeground(data->display, data->gc, foreground);

    xpoint = xpoints = SDL_stack_alloc(XPoint, count);
    xcount = 0;
    minx = INT_MAX;
    miny = INT_MAX;
    maxx = INT_MIN;
    maxy = INT_MIN;
    for (i = 0; i < count; ++i) {
        int x = points[i].x;
        int y = points[i].y;

        /* If the point is inside the window, add it to the list */
        if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
            if (x < minx) {
                minx = x;
            } else if (x > maxx) {
                maxx = x;
            }
            if (y < miny) {
                miny = y;
            } else if (y > maxy) {
                maxy = y;
            }
            xpoint->x = (short)x;
            xpoint->y = (short)y;
            ++xpoint;
            ++xcount;
            continue;
        }

        /* We need to clip the line segments joined by this point */
        if (xcount > 0) {
            int x1 = xpoint[-1].x;
            int y1 = xpoint[-1].y;
            int x2 = x;
            int y2 = y;
            if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
                if (x2 < minx) {
                    minx = x2;
                } else if (x2 > maxx) {
                    maxx = x2;
                }
                if (y2 < miny) {
                    miny = y2;
                } else if (y2 > maxy) {
                    maxy = y2;
                }
                xpoint->x = (short)x2;
                xpoint->y = (short)y2;
                ++xpoint;
                ++xcount;
            }
            XDrawLines(data->display, data->drawable, data->gc,
                       xpoints, xcount, CoordModeOrigin);
            if (xpoints[0].x != x2 || xpoints[0].y != y2) {
                XDrawPoint(data->display, data->drawable, data->gc, x2, y2);
            }
            if (data->makedirty) {
                SDL_Rect rect;

                rect.x = minx;
                rect.y = miny;
                rect.w = (maxx - minx) + 1;
                rect.h = (maxy - miny) + 1;
                SDL_AddDirtyRect(&data->dirty, &rect);
            }
            xpoint = xpoints;
            xcount = 0;
            minx = INT_MAX;
            miny = INT_MAX;
            maxx = INT_MIN;
            maxy = INT_MIN;
        }
        if (i < (count-1)) {
            int x1 = x;
            int y1 = y;
            int x2 = points[i+1].x;
            int y2 = points[i+1].y;
            if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
                if (x1 < minx) {
                    minx = x1;
                } else if (x1 > maxx) {
                    maxx = x1;
                }
                if (y1 < miny) {
                    miny = y1;
                } else if (y1 > maxy) {
                    maxy = y1;
                }
                xpoint->x = (short)x1;
                xpoint->y = (short)y1;
                ++xpoint;
                ++xcount;
            }
        }
    }
    if (xcount > 1) {
        int x2 = xpoint[-1].x;
        int y2 = xpoint[-1].y;
        XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount,
                   CoordModeOrigin);
        if (xpoints[0].x != x2 || xpoints[0].y != y2) {
            XDrawPoint(data->display, data->drawable, data->gc, x2, y2);
        }
        if (data->makedirty) {
            SDL_Rect rect;

            rect.x = minx;
            rect.y = miny;
            rect.w = (maxx - minx) + 1;
            rect.h = (maxy - miny) + 1;
            SDL_AddDirtyRect(&data->dirty, &rect);
        }
    }
    SDL_stack_free(xpoints);

    return 0;
}
Ejemplo n.º 27
0
static SDL_Cursor *
WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    /* msdn says cursor mask has to be padded out to word alignment. Not sure
        if that means machine word or WORD, but this handles either case. */
    const size_t pad = (sizeof (size_t) * 8);  /* 32 or 64, or whatever. */
    SDL_Cursor *cursor;
    HICON hicon;
    HDC hdc;
    BITMAPV4HEADER bmh;
    LPVOID pixels;
    LPVOID maskbits;
    size_t maskbitslen;
    ICONINFO ii;

    SDL_zero(bmh);
    bmh.bV4Size = sizeof(bmh);
    bmh.bV4Width = surface->w;
    bmh.bV4Height = -surface->h; /* Invert the image */
    bmh.bV4Planes = 1;
    bmh.bV4BitCount = 32;
    bmh.bV4V4Compression = BI_BITFIELDS;
    bmh.bV4AlphaMask = 0xFF000000;
    bmh.bV4RedMask   = 0x00FF0000;
    bmh.bV4GreenMask = 0x0000FF00;
    bmh.bV4BlueMask  = 0x000000FF;

    maskbitslen = ((surface->w + (pad - (surface->w % pad))) / 8) * surface->h;
    maskbits = SDL_stack_alloc(Uint8,maskbitslen);
    if (maskbits == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }

    /* AND the cursor against full bits: no change. We already have alpha. */
    SDL_memset(maskbits, 0xFF, maskbitslen);

    hdc = GetDC(NULL);
    SDL_zero(ii);
    ii.fIcon = FALSE;
    ii.xHotspot = (DWORD)hot_x;
    ii.yHotspot = (DWORD)hot_y;
    ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0);
    ii.hbmMask = CreateBitmap(surface->w, surface->h, 1, 1, maskbits);
    ReleaseDC(NULL, hdc);
    SDL_stack_free(maskbits);

    SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
    SDL_assert(surface->pitch == surface->w * 4);
    SDL_memcpy(pixels, surface->pixels, surface->h * surface->pitch);

    hicon = CreateIconIndirect(&ii);

    DeleteObject(ii.hbmColor);
    DeleteObject(ii.hbmMask);

    if (!hicon) {
        WIN_SetError("CreateIconIndirect()");
        return NULL;
    }

    cursor = SDL_calloc(1, sizeof(*cursor));
    if (cursor) {
        cursor->driverdata = hicon;
    } else {
        DestroyIcon(hicon);
        SDL_OutOfMemory();
    }

    return cursor;
}
Ejemplo n.º 28
0
bool GraphicsHelps::setWindowIcon(SDL_Window *window, FIBITMAP *img, int iconSize)
{
#ifdef _WIN32
    struct SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);

    if(-1 == SDL_GetWindowWMInfo(window, &wmInfo))
        return false;

    if(wmInfo.subsystem != SDL_SYSWM_WINDOWS)
        return false;

    HWND windowH = wmInfo.info.win.window;
    HICON hicon = NULL;
    BYTE *icon_bmp;
    unsigned int icon_len, y;
    SDL_RWops *dst;
    unsigned int w = FreeImage_GetWidth(img);
    unsigned int h = FreeImage_GetWidth(img);
    Uint8 *bits = (Uint8 *)FreeImage_GetBits(img);
    unsigned int pitch = FreeImage_GetPitch(img);
    /* Create temporary bitmap buffer */
    icon_len = 40 + h * w * 4;
    icon_bmp = SDL_stack_alloc(BYTE, icon_len);
    dst = SDL_RWFromMem(icon_bmp, icon_len);

    if(!dst)
    {
        SDL_stack_free(icon_bmp);
        return false;
    }

    /* Write the BITMAPINFO header */
    SDL_WriteLE32(dst, 40);
    SDL_WriteLE32(dst, w);
    SDL_WriteLE32(dst, h * 2);
    SDL_WriteLE16(dst, 1);
    SDL_WriteLE16(dst, 32);
    SDL_WriteLE32(dst, BI_RGB);
    SDL_WriteLE32(dst, h * w * 4);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    SDL_WriteLE32(dst, 0);
    y = 0;

    do
    {
        Uint8 *src = bits + y * pitch;
        SDL_RWwrite(dst, src, pitch, 1);
    }
    while(++y < h);

    hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000);
    SDL_RWclose(dst);
    SDL_stack_free(icon_bmp);
    /* Set the icon for the window */
    SendMessage(windowH, WM_SETICON, (iconSize < 32) ? ICON_SMALL : ICON_BIG, (LPARAM) hicon);
#else
    (void)iconSize;
    SDL_Surface *sicon = GraphicsHelps::fi2sdl(img);
    SDL_SetWindowIcon(window, sicon);
    SDL_FreeSurface(sicon);
    const char *error = SDL_GetError();

    if(*error != '\0')
        return false;

#endif
    return true;
}
int
main(int argc, char *argv[])
{
    DrawState *drawstates;
    int i, done;
    SDL_Event event;
    int frames;
    Uint32 then, now;

	/* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Initialize test framework */
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
    if (!state) {
        return 1;
    }
    for (i = 1; i < argc;) {
        int consumed;

        consumed = SDLTest_CommonArg(state, i);
        if (consumed == 0) {
            SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
            return 1;
        }
        i += consumed;
    }
    if (!SDLTest_CommonInit(state)) {
        quit(2);
    }

    drawstates = SDL_stack_alloc(DrawState, state->num_windows);
    for (i = 0; i < state->num_windows; ++i) {
        DrawState *drawstate = &drawstates[i];

        drawstate->window = state->windows[i];
        drawstate->renderer = state->renderers[i];
        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
        if (!drawstate->sprite || !drawstate->background) {
            quit(2);
        }
        SDL_QueryTexture(drawstate->sprite, NULL, NULL,
                         &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
        drawstate->scale_direction = 1;
    }

    /* Main render loop */
    frames = 0;
    then = SDL_GetTicks();
    done = 0;
    while (!done) {
        /* Check for events */
        ++frames;
        while (SDL_PollEvent(&event)) {
            SDLTest_CommonEvent(state, &event, &done);
        }
        for (i = 0; i < state->num_windows; ++i) {
            if (state->windows[i] == NULL)
                continue;
            Draw(&drawstates[i]);
        }
    }

    /* Print out some timing information */
    now = SDL_GetTicks();
    if (now > then) {
        double fps = ((double) frames * 1000) / (now - then);
        SDL_Log("%2.2f frames per second\n", fps);
    }

    SDL_stack_free(drawstates);

    quit(0);
    return 0;
}
int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    size_t size;
    LPBITMAPINFO info;
    HBITMAP hbm;

    /* Free the old framebuffer surface */
    if (data->mdc) {
        DeleteDC(data->mdc);
    }
    if (data->hbm) {
        DeleteObject(data->hbm);
    }

    /* Find out the format of the screen */
    size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD);
    info = (LPBITMAPINFO)SDL_stack_alloc(Uint8, size);

    SDL_memset(info, 0, size);
    info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    /* The second call to GetDIBits() fills in the bitfields */
    hbm = CreateCompatibleBitmap(data->hdc, 1, 1);
    GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
    GetDIBits(data->hdc, hbm, 0, 0, NULL, info, DIB_RGB_COLORS);
    DeleteObject(hbm);

    *format = SDL_PIXELFORMAT_UNKNOWN;
    if (info->bmiHeader.biCompression == BI_BITFIELDS) {
        int bpp;
        Uint32 *masks;

        bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount;
        masks = (Uint32*)((Uint8*)info + info->bmiHeader.biSize);
        *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0);
    }
    if (*format == SDL_PIXELFORMAT_UNKNOWN)
    {
        /* We'll use RGB format for now */
        *format = SDL_PIXELFORMAT_RGB888;

        /* Create a new one */
        SDL_memset(info, 0, size);
        info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        info->bmiHeader.biPlanes = 1;
        info->bmiHeader.biBitCount = 32;
        info->bmiHeader.biCompression = BI_RGB;
    }

    /* Fill in the size information */
    *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
    info->bmiHeader.biWidth = window->w;
    info->bmiHeader.biHeight = -window->h;  /* negative for topdown bitmap */
    info->bmiHeader.biSizeImage = window->h * (*pitch);

    data->mdc = CreateCompatibleDC(data->hdc);
    data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0);
    SDL_stack_free(info);

    if (!data->hbm) {
        return WIN_SetError("Unable to create DIB");
    }
    SelectObject(data->mdc, data->hbm);

    return 0;
}