src/video/gapi/SDL_gapivideo.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 02 Aug 2009 18:39:57 +0000
changeset 3227 458e53d8662c
parent 2985 4e4d814884aa
permissions -rw-r--r--
Clarified API documentation
icculus@1251
     1
/*
icculus@1251
     2
    SDL - Simple DirectMedia Layer
slouken@2859
     3
    Copyright (C) 1997-2009 Sam Lantinga
icculus@1251
     4
icculus@1251
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
icculus@1251
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
icculus@1251
     9
icculus@1251
    10
    This library is distributed in the hope that it will be useful,
icculus@1251
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
icculus@1251
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
icculus@1251
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
icculus@1251
    18
icculus@1251
    19
    Sam Lantinga
icculus@1251
    20
    slouken@libsdl.org
icculus@1251
    21
*/
slouken@1402
    22
#include "SDL_config.h"
icculus@1251
    23
icculus@1251
    24
/* Pocket PC GAPI SDL video driver implementation;
icculus@1251
    25
Implemented by Dmitry Yakimov - support@activekitten.com
icculus@1251
    26
Inspired by http://arisme.free.fr/ports/SDL.php
icculus@1251
    27
*/
icculus@1251
    28
icculus@1251
    29
// TODO: copy surface on window when lost focus
icculus@1251
    30
// TODO: test buttons rotation
icculus@1251
    31
// TODO: test on be300 and HPC ( check WinDib fullscreen keys catching )
icculus@1251
    32
// TODO: test on smartphones
icculus@1251
    33
// TODO: windib on SH3 PPC2000 landscape test
icculus@1251
    34
// TODO: optimize 8bpp landscape mode
icculus@1251
    35
slouken@1465
    36
// there is some problems in runnings apps from a device landscape mode
slouken@1465
    37
// due to WinCE bugs. Some works and some - does not.
slouken@1465
    38
// TODO: finish Axim Dell X30 and user landscape mode, device landscape mode
slouken@1465
    39
// TODO: finish Axim Dell X30 user portrait, device landscape stylus conversion
slouken@1465
    40
// TODO: fix running GAPI apps from landscape mode - 
slouken@1465
    41
//       wince goes to portrait mode, but does not update video memory
slouken@1465
    42
slouken@1465
    43
slouken@1465
    44
#include "SDL_error.h"
icculus@1251
    45
#include "SDL_video.h"
icculus@1251
    46
#include "SDL_mouse.h"
slouken@1361
    47
#include "../SDL_sysvideo.h"
slouken@1361
    48
#include "../SDL_pixels_c.h"
slouken@1361
    49
#include "../../events/SDL_events_c.h"
slouken@1465
    50
#include "../wincommon/SDL_syswm_c.h"
slouken@1465
    51
#include "../wincommon/SDL_sysmouse_c.h"
slouken@1895
    52
#include "../windib/SDL_dibevents_c.h"
icculus@1251
    53
icculus@1251
    54
#include "SDL_gapivideo.h"
icculus@1251
    55
icculus@1251
    56
#define GAPIVID_DRIVER_NAME "gapi"
icculus@1251
    57
icculus@1251
    58
#if defined(DEBUG) || defined (_DEBUG) || defined(NDEBUG)
icculus@1251
    59
#define REPORT_VIDEO_INFO 1
icculus@1251
    60
#else
icculus@1251
    61
#define REPORT_VIDEO_INFO 0
icculus@1251
    62
#endif
icculus@1251
    63
icculus@1251
    64
// for testing with GapiEmu
icculus@1251
    65
#define USE_GAPI_EMU 0
slouken@1465
    66
#define EMULATE_AXIM_X30 0
slouken@1465
    67
#define WITHOUT_GAPI 0
icculus@1251
    68
icculus@1251
    69
#if USE_GAPI_EMU && !REPORT_VIDEO_INFO
icculus@1251
    70
#pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.")
icculus@1251
    71
#endif
icculus@1251
    72
icculus@1251
    73
// defined and used in SDL_sysevents.c
icculus@1251
    74
extern HINSTANCE aygshell;
icculus@1251
    75
extern void SDL_UnregisterApp();
icculus@1251
    76
extern int DIB_AddMode(_THIS, int bpp, int w, int h);
icculus@1251
    77
icculus@1251
    78
/* Initialization/Query functions */
slouken@1895
    79
static int GAPI_VideoInit(_THIS, SDL_PixelFormat * vformat);
slouken@1895
    80
static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat * format,
slouken@1895
    81
                                 Uint32 flags);
slouken@1895
    82
static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1895
    83
                                      int width, int height, int bpp,
slouken@1895
    84
                                      Uint32 flags);
slouken@1895
    85
static int GAPI_SetColors(_THIS, int firstcolor, int ncolors,
slouken@1895
    86
                          SDL_Color * colors);
icculus@1251
    87
static void GAPI_VideoQuit(_THIS);
icculus@1251
    88
icculus@1251
    89
/* Hardware surface functions */
slouken@1895
    90
static int GAPI_AllocHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    91
static int GAPI_LockHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    92
static void GAPI_UnlockHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    93
static void GAPI_FreeHWSurface(_THIS, SDL_Surface * surface);
icculus@1251
    94
icculus@1251
    95
/* Windows message handling functions, will not be processed */
icculus@1251
    96
static void GAPI_RealizePalette(_THIS);
icculus@1251
    97
static void GAPI_PaletteChanged(_THIS, HWND window);
slouken@1895
    98
static void GAPI_WinPAINT(_THIS, HDC hdc);
icculus@1251
    99
icculus@1251
   100
/* etc. */
slouken@1895
   101
static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect * rects);
icculus@1251
   102
icculus@1251
   103
static HMODULE g_hGapiLib = 0;
icculus@1251
   104
#define LINK(type,name,import) \
icculus@1251
   105
	if( g_hGapiLib ) \
slouken@1895
   106
		name = (PFN##type)GetProcAddress( g_hGapiLib, _T(import) );
icculus@1251
   107
icculus@1251
   108
static char g_bRawBufferAvailable = 0;
icculus@1251
   109
icculus@1251
   110
/* GAPI driver bootstrap functions */
icculus@1251
   111
icculus@1251
   112
/* hi res definitions */
icculus@1251
   113
typedef struct _RawFrameBufferInfo
icculus@1251
   114
{
slouken@1895
   115
    WORD wFormat;
slouken@1895
   116
    WORD wBPP;
slouken@1895
   117
    VOID *pFramePointer;
slouken@1895
   118
    int cxStride;
slouken@1895
   119
    int cyStride;
slouken@1895
   120
    int cxPixels;
slouken@1895
   121
    int cyPixels;
slouken@1895
   122
} RawFrameBufferInfo;
icculus@1251
   123
slouken@1895
   124
static struct _RawFrameBufferInfo g_RawFrameBufferInfo = { 0 };
icculus@1251
   125
icculus@1251
   126
#define GETRAWFRAMEBUFFER   0x00020001
icculus@1251
   127
icculus@1251
   128
#define FORMAT_565 1
icculus@1251
   129
#define FORMAT_555 2
slouken@1465
   130
#define FORMAT_OTHER 3
slouken@1465
   131
slouken@1465
   132
/* Dell Axim x30 hangs when we use GAPI from landscape,
slouken@1465
   133
   so lets avoid using GxOpenDisplay there via GETGXINFO trick 
slouken@1465
   134
   It seems that GAPI subsystem use the same ExtEscape code.
slouken@1465
   135
*/
slouken@1465
   136
#define GETGXINFO 0x00020000
slouken@1465
   137
slouken@1465
   138
typedef struct GXDeviceInfo
slouken@1465
   139
{
slouken@1895
   140
    long Version;               //00 (should filled with 100 before calling ExtEscape)
slouken@1895
   141
    void *pvFrameBuffer;        //04
slouken@1895
   142
    unsigned long cbStride;     //08
slouken@1895
   143
    unsigned long cxWidth;      //0c
slouken@1895
   144
    unsigned long cyHeight;     //10
slouken@1895
   145
    unsigned long cBPP;         //14
slouken@1895
   146
    unsigned long ffFormat;     //18
slouken@1895
   147
    char Unused[0x84 - 7 * 4];
slouken@1895
   148
} GXDeviceInfo;
icculus@1251
   149
slouken@1895
   150
static int
slouken@1895
   151
GAPI_Available(void)
icculus@1251
   152
{
slouken@1895
   153
    // try to use VGA display, even on emulator
slouken@1895
   154
    HDC hdc = GetDC(NULL);
slouken@1895
   155
    int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL,
slouken@1895
   156
                           sizeof(RawFrameBufferInfo),
slouken@1895
   157
                           (char *) &g_RawFrameBufferInfo);
slouken@1895
   158
    ReleaseDC(NULL, hdc);
slouken@1895
   159
    g_bRawBufferAvailable = result > 0;
icculus@1251
   160
slouken@1465
   161
#if WITHOUT_GAPI
slouken@1895
   162
    return g_bRawBufferAvailable;
slouken@1465
   163
#endif
slouken@1465
   164
icculus@1251
   165
#if USE_GAPI_EMU
slouken@1895
   166
    g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll"));
slouken@1895
   167
    if (!g_hGapiLib) {
slouken@1895
   168
        SDL_SetError("Gapi Emu not found!");
slouken@1895
   169
    }
slouken@1895
   170
    return g_hGapiLib != 0;
icculus@1251
   171
#endif
icculus@1251
   172
slouken@1895
   173
    // try to find gx.dll
slouken@1895
   174
    g_hGapiLib = LoadLibrary(_T("\\Windows\\gx.dll"));
slouken@1895
   175
    if (!g_hGapiLib) {
slouken@1895
   176
        g_hGapiLib = LoadLibrary(_T("gx.dll"));
slouken@1895
   177
        if (!g_hGapiLib)
slouken@1895
   178
            return g_bRawBufferAvailable;
slouken@1895
   179
    }
icculus@1251
   180
slouken@1895
   181
    return (1);
icculus@1251
   182
}
icculus@1251
   183
slouken@1895
   184
static int
slouken@1895
   185
cmpmodes(const void *va, const void *vb)
icculus@1251
   186
{
slouken@1895
   187
    SDL_Rect *a = *(SDL_Rect **) va;
slouken@1895
   188
    SDL_Rect *b = *(SDL_Rect **) vb;
slouken@1895
   189
    if (a->w == b->w)
icculus@1251
   190
        return b->h - a->h;
icculus@1251
   191
    else
icculus@1251
   192
        return b->w - a->w;
icculus@1251
   193
}
icculus@1251
   194
slouken@1895
   195
static int
slouken@1895
   196
GAPI_AddMode(_THIS, int bpp, int w, int h)
icculus@1251
   197
{
slouken@1895
   198
    SDL_Rect *mode;
slouken@1895
   199
    int i, index;
slouken@1895
   200
    int next_mode;
icculus@1251
   201
slouken@1895
   202
    /* Check to see if we already have this mode */
slouken@1895
   203
    if (bpp < 8) {              /* Not supported */
slouken@1895
   204
        return (0);
slouken@1895
   205
    }
slouken@1895
   206
    index = ((bpp + 7) / 8) - 1;
slouken@1895
   207
    for (i = 0; i < gapi->SDL_nummodes[index]; ++i) {
slouken@1895
   208
        mode = gapi->SDL_modelist[index][i];
slouken@1895
   209
        if ((mode->w == w) && (mode->h == h)) {
slouken@1895
   210
            return (0);
slouken@1895
   211
        }
slouken@1895
   212
    }
icculus@1251
   213
slouken@1895
   214
    /* Set up the new video mode rectangle */
slouken@1895
   215
    mode = (SDL_Rect *) SDL_malloc(sizeof *mode);
slouken@1895
   216
    if (mode == NULL) {
slouken@1895
   217
        SDL_OutOfMemory();
slouken@1895
   218
        return (-1);
slouken@1895
   219
    }
slouken@1895
   220
    mode->x = 0;
slouken@1895
   221
    mode->y = 0;
slouken@1895
   222
    mode->w = w;
slouken@1895
   223
    mode->h = h;
icculus@1251
   224
slouken@1895
   225
    /* Allocate the new list of modes, and fill in the new mode */
slouken@1895
   226
    next_mode = gapi->SDL_nummodes[index];
slouken@1895
   227
    gapi->SDL_modelist[index] = (SDL_Rect **)
slouken@1895
   228
        SDL_realloc(gapi->SDL_modelist[index],
slouken@1895
   229
                    (1 + next_mode + 1) * sizeof(SDL_Rect *));
slouken@1895
   230
    if (gapi->SDL_modelist[index] == NULL) {
slouken@1895
   231
        SDL_OutOfMemory();
slouken@1895
   232
        gapi->SDL_nummodes[index] = 0;
slouken@1895
   233
        SDL_free(mode);
slouken@1895
   234
        return (-1);
slouken@1895
   235
    }
slouken@1895
   236
    gapi->SDL_modelist[index][next_mode] = mode;
slouken@1895
   237
    gapi->SDL_modelist[index][next_mode + 1] = NULL;
slouken@1895
   238
    gapi->SDL_nummodes[index]++;
icculus@1251
   239
slouken@1895
   240
    return (0);
icculus@1251
   241
}
icculus@1251
   242
slouken@1895
   243
static void
slouken@1895
   244
GAPI_DeleteDevice(SDL_VideoDevice * device)
icculus@1251
   245
{
slouken@1895
   246
    if (g_hGapiLib) {
slouken@1895
   247
        FreeLibrary(g_hGapiLib);
slouken@1895
   248
        g_hGapiLib = 0;
slouken@1895
   249
    }
slouken@1895
   250
    SDL_free(device->hidden);
slouken@1895
   251
    SDL_free(device);
icculus@1251
   252
}
icculus@1251
   253
slouken@1895
   254
static SDL_VideoDevice *
slouken@1895
   255
GAPI_CreateDevice(int devindex)
icculus@1251
   256
{
slouken@1895
   257
    SDL_VideoDevice *device;
icculus@1251
   258
slouken@1895
   259
    if (!g_hGapiLib && !g_bRawBufferAvailable) {
slouken@1895
   260
        if (!GAPI_Available()) {
slouken@1895
   261
            SDL_SetError
slouken@1895
   262
                ("GAPI dll is not found and VGA mode is not available!");
slouken@1895
   263
            return 0;
slouken@1895
   264
        }
slouken@1895
   265
    }
icculus@1251
   266
slouken@1895
   267
    /* Initialize all variables that we clean on shutdown */
slouken@1895
   268
    device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
slouken@1895
   269
    if (device) {
slouken@1895
   270
        SDL_memset(device, 0, (sizeof *device));
slouken@1895
   271
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@1895
   272
            SDL_malloc((sizeof *device->hidden));
slouken@1895
   273
    }
slouken@1895
   274
    if ((device == NULL) || (device->hidden == NULL)) {
slouken@1895
   275
        SDL_OutOfMemory();
slouken@1895
   276
        if (device) {
slouken@1895
   277
            SDL_free(device);
slouken@1895
   278
        }
slouken@1895
   279
        return (0);
slouken@1895
   280
    }
slouken@1895
   281
    SDL_memset(device->hidden, 0, (sizeof *device->hidden));
icculus@1251
   282
slouken@1895
   283
    /* Set the function pointers */
slouken@1895
   284
    device->VideoInit = GAPI_VideoInit;
slouken@1895
   285
    device->ListModes = GAPI_ListModes;
slouken@1895
   286
    device->SetVideoMode = GAPI_SetVideoMode;
slouken@1895
   287
    device->UpdateMouse = WIN_UpdateMouse;
slouken@1895
   288
    device->CreateYUVOverlay = NULL;
slouken@1895
   289
    device->SetColors = GAPI_SetColors;
slouken@1895
   290
    device->UpdateRects = GAPI_UpdateRects;
slouken@1895
   291
    device->VideoQuit = GAPI_VideoQuit;
slouken@1895
   292
    device->AllocHWSurface = GAPI_AllocHWSurface;
slouken@1895
   293
    device->CheckHWBlit = NULL;
slouken@1895
   294
    device->FillHWRect = NULL;
slouken@1895
   295
    device->SetHWColorKey = NULL;
slouken@1895
   296
    device->SetHWAlpha = NULL;
slouken@1895
   297
    device->LockHWSurface = GAPI_LockHWSurface;
slouken@1895
   298
    device->UnlockHWSurface = GAPI_UnlockHWSurface;
slouken@1895
   299
    device->FlipHWSurface = NULL;
slouken@1895
   300
    device->FreeHWSurface = GAPI_FreeHWSurface;
slouken@1895
   301
    device->SetCaption = WIN_SetWMCaption;
slouken@1895
   302
    device->SetIcon = WIN_SetWMIcon;
slouken@1895
   303
    device->IconifyWindow = WIN_IconifyWindow;
slouken@1895
   304
    device->GrabInput = WIN_GrabInput;
slouken@1895
   305
    device->GetWMInfo = WIN_GetWMInfo;
slouken@1895
   306
    device->FreeWMCursor = WIN_FreeWMCursor;
slouken@1895
   307
    device->CreateWMCursor = WIN_CreateWMCursor;
slouken@1895
   308
    device->ShowWMCursor = WIN_ShowWMCursor;
slouken@1895
   309
    device->WarpWMCursor = WIN_WarpWMCursor;
icculus@1251
   310
    device->CheckMouseMode = WIN_CheckMouseMode;
slouken@1895
   311
    device->InitOSKeymap = DIB_InitOSKeymap;
slouken@1895
   312
    device->PumpEvents = DIB_PumpEvents;
icculus@1251
   313
slouken@1895
   314
    /* Set up the windows message handling functions */
slouken@1895
   315
    WIN_RealizePalette = GAPI_RealizePalette;
slouken@1895
   316
    WIN_PaletteChanged = GAPI_PaletteChanged;
slouken@1895
   317
    WIN_WinPAINT = GAPI_WinPAINT;
slouken@1895
   318
    HandleMessage = DIB_HandleMessage;
icculus@1251
   319
slouken@1895
   320
    device->free = GAPI_DeleteDevice;
icculus@1251
   321
slouken@1895
   322
    /* Load gapi library */
icculus@1251
   323
#define gx device->hidden->gxFunc
icculus@1251
   324
slouken@1895
   325
    LINK(GXOpenDisplay, gx.GXOpenDisplay,
slouken@1895
   326
         "?GXOpenDisplay@@YAHPAUHWND__@@K@Z") LINK(GXCloseDisplay,
slouken@1895
   327
                                                   gx.GXCloseDisplay,
slouken@1895
   328
                                                   "?GXCloseDisplay@@YAHXZ")
slouken@1895
   329
        LINK(GXBeginDraw, gx.GXBeginDraw,
slouken@1895
   330
             "?GXBeginDraw@@YAPAXXZ") LINK(GXEndDraw, gx.GXEndDraw,
slouken@1895
   331
                                           "?GXEndDraw@@YAHXZ")
slouken@1895
   332
        LINK(GXOpenInput, gx.GXOpenInput,
slouken@1895
   333
             "?GXOpenInput@@YAHXZ") LINK(GXCloseInput, gx.GXCloseInput,
slouken@1895
   334
                                         "?GXCloseInput@@YAHXZ")
slouken@1895
   335
        LINK(GXGetDisplayProperties, gx.GXGetDisplayProperties,
slouken@1895
   336
             "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ")
slouken@1895
   337
        LINK(GXGetDefaultKeys, gx.GXGetDefaultKeys,
slouken@1895
   338
             "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z") LINK(GXSuspend,
slouken@1895
   339
                                                            gx.GXSuspend,
slouken@1895
   340
                                                            "?GXSuspend@@YAHXZ")
slouken@1895
   341
        LINK(GXResume, gx.GXResume, "?GXResume@@YAHXZ") LINK(GXSetViewport,
slouken@2735
   342
                                                             gx.GXSetViewport,
slouken@1895
   343
                                                             "?GXSetViewport@@YAHKKKK@Z")
slouken@1895
   344
        LINK(GXIsDisplayDRAMBuffer, gx.GXIsDisplayDRAMBuffer,
slouken@1895
   345
             "?GXIsDisplayDRAMBuffer@@YAHXZ")
slouken@1895
   346
        /* wrong gapi.dll */
slouken@1895
   347
        if (!gx.GXOpenDisplay) {
slouken@1895
   348
        if (g_hGapiLib) {
slouken@1895
   349
            FreeLibrary(g_hGapiLib);
slouken@1895
   350
            g_hGapiLib = 0;
slouken@1895
   351
        }
slouken@1895
   352
    }
icculus@1251
   353
slouken@1895
   354
    if (!gx.GXOpenDisplay && !g_bRawBufferAvailable) {
slouken@1895
   355
        SDL_SetError("Error: damaged or unknown gapi.dll!\n");
slouken@1895
   356
        GAPI_DeleteDevice(device);
slouken@1895
   357
        return 0;
slouken@1895
   358
    }
icculus@1251
   359
slouken@1895
   360
    return device;
icculus@1251
   361
}
icculus@1251
   362
icculus@1251
   363
VideoBootStrap GAPI_bootstrap = {
slouken@1895
   364
    GAPIVID_DRIVER_NAME, "WinCE GAPI video driver",
slouken@1895
   365
    GAPI_Available, GAPI_CreateDevice
icculus@1251
   366
};
icculus@1251
   367
slouken@1895
   368
static void
slouken@1895
   369
FillStructs(_THIS, BOOL useVga)
icculus@1251
   370
{
icculus@1251
   371
#ifdef _ARM_
slouken@1895
   372
    WCHAR oemstr[100];
icculus@1251
   373
#endif
slouken@1895
   374
    /* fill a device properties */
icculus@1251
   375
slouken@1895
   376
    if (!useVga) {
slouken@1895
   377
        this->hidden->gxProperties =
slouken@1895
   378
            this->hidden->gxFunc.GXGetDisplayProperties();
slouken@1895
   379
        this->hidden->needUpdate = 1;
slouken@1895
   380
        this->hidden->hiresFix = 0;
slouken@1895
   381
        this->hidden->useVga = 0;
slouken@1895
   382
        this->hidden->useGXOpenDisplay = 1;
slouken@1465
   383
icculus@1251
   384
#ifdef _ARM_
slouken@1895
   385
        /* check some devices and extract addition info */
slouken@1895
   386
        SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemstr), oemstr, 0);
icculus@1251
   387
slouken@1895
   388
        // buggy iPaq38xx
slouken@1895
   389
        if ((oemstr[12] == 'H') && (oemstr[13] == '3')
slouken@1895
   390
            && (oemstr[14] == '8')
slouken@1895
   391
            && (this->hidden->gxProperties.cbxPitch > 0)) {
slouken@1895
   392
            this->hidden->videoMem = (PIXEL *) 0xac0755a0;
slouken@1895
   393
            this->hidden->gxProperties.cbxPitch = -640;
slouken@1895
   394
            this->hidden->gxProperties.cbyPitch = 2;
slouken@1895
   395
            this->hidden->needUpdate = 0;
slouken@1895
   396
        }
slouken@1465
   397
#if (EMULATE_AXIM_X30 == 0)
slouken@1895
   398
        // buggy Dell Axim X30
slouken@1895
   399
        if (_tcsncmp(oemstr, L"Dell Axim X30", 13) == 0)
slouken@1465
   400
#endif
slouken@1895
   401
        {
slouken@1895
   402
            GXDeviceInfo gxInfo = { 0 };
slouken@1895
   403
            HDC hdc = GetDC(NULL);
slouken@1895
   404
            int result;
slouken@1465
   405
slouken@1895
   406
            gxInfo.Version = 100;
slouken@1895
   407
            result =
slouken@1895
   408
                ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo),
slouken@1895
   409
                          (char *) &gxInfo);
slouken@1895
   410
            if (result > 0) {
slouken@1895
   411
                this->hidden->useGXOpenDisplay = 0;
slouken@1895
   412
                this->hidden->videoMem = gxInfo.pvFrameBuffer;
slouken@1895
   413
                this->hidden->needUpdate = 0;
slouken@1895
   414
                this->hidden->gxProperties.cbxPitch = 2;
slouken@1895
   415
                this->hidden->gxProperties.cbyPitch = 480;
slouken@1895
   416
                this->hidden->gxProperties.cxWidth = gxInfo.cxWidth;
slouken@1895
   417
                this->hidden->gxProperties.cyHeight = gxInfo.cyHeight;
slouken@1895
   418
                this->hidden->gxProperties.ffFormat = gxInfo.ffFormat;
slouken@1895
   419
            }
slouken@1895
   420
        }
icculus@1251
   421
#endif
slouken@1895
   422
    } else {
slouken@1895
   423
        this->hidden->needUpdate = 0;
slouken@1895
   424
        this->hidden->hiresFix = 0;
slouken@1895
   425
        this->hidden->gxProperties.cBPP = g_RawFrameBufferInfo.wBPP;
slouken@1895
   426
        this->hidden->gxProperties.cbxPitch = g_RawFrameBufferInfo.cxStride;
slouken@1895
   427
        this->hidden->gxProperties.cbyPitch = g_RawFrameBufferInfo.cyStride;
slouken@1895
   428
        this->hidden->gxProperties.cxWidth = g_RawFrameBufferInfo.cxPixels;
slouken@1895
   429
        this->hidden->gxProperties.cyHeight = g_RawFrameBufferInfo.cyPixels;
slouken@1895
   430
        this->hidden->videoMem = g_RawFrameBufferInfo.pFramePointer;
slouken@1895
   431
        this->hidden->useVga = 1;
icculus@1251
   432
slouken@1895
   433
        switch (g_RawFrameBufferInfo.wFormat) {
slouken@1895
   434
        case FORMAT_565:
slouken@1895
   435
            this->hidden->gxProperties.ffFormat = kfDirect565;
slouken@1895
   436
            break;
slouken@1895
   437
        case FORMAT_555:
slouken@1895
   438
            this->hidden->gxProperties.ffFormat = kfDirect555;
slouken@1895
   439
            break;
slouken@1895
   440
        default:
slouken@1895
   441
            /* unknown pixel format, try define by BPP! */
slouken@1895
   442
            switch (g_RawFrameBufferInfo.wBPP) {
slouken@1895
   443
            case 4:
slouken@1895
   444
            case 8:
slouken@1895
   445
                this->hidden->gxProperties.ffFormat = kfDirect;
slouken@1895
   446
            case 16:
slouken@1895
   447
                this->hidden->gxProperties.ffFormat = kfDirect565;
slouken@1895
   448
            default:
slouken@1895
   449
                this->hidden->gxProperties.ffFormat = kfDirect;
slouken@1895
   450
                break;
slouken@1895
   451
            }
slouken@1895
   452
        }
slouken@1895
   453
    }
icculus@1251
   454
slouken@1895
   455
    if (this->hidden->gxProperties.cBPP != 16) {
slouken@1895
   456
        this->hidden->gapiOrientation = SDL_ORIENTATION_UP;
slouken@1895
   457
    } else if ((this->hidden->gxProperties.cbxPitch > 0)
slouken@1895
   458
               && (this->hidden->gxProperties.cbyPitch > 0)) {
slouken@1895
   459
        this->hidden->gapiOrientation = SDL_ORIENTATION_UP;
slouken@1895
   460
    } else if ((this->hidden->gxProperties.cbxPitch > 0)
slouken@1895
   461
               && (this->hidden->gxProperties.cbyPitch < 0)) {
slouken@1895
   462
        this->hidden->gapiOrientation = SDL_ORIENTATION_RIGHT;  // ipaq 3660
slouken@1895
   463
    } else if ((this->hidden->gxProperties.cbxPitch < 0)
slouken@1895
   464
               && (this->hidden->gxProperties.cbyPitch > 0)) {
slouken@1895
   465
        this->hidden->gapiOrientation = SDL_ORIENTATION_LEFT;   // ipaq 3800
slouken@1895
   466
    }
icculus@1251
   467
}
icculus@1251
   468
slouken@1895
   469
static void
slouken@1895
   470
GAPI_CreatePalette(int ncolors, SDL_Color * colors)
icculus@1251
   471
{
slouken@1895
   472
    // Setup a custom color palette
slouken@1895
   473
    BYTE buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
slouken@1895
   474
    int i;
slouken@1895
   475
    LOGPALETTE *pLogical = (LOGPALETTE *) buffer;
slouken@1895
   476
    PALETTEENTRY *entries = pLogical->palPalEntry;
slouken@1895
   477
    HPALETTE hPalette;
slouken@1895
   478
    HDC hdc;
icculus@1251
   479
slouken@1895
   480
    for (i = 0; i < ncolors; ++i) {
slouken@1895
   481
        // Find intensity by replicating the bit patterns over a byte
slouken@1895
   482
        entries[i].peRed = colors[i].r;
slouken@1895
   483
        entries[i].peGreen = colors[i].g;
slouken@1895
   484
        entries[i].peBlue = colors[i].b;
slouken@1895
   485
        entries[i].peFlags = 0;
slouken@1895
   486
    }
icculus@1251
   487
slouken@1895
   488
    // Create the GDI palette object
slouken@1895
   489
    pLogical->palVersion = 0x0300;
slouken@1895
   490
    pLogical->palNumEntries = ncolors;
icculus@1251
   491
slouken@1895
   492
    hPalette = CreatePalette(pLogical);
slouken@1895
   493
    ASSERT(hPalette);
slouken@1895
   494
icculus@1251
   495
slouken@1895
   496
    // Realize the palette
slouken@1895
   497
    hdc = GetDC(0);
icculus@1251
   498
slouken@1895
   499
    SelectPalette(hdc, hPalette, FALSE);
slouken@1895
   500
    RealizePalette(hdc);
icculus@1251
   501
slouken@1895
   502
    ReleaseDC(0, hdc);
slouken@1895
   503
    DeleteObject(hPalette);
icculus@1251
   504
}
icculus@1251
   505
slouken@1895
   506
int
slouken@1895
   507
GAPI_VideoInit(_THIS, SDL_PixelFormat * vformat)
icculus@1251
   508
{
slouken@1895
   509
    int i, bpp;
icculus@1251
   510
slouken@1895
   511
    /* Create the window */
slouken@1895
   512
    if (DIB_CreateWindow(this) < 0) {
slouken@1895
   513
        return (-1);
slouken@1895
   514
    }
icculus@1251
   515
slouken@1895
   516
    if (g_hGapiLib) {
slouken@1895
   517
        FillStructs(this, 0);
slouken@1895
   518
slouken@1895
   519
        // SDL does not supports 2/4bpp mode, so use 16 bpp
slouken@1895
   520
        bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;
icculus@1251
   521
slouken@1895
   522
        /* set up normal and landscape mode */
slouken@1895
   523
        GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight,
slouken@1895
   524
                     gapi->gxProperties.cxWidth);
slouken@1895
   525
        GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth,
slouken@1895
   526
                     gapi->gxProperties.cyHeight);
slouken@1895
   527
    }
icculus@1251
   528
slouken@1895
   529
    /* add hi-res mode */
slouken@1895
   530
    if (g_bRawBufferAvailable &&
slouken@1895
   531
        !((gapi->gxProperties.cxWidth ==
slouken@1895
   532
           (unsigned) g_RawFrameBufferInfo.cxPixels)
slouken@1895
   533
          && (gapi->gxProperties.cyHeight ==
slouken@1895
   534
              (unsigned) g_RawFrameBufferInfo.cyPixels))) {
slouken@1895
   535
        FillStructs(this, 1);
icculus@1251
   536
slouken@1895
   537
        // SDL does not supports 2/4bpp mode, so use 16 bpp
slouken@1895
   538
        bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP;
icculus@1251
   539
slouken@1895
   540
        /* set up normal and landscape mode */
slouken@1895
   541
        GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight,
slouken@1895
   542
                     gapi->gxProperties.cxWidth);
slouken@1895
   543
        GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth,
slouken@1895
   544
                     gapi->gxProperties.cyHeight);
slouken@1895
   545
    }
icculus@1251
   546
slouken@1895
   547
    /* Determine the current screen size */
slouken@1895
   548
    this->info.current_w = gapi->gxProperties.cxWidth;
slouken@1895
   549
    this->info.current_h = gapi->gxProperties.cyHeight;
slouken@1545
   550
slouken@1895
   551
    /* Sort the mode lists */
slouken@1895
   552
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
   553
        if (gapi->SDL_nummodes[i] > 0) {
slouken@1895
   554
            SDL_qsort(gapi->SDL_modelist[i], gapi->SDL_nummodes[i],
slouken@1895
   555
                      sizeof *gapi->SDL_modelist[i], cmpmodes);
slouken@1895
   556
        }
slouken@1895
   557
    }
icculus@1251
   558
slouken@1895
   559
    vformat->BitsPerPixel =
slouken@1895
   560
        this->hidden->gxProperties.cBPP <
slouken@1895
   561
        8 ? 16 : (unsigned char) this->hidden->gxProperties.cBPP;
icculus@1251
   562
slouken@1895
   563
    // Get color mask
slouken@1895
   564
    if (this->hidden->gxProperties.ffFormat & kfDirect565) {
slouken@1895
   565
        vformat->BitsPerPixel = 16;
slouken@1895
   566
        vformat->Rmask = 0x0000f800;
slouken@1895
   567
        vformat->Gmask = 0x000007e0;
slouken@1895
   568
        vformat->Bmask = 0x0000001f;
slouken@1895
   569
        this->hidden->videoMode = GAPI_DIRECT_565;
slouken@1895
   570
    } else if (this->hidden->gxProperties.ffFormat & kfDirect555) {
slouken@1895
   571
        vformat->BitsPerPixel = 16;
slouken@1895
   572
        vformat->Rmask = 0x00007c00;
slouken@1895
   573
        vformat->Gmask = 0x000003e0;
slouken@1895
   574
        vformat->Bmask = 0x0000001f;
slouken@1895
   575
        this->hidden->videoMode = GAPI_DIRECT_555;
slouken@1895
   576
    } else if ((this->hidden->gxProperties.ffFormat & kfDirect)
slouken@1895
   577
               && (this->hidden->gxProperties.cBPP < 8)) {
slouken@1895
   578
        // We'll perform the conversion
slouken@1895
   579
        vformat->BitsPerPixel = 16;
slouken@1895
   580
        vformat->Rmask = 0x0000f800;    // 16 bit 565
slouken@1895
   581
        vformat->Gmask = 0x000007e0;
slouken@1895
   582
        vformat->Bmask = 0x0000001f;
slouken@1895
   583
        if (this->hidden->gxProperties.ffFormat & kfDirectInverted)
slouken@1895
   584
            this->hidden->invert = (1 << this->hidden->gxProperties.cBPP) - 1;
slouken@1895
   585
        this->hidden->colorscale =
slouken@1895
   586
            this->hidden->gxProperties.cBPP <
slouken@1895
   587
            8 ? 8 - this->hidden->gxProperties.cBPP : 0;
slouken@1895
   588
        this->hidden->videoMode = GAPI_MONO;
slouken@1895
   589
    } else if (this->hidden->gxProperties.ffFormat & kfPalette) {
slouken@1895
   590
        this->hidden->videoMode = GAPI_PALETTE;
slouken@1895
   591
    }
icculus@1251
   592
slouken@1895
   593
    /* We're done! */
slouken@1895
   594
    return (0);
icculus@1251
   595
}
icculus@1251
   596
slouken@1895
   597
SDL_Rect **
slouken@1895
   598
GAPI_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
icculus@1251
   599
{
slouken@1895
   600
    return (this->hidden->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
slouken@1895
   601
//       return (SDL_Rect **) -1;
icculus@1251
   602
}
icculus@1251
   603
slouken@1895
   604
SDL_Surface *
slouken@1895
   605
GAPI_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1895
   606
                  int width, int height, int bpp, Uint32 flags)
icculus@1251
   607
{
slouken@1895
   608
    SDL_Surface *video;
slouken@1895
   609
    Uint32 Rmask, Gmask, Bmask;
slouken@1895
   610
    DWORD style;
slouken@1895
   611
    SDL_Rect allScreen;
icculus@1251
   612
slouken@1895
   613
    if (bpp < 4) {
slouken@1895
   614
        SDL_SetError("1 bpp and 2 bpp modes is not implemented yet!");
slouken@1895
   615
        return 0;
slouken@1895
   616
    }
icculus@1251
   617
slouken@1895
   618
    /* Recalculate bitmasks if necessary */
slouken@1895
   619
    if (bpp == current->format->BitsPerPixel) {
slouken@1895
   620
        video = current;
slouken@1895
   621
    } else {
slouken@1895
   622
        switch (bpp) {
slouken@1895
   623
        case 8:
slouken@1895
   624
            Rmask = 0;
slouken@1895
   625
            Gmask = 0;
slouken@1895
   626
            Bmask = 0;
slouken@1895
   627
            break;
slouken@1895
   628
        case 15:
slouken@1895
   629
        case 16:
slouken@1895
   630
            /* Default is 565 unless the display is specifically 555 */
slouken@1895
   631
            if (this->hidden->gxProperties.ffFormat & kfDirect555) {
slouken@1895
   632
                Rmask = 0x00007c00;
slouken@1895
   633
                Gmask = 0x000003e0;
slouken@1895
   634
                Bmask = 0x0000001f;
slouken@1895
   635
            } else {
slouken@1895
   636
                Rmask = 0x0000f800;
slouken@1895
   637
                Gmask = 0x000007e0;
slouken@1895
   638
                Bmask = 0x0000001f;
slouken@1895
   639
            }
slouken@1895
   640
            break;
slouken@1895
   641
        case 24:
slouken@1895
   642
        case 32:
slouken@1895
   643
            Rmask = 0x00ff0000;
slouken@1895
   644
            Gmask = 0x0000ff00;
slouken@1895
   645
            Bmask = 0x000000ff;
slouken@1895
   646
            break;
slouken@1895
   647
        default:
slouken@1895
   648
            SDL_SetError("Unsupported Bits Per Pixel format requested");
slouken@1895
   649
            return NULL;
slouken@1895
   650
        }
slouken@1895
   651
        video = SDL_CreateRGBSurface(SDL_SWSURFACE,
slouken@1895
   652
                                     0, 0, bpp, Rmask, Gmask, Bmask, 0);
slouken@1895
   653
        if (video == NULL) {
slouken@1895
   654
            SDL_OutOfMemory();
slouken@1895
   655
            return (NULL);
slouken@1895
   656
        }
slouken@1895
   657
    }
icculus@1251
   658
slouken@1895
   659
    gapi->userOrientation = SDL_ORIENTATION_UP;
slouken@1895
   660
    video->flags = SDL_FULLSCREEN;      /* Clear flags, GAPI supports fullscreen only */
icculus@1251
   661
slouken@1895
   662
    /* GAPI or VGA? */
slouken@1895
   663
    if (g_hGapiLib) {
slouken@1895
   664
        FillStructs(this, 0);
slouken@1895
   665
        if ((((unsigned) width != gapi->gxProperties.cxWidth)
slouken@1895
   666
             || ((unsigned) height != gapi->gxProperties.cyHeight))
slouken@1895
   667
            && (((unsigned) width != gapi->gxProperties.cyHeight)
slouken@1895
   668
                || ((unsigned) height != gapi->gxProperties.cxWidth)))
slouken@1895
   669
            FillStructs(this, 1);       // gapi is found but we use VGA resolution                        
slouken@1895
   670
    } else
slouken@1895
   671
        FillStructs(this, 1);
icculus@1251
   672
slouken@1895
   673
    if (!this->hidden->needUpdate && !this->hidden->videoMem) {
slouken@1895
   674
        SDL_SetError
slouken@1895
   675
            ("Couldn't get address of video memory, may be unsupported device or bug");
slouken@1895
   676
        return (NULL);
slouken@1895
   677
    }
icculus@1251
   678
slouken@1895
   679
    /* detect user landscape mode */
slouken@1895
   680
    if ((width > height)
slouken@1895
   681
        && (GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN)))
slouken@1895
   682
        gapi->userOrientation = SDL_ORIENTATION_RIGHT;
icculus@1251
   683
slouken@1895
   684
    /* shall we apply hires fix? for example when we do not use hires resource */
slouken@1895
   685
    gapi->hiresFix = 0;
slouken@1895
   686
    if (gapi->userOrientation == SDL_ORIENTATION_RIGHT) {
slouken@1895
   687
        if ((width > GetSystemMetrics(SM_CYSCREEN))
slouken@1895
   688
            || (height > GetSystemMetrics(SM_CXSCREEN)))
slouken@1895
   689
            gapi->hiresFix = 1;
slouken@1895
   690
    } else if ((width > GetSystemMetrics(SM_CXSCREEN))
slouken@1895
   691
               || (height > GetSystemMetrics(SM_CYSCREEN)))
slouken@1895
   692
        if (!((width == GetSystemMetrics(SM_CYSCREEN)) && (height == GetSystemMetrics(SM_CXSCREEN))))   // user portrait, device landscape
slouken@1895
   693
            gapi->hiresFix = 1;
icculus@1251
   694
slouken@1895
   695
    switch (gapi->userOrientation) {
slouken@1895
   696
    case SDL_ORIENTATION_UP:
slouken@1895
   697
        gapi->startOffset = 0;
slouken@1895
   698
        gapi->dstLineStep = gapi->gxProperties.cbyPitch;
slouken@1895
   699
        gapi->dstPixelStep = gapi->gxProperties.cbxPitch;
slouken@1895
   700
        break;
slouken@1895
   701
    case SDL_ORIENTATION_RIGHT:
slouken@1895
   702
        switch (gapi->gapiOrientation) {
slouken@1895
   703
        case SDL_ORIENTATION_UP:
slouken@1895
   704
        case SDL_ORIENTATION_RIGHT:
slouken@1895
   705
        case SDL_ORIENTATION_LEFT:
slouken@1895
   706
            if ((this->hidden->videoMode == GAPI_MONO))
slouken@1895
   707
                gapi->startOffset = -gapi->gxProperties.cbxPitch + 1;   // monochrome mode
slouken@1895
   708
            else
slouken@1895
   709
                gapi->startOffset =
slouken@1895
   710
                    gapi->gxProperties.cbyPitch *
slouken@1895
   711
                    (gapi->gxProperties.cyHeight - 1);
icculus@1251
   712
slouken@1895
   713
            gapi->dstLineStep = gapi->gxProperties.cbxPitch;
slouken@1895
   714
            gapi->dstPixelStep = -gapi->gxProperties.cbyPitch;
slouken@1895
   715
            break;
slouken@1895
   716
        }
slouken@1895
   717
    }
slouken@1895
   718
slouken@1895
   719
    video->w = this->hidden->w = width;
slouken@1895
   720
    video->h = this->hidden->h = height;
slouken@1895
   721
    video->pitch = SDL_CalculatePitch(video);
icculus@1251
   722
slouken@1895
   723
    /* Small fix for WinCE/Win32 - when activating window
slouken@1895
   724
       SDL_VideoSurface is equal to zero, so activating code
slouken@1895
   725
       is not called properly for fullscreen windows because
slouken@1895
   726
       macros WINDIB_FULLSCREEN uses SDL_VideoSurface
slouken@1895
   727
     */
slouken@1895
   728
    SDL_VideoSurface = video;
icculus@1251
   729
slouken@1895
   730
    /* GAPI is always fullscreen, title bar is useless */
slouken@1895
   731
    style = 0;
icculus@1251
   732
slouken@1895
   733
    if (!SDL_windowid)
slouken@1895
   734
        SetWindowLong(SDL_Window, GWL_STYLE, style);
slouken@1465
   735
slouken@1895
   736
    /* Allocate bitmap */
slouken@1895
   737
    if (gapiBuffer) {
slouken@1895
   738
        SDL_free(gapiBuffer);
slouken@1895
   739
        gapiBuffer = NULL;
slouken@1895
   740
    }
slouken@1895
   741
    gapiBuffer = SDL_malloc(video->h * video->pitch);
slouken@1895
   742
    video->pixels = gapiBuffer;
icculus@1251
   743
slouken@1895
   744
    if (!this->hidden->buffer) {
slouken@1895
   745
        SDL_SetError("Couldn't allocate buffer for requested mode");
slouken@1895
   746
        return (NULL);
slouken@1895
   747
    }
icculus@1251
   748
slouken@1895
   749
    SDL_memset(gapiBuffer, 255, video->h * video->pitch);
slouken@1895
   750
    MoveWindow(SDL_Window, 0, 0, GetSystemMetrics(SM_CXSCREEN),
slouken@1895
   751
               GetSystemMetrics(SM_CYSCREEN), FALSE);
slouken@1895
   752
    ShowWindow(SDL_Window, SW_SHOW);
slouken@1895
   753
    SetForegroundWindow(SDL_Window);
icculus@1251
   754
slouken@1895
   755
    /* JC 14 Mar 2006
slouken@1895
   756
       Flush the message loop or this can cause big problems later
slouken@1895
   757
       Especially if the user decides to use dialog boxes or assert()!
slouken@1895
   758
     */
slouken@1895
   759
    WIN_FlushMessageQueue();
slouken@1523
   760
slouken@1895
   761
    /* Open GAPI display */
slouken@1895
   762
    if (!gapi->useVga && this->hidden->useGXOpenDisplay)
slouken@1895
   763
        if (!gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN)) {
slouken@1895
   764
            SDL_SetError("Couldn't initialize GAPI");
slouken@1895
   765
            return (NULL);
slouken@1895
   766
        }
icculus@1251
   767
#if REPORT_VIDEO_INFO
slouken@1895
   768
    printf("Video properties:\n");
slouken@1895
   769
    printf("display bpp: %d\n", gapi->gxProperties.cBPP);
slouken@1895
   770
    printf("display width: %d\n", gapi->gxProperties.cxWidth);
slouken@1895
   771
    printf("display height: %d\n", gapi->gxProperties.cyHeight);
slouken@1895
   772
    printf("x pitch: %d\n", gapi->gxProperties.cbxPitch);
slouken@1895
   773
    printf("y pitch: %d\n", gapi->gxProperties.cbyPitch);
slouken@1895
   774
    printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat);
slouken@1465
   775
slouken@1895
   776
    if (!gapi->useVga && this->hidden->useGXOpenDisplay && gapi->needUpdate) {
slouken@1895
   777
        gapi->videoMem = gapi->gxFunc.GXBeginDraw();
slouken@1895
   778
        gapi->gxFunc.GXEndDraw();
slouken@1895
   779
    }
slouken@1465
   780
slouken@1895
   781
    printf("video memory: 0x%x\n", gapi->videoMem);
slouken@1895
   782
    printf("need update: %d\n", gapi->needUpdate);
slouken@1895
   783
    printf("hi-res fix: %d\n", gapi->hiresFix);
slouken@1895
   784
    printf("VGA is available on the device: %d\n", g_bRawBufferAvailable);
slouken@1895
   785
    printf("use raw framebuffer: %d\n", gapi->useVga);
slouken@1895
   786
    printf("video surface bpp: %d\n", video->format->BitsPerPixel);
slouken@1895
   787
    printf("video surface width: %d\n", video->w);
slouken@1895
   788
    printf("video surface height: %d\n", video->h);
icculus@1251
   789
#endif
icculus@1251
   790
slouken@1465
   791
slouken@1895
   792
    /* Blank screen */
slouken@1895
   793
    allScreen.x = allScreen.y = 0;
slouken@1895
   794
    allScreen.w = video->w - 1;
slouken@1895
   795
    allScreen.h = video->h - 1;
slouken@1895
   796
    GAPI_UpdateRects(this, 1, &allScreen);
icculus@1251
   797
slouken@1895
   798
    /* We're done */
slouken@1895
   799
    return (video);
icculus@1251
   800
}
icculus@1251
   801
icculus@1251
   802
/* We don't actually allow hardware surfaces other than the main one */
slouken@1895
   803
static int
slouken@1895
   804
GAPI_AllocHWSurface(_THIS, SDL_Surface * surface)
icculus@1251
   805
{
slouken@1895
   806
    return (-1);
icculus@1251
   807
}
slouken@2735
   808
slouken@1895
   809
static void
slouken@1895
   810
GAPI_FreeHWSurface(_THIS, SDL_Surface * surface)
icculus@1251
   811
{
slouken@1895
   812
    return;
icculus@1251
   813
}
icculus@1251
   814
icculus@1251
   815
/* We need to wait for vertical retrace on page flipped displays */
slouken@1895
   816
static int
slouken@1895
   817
GAPI_LockHWSurface(_THIS, SDL_Surface * surface)
icculus@1251
   818
{
slouken@1895
   819
    return (0);
icculus@1251
   820
}
icculus@1251
   821
slouken@1895
   822
static void
slouken@1895
   823
GAPI_UnlockHWSurface(_THIS, SDL_Surface * surface)
icculus@1251
   824
{
slouken@1895
   825
    return;
icculus@1251
   826
}
icculus@1251
   827
slouken@1895
   828
static int
slouken@1895
   829
updateLine8to8(_THIS, unsigned char *srcPointer, unsigned char *destPointer,
slouken@1895
   830
               int width, int height, int lines)
icculus@1251
   831
{
slouken@1895
   832
    if (gapi->dstPixelStep == 1) {      /* optimized blitting on most devices */
slouken@1895
   833
        SDL_memcpy(destPointer, srcPointer, width);
slouken@1895
   834
        return 1;
slouken@1895
   835
    } else {
slouken@1895
   836
        // TODO: read 4 pixels, write DWORD
slouken@1895
   837
        int step = gapi->dstPixelStep;
slouken@1895
   838
        while (width--) {
slouken@1895
   839
            *destPointer = *srcPointer++;
slouken@1895
   840
            destPointer += step;
slouken@1895
   841
        }
slouken@1895
   842
    }
slouken@1895
   843
    return 1;
icculus@1251
   844
}
icculus@1251
   845
icculus@1251
   846
/* Video memory is very slow so lets optimize as much as possible */
slouken@1895
   847
static int
slouken@1895
   848
updateLine16to16(_THIS, PIXEL * srcPointer, PIXEL * destPointer, int width,
slouken@1895
   849
                 int height, int lines)
icculus@1251
   850
{
slouken@1895
   851
    PIXEL *line1, *line2;
slouken@1895
   852
    int step = gapi->dstPixelStep / 2;
icculus@1251
   853
slouken@1895
   854
    if (step == 1) {            /* optimized blitting on most devices */
slouken@1895
   855
        SDL_memcpy(destPointer, srcPointer, width * sizeof(PIXEL));
slouken@1895
   856
        return 1;
slouken@1895
   857
    } else {
slouken@1895
   858
        if ((gapi->gapiOrientation != SDL_ORIENTATION_UP) && (gapi->userOrientation == SDL_ORIENTATION_UP))     // iPaq 3660/3800 and user orientation up
slouken@1895
   859
        {
slouken@1895
   860
            // to prevent data misalignment copy only one line
slouken@1895
   861
            if (((((unsigned) destPointer & 3) != 0)
slouken@1895
   862
                 && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT))
slouken@1895
   863
                || ((((unsigned) destPointer & 3) == 0)
slouken@1895
   864
                    && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT))
slouken@1895
   865
                || (lines == 1)) {
slouken@1895
   866
                while (width--) {
slouken@1895
   867
                    *destPointer = *srcPointer++;
slouken@1895
   868
                    destPointer += step;
slouken@1895
   869
                }
slouken@1895
   870
                return 1;
slouken@1895
   871
            }
icculus@1251
   872
slouken@1895
   873
            /* read two lines at the same time, write DWORD */
slouken@1895
   874
            line1 = srcPointer;
slouken@1895
   875
            line2 = srcPointer + SDL_VideoSurface->pitch / 2;
icculus@1251
   876
slouken@1895
   877
            if (gapi->gapiOrientation == SDL_ORIENTATION_LEFT)
slouken@1895
   878
                while (width--) // iPaq 3800
slouken@1895
   879
                {
slouken@1895
   880
                    *(DWORD *) destPointer = (*line2++ << 16) | *line1++;
slouken@1895
   881
                    destPointer += step;
slouken@1895
   882
            } else {
slouken@1895
   883
                destPointer += gapi->gxProperties.cbyPitch / 2;
slouken@1465
   884
slouken@1895
   885
                while (width--) // iPaq 3660
slouken@1895
   886
                {
slouken@1895
   887
                    *(DWORD *) destPointer = (*line1++ << 16) | *line2++;
slouken@1895
   888
                    destPointer += step;
slouken@1895
   889
                }
slouken@1895
   890
            }
slouken@1895
   891
            return 2;
slouken@1895
   892
        } else {
slouken@1895
   893
            // iPaq 3800 and user orientation landscape
slouken@1895
   894
            if (gapi->gapiOrientation == SDL_ORIENTATION_LEFT) {
slouken@1895
   895
                int w1;
icculus@1251
   896
slouken@1895
   897
                // to prevent data misalignment copy only one pixel
slouken@1895
   898
                if ((((unsigned) destPointer & 3) == 0) && (width > 0)) {
slouken@1895
   899
                    *destPointer-- = *srcPointer++;
slouken@1895
   900
                    width--;
slouken@1895
   901
                }
icculus@1251
   902
slouken@1895
   903
                destPointer--;
icculus@1251
   904
slouken@1895
   905
                w1 = width / 2;
icculus@1251
   906
slouken@1895
   907
                while (w1--) {
slouken@1895
   908
                    DWORD p = *(DWORD *) srcPointer;
slouken@1895
   909
                    *((DWORD *) destPointer) = (p << 16) | (p >> 16);
slouken@1895
   910
                    destPointer -= 2;
slouken@1895
   911
                    srcPointer += 2;
slouken@1895
   912
                }
icculus@1251
   913
slouken@1895
   914
                if (width & 1)  // copy the last pixel
slouken@1895
   915
                {
slouken@1895
   916
                    destPointer++;
slouken@1895
   917
                    *destPointer = *srcPointer;
slouken@1895
   918
                }
icculus@1251
   919
slouken@1895
   920
                return 1;
slouken@1895
   921
            }
slouken@1895
   922
            // modern iPaqs and user orientation landscape
slouken@1895
   923
            // read two pixels, write DWORD
icculus@1251
   924
slouken@1895
   925
            line1 = srcPointer;
slouken@1895
   926
            line2 = srcPointer + SDL_VideoSurface->pitch / 2;
icculus@1251
   927
slouken@1895
   928
            if ((((unsigned) destPointer & 3) != 0) || (lines == 1)) {
slouken@1895
   929
                while (width--) {
slouken@1895
   930
                    *destPointer = *srcPointer++;
slouken@1895
   931
                    destPointer += step;
slouken@1895
   932
                }
slouken@1895
   933
                return 1;
slouken@1895
   934
            }
slouken@1895
   935
slouken@1895
   936
            while (width--) {
slouken@1895
   937
                *(DWORD *) destPointer = (*line2++ << 16) | *line1++;
slouken@1895
   938
                destPointer -= gapi->gxProperties.cbyPitch / 2;
slouken@1895
   939
            }
slouken@1895
   940
            return 2;
slouken@1895
   941
        }
slouken@1895
   942
    }
icculus@1251
   943
}
icculus@1251
   944
icculus@1251
   945
// Color component masks for 565
icculus@1251
   946
#define REDMASK (31<<11)
icculus@1251
   947
#define GREENMASK (63<<5)
icculus@1251
   948
#define BLUEMASK (31)
icculus@1251
   949
icculus@1251
   950
slouken@1895
   951
static int
slouken@1895
   952
updateLine16to4(_THIS, PIXEL * srcPointer, unsigned char *destPointer,
slouken@1895
   953
                int width, int height, int lines, int yNibble, int xNibble)
icculus@1251
   954
{
slouken@1895
   955
    PIXEL *line1, *line2;
slouken@1895
   956
    int step = gapi->dstPixelStep;
icculus@1251
   957
slouken@1895
   958
    if (gapi->userOrientation == SDL_ORIENTATION_UP) {
slouken@1895
   959
        if (yNibble)            // copy bottom half of a line
slouken@1895
   960
        {
slouken@1895
   961
            while (width--) {
slouken@1895
   962
                PIXEL c1 = *srcPointer++;
slouken@1895
   963
                c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
   964
                    (c1 & BLUEMASK);
slouken@1895
   965
                *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
slouken@1895
   966
                destPointer += step;
slouken@1895
   967
            }
slouken@1895
   968
            return 1;
slouken@1895
   969
        }
slouken@1895
   970
        // either 1 pixel picture or tail, anyway this is the last line
slouken@1895
   971
        if (lines == 1) {
slouken@1895
   972
            while (width--) {
slouken@1895
   973
                PIXEL c1 = *srcPointer++;
slouken@1895
   974
                c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
   975
                    (c1 & BLUEMASK);
slouken@1895
   976
                *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
slouken@1895
   977
                destPointer += step;
slouken@1895
   978
            }
slouken@1895
   979
            return 1;
slouken@1895
   980
        }
icculus@1251
   981
slouken@1895
   982
        line1 = srcPointer;
slouken@1895
   983
        line2 = srcPointer + SDL_VideoSurface->pitch / 2;
icculus@1251
   984
slouken@1895
   985
        while (width--) {
slouken@1895
   986
            PIXEL c1 = *line1++;
slouken@1895
   987
            PIXEL c2 = *line2++;
slouken@1895
   988
            c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
   989
                (c1 & BLUEMASK);
slouken@1895
   990
            c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) +
slouken@1895
   991
                (c2 & BLUEMASK);
slouken@1895
   992
            *destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4));
slouken@1895
   993
            destPointer += step;
slouken@1895
   994
        }
slouken@1895
   995
        return 2;
slouken@1895
   996
    } else {
slouken@1895
   997
        int w1;
slouken@1895
   998
        w1 = width / 2;
icculus@1251
   999
slouken@1895
  1000
        if (xNibble) {
slouken@1895
  1001
            // copy one pixel
slouken@1895
  1002
            PIXEL c1 = *srcPointer++;
slouken@1895
  1003
            c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
  1004
                (c1 & BLUEMASK);
slouken@1895
  1005
            *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF));
slouken@1895
  1006
            destPointer++;
slouken@1895
  1007
        }
icculus@1251
  1008
slouken@1895
  1009
        while (w1--) {
slouken@1895
  1010
            PIXEL c1 = *srcPointer;
slouken@1895
  1011
            PIXEL c2 = *(srcPointer + 1);
slouken@1895
  1012
            c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
  1013
                (c1 & BLUEMASK);
slouken@1895
  1014
            c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) +
slouken@1895
  1015
                (c2 & BLUEMASK);
slouken@1895
  1016
            *destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4));
slouken@1895
  1017
            srcPointer += 2;
slouken@1895
  1018
        }
icculus@1251
  1019
slouken@1895
  1020
        // copy tail
slouken@1895
  1021
        if ((width & 1) && !xNibble) {
slouken@1895
  1022
            PIXEL c1 = *srcPointer;
slouken@1895
  1023
            c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) +
slouken@1895
  1024
                (c1 & BLUEMASK);
slouken@1895
  1025
            *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4));
slouken@1895
  1026
        }
icculus@1251
  1027
slouken@1895
  1028
        return 1;
slouken@1895
  1029
    }
icculus@1251
  1030
}
icculus@1251
  1031
slouken@1895
  1032
static void
slouken@1895
  1033
GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect * rects)
icculus@1251
  1034
{
slouken@1895
  1035
    int i, height;
slouken@1895
  1036
    int linesProcessed;
slouken@1895
  1037
    int xNibble, yNibble;
slouken@1895
  1038
slouken@1895
  1039
    for (i = 0; i < numrects; i++) {
slouken@1895
  1040
        unsigned char *destPointer;
slouken@1895
  1041
        unsigned char *srcPointer;
icculus@1251
  1042
slouken@1895
  1043
        if (gapi->userOrientation == SDL_ORIENTATION_UP)
slouken@1895
  1044
            destPointer =
slouken@1895
  1045
                (unsigned char *) gapi->videoMem + gapi->startOffset -
slouken@1895
  1046
                rects[i].y * gapi->gxProperties.cBPP / 8 +
slouken@1895
  1047
                rects[i].x * gapi->dstPixelStep;
slouken@1895
  1048
        else
slouken@1895
  1049
            destPointer =
slouken@1895
  1050
                (unsigned char *) gapi->videoMem + gapi->startOffset +
slouken@1895
  1051
                rects[i].x * gapi->gxProperties.cBPP / 8 +
slouken@1895
  1052
                rects[i].y * gapi->dstLineStep;
icculus@1251
  1053
slouken@1895
  1054
        srcPointer =
slouken@1895
  1055
            ((unsigned char *) SDL_VideoSurface->pixels) +
slouken@1895
  1056
            rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2;
slouken@1895
  1057
        yNibble = rects[i].y & 1;       // TODO: only for 4 bpp
slouken@1895
  1058
        xNibble = rects[i].x & 1;
slouken@1895
  1059
        height = rects[i].h;
slouken@1895
  1060
        while (height > 0) {
slouken@1895
  1061
            switch (gapi->gxProperties.cBPP) {
slouken@1895
  1062
            case 2:            // TODO
slouken@1895
  1063
            case 4:
slouken@1895
  1064
                linesProcessed =
slouken@1895
  1065
                    updateLine16to4(this, (PIXEL *) srcPointer,
slouken@1895
  1066
                                    destPointer, rects[i].w,
slouken@1895
  1067
                                    rects[i].h, height, yNibble, xNibble);
slouken@1895
  1068
                yNibble = 0;
slouken@1895
  1069
            }
slouken@1895
  1070
            height -= linesProcessed;
slouken@1895
  1071
            if (gapi->userOrientation == SDL_ORIENTATION_UP)
slouken@1895
  1072
                destPointer--;  // always fill 1 byte
slouken@1895
  1073
            else
slouken@1895
  1074
                destPointer += gapi->dstLineStep;
slouken@1895
  1075
            srcPointer += SDL_VideoSurface->pitch * linesProcessed;     // pitch in bytes
slouken@1895
  1076
        }
slouken@1895
  1077
    }
icculus@1251
  1078
}
icculus@1251
  1079
slouken@1895
  1080
static void
slouken@1895
  1081
GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect * rects)
icculus@1251
  1082
{
slouken@1895
  1083
    int i, height;
slouken@1895
  1084
    int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8;
slouken@1895
  1085
    int linesProcessed;
slouken@1895
  1086
    for (i = 0; i < numrects; i++) {
slouken@1895
  1087
        unsigned char *destPointer =
slouken@1895
  1088
            (unsigned char *) gapi->videoMem + gapi->startOffset +
slouken@1895
  1089
            rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep;
slouken@1895
  1090
        unsigned char *srcPointer =
slouken@1895
  1091
            ((unsigned char *) SDL_VideoSurface->pixels) +
slouken@1895
  1092
            rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel;
slouken@1895
  1093
        height = rects[i].h;
icculus@1251
  1094
slouken@1895
  1095
//              fprintf(stderr, "Starting rect %dx%d, dst=0x%x, w = %d, h = %d\n", rects[i].w, rects[i].h,destPointer,rects[i].w,rects[i].h);
slouken@1895
  1096
//              fflush(stderr);
slouken@1895
  1097
        linesProcessed = height;
icculus@1251
  1098
slouken@1895
  1099
        while (height > 0) {
slouken@1895
  1100
            switch (bytesPerPixel) {
slouken@1895
  1101
            case 1:
slouken@1895
  1102
                linesProcessed =
slouken@1895
  1103
                    updateLine8to8(this, srcPointer,
slouken@1895
  1104
                                   (unsigned char *) destPointer,
slouken@1895
  1105
                                   rects[i].w, rects[i].h, height);
slouken@1895
  1106
                break;
slouken@1895
  1107
            case 2:
icculus@1251
  1108
#pragma warning(disable: 4133)
slouken@1895
  1109
                linesProcessed =
slouken@1895
  1110
                    updateLine16to16(this, (PIXEL *) srcPointer,
slouken@1895
  1111
                                     destPointer, rects[i].w,
slouken@1895
  1112
                                     rects[i].h, height);
slouken@1895
  1113
                break;
slouken@1895
  1114
            }
slouken@1895
  1115
            height -= linesProcessed;
slouken@1895
  1116
            destPointer += gapi->dstLineStep * linesProcessed;
slouken@1895
  1117
            srcPointer += SDL_VideoSurface->pitch * linesProcessed;     // pitch in bytes
slouken@1895
  1118
        }
slouken@1895
  1119
//              fprintf(stderr, "End of rect\n");
slouken@1895
  1120
//              fflush(stderr);
slouken@1895
  1121
    }
icculus@1251
  1122
}
icculus@1251
  1123
icculus@1251
  1124
slouken@1895
  1125
static void
slouken@1895
  1126
GAPI_UpdateRects(_THIS, int numrects, SDL_Rect * rects)
icculus@1251
  1127
{
slouken@1895
  1128
    // we do not want to corrupt video memory
slouken@1895
  1129
    if (gapi->suspended)
slouken@1895
  1130
        return;
icculus@1251
  1131
slouken@1895
  1132
    if (gapi->needUpdate)
slouken@1895
  1133
        gapi->videoMem = gapi->gxFunc.GXBeginDraw();
icculus@1251
  1134
slouken@1895
  1135
    if (gapi->gxProperties.cBPP < 8)
slouken@1895
  1136
        GAPI_UpdateRectsMono(this, numrects, rects);
slouken@1895
  1137
    else
slouken@1895
  1138
        GAPI_UpdateRectsColor(this, numrects, rects);
slouken@1895
  1139
slouken@1895
  1140
    if (gapi->needUpdate)
slouken@1895
  1141
        gapi->gxFunc.GXEndDraw();
icculus@1251
  1142
}
icculus@1251
  1143
icculus@1251
  1144
/* Note:  If we are terminated, this could be called in the middle of
icculus@1251
  1145
   another SDL video routine -- notably UpdateRects.
icculus@1251
  1146
*/
slouken@1895
  1147
void
slouken@1895
  1148
GAPI_VideoQuit(_THIS)
icculus@1251
  1149
{
slouken@1895
  1150
    int i, j;
slouken@1895
  1151
    /* Destroy the window and everything associated with it */
slouken@1895
  1152
    if (SDL_Window) {
slouken@1895
  1153
        if ((g_hGapiLib != 0) && this && this->hidden
slouken@1895
  1154
            && this->hidden->gxFunc.GXCloseDisplay && !this->hidden->useVga)
slouken@1895
  1155
            this->hidden->gxFunc.GXCloseDisplay();
icculus@1251
  1156
slouken@1895
  1157
        if (this->screen->pixels != NULL) {
slouken@1895
  1158
            SDL_free(this->screen->pixels);
slouken@1895
  1159
            this->screen->pixels = NULL;
slouken@1895
  1160
        }
slouken@1895
  1161
        if (screen_icn) {
slouken@1895
  1162
            DestroyIcon(screen_icn);
slouken@1895
  1163
            screen_icn = NULL;
slouken@1895
  1164
        }
icculus@1251
  1165
slouken@1895
  1166
        DIB_DestroyWindow(this);
slouken@1895
  1167
        SDL_UnregisterApp();
icculus@1251
  1168
slouken@1895
  1169
        SDL_Window = NULL;
icculus@1251
  1170
#if defined(_WIN32_WCE)
icculus@1251
  1171
icculus@1251
  1172
// Unload wince aygshell library to prevent leak
slouken@1895
  1173
        if (aygshell) {
slouken@1895
  1174
            FreeLibrary(aygshell);
slouken@1895
  1175
            aygshell = NULL;
slouken@1895
  1176
        }
icculus@1251
  1177
#endif
icculus@1251
  1178
slouken@1895
  1179
        /* Free video mode lists */
slouken@1895
  1180
        for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
  1181
            if (gapi->SDL_modelist[i] != NULL) {
slouken@1895
  1182
                for (j = 0; gapi->SDL_modelist[i][j]; ++j)
slouken@1895
  1183
                    SDL_free(gapi->SDL_modelist[i][j]);
slouken@1895
  1184
                SDL_free(gapi->SDL_modelist[i]);
slouken@1895
  1185
                gapi->SDL_modelist[i] = NULL;
slouken@1895
  1186
            }
slouken@1895
  1187
        }
icculus@1251
  1188
slouken@1895
  1189
    }
icculus@1251
  1190
icculus@1251
  1191
}
icculus@1251
  1192
slouken@1895
  1193
static void
slouken@1895
  1194
GAPI_RealizePalette(_THIS)
icculus@1251
  1195
{
slouken@1895
  1196
    OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
icculus@1251
  1197
}
icculus@1251
  1198
slouken@1895
  1199
static void
slouken@1895
  1200
GAPI_PaletteChanged(_THIS, HWND window)
icculus@1251
  1201
{
slouken@1895
  1202
    OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
icculus@1251
  1203
}
icculus@1251
  1204
slouken@1895
  1205
static void
slouken@1895
  1206
GAPI_WinPAINT(_THIS, HDC hdc)
icculus@1251
  1207
{
slouken@1895
  1208
    // draw current offscreen buffer on hdc
slouken@1497
  1209
slouken@1895
  1210
    int bpp = 16;               // we always use either 8 or 16 bpp internally
slouken@1497
  1211
slouken@1895
  1212
    unsigned short *bitmapData;
slouken@1895
  1213
    HBITMAP hb;
slouken@1895
  1214
    HDC srcDC;
slouken@1497
  1215
slouken@1497
  1216
    // Create a DIB
slouken@1895
  1217
    BYTE buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)] = { 0 };
slouken@1895
  1218
    BITMAPINFO *pBMI = (BITMAPINFO *) buffer;
slouken@1895
  1219
    BITMAPINFOHEADER *pHeader = &pBMI->bmiHeader;
slouken@1895
  1220
    DWORD *pColors = (DWORD *) & pBMI->bmiColors;
slouken@1497
  1221
slouken@1895
  1222
    // CreateDIBSection does not support 332 pixel format on wce
slouken@1895
  1223
    if (gapi->gxProperties.cBPP == 8)
slouken@1895
  1224
        return;
slouken@1497
  1225
slouken@1497
  1226
    // DIB Header
slouken@1895
  1227
    pHeader->biSize = sizeof(BITMAPINFOHEADER);
slouken@1895
  1228
    pHeader->biWidth = this->hidden->w;
slouken@1895
  1229
    pHeader->biHeight = -this->hidden->h;
slouken@1895
  1230
    pHeader->biPlanes = 1;
slouken@1895
  1231
    pHeader->biBitCount = bpp;
slouken@1895
  1232
    pHeader->biCompression = BI_RGB;
slouken@1895
  1233
    pHeader->biSizeImage = (this->hidden->w * this->hidden->h * bpp) / 8;
slouken@1895
  1234
slouken@1497
  1235
    // Color masks
slouken@1895
  1236
    if (bpp == 16) {
slouken@1895
  1237
        pColors[0] = REDMASK;
slouken@1895
  1238
        pColors[1] = GREENMASK;
slouken@1895
  1239
        pColors[2] = BLUEMASK;
slouken@1895
  1240
        pHeader->biCompression = BI_BITFIELDS;
slouken@1895
  1241
    }
slouken@1497
  1242
    // Create the DIB
slouken@1895
  1243
    hb = CreateDIBSection(0, pBMI, DIB_RGB_COLORS, (void **) &bitmapData, 0,
slouken@1895
  1244
                          0);
slouken@1497
  1245
slouken@1895
  1246
    // copy data
slouken@1895
  1247
    // FIXME: prevent misalignment, but I've never seen non aligned width of screen
slouken@1895
  1248
    memcpy(bitmapData, this->hidden->buffer, pHeader->biSizeImage);
slouken@1895
  1249
    srcDC = CreateCompatibleDC(hdc);
slouken@1895
  1250
    SelectObject(srcDC, hb);
slouken@1497
  1251
slouken@1895
  1252
    BitBlt(hdc, 0, 0, this->hidden->w, this->hidden->h, srcDC, 0, 0, SRCCOPY);
slouken@1497
  1253
slouken@1895
  1254
    DeleteObject(hb);
slouken@1895
  1255
    DeleteDC(srcDC);
icculus@1251
  1256
}
icculus@1251
  1257
slouken@1895
  1258
int
slouken@1895
  1259
GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
icculus@1251
  1260
{
slouken@1895
  1261
    GAPI_CreatePalette(ncolors, colors);
slouken@1895
  1262
    return 1;
slouken@1312
  1263
}
slouken@1895
  1264
slouken@1895
  1265
/* vi: set ts=4 sw=4 expandtab: */