1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    SDL - Simple DirectMedia Layer
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Copyright (C) 1997-2012 Sam Lantinga
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    This library is free software; you can redistribute it and/or
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    modify it under the terms of the GNU Lesser General Public
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    License as published by the Free Software Foundation; either
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    version 2.1 of the License, or (at your option) any later version.
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    This library is distributed in the hope that it will be useful,
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    but WITHOUT ANY WARRANTY; without even the implied warranty of
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Lesser General Public License for more details.
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    You should have received a copy of the GNU Lesser General Public
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    License along with this library; if not, write to the Free Software
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Sam Lantinga
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    slouken@libsdl.org
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_config.h"
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* AAlib based SDL video driver implementation.
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <unistd.h>
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sys/stat.h>
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_video.h"
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_mouse.h"
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "../SDL_sysvideo.h"
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "../SDL_pixels_c.h"
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "../../events/SDL_events_c.h"
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_aavideo.h"
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_aaevents_c.h"
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "SDL_aamouse_c.h"
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <aalib.h>
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Initialization/Query functions */
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_VideoInit(_THIS, SDL_PixelFormat *vformat);
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic SDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic SDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_VideoQuit(_THIS);
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Hardware surface functions */
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_AllocHWSurface(_THIS, SDL_Surface *surface);
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_LockHWSurface(_THIS, SDL_Surface *surface);
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_FlipHWSurface(_THIS, SDL_Surface *surface);
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_UnlockHWSurface(_THIS, SDL_Surface *surface);
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_FreeHWSurface(_THIS, SDL_Surface *surface);
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Cache the VideoDevice struct */
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic struct SDL_VideoDevice *local_this;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* AAlib driver bootstrap functions */
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_Available(void)
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return 1; /* Always available ! */
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_DeleteDevice(SDL_VideoDevice *device)
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_free(device->hidden);
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_free(device);
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic SDL_VideoDevice *AA_CreateDevice(int devindex)
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_VideoDevice *device;
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Initialize all variables that we clean on shutdown */
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( device ) {
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_memset(device, 0, (sizeof *device));
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		device->hidden = (struct SDL_PrivateVideoData *)
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott				SDL_malloc((sizeof *device->hidden));
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( (device == NULL) || (device->hidden == NULL) ) {
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_OutOfMemory();
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		if ( device ) {
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			SDL_free(device);
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		}
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return(0);
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Set the function pointers */
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->VideoInit = AA_VideoInit;
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->ListModes = AA_ListModes;
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetVideoMode = AA_SetVideoMode;
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->CreateYUVOverlay = NULL;
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetColors = AA_SetColors;
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->UpdateRects = NULL;
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->VideoQuit = AA_VideoQuit;
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->AllocHWSurface = AA_AllocHWSurface;
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->CheckHWBlit = NULL;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->FillHWRect = NULL;
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetHWColorKey = NULL;
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetHWAlpha = NULL;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->LockHWSurface = AA_LockHWSurface;
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->UnlockHWSurface = AA_UnlockHWSurface;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->FlipHWSurface = NULL;
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->FreeHWSurface = AA_FreeHWSurface;
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetCaption = NULL;
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->SetIcon = NULL;
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->IconifyWindow = NULL;
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->GrabInput = NULL;
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->GetWMInfo = NULL;
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->InitOSKeymap = AA_InitOSKeymap;
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->PumpEvents = AA_PumpEvents;
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	device->free = AA_DeleteDevice;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return device;
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottVideoBootStrap AALIB_bootstrap = {
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	"aalib", "ASCII Art Library",
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_Available, AA_CreateDevice
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott};
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_ResizeHandler(aa_context *);
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint AA_VideoInit(_THIS, SDL_PixelFormat *vformat)
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int keyboard;
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int i;
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Initialize all variables that we clean on shutdown */
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for ( i=0; i<SDL_NUMMODES; ++i ) {
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_modelist[i] = SDL_malloc(sizeof(SDL_Rect));
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_modelist[i]->x = SDL_modelist[i]->y = 0;
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Modes sorted largest to smallest */
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[0]->w = 1024; SDL_modelist[0]->h = 768;
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[1]->w = 800; SDL_modelist[1]->h = 600;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[2]->w = 640; SDL_modelist[2]->h = 480;
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[3]->w = 320; SDL_modelist[3]->h = 400;
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[4]->w = 320; SDL_modelist[4]->h = 240;
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[5]->w = 320; SDL_modelist[5]->h = 200;
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_modelist[6] = NULL;
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Initialize the library */
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_mutex = SDL_CreateMutex();
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_parseoptions (NULL, NULL, NULL, NULL);
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_context = aa_autoinit(&aa_defparams);
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( ! AA_context ) {
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_SetError("Unable to initialize AAlib");
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return(-1);
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Enable mouse and keyboard support */
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( ! aa_autoinitkbd (AA_context, AA_SENDRELEASE) ) {
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_SetError("Unable to initialize AAlib keyboard");
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return(-1);
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( ! aa_autoinitmouse (AA_context, AA_SENDRELEASE) ) {
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		fprintf(stderr,"Warning: Unable to initialize AAlib mouse");
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_rparams = aa_getrenderparams();
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	local_this = this;
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_resizehandler(AA_context, AA_ResizeHandler);
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fprintf(stderr,"Using AAlib driver: %s (%s)\n", AA_context->driver->name, AA_context->driver->shortname);
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_in_x11 = (SDL_strcmp(AA_context->driver->shortname,"X11") == 0);
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Determine the screen depth (use default 8-bit depth) */
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	vformat->BitsPerPixel = 8;
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	vformat->BytesPerPixel = 1;
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* We're done! */
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(0);
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSDL_Rect **AA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott     if(format->BitsPerPixel != 8)
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 		return NULL;
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 if ( flags & SDL_FULLSCREEN ) {
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		 return SDL_modelist;
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 } else {
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		 return (SDL_Rect **) -1;
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	 }
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* From aavga.c
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   AAlib does not give us the choice of the actual resolution, thus we have to simulate additional
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   resolution by scaling down manually each frame
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void fastscale (register char *b1, register char *b2, int x1, int x2, int y1, int y2)
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	register int ex, spx = 0, ddx, ddx1;
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int ddy1, ddy, spy = 0, ey;
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int x;
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	char *bb1 = b1;
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (!x1 || !x2 || !y1 || !y2)
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return;
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	ddx = x1 + x1;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	ddx1 = x2 + x2;
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (ddx1 < ddx)
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		spx = ddx / ddx1, ddx %= ddx1;
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	ddy = y1 + y1;
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	ddy1 = y2 + y2;
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if (ddy1 < ddy)
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		spy = (ddy / ddy1) * x1, ddy %= ddy1;
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	ey = -ddy1;
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for (; y2; y2--) {
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		ex = -ddx1;
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		for (x = x2; x; x--) {
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			*b2 = *b1;
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			b2++;
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			b1 += spx;
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			ex += ddx;
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			if (ex > 0) {
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott				b1++;
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott				ex -= ddx1;
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			}
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		}
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		bb1 += spy;
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		ey += ddy;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		if (ey > 0) {
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			bb1 += x1;
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			ey -= ddy1;
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		}
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		b1 = bb1;
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Various screen update functions available */
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSDL_Surface *AA_SetVideoMode(_THIS, SDL_Surface *current,
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott				int width, int height, int bpp, Uint32 flags)
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int mode;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( AA_buffer ) {
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_free( AA_buffer );
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_buffer = SDL_malloc(width * height);
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( ! AA_buffer ) {
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		SDL_SetError("Couldn't allocate buffer for requested mode");
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return(NULL);
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 	printf("Setting mode %dx%d\n", width, height); */
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_memset(aa_image(AA_context), 0, aa_imgwidth(AA_context) * aa_imgheight(AA_context));
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_memset(AA_buffer, 0, width * height);
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Allocate the new pixel format for the screen */
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	if ( ! SDL_ReallocFormat(current, 8, 0, 0, 0, 0) ) {
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		return(NULL);
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Set up the new mode framebuffer */
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	current->flags = SDL_FULLSCREEN;
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_w = current->w = width;
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_h = current->h = height;
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	current->pitch = current->w;
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	current->pixels = AA_buffer;
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_x_ratio = ((double)aa_imgwidth(AA_context)) / ((double)width);
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	AA_y_ratio = ((double)aa_imgheight(AA_context)) / ((double)height);
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Set the blit function */
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	this->UpdateRects = AA_DirectUpdate;
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* We're done */
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(current);
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_ResizeHandler(aa_context *context)
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_resize(context);
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	local_this->hidden->x_ratio = ((double)aa_imgwidth(context)) / ((double)local_this->screen->w);
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	local_this->hidden->y_ratio = ((double)aa_imgheight(context)) / ((double)local_this->screen->h);
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fastscale (local_this->hidden->buffer, aa_image(context), local_this->hidden->w, aa_imgwidth (context), local_this->hidden->h, aa_imgheight (context));
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_renderpalette(context, local_this->hidden->palette, local_this->hidden->rparams, 0, 0, aa_scrwidth(context), aa_scrheight(context));
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_flush(context);
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* We don't actually allow hardware surfaces other than the main one */
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_AllocHWSurface(_THIS, SDL_Surface *surface)
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(-1);
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_FreeHWSurface(_THIS, SDL_Surface *surface)
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return;
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* We need to wait for vertical retrace on page flipped displays */
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_LockHWSurface(_THIS, SDL_Surface *surface)
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* TODO ? */
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(0);
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_UnlockHWSurface(_THIS, SDL_Surface *surface)
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return;
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* FIXME: How is this done with AAlib? */
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic int AA_FlipHWSurface(_THIS, SDL_Surface *surface)
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_mutexP(AA_mutex);
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_flush(AA_context);
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_mutexV(AA_mutex);
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(0);
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void AA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int i;
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_Rect *rect;
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	fastscale (AA_buffer, aa_image(AA_context), AA_w, aa_imgwidth (AA_context), AA_h, aa_imgheight (AA_context));
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 1
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_renderpalette(AA_context, AA_palette, AA_rparams, 0, 0, aa_scrwidth(AA_context), aa_scrheight(AA_context));
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Render only the rectangles in the list */
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	printf("Update rects : ");
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for ( i=0; i < numrects; ++i ) {
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		rect = &rects[i];
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		printf("(%d,%d-%d,%d)", rect->x, rect->y, rect->w, rect->h);
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		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);
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	printf("\n");
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_mutexP(AA_mutex);
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_flush(AA_context);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_mutexV(AA_mutex);
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return;
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint AA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int i;
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for ( i=0; i < ncolors; i++ ) {
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	        aa_setpalette(AA_palette, firstcolor + i,
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			      colors[i].r>>2,
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			      colors[i].g>>2,
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			      colors[i].b>>2);
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	return(1);
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Note:  If we are terminated, this could be called in the middle of
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott   another SDL video routine -- notably UpdateRects.
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid AA_VideoQuit(_THIS)
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	int i;
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_uninitkbd(AA_context);
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_uninitmouse(AA_context);
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	/* Free video mode lists */
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	for ( i=0; i<SDL_NUMMODES; ++i ) {
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		if ( SDL_modelist[i] != NULL ) {
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			SDL_free(SDL_modelist[i]);
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott			SDL_modelist[i] = NULL;
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott		}
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	}
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	aa_close(AA_context);
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	SDL_DestroyMutex(AA_mutex);
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott	this->screen->pixels = NULL;
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott