/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2012 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ #include "SDL.h" #include "SDL_config.h" #include "SDL_mouse.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" #include "SDL_prizmvideo.h" #include "SDL_prizmevents_c.h" #include #include //#include "SDL_tinspireevents_c.h" static Uint16 prz_palette[256] = {0}; /* Initialization/Query functions */ static int PRZ_VideoInit(_THIS, SDL_PixelFormat *vformat); static SDL_Rect **PRZ_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); static SDL_Surface *PRZ_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); static int PRZ_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); static void PRZ_VideoQuit(_THIS); /* etc. */ static void PRZ_UpdateRects(_THIS, int numrects, SDL_Rect *rects); /* NSP driver bootstrap functions */ static int PRZ_Available(void) { return(1); } static void PRZ_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device->hidden); SDL_free(device); } static SDL_VideoDevice *PRZ_CreateDevice(int devindex) { SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); if ( device ) { SDL_memset(device, 0, (sizeof *device)); device->hidden = (struct SDL_PrivateVideoData *) SDL_malloc((sizeof *device->hidden)); } if ( (device == NULL) || (device->hidden == NULL) ) { SDL_OutOfMemory(); if ( device ) { SDL_free(device); } return(0); } SDL_memset(device->hidden, 0, (sizeof *device->hidden)); /* Set the function pointers */ device->VideoInit = PRZ_VideoInit; device->ListModes = PRZ_ListModes; device->SetVideoMode = PRZ_SetVideoMode; device->SetColors = PRZ_SetColors; device->UpdateRects = PRZ_UpdateRects; device->VideoQuit = PRZ_VideoQuit; device->InitOSKeymap = PRZ_InitOSKeymap; device->PumpEvents = PRZ_PumpEvents; device->free = PRZ_DeleteDevice; return device; } VideoBootStrap PRZ_bootstrap = { "prizm", "SDL Casio PRIZM video driver", PRZ_Available, PRZ_CreateDevice }; static int PRZ_VideoInit(_THIS, SDL_PixelFormat *vformat) { this->hidden->cx = (int) true; this->info.current_w = DWIDTH; this->info.current_h = DHEIGHT; if ( this->hidden->cx ) { vformat->BitsPerPixel = 16; vformat->Rmask = PRZ_RMASK16; vformat->Gmask = PRZ_GMASK16; vformat->Bmask = PRZ_BMASK16; } return(0); } static SDL_Rect **PRZ_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) { return (SDL_Rect **) -1; } static SDL_Surface *PRZ_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { Uint32 rmask, gmask, bmask; //NSP_DEBUG("Initializing display (%dx%dx%d)", width, height, bpp); //if ( flags != SDL_SWSURFACE ) // NSP_WARNING("Initializing with non-typical flags"); if ( width < DWIDTH || height < DHEIGHT ) { int win_x = (DWIDTH - width) / 2; int win_y = (DHEIGHT - height) / 2; this->hidden->offset = (int)PRZ_PIXEL_ADDR(0, win_x, win_y, 2 * DWIDTH, 2); this->hidden->win_x = win_x; } else this->hidden->offset = this->hidden->win_x = 0; if ( bpp == 16 ) { rmask = PRZ_RMASK16; gmask = PRZ_GMASK16; bmask = PRZ_BMASK16; } if ( this->hidden->buffer ) { SDL_free( this->hidden->buffer ); } this->hidden->buffer2 = SDL_malloc((bpp / 8) * DWIDTH * DHEIGHT); if ( ! this->hidden->buffer2 ) { //SDL_SetError("Couldn't allocate buffer2 for requested mode"); return(NULL); } this->hidden->buffer = SDL_malloc((bpp / 8) * width * height); if ( ! this->hidden->buffer ) { SDL_free(this->hidden->buffer2); //SDL_SetError("Couldn't allocate buffer for requested mode"); return(NULL); } memset(this->hidden->buffer2, 0, (bpp / 8) * DWIDTH * DHEIGHT); memset(this->hidden->buffer, 0, (bpp / 8) * width * height); /* Allocate the new pixel format for the screen */ if ( ! SDL_ReallocFormat(current, bpp, rmask, gmask, bmask, 0) ) { SDL_free(this->hidden->buffer); this->hidden->buffer = NULL; //SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } /* Set up the new mode framebuffer */ current->flags = flags; this->hidden->w = this->info.current_w = current->w = width; this->hidden->h = this->info.current_h = current->h = height; current->pitch = (bpp / 8) * current->w; current->pixels = this->hidden->buffer; //NSP_DEBUG("Done (0x%p)", current); /* We're done */ return(current); } #define PRZ_DRAW_LOOP(code) do { \ while ( rows-- ) { \ j = 0, k = 0; \ code \ src_addr += src_skip; \ dst_addr += dst_skip; \ } \ } while (0) static void PRZ_UpdateRects(_THIS, int numrects, SDL_Rect *rects) { int src_skip = SDL_VideoSurface->pitch; int dst_skip = (2 * DWIDTH); int i, j, k; if ( this->hidden->buffer2 == NULL ) return; for ( i = 0; i < numrects; ++i ) { SDL_Rect *rect = &rects[i]; Uint8 *src_addr, *dst_addr; SDL_bool odd_left, odd_right; int row_bytes, rows; if ( ! rect ) continue; src_addr = PRZ_PIXEL_ADDR(SDL_VideoSurface->pixels, rect->x, rect->y, SDL_VideoSurface->pitch, SDL_VideoSurface->format->BytesPerPixel); dst_addr = PRZ_PIXEL_ADDR(this->hidden->buffer2, rect->x, rect->y, 2 * DWIDTH, 2); dst_addr += this->hidden->offset; odd_left = (this->hidden->win_x + rect->x) & 1; odd_right = (this->hidden->win_x + rect->x + rect->w) & 1; row_bytes = SDL_VideoSurface->format->BytesPerPixel * ((rect->x + rect->w > DWIDTH) ? DWIDTH : rect->w); rows = (rect->y + rect->h > DHEIGHT) ? DHEIGHT : rect->h; if ( ! this->hidden->cx && odd_right ) --row_bytes; if ( this->hidden->cx ) { if ( SDL_VideoSurface->format->BitsPerPixel == 16 ) { /* 16 bpp SW, 16 bpp HW */ PRZ_DRAW_LOOP( SDL_memcpy(dst_addr, src_addr, row_bytes); ); } dupdate(); } } } #define PRZ_MAP_RGB(r, g, b) ((((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))) static int PRZ_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { int i; for ( i = firstcolor; i < firstcolor + ncolors; ++i ) prz_palette[i] = PRZ_MAP_RGB(colors[i].r, colors[i].g, colors[i].b); return(1); } /* Note: If we are terminated, this could be called in the middle of another SDL video routine -- notably UpdateRects. */ static void PRZ_VideoQuit(_THIS) { //NSP_DEBUG("Closing video"); }