2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SDL_config.h"
24 /* AAlib based SDL video driver implementation.
31 #include "SDL_video.h"
32 #include "SDL_mouse.h"
33 #include "../SDL_sysvideo.h"
34 #include "../SDL_pixels_c.h"
35 #include "../../events/SDL_events_c.h"
37 #include "SDL_aavideo.h"
38 #include "SDL_aaevents_c.h"
39 #include "SDL_aamouse_c.h"
43 /* Initialization/Query functions */
44 static int AA_VideoInit(_THIS, SDL_PixelFormat *vformat);
45 static SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
46 static SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
47 static int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
48 static void AA_VideoQuit(_THIS);
50 /* Hardware surface functions */
51 static int AA_AllocHWSurface(_THIS, SDL_Surface *surface);
52 static int AA_LockHWSurface(_THIS, SDL_Surface *surface);
53 static int AA_FlipHWSurface(_THIS, SDL_Surface *surface);
54 static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface);
55 static void AA_FreeHWSurface(_THIS, SDL_Surface *surface);
57 /* Cache the VideoDevice struct */
58 static struct SDL_VideoDevice *local_this;
60 /* AAlib driver bootstrap functions */
62 static int AA_Available(void)
64 return 1; /* Always available ! */
67 static void AA_DeleteDevice(SDL_VideoDevice *device)
69 SDL_free(device->hidden);
73 static SDL_VideoDevice *AA_CreateDevice(int devindex)
75 SDL_VideoDevice *device;
77 /* Initialize all variables that we clean on shutdown */
78 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
80 SDL_memset(device, 0, (sizeof *device));
81 device->hidden = (struct SDL_PrivateVideoData *)
82 SDL_malloc((sizeof *device->hidden));
84 if ( (device == NULL) || (device->hidden == NULL) ) {
91 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
93 /* Set the function pointers */
94 device->VideoInit = AA_VideoInit;
95 device->ListModes = AA_ListModes;
96 device->SetVideoMode = AA_SetVideoMode;
97 device->CreateYUVOverlay = NULL;
98 device->SetColors = AA_SetColors;
99 device->UpdateRects = NULL;
100 device->VideoQuit = AA_VideoQuit;
101 device->AllocHWSurface = AA_AllocHWSurface;
102 device->CheckHWBlit = NULL;
103 device->FillHWRect = NULL;
104 device->SetHWColorKey = NULL;
105 device->SetHWAlpha = NULL;
106 device->LockHWSurface = AA_LockHWSurface;
107 device->UnlockHWSurface = AA_UnlockHWSurface;
108 device->FlipHWSurface = NULL;
109 device->FreeHWSurface = AA_FreeHWSurface;
110 device->SetCaption = NULL;
111 device->SetIcon = NULL;
112 device->IconifyWindow = NULL;
113 device->GrabInput = NULL;
114 device->GetWMInfo = NULL;
115 device->InitOSKeymap = AA_InitOSKeymap;
116 device->PumpEvents = AA_PumpEvents;
118 device->free = AA_DeleteDevice;
123 VideoBootStrap AALIB_bootstrap = {
124 "aalib", "ASCII Art Library",
125 AA_Available, AA_CreateDevice
128 static void AA_ResizeHandler(aa_context *);
130 int AA_VideoInit(_THIS, SDL_PixelFormat *vformat)
135 /* Initialize all variables that we clean on shutdown */
136 for ( i=0; i<SDL_NUMMODES; ++i ) {
137 SDL_modelist[i] = SDL_malloc(sizeof(SDL_Rect));
138 SDL_modelist[i]->x = SDL_modelist[i]->y = 0;
140 /* Modes sorted largest to smallest */
141 SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768;
142 SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600;
143 SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480;
144 SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400;
145 SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240;
146 SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200;
147 SDL_modelist[6] = NULL;
149 /* Initialize the library */
151 AA_mutex = SDL_CreateMutex();
153 aa_parseoptions (NULL, NULL, NULL, NULL);
155 AA_context = aa_autoinit(&aa_defparams);
156 if ( ! AA_context ) {
157 SDL_SetError("Unable to initialize AAlib");
161 /* Enable mouse and keyboard support */
163 if ( ! aa_autoinitkbd (AA_context, AA_SENDRELEASE) ) {
164 SDL_SetError("Unable to initialize AAlib keyboard");
167 if ( ! aa_autoinitmouse (AA_context, AA_SENDRELEASE) ) {
168 fprintf(stderr,"Warning: Unable to initialize AAlib mouse");
170 AA_rparams = aa_getrenderparams();
174 aa_resizehandler(AA_context, AA_ResizeHandler);
176 fprintf(stderr,"Using AAlib driver: %s (%s)\n", AA_context->driver->name, AA_context->driver->shortname);
178 AA_in_x11 = (SDL_strcmp(AA_context->driver->shortname,"X11") == 0);
179 /* Determine the screen depth (use default 8-bit depth) */
180 vformat->BitsPerPixel = 8;
181 vformat->BytesPerPixel = 1;
187 SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
189 if(format->BitsPerPixel != 8)
192 if ( flags & SDL_FULLSCREEN ) {
195 return (SDL_Rect **) -1;
200 AAlib does not give us the choice of the actual resolution, thus we have to simulate additional
201 resolution by scaling down manually each frame
203 static void fastscale (register char *b1, register char *b2, int x1, int x2, int y1, int y2)
205 register int ex, spx = 0, ddx, ddx1;
206 int ddy1, ddy, spy = 0, ey;
209 if (!x1 || !x2 || !y1 || !y2)
214 spx = ddx / ddx1, ddx %= ddx1;
218 spy = (ddy / ddy1) * x1, ddy %= ddy1;
222 for (x = x2; x; x--) {
242 /* Various screen update functions available */
243 static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
245 SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current,
246 int width, int height, int bpp, Uint32 flags)
251 SDL_free( AA_buffer );
254 AA_buffer = SDL_malloc(width * height);
256 SDL_SetError("Couldn't allocate buffer for requested mode");
260 /* printf("Setting mode %dx%d\n", width, height); */
262 SDL_memset(aa_image(AA_context), 0, aa_imgwidth(AA_context) * aa_imgheight(AA_context));
263 SDL_memset(AA_buffer, 0, width * height);
265 /* Allocate the new pixel format for the screen */
266 if ( ! SDL_ReallocFormat(current, 8, 0, 0, 0, 0) ) {
270 /* Set up the new mode framebuffer */
271 current->flags = SDL_FULLSCREEN;
272 AA_w = current->w = width;
273 AA_h = current->h = height;
274 current->pitch = current->w;
275 current->pixels = AA_buffer;
277 AA_x_ratio = ((double)aa_imgwidth(AA_context)) / ((double)width);
278 AA_y_ratio = ((double)aa_imgheight(AA_context)) / ((double)height);
280 /* Set the blit function */
281 this->UpdateRects = AA_DirectUpdate;
287 static void AA_ResizeHandler(aa_context *context)
290 local_this->hidden->x_ratio = ((double)aa_imgwidth(context)) / ((double)local_this->screen->w);
291 local_this->hidden->y_ratio = ((double)aa_imgheight(context)) / ((double)local_this->screen->h);
293 fastscale (local_this->hidden->buffer, aa_image(context), local_this->hidden->w, aa_imgwidth (context), local_this->hidden->h, aa_imgheight (context));
294 aa_renderpalette(context, local_this->hidden->palette, local_this->hidden->rparams, 0, 0, aa_scrwidth(context), aa_scrheight(context));
298 /* We don't actually allow hardware surfaces other than the main one */
299 static int AA_AllocHWSurface(_THIS, SDL_Surface *surface)
303 static void AA_FreeHWSurface(_THIS, SDL_Surface *surface)
308 /* We need to wait for vertical retrace on page flipped displays */
309 static int AA_LockHWSurface(_THIS, SDL_Surface *surface)
314 static void AA_UnlockHWSurface(_THIS, SDL_Surface *surface)
319 /* FIXME: How is this done with AAlib? */
320 static int AA_FlipHWSurface(_THIS, SDL_Surface *surface)
322 SDL_mutexP(AA_mutex);
323 aa_flush(AA_context);
324 SDL_mutexV(AA_mutex);
328 static void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
333 fastscale (AA_buffer, aa_image(AA_context), AA_w, aa_imgwidth (AA_context), AA_h, aa_imgheight (AA_context));
335 aa_renderpalette(AA_context, AA_palette, AA_rparams, 0, 0, aa_scrwidth(AA_context), aa_scrheight(AA_context));
337 /* Render only the rectangles in the list */
338 printf("Update rects : ");
339 for ( i=0; i < numrects; ++i ) {
341 printf("(%d,%d-%d,%d)", rect->x, rect->y, rect->w, rect->h);
342 aa_renderpalette(AA_context, AA_palette, AA_rparams, rect->x * AA_x_ratio, rect->y * AA_y_ratio, rect->w * AA_x_ratio, rect->h * AA_y_ratio);
346 SDL_mutexP(AA_mutex);
347 aa_flush(AA_context);
348 SDL_mutexV(AA_mutex);
352 int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
356 for ( i=0; i < ncolors; i++ ) {
357 aa_setpalette(AA_palette, firstcolor + i,
365 /* Note: If we are terminated, this could be called in the middle of
366 another SDL video routine -- notably UpdateRects.
368 void AA_VideoQuit(_THIS)
372 aa_uninitkbd(AA_context);
373 aa_uninitmouse(AA_context);
375 /* Free video mode lists */
376 for ( i=0; i<SDL_NUMMODES; ++i ) {
377 if ( SDL_modelist[i] != NULL ) {
378 SDL_free(SDL_modelist[i]);
379 SDL_modelist[i] = NULL;
383 aa_close(AA_context);
385 SDL_DestroyMutex(AA_mutex);
387 this->screen->pixels = NULL;