src/video/svga/SDL_svgavideo.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 27 Aug 2008 15:10:03 +0000
changeset 2735 204be4fc2726
parent 1895 c121d94672cb
child 2859 99210400e8b9
permissions -rw-r--r--
Final merge of Google Summer of Code 2008 work...

Port SDL 1.3 to the Nintendo DS
by Darren Alton, mentored by Sam Lantinga
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     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
slouken@0
     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.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    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
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* SVGAlib based SDL video driver implementation.
slouken@0
    25
*/
slouken@0
    26
slouken@0
    27
#include <unistd.h>
slouken@0
    28
#include <sys/stat.h>
slouken@67
    29
#include <sys/types.h>
slouken@67
    30
#include <sys/ioctl.h>
slouken@67
    31
#include <fcntl.h>
slouken@0
    32
slouken@1402
    33
#if defined(__LINUX__)
slouken@0
    34
#include <linux/vt.h>
slouken@1402
    35
#elif defined(__FREEBSD__)
slouken@0
    36
#include <sys/consio.h>
slouken@0
    37
#else
slouken@0
    38
#error You must choose your operating system here
slouken@0
    39
#endif
slouken@0
    40
#include <vga.h>
slouken@0
    41
#include <vgamouse.h>
slouken@0
    42
#include <vgakeyboard.h>
slouken@0
    43
slouken@0
    44
#include "SDL_video.h"
slouken@0
    45
#include "SDL_mouse.h"
slouken@1361
    46
#include "../SDL_sysvideo.h"
slouken@1361
    47
#include "../SDL_pixels_c.h"
slouken@1361
    48
#include "../../events/SDL_events_c.h"
slouken@0
    49
#include "SDL_svgavideo.h"
slouken@0
    50
#include "SDL_svgaevents_c.h"
slouken@0
    51
#include "SDL_svgamouse_c.h"
slouken@0
    52
slouken@0
    53
/* Initialization/Query functions */
slouken@1895
    54
static int SVGA_VideoInit(_THIS, SDL_PixelFormat * vformat);
slouken@1895
    55
static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat * format,
slouken@1895
    56
                                 Uint32 flags);
slouken@1895
    57
static SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1895
    58
                                      int width, int height, int bpp,
slouken@1895
    59
                                      Uint32 flags);
slouken@0
    60
static int SVGA_SetColors(_THIS, int firstcolor, int ncolors,
slouken@1895
    61
                          SDL_Color * colors);
slouken@0
    62
static void SVGA_VideoQuit(_THIS);
slouken@0
    63
slouken@0
    64
/* Hardware surface functions */
slouken@1895
    65
static int SVGA_AllocHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    66
static int SVGA_LockHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    67
static int SVGA_FlipHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    68
static void SVGA_UnlockHWSurface(_THIS, SDL_Surface * surface);
slouken@1895
    69
static void SVGA_FreeHWSurface(_THIS, SDL_Surface * surface);
slouken@0
    70
slouken@0
    71
/* SVGAlib driver bootstrap functions */
slouken@0
    72
slouken@1895
    73
static int
slouken@1895
    74
SVGA_Available(void)
slouken@0
    75
{
slouken@1895
    76
    /* Check to see if we are root and stdin is a virtual console */
slouken@1895
    77
    int console;
slouken@0
    78
slouken@1895
    79
    /* SVGALib 1.9.x+ doesn't require root (via /dev/svga) */
slouken@1895
    80
    int svgalib2 = -1;
slouken@0
    81
slouken@1895
    82
    /* See if we are connected to a virtual terminal */
slouken@1895
    83
    console = STDIN_FILENO;
slouken@1895
    84
#if 0                           /* This is no longer needed, SVGAlib can switch consoles for us */
slouken@1895
    85
    if (console >= 0) {
slouken@1895
    86
        struct stat sb;
slouken@1895
    87
        struct vt_mode dummy;
slouken@1895
    88
slouken@1895
    89
        if ((fstat(console, &sb) < 0) ||
slouken@1895
    90
            (ioctl(console, VT_GETMODE, &dummy) < 0)) {
slouken@1895
    91
            console = -1;
slouken@1895
    92
        }
slouken@1895
    93
    }
slouken@226
    94
#endif /* 0 */
slouken@67
    95
slouken@1895
    96
    /* See if SVGAlib 2.0 is available */
slouken@1895
    97
    svgalib2 = open("/dev/svga", O_RDONLY);
slouken@1895
    98
    if (svgalib2 != -1) {
slouken@1895
    99
        close(svgalib2);
slouken@1895
   100
    }
slouken@67
   101
slouken@1895
   102
    return (((svgalib2 != -1) || (geteuid() == 0)) && (console >= 0));
slouken@0
   103
}
slouken@0
   104
slouken@1895
   105
static void
slouken@1895
   106
SVGA_DeleteDevice(SDL_VideoDevice * device)
slouken@0
   107
{
slouken@1895
   108
    SDL_free(device->hidden);
slouken@1895
   109
    SDL_free(device);
slouken@0
   110
}
slouken@0
   111
slouken@1895
   112
static SDL_VideoDevice *
slouken@1895
   113
SVGA_CreateDevice(int devindex)
slouken@0
   114
{
slouken@1895
   115
    SDL_VideoDevice *device;
slouken@0
   116
slouken@1895
   117
    /* Initialize all variables that we clean on shutdown */
slouken@1895
   118
    device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
slouken@1895
   119
    if (device) {
slouken@1895
   120
        SDL_memset(device, 0, (sizeof *device));
slouken@1895
   121
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@1895
   122
            SDL_malloc((sizeof *device->hidden));
slouken@1895
   123
    }
slouken@1895
   124
    if ((device == NULL) || (device->hidden == NULL)) {
slouken@1895
   125
        SDL_OutOfMemory();
slouken@1895
   126
        if (device) {
slouken@1895
   127
            SDL_free(device);
slouken@1895
   128
        }
slouken@1895
   129
        return (0);
slouken@1895
   130
    }
slouken@1895
   131
    SDL_memset(device->hidden, 0, (sizeof *device->hidden));
slouken@0
   132
slouken@1895
   133
    /* Set the function pointers */
slouken@1895
   134
    device->VideoInit = SVGA_VideoInit;
slouken@1895
   135
    device->ListModes = SVGA_ListModes;
slouken@1895
   136
    device->SetVideoMode = SVGA_SetVideoMode;
slouken@1895
   137
    device->SetColors = SVGA_SetColors;
slouken@1895
   138
    device->UpdateRects = NULL;
slouken@1895
   139
    device->VideoQuit = SVGA_VideoQuit;
slouken@1895
   140
    device->AllocHWSurface = SVGA_AllocHWSurface;
slouken@1895
   141
    device->CheckHWBlit = NULL;
slouken@1895
   142
    device->FillHWRect = NULL;
slouken@1895
   143
    device->SetHWColorKey = NULL;
slouken@1895
   144
    device->SetHWAlpha = NULL;
slouken@1895
   145
    device->LockHWSurface = SVGA_LockHWSurface;
slouken@1895
   146
    device->UnlockHWSurface = SVGA_UnlockHWSurface;
slouken@1895
   147
    device->FlipHWSurface = SVGA_FlipHWSurface;
slouken@1895
   148
    device->FreeHWSurface = SVGA_FreeHWSurface;
slouken@1895
   149
    device->SetCaption = NULL;
slouken@1895
   150
    device->SetIcon = NULL;
slouken@1895
   151
    device->IconifyWindow = NULL;
slouken@1895
   152
    device->GrabInput = NULL;
slouken@1895
   153
    device->GetWMInfo = NULL;
slouken@1895
   154
    device->InitOSKeymap = SVGA_InitOSKeymap;
slouken@1895
   155
    device->PumpEvents = SVGA_PumpEvents;
slouken@0
   156
slouken@1895
   157
    device->free = SVGA_DeleteDevice;
slouken@0
   158
slouken@1895
   159
    return device;
slouken@0
   160
}
slouken@0
   161
slouken@0
   162
VideoBootStrap SVGALIB_bootstrap = {
slouken@1895
   163
    "svgalib", "SVGAlib",
slouken@1895
   164
    SVGA_Available, SVGA_CreateDevice
slouken@0
   165
};
slouken@0
   166
slouken@1895
   167
static int
slouken@1895
   168
SVGA_AddMode(_THIS, int mode, int actually_add)
slouken@0
   169
{
slouken@1895
   170
    int i, j;
slouken@1895
   171
    vga_modeinfo *modeinfo;
slouken@0
   172
slouken@1895
   173
    modeinfo = vga_getmodeinfo(mode);
slouken@0
   174
slouken@1895
   175
    i = modeinfo->bytesperpixel - 1;
slouken@1895
   176
    if (i < 0) {
slouken@1895
   177
        return 0;
slouken@1895
   178
    }
slouken@1895
   179
    if (actually_add) {
slouken@1895
   180
        SDL_Rect saved_rect[2];
slouken@1895
   181
        int saved_mode[2];
slouken@1895
   182
        int b;
slouken@1556
   183
slouken@1895
   184
        /* Add the mode, sorted largest to smallest */
slouken@1895
   185
        b = 0;
slouken@1895
   186
        j = 0;
slouken@1895
   187
        while ((SDL_modelist[i][j]->w > modeinfo->width) ||
slouken@1895
   188
               (SDL_modelist[i][j]->h > modeinfo->height)) {
slouken@1895
   189
            ++j;
slouken@1895
   190
        }
slouken@1895
   191
        /* Skip modes that are already in our list */
slouken@1895
   192
        if ((SDL_modelist[i][j]->w == modeinfo->width) &&
slouken@1895
   193
            (SDL_modelist[i][j]->h == modeinfo->height)) {
slouken@1895
   194
            return (0);
slouken@1895
   195
        }
slouken@1895
   196
        /* Insert the new mode */
slouken@1895
   197
        saved_rect[b] = *SDL_modelist[i][j];
slouken@1895
   198
        saved_mode[b] = SDL_vgamode[i][j];
slouken@1895
   199
        SDL_modelist[i][j]->w = modeinfo->width;
slouken@1895
   200
        SDL_modelist[i][j]->h = modeinfo->height;
slouken@1895
   201
        SDL_vgamode[i][j] = mode;
slouken@1895
   202
        /* Everybody scoot down! */
slouken@1895
   203
        if (saved_rect[b].w && saved_rect[b].h) {
slouken@1895
   204
            for (++j; SDL_modelist[i][j]->w; ++j) {
slouken@1895
   205
                saved_rect[!b] = *SDL_modelist[i][j];
slouken@1895
   206
                saved_mode[!b] = SDL_vgamode[i][j];
slouken@1895
   207
                *SDL_modelist[i][j] = saved_rect[b];
slouken@1895
   208
                SDL_vgamode[i][j] = saved_mode[b];
slouken@1895
   209
                b = !b;
slouken@1895
   210
            }
slouken@1895
   211
            *SDL_modelist[i][j] = saved_rect[b];
slouken@1895
   212
            SDL_vgamode[i][j] = saved_mode[b];
slouken@1895
   213
        }
slouken@1895
   214
    } else {
slouken@1895
   215
        ++SDL_nummodes[i];
slouken@1895
   216
    }
slouken@1895
   217
    return (1);
slouken@0
   218
}
slouken@0
   219
slouken@1895
   220
static void
slouken@1895
   221
SVGA_UpdateVideoInfo(_THIS)
slouken@0
   222
{
slouken@1895
   223
    vga_modeinfo *modeinfo;
slouken@0
   224
slouken@1895
   225
    this->info.wm_available = 0;
slouken@1895
   226
    this->info.hw_available = (banked ? 0 : 1);
slouken@1895
   227
    modeinfo = vga_getmodeinfo(vga_getcurrentmode());
slouken@1895
   228
    this->info.video_mem = modeinfo->memory;
slouken@1895
   229
    /* FIXME: Add hardware accelerated blit information */
slouken@226
   230
#ifdef SVGALIB_DEBUG
slouken@1895
   231
    printf("Hardware accelerated blit: %savailable\n",
slouken@1895
   232
           modeinfo->haveblit ? "" : "not ");
slouken@0
   233
#endif
slouken@0
   234
}
slouken@0
   235
slouken@1895
   236
int
slouken@1895
   237
SVGA_VideoInit(_THIS, SDL_PixelFormat * vformat)
slouken@0
   238
{
slouken@1895
   239
    int keyboard;
slouken@1895
   240
    int i, j;
slouken@1895
   241
    int mode, total_modes;
slouken@0
   242
slouken@1895
   243
    /* Initialize all variables that we clean on shutdown */
slouken@1895
   244
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
   245
        SDL_nummodes[i] = 0;
slouken@1895
   246
        SDL_modelist[i] = NULL;
slouken@1895
   247
        SDL_vgamode[i] = NULL;
slouken@1895
   248
    }
slouken@0
   249
slouken@1895
   250
    /* Initialize the library */
slouken@1895
   251
    vga_disabledriverreport();
slouken@1895
   252
    if (vga_init() < 0) {
slouken@1895
   253
        SDL_SetError("Unable to initialize SVGAlib");
slouken@1895
   254
        return (-1);
slouken@1895
   255
    }
slouken@1895
   256
    vga_setmode(TEXT);
slouken@0
   257
slouken@1895
   258
    /* Enable mouse and keyboard support */
slouken@1895
   259
    vga_setmousesupport(1);
slouken@1895
   260
    keyboard = keyboard_init_return_fd();
slouken@1895
   261
    if (keyboard < 0) {
slouken@1895
   262
        SDL_SetError("Unable to initialize keyboard");
slouken@1895
   263
        return (-1);
slouken@1895
   264
    }
slouken@1895
   265
    if (SVGA_initkeymaps(keyboard) < 0) {
slouken@1895
   266
        return (-1);
slouken@1895
   267
    }
slouken@1895
   268
    keyboard_seteventhandler(SVGA_keyboardcallback);
slouken@0
   269
slouken@1895
   270
    /* Determine the current screen size */
slouken@1895
   271
    this->info.current_w = 0;
slouken@1895
   272
    this->info.current_h = 0;
slouken@1545
   273
slouken@1895
   274
    /* Determine the screen depth (use default 8-bit depth) */
slouken@1895
   275
    vformat->BitsPerPixel = 8;
slouken@0
   276
slouken@1895
   277
    /* Enumerate the available fullscreen modes */
slouken@1895
   278
    total_modes = 0;
slouken@1895
   279
    for (mode = vga_lastmodenumber(); mode; --mode) {
slouken@1895
   280
        if (vga_hasmode(mode)) {
slouken@1895
   281
            if (SVGA_AddMode(this, mode, 0)) {
slouken@1895
   282
                ++total_modes;
slouken@1895
   283
            }
slouken@1895
   284
        }
slouken@1895
   285
    }
slouken@1895
   286
    if (SVGA_AddMode(this, G320x200x256, 0))
slouken@1895
   287
        ++total_modes;
slouken@1895
   288
    if (total_modes == 0) {
slouken@1895
   289
        SDL_SetError("No linear video modes available");
slouken@1895
   290
        return (-1);
slouken@1895
   291
    }
slouken@1895
   292
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
   293
        SDL_vgamode[i] = (int *) SDL_malloc(SDL_nummodes[i] * sizeof(int));
slouken@1895
   294
        if (SDL_vgamode[i] == NULL) {
slouken@1895
   295
            SDL_OutOfMemory();
slouken@1895
   296
            return (-1);
slouken@1895
   297
        }
slouken@1895
   298
        SDL_modelist[i] = (SDL_Rect **)
slouken@1895
   299
            SDL_malloc((SDL_nummodes[i] + 1) * sizeof(SDL_Rect *));
slouken@1895
   300
        if (SDL_modelist[i] == NULL) {
slouken@1895
   301
            SDL_OutOfMemory();
slouken@1895
   302
            return (-1);
slouken@1895
   303
        }
slouken@1895
   304
        for (j = 0; j < SDL_nummodes[i]; ++j) {
slouken@1895
   305
            SDL_modelist[i][j] = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
slouken@1895
   306
            if (SDL_modelist[i][j] == NULL) {
slouken@1895
   307
                SDL_OutOfMemory();
slouken@1895
   308
                return (-1);
slouken@1895
   309
            }
slouken@1895
   310
            SDL_memset(SDL_modelist[i][j], 0, sizeof(SDL_Rect));
slouken@1895
   311
        }
slouken@1895
   312
        SDL_modelist[i][j] = NULL;
slouken@1895
   313
    }
slouken@1895
   314
    for (mode = vga_lastmodenumber(); mode; --mode) {
slouken@1895
   315
        if (vga_hasmode(mode)) {
slouken@1895
   316
            SVGA_AddMode(this, mode, 1);
slouken@1895
   317
        }
slouken@1895
   318
    }
slouken@1895
   319
    SVGA_AddMode(this, G320x200x256, 1);
slouken@0
   320
slouken@1895
   321
    /* Free extra (duplicated) modes */
slouken@1895
   322
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
   323
        j = 0;
slouken@1895
   324
        while (SDL_modelist[i][j] && SDL_modelist[i][j]->w) {
slouken@1895
   325
            j++;
slouken@1895
   326
        }
slouken@1895
   327
        while (SDL_modelist[i][j]) {
slouken@1895
   328
            SDL_free(SDL_modelist[i][j]);
slouken@1895
   329
            SDL_modelist[i][j] = NULL;
slouken@1895
   330
            j++;
slouken@1895
   331
        }
slouken@1895
   332
    }
slouken@0
   333
slouken@1895
   334
    /* Fill in our hardware acceleration capabilities */
slouken@1895
   335
    SVGA_UpdateVideoInfo(this);
slouken@0
   336
slouken@1895
   337
    /* We're done! */
slouken@1895
   338
    return (0);
slouken@0
   339
}
slouken@0
   340
slouken@1895
   341
SDL_Rect **
slouken@1895
   342
SVGA_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
slouken@0
   343
{
slouken@1895
   344
    return (SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1]);
slouken@0
   345
}
slouken@0
   346
slouken@0
   347
/* Various screen update functions available */
slouken@1895
   348
static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect * rects);
slouken@1895
   349
static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect * rects);
slouken@0
   350
slouken@1895
   351
SDL_Surface *
slouken@1895
   352
SVGA_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1895
   353
                  int width, int height, int bpp, Uint32 flags)
slouken@0
   354
{
slouken@1895
   355
    int mode;
slouken@1895
   356
    int vgamode;
slouken@1895
   357
    vga_modeinfo *modeinfo;
slouken@1895
   358
    int screenpage_len;
slouken@0
   359
slouken@1895
   360
    /* Free old pixels if we were in banked mode */
slouken@1895
   361
    if (banked && current->pixels) {
slouken@1895
   362
        free(current->pixels);
slouken@1895
   363
        current->pixels = NULL;
slouken@1895
   364
    }
slouken@1554
   365
slouken@1895
   366
    /* Try to set the requested linear video mode */
slouken@1895
   367
    bpp = (bpp + 7) / 8 - 1;
slouken@1895
   368
    for (mode = 0; SDL_modelist[bpp][mode]; ++mode) {
slouken@1895
   369
        if ((SDL_modelist[bpp][mode]->w == width) &&
slouken@1895
   370
            (SDL_modelist[bpp][mode]->h == height)) {
slouken@1895
   371
            break;
slouken@1895
   372
        }
slouken@1895
   373
    }
slouken@1895
   374
    if (SDL_modelist[bpp][mode] == NULL) {
slouken@1895
   375
        SDL_SetError("Couldn't find requested mode in list");
slouken@1895
   376
        return (NULL);
slouken@1895
   377
    }
slouken@1895
   378
    vgamode = SDL_vgamode[bpp][mode];
slouken@1895
   379
    vga_setmode(vgamode);
slouken@1895
   380
    vga_setpage(0);
slouken@0
   381
slouken@1895
   382
    if ((vga_setlinearaddressing() < 0) && (vgamode != G320x200x256)) {
slouken@1895
   383
        banked = 1;
slouken@1895
   384
    } else {
slouken@1895
   385
        banked = 0;
slouken@1895
   386
    }
slouken@0
   387
slouken@1895
   388
    modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]);
slouken@0
   389
slouken@1895
   390
    /* Update hardware acceleration info */
slouken@1895
   391
    SVGA_UpdateVideoInfo(this);
slouken@0
   392
slouken@1895
   393
    /* Allocate the new pixel format for the screen */
slouken@1895
   394
    bpp = (bpp + 1) * 8;
slouken@1895
   395
    if ((bpp == 16) && (modeinfo->colors == 32768)) {
slouken@1895
   396
        bpp = 15;
slouken@1895
   397
    }
slouken@1895
   398
    if (!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0)) {
slouken@1895
   399
        return (NULL);
slouken@1895
   400
    }
slouken@0
   401
slouken@1895
   402
    /* Set up the new mode framebuffer */
slouken@1895
   403
    current->flags = SDL_FULLSCREEN;
slouken@1895
   404
    if (!banked) {
slouken@1895
   405
        current->flags |= SDL_HWSURFACE;
slouken@1895
   406
    }
slouken@1895
   407
    if (bpp == 8) {
slouken@1895
   408
        /* FIXME: What about DirectColor? */
slouken@1895
   409
        current->flags |= SDL_HWPALETTE;
slouken@1895
   410
    }
slouken@1895
   411
    current->w = width;
slouken@1895
   412
    current->h = height;
slouken@1895
   413
    current->pitch = modeinfo->linewidth;
slouken@1895
   414
    if (banked) {
slouken@1895
   415
        current->pixels = SDL_malloc(current->h * current->pitch);
slouken@1895
   416
        if (!current->pixels) {
slouken@1895
   417
            SDL_OutOfMemory();
slouken@1895
   418
            return (NULL);
slouken@1895
   419
        }
slouken@1895
   420
    } else {
slouken@1895
   421
        current->pixels = vga_getgraphmem();
slouken@1895
   422
    }
slouken@205
   423
slouken@1895
   424
    /* set double-buffering */
slouken@1895
   425
    if ((flags & SDL_DOUBLEBUF) && !banked) {
slouken@1895
   426
        /* length of one screen page in bytes */
slouken@1895
   427
        screenpage_len = current->h * modeinfo->linewidth;
slouken@205
   428
slouken@1895
   429
        /* if start address should be aligned */
slouken@1895
   430
        if (modeinfo->linewidth_unit) {
slouken@1895
   431
            if (screenpage_len % modeinfo->linewidth_unit) {
slouken@1895
   432
                screenpage_len +=
slouken@1895
   433
                    modeinfo->linewidth_unit -
slouken@1895
   434
                    (screenpage_len % modeinfo->linewidth_unit);
slouken@1895
   435
            }
slouken@1895
   436
        }
slouken@205
   437
slouken@1895
   438
        /* if we heve enough videomemory =  ak je dost videopamete  */
slouken@1895
   439
        if (modeinfo->memory > (screenpage_len * 2 / 1024)) {
slouken@1895
   440
            current->flags |= SDL_DOUBLEBUF;
slouken@1895
   441
            flip_page = 0;
slouken@1895
   442
            flip_offset[0] = 0;
slouken@1895
   443
            flip_offset[1] = screenpage_len;
slouken@1895
   444
            flip_address[0] = vga_getgraphmem();
slouken@1895
   445
            flip_address[1] = flip_address[0] + screenpage_len;
slouken@1895
   446
            SVGA_FlipHWSurface(this, current);
slouken@1895
   447
        }
slouken@1895
   448
    }
slouken@0
   449
slouken@1895
   450
    /* Set the blit function */
slouken@1895
   451
    if (banked) {
slouken@1895
   452
        this->UpdateRects = SVGA_BankedUpdate;
slouken@1895
   453
    } else {
slouken@1895
   454
        this->UpdateRects = SVGA_DirectUpdate;
slouken@1895
   455
    }
slouken@0
   456
slouken@1895
   457
    /* Set up the mouse handler again (buggy SVGAlib 1.40) */
slouken@1895
   458
    mouse_seteventhandler(SVGA_mousecallback);
slouken@1895
   459
slouken@1895
   460
    /* We're done */
slouken@1895
   461
    return (current);
slouken@0
   462
}
slouken@0
   463
slouken@0
   464
/* We don't actually allow hardware surfaces other than the main one */
slouken@1895
   465
static int
slouken@1895
   466
SVGA_AllocHWSurface(_THIS, SDL_Surface * surface)
slouken@0
   467
{
slouken@1895
   468
    return (-1);
slouken@0
   469
}
slouken@2735
   470
slouken@1895
   471
static void
slouken@1895
   472
SVGA_FreeHWSurface(_THIS, SDL_Surface * surface)
slouken@0
   473
{
slouken@1895
   474
    return;
slouken@0
   475
}
slouken@0
   476
slouken@0
   477
/* We need to wait for vertical retrace on page flipped displays */
slouken@1895
   478
static int
slouken@1895
   479
SVGA_LockHWSurface(_THIS, SDL_Surface * surface)
slouken@0
   480
{
slouken@1895
   481
    /* The waiting is done in SVGA_FlipHWSurface() */
slouken@1895
   482
    return (0);
slouken@0
   483
}
slouken@2735
   484
slouken@1895
   485
static void
slouken@1895
   486
SVGA_UnlockHWSurface(_THIS, SDL_Surface * surface)
slouken@0
   487
{
slouken@1895
   488
    return;
slouken@0
   489
}
slouken@0
   490
slouken@1895
   491
static int
slouken@1895
   492
SVGA_FlipHWSurface(_THIS, SDL_Surface * surface)
slouken@0
   493
{
slouken@1895
   494
    if (!banked) {
slouken@1895
   495
        vga_setdisplaystart(flip_offset[flip_page]);
slouken@1895
   496
        flip_page = !flip_page;
slouken@1895
   497
        surface->pixels = flip_address[flip_page];
slouken@1895
   498
        vga_waitretrace();
slouken@1895
   499
    }
slouken@1895
   500
    return (0);
slouken@0
   501
}
slouken@0
   502
slouken@1895
   503
static void
slouken@1895
   504
SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect * rects)
slouken@0
   505
{
slouken@1895
   506
    return;
slouken@0
   507
}
slouken@0
   508
slouken@1895
   509
static void
slouken@1895
   510
SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect * rects)
slouken@0
   511
{
slouken@1895
   512
    int i, j;
slouken@1895
   513
    SDL_Rect *rect;
slouken@1895
   514
    int page, vp;
slouken@1895
   515
    int x, y, w, h;
slouken@1895
   516
    unsigned char *src;
slouken@1895
   517
    unsigned char *dst;
slouken@1895
   518
    int bpp = this->screen->format->BytesPerPixel;
slouken@1895
   519
    int pitch = this->screen->pitch;
slouken@1554
   520
slouken@1895
   521
    dst = vga_getgraphmem();
slouken@1895
   522
    for (i = 0; i < numrects; ++i) {
slouken@1895
   523
        rect = &rects[i];
slouken@1895
   524
        x = rect->x;
slouken@1895
   525
        y = rect->y;
slouken@1895
   526
        w = rect->w * bpp;
slouken@1895
   527
        h = rect->h;
slouken@1556
   528
slouken@1895
   529
        vp = y * pitch + x * bpp;
slouken@1895
   530
        src = (unsigned char *) this->screen->pixels + vp;
slouken@1895
   531
        page = vp >> 16;
slouken@1895
   532
        vp &= 0xffff;
slouken@1895
   533
        vga_setpage(page);
slouken@1895
   534
        for (j = 0; j < h; j++) {
slouken@1895
   535
            if (vp + w > 0x10000) {
slouken@1895
   536
                if (vp >= 0x10000) {
slouken@1895
   537
                    page++;
slouken@1895
   538
                    vga_setpage(page);
slouken@1895
   539
                    vp &= 0xffff;
slouken@1895
   540
                } else {
slouken@1895
   541
                    SDL_memcpy(dst + vp, src, 0x10000 - vp);
slouken@1895
   542
                    page++;
slouken@1895
   543
                    vga_setpage(page);
slouken@1895
   544
                    SDL_memcpy(dst, src + 0x10000 - vp, (vp + w) & 0xffff);
slouken@1895
   545
                    vp = (vp + pitch) & 0xffff;
slouken@1895
   546
                    src += pitch;
slouken@1895
   547
                    continue;
slouken@1895
   548
                }
slouken@1895
   549
            }
slouken@1895
   550
            SDL_memcpy(dst + vp, src, w);
slouken@1895
   551
            src += pitch;
slouken@1895
   552
            vp += pitch;
slouken@1895
   553
        }
slouken@1895
   554
    }
slouken@0
   555
}
slouken@0
   556
slouken@1895
   557
int
slouken@1895
   558
SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
slouken@0
   559
{
slouken@1895
   560
    int i;
slouken@0
   561
slouken@1895
   562
    for (i = 0; i < ncolors; i++) {
slouken@1895
   563
        vga_setpalette(firstcolor + i,
slouken@1895
   564
                       colors[i].r >> 2, colors[i].g >> 2, colors[i].b >> 2);
slouken@1895
   565
    }
slouken@1895
   566
    return (1);
slouken@0
   567
}
slouken@0
   568
slouken@0
   569
/* Note:  If we are terminated, this could be called in the middle of
slouken@0
   570
   another SDL video routine -- notably UpdateRects.
slouken@0
   571
*/
slouken@1895
   572
void
slouken@1895
   573
SVGA_VideoQuit(_THIS)
slouken@0
   574
{
slouken@1895
   575
    int i, j;
slouken@0
   576
slouken@1895
   577
    /* Reset the console video mode */
slouken@1895
   578
    if (this->screen && (this->screen->w && this->screen->h)) {
slouken@1895
   579
        vga_setmode(TEXT);
slouken@1895
   580
    }
slouken@1895
   581
    keyboard_close();
slouken@0
   582
slouken@1895
   583
    /* Free video mode lists */
slouken@1895
   584
    for (i = 0; i < NUM_MODELISTS; ++i) {
slouken@1895
   585
        if (SDL_modelist[i] != NULL) {
slouken@1895
   586
            for (j = 0; SDL_modelist[i][j]; ++j)
slouken@1895
   587
                SDL_free(SDL_modelist[i][j]);
slouken@1895
   588
            SDL_free(SDL_modelist[i]);
slouken@1895
   589
            SDL_modelist[i] = NULL;
slouken@1895
   590
        }
slouken@1895
   591
        if (SDL_vgamode[i] != NULL) {
slouken@1895
   592
            SDL_free(SDL_vgamode[i]);
slouken@1895
   593
            SDL_vgamode[i] = NULL;
slouken@1895
   594
        }
slouken@1895
   595
    }
slouken@1895
   596
    if (this->screen) {
slouken@1895
   597
        if (banked && this->screen->pixels) {
slouken@1895
   598
            SDL_free(this->screen->pixels);
slouken@1895
   599
        }
slouken@1895
   600
        this->screen->pixels = NULL;
slouken@1895
   601
    }
slouken@0
   602
}
slouken@205
   603
slouken@1895
   604
/* vi: set ts=4 sw=4 expandtab: */