Mercurial > sdl-ios-xcode
annotate src/video/fbcon/SDL_fbvideo.c @ 1555:780fd5b61df1
Fixed bug #89
Date: Sun, 23 Oct 2005 16:39:03 +0200
From: "A. Schmid" <sahib@phreaker.net>
Subject: [SDL] no software surfaces with svgalib driver?
Hi,
I noticed that the SDL (1.2.9) svgalib driver only makes use of linear
addressable (framebuffer) video modes. On older systems (like one of
mine), linear addressable modes are often not available.
Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is
unusable, since VESA only supports framebuffering for VBE 2.0 and later.
The changes necessary to add support for software surfaces seem to be
relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see
attached patch). The code worked fine for me, but it is no more than a
proof of concept and should be reviewed (probably has a memory leak when
switching modes). It also uses the vgagl library (included in the
svgalib package) and needs to be linked against it.
-Alex
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 12:05:16 +0000 |
parents | 8d9bb0cf2c2a |
children | 980d2a0dc2a3 |
rev | line source |
---|---|
0 | 1 /* |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
5 This library is free software; you can redistribute it and/or |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
7 License as published by the Free Software Foundation; either |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
10 This library is distributed in the hope that it will be useful, |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
19 Sam Lantinga |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
20 slouken@libsdl.org |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
1217
diff
changeset
|
21 */ |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1373
diff
changeset
|
22 #include "SDL_config.h" |
0 | 23 |
24 /* Framebuffer console based SDL video driver implementation. | |
25 */ | |
26 | |
27 #include <stdio.h> | |
28 #include <fcntl.h> | |
29 #include <unistd.h> | |
30 #include <sys/ioctl.h> | |
31 #include <sys/mman.h> | |
32 #include <asm/page.h> /* For definition of PAGE_SIZE */ | |
33 | |
34 #include "SDL_video.h" | |
35 #include "SDL_mouse.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
36 #include "../SDL_sysvideo.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
37 #include "../SDL_pixels_c.h" |
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
38 #include "../../events/SDL_events_c.h" |
0 | 39 #include "SDL_fbvideo.h" |
40 #include "SDL_fbmouse_c.h" | |
41 #include "SDL_fbevents_c.h" | |
42 #include "SDL_fb3dfx.h" | |
43 #include "SDL_fbmatrox.h" | |
133
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
44 #include "SDL_fbriva.h" |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
45 |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
46 /*#define FBCON_DEBUG*/ |
0 | 47 |
48 #if defined(i386) && defined(FB_TYPE_VGA_PLANES) | |
49 #define VGA16_FBCON_SUPPORT | |
1373
04499d3e1b6b
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
50 #include <sys/io.h> /* For ioperm() */ |
0 | 51 #ifndef FB_AUX_VGA_PLANES_VGA4 |
52 #define FB_AUX_VGA_PLANES_VGA4 0 | |
53 #endif | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
54 /* |
0 | 55 static inline void outb (unsigned char value, unsigned short port) |
56 { | |
57 __asm__ __volatile__ ("outb %b0,%w1"::"a" (value), "Nd" (port)); | |
58 } | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
59 */ |
0 | 60 #endif /* FB_TYPE_VGA_PLANES */ |
61 | |
62 /* A list of video resolutions that we query for (sorted largest to smallest) */ | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
6
diff
changeset
|
63 static const SDL_Rect checkres[] = { |
0 | 64 { 0, 0, 1600, 1200 }, /* 16 bpp: 0x11E, or 286 */ |
65 { 0, 0, 1408, 1056 }, /* 16 bpp: 0x19A, or 410 */ | |
66 { 0, 0, 1280, 1024 }, /* 16 bpp: 0x11A, or 282 */ | |
67 { 0, 0, 1152, 864 }, /* 16 bpp: 0x192, or 402 */ | |
68 { 0, 0, 1024, 768 }, /* 16 bpp: 0x117, or 279 */ | |
69 { 0, 0, 960, 720 }, /* 16 bpp: 0x18A, or 394 */ | |
70 { 0, 0, 800, 600 }, /* 16 bpp: 0x114, or 276 */ | |
71 { 0, 0, 768, 576 }, /* 16 bpp: 0x182, or 386 */ | |
330
5fed858d551c
Date: 03 Apr 2002 15:28:09 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
72 { 0, 0, 720, 576 }, /* PAL */ |
5fed858d551c
Date: 03 Apr 2002 15:28:09 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
73 { 0, 0, 720, 480 }, /* NTSC */ |
0 | 74 { 0, 0, 640, 480 }, /* 16 bpp: 0x111, or 273 */ |
75 { 0, 0, 640, 400 }, /* 8 bpp: 0x100, or 256 */ | |
76 { 0, 0, 512, 384 }, | |
77 { 0, 0, 320, 240 }, | |
78 { 0, 0, 320, 200 } | |
79 }; | |
91
e85e03f195b4
From: "Markus F.X.J. Oberhumer"
Sam Lantinga <slouken@lokigames.com>
parents:
6
diff
changeset
|
80 static const struct { |
0 | 81 int xres; |
82 int yres; | |
83 int pixclock; | |
84 int left; | |
85 int right; | |
86 int upper; | |
87 int lower; | |
88 int hslen; | |
89 int vslen; | |
90 int sync; | |
91 int vmode; | |
92 } vesa_timings[] = { | |
93 #ifdef USE_VESA_TIMINGS /* Only tested on Matrox Millenium I */ | |
94 { 640, 400, 39771, 48, 16, 39, 8, 96, 2, 2, 0 }, /* 70 Hz */ | |
95 { 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0, 0 }, /* 60 Hz */ | |
96 { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ | |
97 { 800, 600, 24038, 144, 24, 28, 8, 112, 6, 0, 0 }, /* 60 Hz */ | |
98 { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ | |
99 { 1024, 768, 15386, 160, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
100 { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
101 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ | |
102 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ | |
103 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ | |
104 #else | |
105 /* You can generate these timings from your XF86Config file using | |
106 the 'modeline2fb' perl script included with the fbset package. | |
107 These timings were generated for Matrox Millenium I, 15" monitor. | |
108 */ | |
109 { 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0, 2 }, /* 70 Hz */ | |
110 { 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0, 2 }, /* 72 Hz */ | |
111 { 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0, 0 }, /* 78 Hz */ | |
112 { 640, 400, 31746, 96, 32, 41, 1, 64, 3, 2, 0 }, /* 85 Hz */ | |
113 { 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0 }, /* 75 Hz */ | |
114 { 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */ | |
115 { 800, 600, 20000, 64, 56, 23, 37, 120, 6, 3, 0 }, /* 72 Hz */ | |
116 { 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */ | |
117 { 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0, 0 }, /* 70 Hz */ | |
118 { 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */ | |
119 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ | |
120 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ | |
121 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ | |
122 #endif | |
123 }; | |
124 | |
125 /* Initialization/Query functions */ | |
126 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
127 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
128 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
129 #ifdef VGA16_FBCON_SUPPORT | |
130 static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
131 #endif | |
132 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); | |
133 static void FB_VideoQuit(_THIS); | |
134 | |
135 /* Hardware surface functions */ | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
136 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size); |
0 | 137 static void FB_FreeHWSurfaces(_THIS); |
138 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface); | |
139 static int FB_LockHWSurface(_THIS, SDL_Surface *surface); | |
140 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
141 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface); | |
142 static void FB_WaitVBL(_THIS); | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
143 static void FB_WaitIdle(_THIS); |
0 | 144 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface); |
145 | |
146 /* Internal palette functions */ | |
147 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | |
148 struct fb_var_screeninfo *vinfo); | |
149 static void FB_RestorePalette(_THIS); | |
150 | |
151 /* FB driver bootstrap functions */ | |
152 | |
153 static int FB_Available(void) | |
154 { | |
155 int console; | |
156 const char *SDL_fbdev; | |
157 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
158 SDL_fbdev = SDL_getenv("SDL_FBDEV"); |
0 | 159 if ( SDL_fbdev == NULL ) { |
160 SDL_fbdev = "/dev/fb0"; | |
161 } | |
162 console = open(SDL_fbdev, O_RDWR, 0); | |
163 if ( console >= 0 ) { | |
164 close(console); | |
165 } | |
166 return(console >= 0); | |
167 } | |
168 | |
169 static void FB_DeleteDevice(SDL_VideoDevice *device) | |
170 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
171 SDL_free(device->hidden); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
172 SDL_free(device); |
0 | 173 } |
174 | |
175 static SDL_VideoDevice *FB_CreateDevice(int devindex) | |
176 { | |
177 SDL_VideoDevice *this; | |
178 | |
179 /* Initialize all variables that we clean on shutdown */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
180 this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); |
0 | 181 if ( this ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
182 SDL_memset(this, 0, (sizeof *this)); |
0 | 183 this->hidden = (struct SDL_PrivateVideoData *) |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
184 SDL_malloc((sizeof *this->hidden)); |
0 | 185 } |
186 if ( (this == NULL) || (this->hidden == NULL) ) { | |
187 SDL_OutOfMemory(); | |
188 if ( this ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
189 SDL_free(this); |
0 | 190 } |
191 return(0); | |
192 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
193 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); |
0 | 194 wait_vbl = FB_WaitVBL; |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
195 wait_idle = FB_WaitIdle; |
0 | 196 mouse_fd = -1; |
197 keyboard_fd = -1; | |
198 | |
199 /* Set the function pointers */ | |
200 this->VideoInit = FB_VideoInit; | |
201 this->ListModes = FB_ListModes; | |
202 this->SetVideoMode = FB_SetVideoMode; | |
203 this->SetColors = FB_SetColors; | |
204 this->UpdateRects = NULL; | |
205 this->VideoQuit = FB_VideoQuit; | |
206 this->AllocHWSurface = FB_AllocHWSurface; | |
207 this->CheckHWBlit = NULL; | |
208 this->FillHWRect = NULL; | |
209 this->SetHWColorKey = NULL; | |
210 this->SetHWAlpha = NULL; | |
211 this->LockHWSurface = FB_LockHWSurface; | |
212 this->UnlockHWSurface = FB_UnlockHWSurface; | |
213 this->FlipHWSurface = FB_FlipHWSurface; | |
214 this->FreeHWSurface = FB_FreeHWSurface; | |
215 this->SetCaption = NULL; | |
216 this->SetIcon = NULL; | |
217 this->IconifyWindow = NULL; | |
218 this->GrabInput = NULL; | |
219 this->GetWMInfo = NULL; | |
220 this->InitOSKeymap = FB_InitOSKeymap; | |
221 this->PumpEvents = FB_PumpEvents; | |
222 | |
223 this->free = FB_DeleteDevice; | |
224 | |
225 return this; | |
226 } | |
227 | |
228 VideoBootStrap FBCON_bootstrap = { | |
229 "fbcon", "Linux Framebuffer Console", | |
230 FB_Available, FB_CreateDevice | |
231 }; | |
232 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
233 #define FB_MODES_DB "/etc/fb.modes" |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
234 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
235 static int read_fbmodes_line(FILE*f, char* line, int length) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
236 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
237 int blank; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
238 char* c; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
239 int i; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
240 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
241 blank=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
242 /* find a relevant line */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
243 do |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
244 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
245 if (fgets(line,length,f)<=0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
246 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
247 c=line; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
248 while(((*c=='\t')||(*c==' '))&&(*c!=0)) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
249 c++; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
250 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
251 if ((*c=='\n')||(*c=='#')||(*c==0)) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
252 blank=1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
253 else |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
254 blank=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
255 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
256 while(blank); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
257 /* remove whitespace at the begining of the string */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
258 i=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
259 do |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
260 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
261 line[i]=c[i]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
262 i++; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
263 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
264 while(c[i]!=0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
265 return 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
266 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
267 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
268 static int read_fbmodes_mode(FILE *f, struct fb_var_screeninfo *vinfo) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
269 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
270 char line[1024]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
271 char option[256]; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
272 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
273 /* Find a "geometry" */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
274 do { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
275 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
276 return 0; |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
277 if (SDL_strncmp(line,"geometry",8)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
278 break; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
279 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
280 while(1); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
281 |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
282 SDL_sscanf(line, "geometry %d %d %d %d %d", &vinfo->xres, &vinfo->yres, |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
283 &vinfo->xres_virtual, &vinfo->yres_virtual, &vinfo->bits_per_pixel); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
284 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
285 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
286 |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
287 SDL_sscanf(line, "timings %d %d %d %d %d %d %d", &vinfo->pixclock, |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
288 &vinfo->left_margin, &vinfo->right_margin, &vinfo->upper_margin, |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
289 &vinfo->lower_margin, &vinfo->hsync_len, &vinfo->vsync_len); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
290 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
291 vinfo->sync=0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
292 vinfo->vmode=FB_VMODE_NONINTERLACED; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
293 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
294 /* Parse misc options */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
295 do { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
296 if (read_fbmodes_line(f, line, sizeof(line))==0) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
297 return 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
298 |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
299 if (SDL_strncmp(line,"hsync",5)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
300 SDL_sscanf(line,"hsync %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
301 if (SDL_strncmp(option,"high",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
302 vinfo->sync |= FB_SYNC_HOR_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
303 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
304 else if (SDL_strncmp(line,"vsync",5)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
305 SDL_sscanf(line,"vsync %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
306 if (SDL_strncmp(option,"high",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
307 vinfo->sync |= FB_SYNC_VERT_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
308 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
309 else if (SDL_strncmp(line,"csync",5)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
310 SDL_sscanf(line,"csync %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
311 if (SDL_strncmp(option,"high",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
312 vinfo->sync |= FB_SYNC_COMP_HIGH_ACT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
313 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
314 else if (SDL_strncmp(line,"extsync",5)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
315 SDL_sscanf(line,"extsync %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
316 if (SDL_strncmp(option,"true",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
317 vinfo->sync |= FB_SYNC_EXT; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
318 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
319 else if (SDL_strncmp(line,"laced",5)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
320 SDL_sscanf(line,"laced %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
321 if (SDL_strncmp(option,"true",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
322 vinfo->vmode |= FB_VMODE_INTERLACED; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
323 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
324 else if (SDL_strncmp(line,"double",6)==0) { |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
325 SDL_sscanf(line,"double %s",option); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
326 if (SDL_strncmp(option,"true",4)==0) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
327 vinfo->vmode |= FB_VMODE_DOUBLE; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
328 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
329 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
330 while(SDL_strncmp(line,"endmode",7)!=0); |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
331 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
332 return 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
333 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
334 |
0 | 335 static int FB_CheckMode(_THIS, struct fb_var_screeninfo *vinfo, |
336 int index, unsigned int *w, unsigned int *h) | |
337 { | |
338 int mode_okay; | |
339 | |
340 mode_okay = 0; | |
341 vinfo->bits_per_pixel = (index+1)*8; | |
342 vinfo->xres = *w; | |
343 vinfo->xres_virtual = *w; | |
344 vinfo->yres = *h; | |
345 vinfo->yres_virtual = *h; | |
346 vinfo->activate = FB_ACTIVATE_TEST; | |
347 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, vinfo) == 0 ) { | |
348 #ifdef FBCON_DEBUG | |
349 fprintf(stderr, "Checked mode %dx%d at %d bpp, got mode %dx%d at %d bpp\n", *w, *h, (index+1)*8, vinfo->xres, vinfo->yres, vinfo->bits_per_pixel); | |
350 #endif | |
351 if ( (((vinfo->bits_per_pixel+7)/8)-1) == index ) { | |
352 *w = vinfo->xres; | |
353 *h = vinfo->yres; | |
354 mode_okay = 1; | |
355 } | |
356 } | |
357 return mode_okay; | |
358 } | |
359 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
360 static int FB_AddMode(_THIS, int index, unsigned int w, unsigned int h, int check_timings) |
0 | 361 { |
362 SDL_Rect *mode; | |
363 int i; | |
364 int next_mode; | |
365 | |
366 /* Check to see if we already have this mode */ | |
367 if ( SDL_nummodes[index] > 0 ) { | |
368 mode = SDL_modelist[index][SDL_nummodes[index]-1]; | |
369 if ( (mode->w == w) && (mode->h == h) ) { | |
370 #ifdef FBCON_DEBUG | |
371 fprintf(stderr, "We already have mode %dx%d at %d bytes per pixel\n", w, h, index+1); | |
372 #endif | |
373 return(0); | |
374 } | |
375 } | |
376 | |
377 /* Only allow a mode if we have a valid timing for it */ | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
378 if ( check_timings ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
379 int found_timing = 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
380 for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
381 if ( (w == vesa_timings[i].xres) && |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
382 (h == vesa_timings[i].yres) && vesa_timings[i].pixclock ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
383 found_timing = 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
384 break; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
385 } |
0 | 386 } |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
387 if ( !found_timing ) { |
0 | 388 #ifdef FBCON_DEBUG |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
389 fprintf(stderr, "No valid timing line for mode %dx%d\n", w, h); |
0 | 390 #endif |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
391 return(0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
392 } |
0 | 393 } |
394 | |
395 /* Set up the new video mode rectangle */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
396 mode = (SDL_Rect *)SDL_malloc(sizeof *mode); |
0 | 397 if ( mode == NULL ) { |
398 SDL_OutOfMemory(); | |
399 return(-1); | |
400 } | |
401 mode->x = 0; | |
402 mode->y = 0; | |
403 mode->w = w; | |
404 mode->h = h; | |
405 #ifdef FBCON_DEBUG | |
406 fprintf(stderr, "Adding mode %dx%d at %d bytes per pixel\n", w, h, index+1); | |
407 #endif | |
408 | |
409 /* Allocate the new list of modes, and fill in the new mode */ | |
410 next_mode = SDL_nummodes[index]; | |
411 SDL_modelist[index] = (SDL_Rect **) | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
412 SDL_realloc(SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); |
0 | 413 if ( SDL_modelist[index] == NULL ) { |
414 SDL_OutOfMemory(); | |
415 SDL_nummodes[index] = 0; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
416 SDL_free(mode); |
0 | 417 return(-1); |
418 } | |
419 SDL_modelist[index][next_mode] = mode; | |
420 SDL_modelist[index][next_mode+1] = NULL; | |
421 SDL_nummodes[index]++; | |
422 | |
423 return(0); | |
424 } | |
425 | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
426 static int cmpmodes(const void *va, const void *vb) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
427 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
428 const SDL_Rect *a = *(const SDL_Rect**)va; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
429 const SDL_Rect *b = *(const SDL_Rect**)vb; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
430 if ( a->h == b->h ) |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
431 return b->w - a->w; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
432 else |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
433 return b->h - a->h; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
434 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
435 |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
436 static void FB_SortModes(_THIS) |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
437 { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
438 int i; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
439 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
440 if ( SDL_nummodes[i] > 0 ) { |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
441 SDL_qsort(SDL_modelist[i], SDL_nummodes[i], sizeof *SDL_modelist[i], cmpmodes); |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
442 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
443 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
444 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
445 |
0 | 446 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat) |
447 { | |
448 struct fb_fix_screeninfo finfo; | |
449 struct fb_var_screeninfo vinfo; | |
450 int i, j; | |
451 int current_index; | |
452 unsigned int current_w; | |
453 unsigned int current_h; | |
454 const char *SDL_fbdev; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
455 FILE *modesdb; |
0 | 456 |
457 /* Initialize the library */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
458 SDL_fbdev = SDL_getenv("SDL_FBDEV"); |
0 | 459 if ( SDL_fbdev == NULL ) { |
460 SDL_fbdev = "/dev/fb0"; | |
461 } | |
462 console_fd = open(SDL_fbdev, O_RDWR, 0); | |
463 if ( console_fd < 0 ) { | |
464 SDL_SetError("Unable to open %s", SDL_fbdev); | |
465 return(-1); | |
466 } | |
467 | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
468 #if !SDL_THREADS_DISABLED |
0 | 469 /* Create the hardware surface lock mutex */ |
470 hw_lock = SDL_CreateMutex(); | |
471 if ( hw_lock == NULL ) { | |
472 SDL_SetError("Unable to create lock mutex"); | |
473 FB_VideoQuit(this); | |
474 return(-1); | |
475 } | |
476 #endif | |
477 | |
478 /* Get the type of video hardware */ | |
479 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
480 SDL_SetError("Couldn't get console hardware info"); | |
481 FB_VideoQuit(this); | |
482 return(-1); | |
483 } | |
484 switch (finfo.type) { | |
485 case FB_TYPE_PACKED_PIXELS: | |
486 /* Supported, no worries.. */ | |
487 break; | |
488 #ifdef VGA16_FBCON_SUPPORT | |
489 case FB_TYPE_VGA_PLANES: | |
490 /* VGA16 is supported, but that's it */ | |
491 if ( finfo.type_aux == FB_AUX_VGA_PLANES_VGA4 ) { | |
492 if ( ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1) < 0 ) { | |
493 SDL_SetError("No I/O port permissions"); | |
494 FB_VideoQuit(this); | |
495 return(-1); | |
496 } | |
497 this->SetVideoMode = FB_SetVGA16Mode; | |
498 break; | |
499 } | |
500 /* Fall through to unsupported case */ | |
501 #endif /* VGA16_FBCON_SUPPORT */ | |
502 default: | |
503 SDL_SetError("Unsupported console hardware"); | |
504 FB_VideoQuit(this); | |
505 return(-1); | |
506 } | |
507 switch (finfo.visual) { | |
508 case FB_VISUAL_TRUECOLOR: | |
509 case FB_VISUAL_PSEUDOCOLOR: | |
510 case FB_VISUAL_STATIC_PSEUDOCOLOR: | |
511 case FB_VISUAL_DIRECTCOLOR: | |
512 break; | |
513 default: | |
514 SDL_SetError("Unsupported console hardware"); | |
515 FB_VideoQuit(this); | |
516 return(-1); | |
517 } | |
518 | |
519 /* Check if the user wants to disable hardware acceleration */ | |
520 { const char *fb_accel; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
521 fb_accel = SDL_getenv("SDL_FBACCEL"); |
0 | 522 if ( fb_accel ) { |
1341
d02b552e5304
Configure dynamically generates SDL_config.h
Sam Lantinga <slouken@libsdl.org>
parents:
1338
diff
changeset
|
523 finfo.accel = SDL_atoi(fb_accel); |
0 | 524 } |
525 } | |
526 | |
527 /* Memory map the device, compensating for buggy PPC mmap() */ | |
528 mapped_offset = (((long)finfo.smem_start) - | |
529 (((long)finfo.smem_start)&~(PAGE_SIZE-1))); | |
530 mapped_memlen = finfo.smem_len+mapped_offset; | |
531 mapped_mem = mmap(NULL, mapped_memlen, | |
532 PROT_READ|PROT_WRITE, MAP_SHARED, console_fd, 0); | |
533 if ( mapped_mem == (char *)-1 ) { | |
534 SDL_SetError("Unable to memory map the video hardware"); | |
535 mapped_mem = NULL; | |
536 FB_VideoQuit(this); | |
537 return(-1); | |
538 } | |
539 | |
540 /* Determine the current screen depth */ | |
541 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
542 SDL_SetError("Couldn't get console pixel format"); | |
543 FB_VideoQuit(this); | |
544 return(-1); | |
545 } | |
546 vformat->BitsPerPixel = vinfo.bits_per_pixel; | |
547 if ( vformat->BitsPerPixel < 8 ) { | |
548 /* Assuming VGA16, we handle this via a shadow framebuffer */ | |
549 vformat->BitsPerPixel = 8; | |
550 } | |
551 for ( i=0; i<vinfo.red.length; ++i ) { | |
552 vformat->Rmask <<= 1; | |
553 vformat->Rmask |= (0x00000001<<vinfo.red.offset); | |
554 } | |
555 for ( i=0; i<vinfo.green.length; ++i ) { | |
556 vformat->Gmask <<= 1; | |
557 vformat->Gmask |= (0x00000001<<vinfo.green.offset); | |
558 } | |
559 for ( i=0; i<vinfo.blue.length; ++i ) { | |
560 vformat->Bmask <<= 1; | |
561 vformat->Bmask |= (0x00000001<<vinfo.blue.offset); | |
562 } | |
563 saved_vinfo = vinfo; | |
564 | |
565 /* Save hardware palette, if needed */ | |
566 FB_SavePalette(this, &finfo, &vinfo); | |
567 | |
568 /* If the I/O registers are available, memory map them so we | |
569 can take advantage of any supported hardware acceleration. | |
570 */ | |
571 vinfo.accel_flags = 0; /* Temporarily reserve registers */ | |
572 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo); | |
573 if ( finfo.accel && finfo.mmio_len ) { | |
574 mapped_iolen = finfo.mmio_len; | |
575 mapped_io = mmap(NULL, mapped_iolen, PROT_READ|PROT_WRITE, | |
576 MAP_SHARED, console_fd, mapped_memlen); | |
577 if ( mapped_io == (char *)-1 ) { | |
578 /* Hmm, failed to memory map I/O registers */ | |
579 mapped_io = NULL; | |
580 } | |
581 } | |
582 | |
583 /* Query for the list of available video modes */ | |
584 current_w = vinfo.xres; | |
585 current_h = vinfo.yres; | |
586 current_index = ((vinfo.bits_per_pixel+7)/8)-1; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
587 modesdb = fopen(FB_MODES_DB, "r"); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
588 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
589 SDL_nummodes[i] = 0; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
590 SDL_modelist[i] = NULL; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
591 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
592 if ( SDL_getenv("SDL_FB_BROKEN_MODES") != NULL ) { |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
593 FB_AddMode(this, current_index, current_w, current_h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
594 } else if(modesdb) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
595 while ( read_fbmodes_mode(modesdb, &vinfo) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
596 for ( i=0; i<NUM_MODELISTS; ++i ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
597 unsigned int w, h; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
598 |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
599 /* See if we are querying for the current mode */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
600 w = vinfo.xres; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
601 h = vinfo.yres; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
602 if ( i == current_index ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
603 if ( (current_w > w) || (current_h > h) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
604 /* Only check once */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
605 FB_AddMode(this, i, current_w, current_h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
606 current_index = -1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
607 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
608 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
609 if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
610 FB_AddMode(this, i, w, h, 0); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
611 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
612 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
613 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
614 fclose(modesdb); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
615 FB_SortModes(this); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
616 } else { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
617 for ( i=0; i<NUM_MODELISTS; ++i ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
618 for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
619 unsigned int w, h; |
0 | 620 |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
621 /* See if we are querying for the current mode */ |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
622 w = checkres[j].w; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
623 h = checkres[j].h; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
624 if ( i == current_index ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
625 if ( (current_w > w) || (current_h > h) ) { |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
626 /* Only check once */ |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
627 FB_AddMode(this, i, current_w, current_h, 0); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
628 current_index = -1; |
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
629 } |
0 | 630 } |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
631 if ( FB_CheckMode(this, &vinfo, i, &w, &h) ) { |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
632 FB_AddMode(this, i, w, h, 1); |
941
5095c4a264aa
Date: Mon, 12 Jul 2004 14:17:47 -0500
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
633 } |
0 | 634 } |
635 } | |
636 } | |
637 | |
638 /* Fill in our hardware acceleration capabilities */ | |
1545
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
639 this->info.current_w = current_w; |
8d9bb0cf2c2a
Added current_w and current_h to the SDL_VideoInfo structure, which is set to the desktop resolution during video intialization, and then set to the current resolution when a video mode is set.
Sam Lantinga <slouken@libsdl.org>
parents:
1402
diff
changeset
|
640 this->info.current_h = current_h; |
0 | 641 this->info.wm_available = 0; |
642 this->info.hw_available = 1; | |
643 this->info.video_mem = finfo.smem_len/1024; | |
644 if ( mapped_io ) { | |
645 switch (finfo.accel) { | |
646 case FB_ACCEL_MATROX_MGA2064W: | |
647 case FB_ACCEL_MATROX_MGA1064SG: | |
648 case FB_ACCEL_MATROX_MGA2164W: | |
649 case FB_ACCEL_MATROX_MGA2164W_AGP: | |
650 case FB_ACCEL_MATROX_MGAG100: | |
651 /*case FB_ACCEL_MATROX_MGAG200: G200 acceleration broken! */ | |
652 case FB_ACCEL_MATROX_MGAG400: | |
653 #ifdef FBACCEL_DEBUG | |
654 printf("Matrox hardware accelerator!\n"); | |
655 #endif | |
656 FB_MatroxAccel(this, finfo.accel); | |
657 break; | |
658 case FB_ACCEL_3DFX_BANSHEE: | |
659 #ifdef FBACCEL_DEBUG | |
660 printf("3DFX hardware accelerator!\n"); | |
661 #endif | |
662 FB_3DfxAccel(this, finfo.accel); | |
663 break; | |
133
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
664 case FB_ACCEL_NV3: |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
665 case FB_ACCEL_NV4: |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
666 #ifdef FBACCEL_DEBUG |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
667 printf("NVidia hardware accelerator!\n"); |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
668 #endif |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
669 FB_RivaAccel(this, finfo.accel); |
5d4bafca35cd
Added support for hardware accelerated NVidia driver on framebuffer console
Sam Lantinga <slouken@libsdl.org>
parents:
106
diff
changeset
|
670 break; |
0 | 671 default: |
672 #ifdef FBACCEL_DEBUG | |
673 printf("Unknown hardware accelerator.\n"); | |
674 #endif | |
675 break; | |
676 } | |
677 } | |
678 | |
679 /* Enable mouse and keyboard support */ | |
680 if ( FB_OpenKeyboard(this) < 0 ) { | |
681 FB_VideoQuit(this); | |
682 return(-1); | |
683 } | |
684 if ( FB_OpenMouse(this) < 0 ) { | |
685 const char *sdl_nomouse; | |
686 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
687 sdl_nomouse = SDL_getenv("SDL_NOMOUSE"); |
0 | 688 if ( ! sdl_nomouse ) { |
689 SDL_SetError("Unable to open mouse"); | |
690 FB_VideoQuit(this); | |
691 return(-1); | |
692 } | |
693 } | |
694 | |
695 /* We're done! */ | |
696 return(0); | |
697 } | |
698 | |
699 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
700 { | |
701 return(SDL_modelist[((format->BitsPerPixel+7)/8)-1]); | |
702 } | |
703 | |
704 /* Various screen update functions available */ | |
705 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
706 #ifdef VGA16_FBCON_SUPPORT | |
707 static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects); | |
708 #endif | |
709 | |
710 #ifdef FBCON_DEBUG | |
711 static void print_vinfo(struct fb_var_screeninfo *vinfo) | |
712 { | |
713 fprintf(stderr, "Printing vinfo:\n"); | |
714 fprintf(stderr, "\txres: %d\n", vinfo->xres); | |
715 fprintf(stderr, "\tyres: %d\n", vinfo->yres); | |
716 fprintf(stderr, "\txres_virtual: %d\n", vinfo->xres_virtual); | |
717 fprintf(stderr, "\tyres_virtual: %d\n", vinfo->yres_virtual); | |
718 fprintf(stderr, "\txoffset: %d\n", vinfo->xoffset); | |
719 fprintf(stderr, "\tyoffset: %d\n", vinfo->yoffset); | |
720 fprintf(stderr, "\tbits_per_pixel: %d\n", vinfo->bits_per_pixel); | |
721 fprintf(stderr, "\tgrayscale: %d\n", vinfo->grayscale); | |
722 fprintf(stderr, "\tnonstd: %d\n", vinfo->nonstd); | |
723 fprintf(stderr, "\tactivate: %d\n", vinfo->activate); | |
724 fprintf(stderr, "\theight: %d\n", vinfo->height); | |
725 fprintf(stderr, "\twidth: %d\n", vinfo->width); | |
726 fprintf(stderr, "\taccel_flags: %d\n", vinfo->accel_flags); | |
727 fprintf(stderr, "\tpixclock: %d\n", vinfo->pixclock); | |
728 fprintf(stderr, "\tleft_margin: %d\n", vinfo->left_margin); | |
729 fprintf(stderr, "\tright_margin: %d\n", vinfo->right_margin); | |
730 fprintf(stderr, "\tupper_margin: %d\n", vinfo->upper_margin); | |
731 fprintf(stderr, "\tlower_margin: %d\n", vinfo->lower_margin); | |
732 fprintf(stderr, "\thsync_len: %d\n", vinfo->hsync_len); | |
733 fprintf(stderr, "\tvsync_len: %d\n", vinfo->vsync_len); | |
734 fprintf(stderr, "\tsync: %d\n", vinfo->sync); | |
735 fprintf(stderr, "\tvmode: %d\n", vinfo->vmode); | |
736 fprintf(stderr, "\tred: %d/%d\n", vinfo->red.length, vinfo->red.offset); | |
737 fprintf(stderr, "\tgreen: %d/%d\n", vinfo->green.length, vinfo->green.offset); | |
738 fprintf(stderr, "\tblue: %d/%d\n", vinfo->blue.length, vinfo->blue.offset); | |
739 fprintf(stderr, "\talpha: %d/%d\n", vinfo->transp.length, vinfo->transp.offset); | |
740 } | |
741 static void print_finfo(struct fb_fix_screeninfo *finfo) | |
742 { | |
743 fprintf(stderr, "Printing finfo:\n"); | |
744 fprintf(stderr, "\tsmem_start = %p\n", (char *)finfo->smem_start); | |
745 fprintf(stderr, "\tsmem_len = %d\n", finfo->smem_len); | |
746 fprintf(stderr, "\ttype = %d\n", finfo->type); | |
747 fprintf(stderr, "\ttype_aux = %d\n", finfo->type_aux); | |
748 fprintf(stderr, "\tvisual = %d\n", finfo->visual); | |
749 fprintf(stderr, "\txpanstep = %d\n", finfo->xpanstep); | |
750 fprintf(stderr, "\typanstep = %d\n", finfo->ypanstep); | |
751 fprintf(stderr, "\tywrapstep = %d\n", finfo->ywrapstep); | |
752 fprintf(stderr, "\tline_length = %d\n", finfo->line_length); | |
753 fprintf(stderr, "\tmmio_start = %p\n", (char *)finfo->mmio_start); | |
754 fprintf(stderr, "\tmmio_len = %d\n", finfo->mmio_len); | |
755 fprintf(stderr, "\taccel = %d\n", finfo->accel); | |
756 } | |
757 #endif | |
758 | |
759 static int choose_fbmodes_mode(struct fb_var_screeninfo *vinfo) | |
760 { | |
761 int matched; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
762 FILE *modesdb; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
763 struct fb_var_screeninfo cinfo; |
0 | 764 |
765 matched = 0; | |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
766 modesdb = fopen(FB_MODES_DB, "r"); |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
767 if ( modesdb ) { |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
768 /* Parse the mode definition file */ |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
769 while ( read_fbmodes_mode(modesdb, &cinfo) ) { |
1217
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
770 if ( (vinfo->xres == cinfo.xres && vinfo->yres == cinfo.yres) && |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
771 (!matched || (vinfo->bits_per_pixel == cinfo.bits_per_pixel)) ) { |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
772 vinfo->pixclock = cinfo.pixclock; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
773 vinfo->left_margin = cinfo.left_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
774 vinfo->right_margin = cinfo.right_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
775 vinfo->upper_margin = cinfo.upper_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
776 vinfo->lower_margin = cinfo.lower_margin; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
777 vinfo->hsync_len = cinfo.hsync_len; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
778 vinfo->vsync_len = cinfo.vsync_len; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
779 if ( matched ) { |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
780 break; |
ae9981987c2f
Oops, actually use the timings in the modes db. :)
Sam Lantinga <slouken@libsdl.org>
parents:
1215
diff
changeset
|
781 } |
1215
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
782 matched = 1; |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
783 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
784 } |
d082d2d66ec8
Added support for parsing /etc/fb.modes, based on Stephane Marchesin's patch
Sam Lantinga <slouken@libsdl.org>
parents:
1036
diff
changeset
|
785 fclose(modesdb); |
0 | 786 } |
787 return(matched); | |
788 } | |
789 | |
790 static int choose_vesa_mode(struct fb_var_screeninfo *vinfo) | |
791 { | |
792 int matched; | |
793 int i; | |
794 | |
795 /* Check for VESA timings */ | |
796 matched = 0; | |
797 for ( i=0; i<(sizeof(vesa_timings)/sizeof(vesa_timings[0])); ++i ) { | |
798 if ( (vinfo->xres == vesa_timings[i].xres) && | |
799 (vinfo->yres == vesa_timings[i].yres) ) { | |
800 #ifdef FBCON_DEBUG | |
801 fprintf(stderr, "Using VESA timings for %dx%d\n", | |
802 vinfo->xres, vinfo->yres); | |
803 #endif | |
804 if ( vesa_timings[i].pixclock ) { | |
805 vinfo->pixclock = vesa_timings[i].pixclock; | |
806 } | |
807 vinfo->left_margin = vesa_timings[i].left; | |
808 vinfo->right_margin = vesa_timings[i].right; | |
809 vinfo->upper_margin = vesa_timings[i].upper; | |
810 vinfo->lower_margin = vesa_timings[i].lower; | |
811 vinfo->hsync_len = vesa_timings[i].hslen; | |
812 vinfo->vsync_len = vesa_timings[i].vslen; | |
813 vinfo->sync = vesa_timings[i].sync; | |
814 vinfo->vmode = vesa_timings[i].vmode; | |
815 matched = 1; | |
816 break; | |
817 } | |
818 } | |
819 return(matched); | |
820 } | |
821 | |
822 #ifdef VGA16_FBCON_SUPPORT | |
823 static SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current, | |
824 int width, int height, int bpp, Uint32 flags) | |
825 { | |
826 struct fb_fix_screeninfo finfo; | |
827 struct fb_var_screeninfo vinfo; | |
828 | |
829 /* Set the terminal into graphics mode */ | |
830 if ( FB_EnterGraphicsMode(this) < 0 ) { | |
831 return(NULL); | |
832 } | |
833 | |
834 /* Restore the original palette */ | |
835 FB_RestorePalette(this); | |
836 | |
837 /* Set the video mode and get the final screen format */ | |
838 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
839 SDL_SetError("Couldn't get console screen info"); | |
840 return(NULL); | |
841 } | |
842 cache_vinfo = vinfo; | |
843 #ifdef FBCON_DEBUG | |
844 fprintf(stderr, "Printing actual vinfo:\n"); | |
845 print_vinfo(&vinfo); | |
846 #endif | |
847 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { | |
848 return(NULL); | |
849 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
850 current->format->palette->ncolors = 16; |
0 | 851 |
852 /* Get the fixed information about the console hardware. | |
853 This is necessary since finfo.line_length changes. | |
854 */ | |
855 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
856 SDL_SetError("Couldn't get console hardware info"); | |
857 return(NULL); | |
858 } | |
859 #ifdef FBCON_DEBUG | |
860 fprintf(stderr, "Printing actual finfo:\n"); | |
861 print_finfo(&finfo); | |
862 #endif | |
863 | |
864 /* Save hardware palette, if needed */ | |
865 FB_SavePalette(this, &finfo, &vinfo); | |
866 | |
867 /* Set up the new mode framebuffer */ | |
868 current->flags = SDL_FULLSCREEN; | |
869 current->w = vinfo.xres; | |
870 current->h = vinfo.yres; | |
871 current->pitch = current->w; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
872 current->pixels = SDL_malloc(current->h*current->pitch); |
0 | 873 |
874 /* Set the update rectangle function */ | |
875 this->UpdateRects = FB_VGA16Update; | |
876 | |
877 /* We're done */ | |
878 return(current); | |
879 } | |
880 #endif /* VGA16_FBCON_SUPPORT */ | |
881 | |
882 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, | |
883 int width, int height, int bpp, Uint32 flags) | |
884 { | |
885 struct fb_fix_screeninfo finfo; | |
886 struct fb_var_screeninfo vinfo; | |
887 int i; | |
888 Uint32 Rmask; | |
889 Uint32 Gmask; | |
890 Uint32 Bmask; | |
891 char *surfaces_mem; | |
892 int surfaces_len; | |
893 | |
894 /* Set the terminal into graphics mode */ | |
895 if ( FB_EnterGraphicsMode(this) < 0 ) { | |
896 return(NULL); | |
897 } | |
898 | |
899 /* Restore the original palette */ | |
900 FB_RestorePalette(this); | |
901 | |
902 /* Set the video mode and get the final screen format */ | |
903 if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) { | |
904 SDL_SetError("Couldn't get console screen info"); | |
905 return(NULL); | |
906 } | |
907 #ifdef FBCON_DEBUG | |
908 fprintf(stderr, "Printing original vinfo:\n"); | |
909 print_vinfo(&vinfo); | |
910 #endif | |
911 if ( (vinfo.xres != width) || (vinfo.yres != height) || | |
912 (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) { | |
913 vinfo.activate = FB_ACTIVATE_NOW; | |
914 vinfo.accel_flags = 0; | |
915 vinfo.bits_per_pixel = bpp; | |
916 vinfo.xres = width; | |
917 vinfo.xres_virtual = width; | |
918 vinfo.yres = height; | |
919 if ( flags & SDL_DOUBLEBUF ) { | |
920 vinfo.yres_virtual = height*2; | |
921 } else { | |
922 vinfo.yres_virtual = height; | |
923 } | |
924 vinfo.xoffset = 0; | |
925 vinfo.yoffset = 0; | |
926 vinfo.red.length = vinfo.red.offset = 0; | |
927 vinfo.green.length = vinfo.green.offset = 0; | |
928 vinfo.blue.length = vinfo.blue.offset = 0; | |
929 vinfo.transp.length = vinfo.transp.offset = 0; | |
930 if ( ! choose_fbmodes_mode(&vinfo) ) { | |
931 choose_vesa_mode(&vinfo); | |
932 } | |
933 #ifdef FBCON_DEBUG | |
934 fprintf(stderr, "Printing wanted vinfo:\n"); | |
935 print_vinfo(&vinfo); | |
936 #endif | |
937 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | |
938 vinfo.yres_virtual = height; | |
939 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | |
940 SDL_SetError("Couldn't set console screen info"); | |
941 return(NULL); | |
942 } | |
943 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
944 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
945 int maxheight; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
946 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
947 /* Figure out how much video memory is available */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
948 if ( flags & SDL_DOUBLEBUF ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
949 maxheight = height*2; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
950 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
951 maxheight = height; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
952 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
953 if ( vinfo.yres_virtual > maxheight ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
954 vinfo.yres_virtual = maxheight; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
955 } |
0 | 956 } |
957 cache_vinfo = vinfo; | |
958 #ifdef FBCON_DEBUG | |
959 fprintf(stderr, "Printing actual vinfo:\n"); | |
960 print_vinfo(&vinfo); | |
961 #endif | |
962 Rmask = 0; | |
963 for ( i=0; i<vinfo.red.length; ++i ) { | |
964 Rmask <<= 1; | |
965 Rmask |= (0x00000001<<vinfo.red.offset); | |
966 } | |
967 Gmask = 0; | |
968 for ( i=0; i<vinfo.green.length; ++i ) { | |
969 Gmask <<= 1; | |
970 Gmask |= (0x00000001<<vinfo.green.offset); | |
971 } | |
972 Bmask = 0; | |
973 for ( i=0; i<vinfo.blue.length; ++i ) { | |
974 Bmask <<= 1; | |
975 Bmask |= (0x00000001<<vinfo.blue.offset); | |
976 } | |
977 if ( ! SDL_ReallocFormat(current, vinfo.bits_per_pixel, | |
978 Rmask, Gmask, Bmask, 0) ) { | |
979 return(NULL); | |
980 } | |
981 | |
982 /* Get the fixed information about the console hardware. | |
983 This is necessary since finfo.line_length changes. | |
984 */ | |
985 if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) { | |
986 SDL_SetError("Couldn't get console hardware info"); | |
987 return(NULL); | |
988 } | |
989 | |
990 /* Save hardware palette, if needed */ | |
991 FB_SavePalette(this, &finfo, &vinfo); | |
992 | |
993 /* Set up the new mode framebuffer */ | |
994 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); | |
995 current->w = vinfo.xres; | |
996 current->h = vinfo.yres; | |
997 current->pitch = finfo.line_length; | |
998 current->pixels = mapped_mem+mapped_offset; | |
999 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1000 /* Set up the information for hardware surfaces */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1001 surfaces_mem = (char *)current->pixels + |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1002 vinfo.yres_virtual*current->pitch; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1003 surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1004 FB_FreeHWSurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1005 FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1006 |
0 | 1007 /* Let the application know we have a hardware palette */ |
1008 switch (finfo.visual) { | |
1009 case FB_VISUAL_PSEUDOCOLOR: | |
1010 current->flags |= SDL_HWPALETTE; | |
1011 break; | |
1012 default: | |
1013 break; | |
1014 } | |
1015 | |
1016 /* Update for double-buffering, if we can */ | |
1017 if ( flags & SDL_DOUBLEBUF ) { | |
1018 if ( vinfo.yres_virtual == (height*2) ) { | |
1019 current->flags |= SDL_DOUBLEBUF; | |
1020 flip_page = 0; | |
1021 flip_address[0] = (char *)current->pixels; | |
1022 flip_address[1] = (char *)current->pixels+ | |
1023 current->h*current->pitch; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1024 this->screen = current; |
0 | 1025 FB_FlipHWSurface(this, current); |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1026 this->screen = NULL; |
0 | 1027 } |
1028 } | |
1029 | |
1030 /* Set the update rectangle function */ | |
1031 this->UpdateRects = FB_DirectUpdate; | |
1032 | |
1033 /* We're done */ | |
1034 return(current); | |
1035 } | |
1036 | |
1037 #ifdef FBCON_DEBUG | |
1038 void FB_DumpHWSurfaces(_THIS) | |
1039 { | |
1040 vidmem_bucket *bucket; | |
1041 | |
1042 printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal); | |
1043 printf("\n"); | |
1044 printf(" Base Size\n"); | |
1045 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
1046 printf("Bucket: %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free"); | |
1047 if ( bucket->prev ) { | |
1048 if ( bucket->base != bucket->prev->base+bucket->prev->size ) { | |
1049 printf("Warning, corrupt bucket list! (prev)\n"); | |
1050 } | |
1051 } else { | |
1052 if ( bucket != &surfaces ) { | |
1053 printf("Warning, corrupt bucket list! (!prev)\n"); | |
1054 } | |
1055 } | |
1056 if ( bucket->next ) { | |
1057 if ( bucket->next->base != bucket->base+bucket->size ) { | |
1058 printf("Warning, corrupt bucket list! (next)\n"); | |
1059 } | |
1060 } | |
1061 } | |
1062 printf("\n"); | |
1063 } | |
1064 #endif | |
1065 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1066 static int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size) |
0 | 1067 { |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1068 vidmem_bucket *bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1069 |
0 | 1070 surfaces_memtotal = size; |
1071 surfaces_memleft = size; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1072 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1073 if ( surfaces_memleft > 0 ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1074 bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket)); |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1075 if ( bucket == NULL ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1076 SDL_OutOfMemory(); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1077 return(-1); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1078 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1079 bucket->prev = &surfaces; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1080 bucket->used = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1081 bucket->dirty = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1082 bucket->base = base; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1083 bucket->size = size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1084 bucket->next = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1085 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1086 bucket = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1087 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1088 |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1089 surfaces.prev = NULL; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1090 surfaces.used = 1; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1091 surfaces.dirty = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1092 surfaces.base = screen->pixels; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1093 surfaces.size = (unsigned int)((long)base - (long)surfaces.base); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1094 surfaces.next = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1095 screen->hwdata = (struct private_hwdata *)&surfaces; |
0 | 1096 return(0); |
1097 } | |
1098 static void FB_FreeHWSurfaces(_THIS) | |
1099 { | |
1100 vidmem_bucket *bucket, *freeable; | |
1101 | |
1102 bucket = surfaces.next; | |
1103 while ( bucket ) { | |
1104 freeable = bucket; | |
1105 bucket = bucket->next; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1106 SDL_free(freeable); |
0 | 1107 } |
1108 surfaces.next = NULL; | |
1109 } | |
1110 | |
1111 static int FB_AllocHWSurface(_THIS, SDL_Surface *surface) | |
1112 { | |
1113 vidmem_bucket *bucket; | |
1114 int size; | |
1115 int extra; | |
1116 | |
1117 /* Temporarily, we only allow surfaces the same width as display. | |
1118 Some blitters require the pitch between two hardware surfaces | |
1119 to be the same. Others have interesting alignment restrictions. | |
1120 Until someone who knows these details looks at the code... | |
1121 */ | |
1122 if ( surface->pitch > SDL_VideoSurface->pitch ) { | |
1123 SDL_SetError("Surface requested wider than screen"); | |
1124 return(-1); | |
1125 } | |
1126 surface->pitch = SDL_VideoSurface->pitch; | |
1127 size = surface->h * surface->pitch; | |
1128 #ifdef FBCON_DEBUG | |
1129 fprintf(stderr, "Allocating bucket of %d bytes\n", size); | |
1130 #endif | |
1131 | |
1132 /* Quick check for available mem */ | |
1133 if ( size > surfaces_memleft ) { | |
1134 SDL_SetError("Not enough video memory"); | |
1135 return(-1); | |
1136 } | |
1137 | |
1138 /* Search for an empty bucket big enough */ | |
1139 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
1140 if ( ! bucket->used && (size <= bucket->size) ) { | |
1141 break; | |
1142 } | |
1143 } | |
1144 if ( bucket == NULL ) { | |
1145 SDL_SetError("Video memory too fragmented"); | |
1146 return(-1); | |
1147 } | |
1148 | |
1149 /* Create a new bucket for left-over memory */ | |
1150 extra = (bucket->size - size); | |
1151 if ( extra ) { | |
1152 vidmem_bucket *newbucket; | |
1153 | |
1154 #ifdef FBCON_DEBUG | |
1155 fprintf(stderr, "Adding new free bucket of %d bytes\n", extra); | |
1156 #endif | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1157 newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket)); |
0 | 1158 if ( newbucket == NULL ) { |
1159 SDL_OutOfMemory(); | |
1160 return(-1); | |
1161 } | |
1162 newbucket->prev = bucket; | |
1163 newbucket->used = 0; | |
1164 newbucket->base = bucket->base+size; | |
1165 newbucket->size = extra; | |
1166 newbucket->next = bucket->next; | |
1167 if ( bucket->next ) { | |
1168 bucket->next->prev = newbucket; | |
1169 } | |
1170 bucket->next = newbucket; | |
1171 } | |
1172 | |
1173 /* Set the current bucket values and return it! */ | |
1174 bucket->used = 1; | |
1175 bucket->size = size; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1176 bucket->dirty = 0; |
0 | 1177 #ifdef FBCON_DEBUG |
1178 fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base); | |
1179 #endif | |
1180 surfaces_memleft -= size; | |
1181 surface->flags |= SDL_HWSURFACE; | |
1182 surface->pixels = bucket->base; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1183 surface->hwdata = (struct private_hwdata *)bucket; |
0 | 1184 return(0); |
1185 } | |
1186 static void FB_FreeHWSurface(_THIS, SDL_Surface *surface) | |
1187 { | |
1188 vidmem_bucket *bucket, *freeable; | |
1189 | |
1190 /* Look for the bucket in the current list */ | |
1191 for ( bucket=&surfaces; bucket; bucket=bucket->next ) { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1192 if ( bucket == (vidmem_bucket *)surface->hwdata ) { |
0 | 1193 break; |
1194 } | |
1195 } | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1196 if ( bucket && bucket->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1197 /* Add the memory back to the total */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1198 #ifdef DGA_DEBUG |
0 | 1199 printf("Freeing bucket of %d bytes\n", bucket->size); |
1200 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1201 surfaces_memleft += bucket->size; |
0 | 1202 |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1203 /* Can we merge the space with surrounding buckets? */ |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1204 bucket->used = 0; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1205 if ( bucket->next && ! bucket->next->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1206 #ifdef DGA_DEBUG |
0 | 1207 printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size); |
1208 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1209 freeable = bucket->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1210 bucket->size += bucket->next->size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1211 bucket->next = bucket->next->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1212 if ( bucket->next ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1213 bucket->next->prev = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1214 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1215 SDL_free(freeable); |
0 | 1216 } |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1217 if ( bucket->prev && ! bucket->prev->used ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1218 #ifdef DGA_DEBUG |
0 | 1219 printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size); |
1220 #endif | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1221 freeable = bucket; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1222 bucket->prev->size += bucket->size; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1223 bucket->prev->next = bucket->next; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1224 if ( bucket->next ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1225 bucket->next->prev = bucket->prev; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1226 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1227 SDL_free(freeable); |
0 | 1228 } |
1229 } | |
1230 surface->pixels = NULL; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1231 surface->hwdata = NULL; |
0 | 1232 } |
1233 static int FB_LockHWSurface(_THIS, SDL_Surface *surface) | |
1234 { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1235 if ( surface == this->screen ) { |
0 | 1236 SDL_mutexP(hw_lock); |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1237 if ( FB_IsSurfaceBusy(surface) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1238 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1239 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1240 } else { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1241 if ( FB_IsSurfaceBusy(surface) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1242 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1243 } |
0 | 1244 } |
1245 return(0); | |
1246 } | |
1247 static void FB_UnlockHWSurface(_THIS, SDL_Surface *surface) | |
1248 { | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1249 if ( surface == this->screen ) { |
0 | 1250 SDL_mutexV(hw_lock); |
1251 } | |
1252 } | |
1253 | |
1254 static void FB_WaitVBL(_THIS) | |
1255 { | |
1256 #ifdef FBIOWAITRETRACE /* Heheh, this didn't make it into the main kernel */ | |
1257 ioctl(console_fd, FBIOWAITRETRACE, 0); | |
1258 #endif | |
1259 return; | |
1260 } | |
1261 | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1262 static void FB_WaitIdle(_THIS) |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1263 { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1264 return; |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1265 } |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1266 |
0 | 1267 static int FB_FlipHWSurface(_THIS, SDL_Surface *surface) |
1268 { | |
1269 /* Wait for vertical retrace and then flip display */ | |
1270 cache_vinfo.yoffset = flip_page*surface->h; | |
106
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1271 if ( FB_IsSurfaceBusy(this->screen) ) { |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1272 FB_WaitBusySurfaces(this); |
63ec24e0575f
Merged DGA video surface handling improvements, unified locking code.
Sam Lantinga <slouken@lokigames.com>
parents:
91
diff
changeset
|
1273 } |
0 | 1274 wait_vbl(this); |
1275 if ( ioctl(console_fd, FBIOPAN_DISPLAY, &cache_vinfo) < 0 ) { | |
1276 SDL_SetError("ioctl(FBIOPAN_DISPLAY) failed"); | |
1277 return(-1); | |
1278 } | |
1279 flip_page = !flip_page; | |
1280 | |
1281 surface->pixels = flip_address[flip_page]; | |
1282 return(0); | |
1283 } | |
1284 | |
1285 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
1286 { | |
1287 /* The application is already updating the visible video memory */ | |
1288 return; | |
1289 } | |
1290 | |
1291 #ifdef VGA16_FBCON_SUPPORT | |
1292 /* Code adapted with thanks from the XFree86 VGA16 driver! :) */ | |
1293 #define writeGr(index, value) \ | |
1294 outb(index, 0x3CE); \ | |
1295 outb(value, 0x3CF); | |
1296 #define writeSeq(index, value) \ | |
1297 outb(index, 0x3C4); \ | |
1298 outb(value, 0x3C5); | |
1299 | |
1300 static void FB_VGA16Update(_THIS, int numrects, SDL_Rect *rects) | |
1301 { | |
1302 SDL_Surface *screen; | |
1303 int width, height, FBPitch, left, i, j, SRCPitch, phase; | |
1304 register Uint32 m; | |
1305 Uint8 s1, s2, s3, s4; | |
1306 Uint32 *src, *srcPtr; | |
1307 Uint8 *dst, *dstPtr; | |
1308 | |
1309 screen = this->screen; | |
1310 FBPitch = screen->w >> 3; | |
1311 SRCPitch = screen->pitch >> 2; | |
1312 | |
1313 writeGr(0x03, 0x00); | |
1314 writeGr(0x05, 0x00); | |
1315 writeGr(0x01, 0x00); | |
1316 writeGr(0x08, 0xFF); | |
1317 | |
1318 while(numrects--) { | |
1319 left = rects->x & ~7; | |
1320 width = (rects->w + 7) >> 3; | |
1321 height = rects->h; | |
1322 src = (Uint32*)screen->pixels + (rects->y * SRCPitch) + (left >> 2); | |
1323 dst = (Uint8*)mapped_mem + (rects->y * FBPitch) + (left >> 3); | |
1324 | |
1325 if((phase = (long)dst & 3L)) { | |
1326 phase = 4 - phase; | |
1327 if(phase > width) phase = width; | |
1328 width -= phase; | |
1329 } | |
1330 | |
1331 while(height--) { | |
1332 writeSeq(0x02, 1 << 0); | |
1333 dstPtr = dst; | |
1334 srcPtr = src; | |
1335 i = width; | |
1336 j = phase; | |
1337 while(j--) { | |
1338 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1339 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1340 srcPtr += 2; | |
1341 } | |
1342 while(i >= 4) { | |
1343 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1344 s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1345 m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4); | |
1346 s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1347 m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4); | |
1348 s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1349 m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4); | |
1350 s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1351 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1352 srcPtr += 8; | |
1353 dstPtr += 4; | |
1354 i -= 4; | |
1355 } | |
1356 while(i--) { | |
1357 m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); | |
1358 *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); | |
1359 srcPtr += 2; | |
1360 } | |
1361 | |
1362 writeSeq(0x02, 1 << 1); | |
1363 dstPtr = dst; | |
1364 srcPtr = src; | |
1365 i = width; | |
1366 j = phase; | |
1367 while(j--) { | |
1368 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1369 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1370 srcPtr += 2; | |
1371 } | |
1372 while(i >= 4) { | |
1373 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1374 s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1375 m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4); | |
1376 s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1377 m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4); | |
1378 s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1379 m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4); | |
1380 s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1381 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1382 srcPtr += 8; | |
1383 dstPtr += 4; | |
1384 i -= 4; | |
1385 } | |
1386 while(i--) { | |
1387 m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); | |
1388 *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); | |
1389 srcPtr += 2; | |
1390 } | |
1391 | |
1392 writeSeq(0x02, 1 << 2); | |
1393 dstPtr = dst; | |
1394 srcPtr = src; | |
1395 i = width; | |
1396 j = phase; | |
1397 while(j--) { | |
1398 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1399 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1400 srcPtr += 2; | |
1401 } | |
1402 while(i >= 4) { | |
1403 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1404 s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1405 m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4); | |
1406 s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1407 m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4); | |
1408 s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1409 m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4); | |
1410 s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1411 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1412 srcPtr += 8; | |
1413 dstPtr += 4; | |
1414 i -= 4; | |
1415 } | |
1416 while(i--) { | |
1417 m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); | |
1418 *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); | |
1419 srcPtr += 2; | |
1420 } | |
1421 | |
1422 writeSeq(0x02, 1 << 3); | |
1423 dstPtr = dst; | |
1424 srcPtr = src; | |
1425 i = width; | |
1426 j = phase; | |
1427 while(j--) { | |
1428 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1429 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1430 srcPtr += 2; | |
1431 } | |
1432 while(i >= 4) { | |
1433 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1434 s1 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1435 m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4); | |
1436 s2 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1437 m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4); | |
1438 s3 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1439 m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4); | |
1440 s4 = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1441 *((Uint32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); | |
1442 srcPtr += 8; | |
1443 dstPtr += 4; | |
1444 i -= 4; | |
1445 } | |
1446 while(i--) { | |
1447 m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); | |
1448 *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; | |
1449 srcPtr += 2; | |
1450 } | |
1451 | |
1452 dst += FBPitch; | |
1453 src += SRCPitch; | |
1454 } | |
1455 rects++; | |
1456 } | |
1457 } | |
1458 #endif /* VGA16_FBCON_SUPPORT */ | |
1459 | |
1460 void FB_SavePaletteTo(_THIS, int palette_len, __u16 *area) | |
1461 { | |
1462 struct fb_cmap cmap; | |
1463 | |
1464 cmap.start = 0; | |
1465 cmap.len = palette_len; | |
1466 cmap.red = &area[0*palette_len]; | |
1467 cmap.green = &area[1*palette_len]; | |
1468 cmap.blue = &area[2*palette_len]; | |
1469 cmap.transp = NULL; | |
1470 ioctl(console_fd, FBIOGETCMAP, &cmap); | |
1471 } | |
1472 | |
1473 void FB_RestorePaletteFrom(_THIS, int palette_len, __u16 *area) | |
1474 { | |
1475 struct fb_cmap cmap; | |
1476 | |
1477 cmap.start = 0; | |
1478 cmap.len = palette_len; | |
1479 cmap.red = &area[0*palette_len]; | |
1480 cmap.green = &area[1*palette_len]; | |
1481 cmap.blue = &area[2*palette_len]; | |
1482 cmap.transp = NULL; | |
1483 ioctl(console_fd, FBIOPUTCMAP, &cmap); | |
1484 } | |
1485 | |
1486 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | |
1487 struct fb_var_screeninfo *vinfo) | |
1488 { | |
1489 int i; | |
1490 | |
1491 /* Save hardware palette, if needed */ | |
1492 if ( finfo->visual == FB_VISUAL_PSEUDOCOLOR ) { | |
1493 saved_cmaplen = 1<<vinfo->bits_per_pixel; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1494 saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap)); |
0 | 1495 if ( saved_cmap != NULL ) { |
1496 FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); | |
1497 } | |
1498 } | |
1499 | |
1500 /* Added support for FB_VISUAL_DIRECTCOLOR. | |
1501 With this mode pixel information is passed through the palette... | |
1502 Neat fading and gamma correction effects can be had by simply | |
1503 fooling around with the palette instead of changing the pixel | |
1504 values themselves... Very neat! | |
1505 | |
1506 Adam Meyerowitz 1/19/2000 | |
1507 ameyerow@optonline.com | |
1508 */ | |
1509 if ( finfo->visual == FB_VISUAL_DIRECTCOLOR ) { | |
1510 __u16 new_entries[3*256]; | |
1511 | |
1512 /* Save the colormap */ | |
1513 saved_cmaplen = 256; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1514 saved_cmap=(__u16 *)SDL_malloc(3*saved_cmaplen*sizeof(*saved_cmap)); |
0 | 1515 if ( saved_cmap != NULL ) { |
1516 FB_SavePaletteTo(this, saved_cmaplen, saved_cmap); | |
1517 } | |
1518 | |
1519 /* Allocate new identity colormap */ | |
1520 for ( i=0; i<256; ++i ) { | |
1521 new_entries[(0*256)+i] = | |
1522 new_entries[(1*256)+i] = | |
1523 new_entries[(2*256)+i] = (i<<8)|i; | |
1524 } | |
1525 FB_RestorePaletteFrom(this, 256, new_entries); | |
1526 } | |
1527 } | |
1528 | |
1529 static void FB_RestorePalette(_THIS) | |
1530 { | |
1531 /* Restore the original palette */ | |
1532 if ( saved_cmap ) { | |
1533 FB_RestorePaletteFrom(this, saved_cmaplen, saved_cmap); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1534 SDL_free(saved_cmap); |
0 | 1535 saved_cmap = NULL; |
1536 } | |
1537 } | |
1538 | |
1539 static int FB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
1540 { | |
1541 int i; | |
1542 __u16 r[256]; | |
1543 __u16 g[256]; | |
1544 __u16 b[256]; | |
1545 struct fb_cmap cmap; | |
1546 | |
1547 /* Set up the colormap */ | |
1548 for (i = 0; i < ncolors; i++) { | |
1549 r[i] = colors[i].r << 8; | |
1550 g[i] = colors[i].g << 8; | |
1551 b[i] = colors[i].b << 8; | |
1552 } | |
1553 cmap.start = firstcolor; | |
1554 cmap.len = ncolors; | |
1555 cmap.red = r; | |
1556 cmap.green = g; | |
1557 cmap.blue = b; | |
1558 cmap.transp = NULL; | |
1559 | |
1560 if( (ioctl(console_fd, FBIOPUTCMAP, &cmap) < 0) || | |
1561 !(this->screen->flags & SDL_HWPALETTE) ) { | |
1562 colors = this->screen->format->palette->colors; | |
1563 ncolors = this->screen->format->palette->ncolors; | |
1564 cmap.start = 0; | |
1565 cmap.len = ncolors; | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1566 SDL_memset(r, 0, sizeof(r)); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1567 SDL_memset(g, 0, sizeof(g)); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1568 SDL_memset(b, 0, sizeof(b)); |
0 | 1569 if ( ioctl(console_fd, FBIOGETCMAP, &cmap) == 0 ) { |
1570 for ( i=ncolors-1; i>=0; --i ) { | |
1571 colors[i].r = (r[i]>>8); | |
1572 colors[i].g = (g[i]>>8); | |
1573 colors[i].b = (b[i]>>8); | |
1574 } | |
1575 } | |
1576 return(0); | |
1577 } | |
1578 return(1); | |
1579 } | |
1580 | |
1581 /* Note: If we are terminated, this could be called in the middle of | |
1582 another SDL video routine -- notably UpdateRects. | |
1583 */ | |
1584 static void FB_VideoQuit(_THIS) | |
1585 { | |
1586 int i, j; | |
1587 | |
1588 if ( this->screen ) { | |
1589 /* Clear screen and tell SDL not to free the pixels */ | |
1590 if ( this->screen->pixels && FB_InGraphicsMode(this) ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1591 #if defined(__powerpc__) || defined(__ia64__) /* SIGBUS when using SDL_memset() ?? */ |
0 | 1592 Uint8 *rowp = (Uint8 *)this->screen->pixels; |
1593 int left = this->screen->pitch*this->screen->h; | |
1594 while ( left-- ) { *rowp++ = 0; } | |
1595 #else | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1596 SDL_memset(this->screen->pixels,0,this->screen->h*this->screen->pitch); |
0 | 1597 #endif |
1598 } | |
1599 /* This test fails when using the VGA16 shadow memory */ | |
1600 if ( ((char *)this->screen->pixels >= mapped_mem) && | |
1601 ((char *)this->screen->pixels < (mapped_mem+mapped_memlen)) ) { | |
1602 this->screen->pixels = NULL; | |
1603 } | |
1604 } | |
1605 | |
1606 /* Clear the lock mutex */ | |
1607 if ( hw_lock ) { | |
1608 SDL_DestroyMutex(hw_lock); | |
1609 hw_lock = NULL; | |
1610 } | |
1611 | |
1612 /* Clean up defined video modes */ | |
1613 for ( i=0; i<NUM_MODELISTS; ++i ) { | |
1614 if ( SDL_modelist[i] != NULL ) { | |
1615 for ( j=0; SDL_modelist[i][j]; ++j ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1616 SDL_free(SDL_modelist[i][j]); |
0 | 1617 } |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
1618 SDL_free(SDL_modelist[i]); |
0 | 1619 SDL_modelist[i] = NULL; |
1620 } | |
1621 } | |
1622 | |
1623 /* Clean up the memory bucket list */ | |
1624 FB_FreeHWSurfaces(this); | |
1625 | |
1626 /* Close console and input file descriptors */ | |
1627 if ( console_fd > 0 ) { | |
1628 /* Unmap the video framebuffer and I/O registers */ | |
1629 if ( mapped_mem ) { | |
1630 munmap(mapped_mem, mapped_memlen); | |
1631 mapped_mem = NULL; | |
1632 } | |
1633 if ( mapped_io ) { | |
1634 munmap(mapped_io, mapped_iolen); | |
1635 mapped_io = NULL; | |
1636 } | |
1637 | |
1638 /* Restore the original video mode and palette */ | |
1639 if ( FB_InGraphicsMode(this) ) { | |
1640 FB_RestorePalette(this); | |
1641 ioctl(console_fd, FBIOPUT_VSCREENINFO, &saved_vinfo); | |
1642 } | |
1643 | |
1644 /* We're all done with the framebuffer */ | |
1645 close(console_fd); | |
1646 console_fd = -1; | |
1647 } | |
1648 FB_CloseMouse(this); | |
1649 FB_CloseKeyboard(this); | |
1650 } |