• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2012 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 #include "SDL_video.h"
25 #include "SDL_mouse.h"
26 #include "../SDL_sysvideo.h"
27 #include "../SDL_pixels_c.h"
28 #include "../../events/SDL_events_c.h"
29 
30 #include "SDL_dcvideo.h"
31 #include "SDL_dcevents_c.h"
32 #include "SDL_dcmouse_c.h"
33 
34 #include <dc/video.h>
35 #include <dc/pvr.h>
36 
37 
38 /* Initialization/Query functions */
39 static int DC_VideoInit(_THIS, SDL_PixelFormat *vformat);
40 static SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
41 static SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
42 static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
43 static void DC_VideoQuit(_THIS);
44 
45 /* Hardware surface functions */
46 static int DC_AllocHWSurface(_THIS, SDL_Surface *surface);
47 static int DC_LockHWSurface(_THIS, SDL_Surface *surface);
48 static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface);
49 static void DC_FreeHWSurface(_THIS, SDL_Surface *surface);
50 static int DC_FlipHWSurface(_THIS, SDL_Surface *surface);
51 
52 /* etc. */
53 static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
54 
55 /* OpenGL */
56 #if SDL_VIDEO_OPENGL
57 static void *DC_GL_GetProcAddress(_THIS, const char *proc);
58 static int DC_GL_LoadLibrary(_THIS, const char *path);
59 static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
60 static void DC_GL_SwapBuffers(_THIS);
61 #endif
62 
63 /* DC driver bootstrap functions */
64 
DC_Available(void)65 static int DC_Available(void)
66 {
67 	return 1;
68 }
69 
DC_DeleteDevice(SDL_VideoDevice * device)70 static void DC_DeleteDevice(SDL_VideoDevice *device)
71 {
72 	SDL_free(device->hidden);
73 	SDL_free(device);
74 }
75 
DC_CreateDevice(int devindex)76 static SDL_VideoDevice *DC_CreateDevice(int devindex)
77 {
78 	SDL_VideoDevice *device;
79 
80 	/* Initialize all variables that we clean on shutdown */
81 	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
82 	if ( device ) {
83 		SDL_memset(device, 0, (sizeof *device));
84 		device->hidden = (struct SDL_PrivateVideoData *)
85 				SDL_malloc((sizeof *device->hidden));
86 	}
87 	if ( (device == NULL) || (device->hidden == NULL) ) {
88 		SDL_OutOfMemory();
89 		if ( device ) {
90 			SDL_free(device);
91 		}
92 		return(0);
93 	}
94 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
95 
96 	/* Set the function pointers */
97 	device->VideoInit = DC_VideoInit;
98 	device->ListModes = DC_ListModes;
99 	device->SetVideoMode = DC_SetVideoMode;
100 	device->CreateYUVOverlay = NULL;
101 	device->SetColors = DC_SetColors;
102 	device->UpdateRects = DC_UpdateRects;
103 	device->VideoQuit = DC_VideoQuit;
104 	device->AllocHWSurface = DC_AllocHWSurface;
105 	device->CheckHWBlit = NULL;
106 	device->FillHWRect = NULL;
107 	device->SetHWColorKey = NULL;
108 	device->SetHWAlpha = NULL;
109 	device->LockHWSurface = DC_LockHWSurface;
110 	device->UnlockHWSurface = DC_UnlockHWSurface;
111 	device->FlipHWSurface = DC_FlipHWSurface;
112 	device->FreeHWSurface = DC_FreeHWSurface;
113 #if SDL_VIDEO_OPENGL
114 	device->GL_LoadLibrary = DC_GL_LoadLibrary;
115 	device->GL_GetProcAddress = DC_GL_GetProcAddress;
116 	device->GL_GetAttribute = DC_GL_GetAttribute;
117 	device->GL_MakeCurrent = NULL;
118 	device->GL_SwapBuffers = DC_GL_SwapBuffers;
119 #endif
120 	device->SetCaption = NULL;
121 	device->SetIcon = NULL;
122 	device->IconifyWindow = NULL;
123 	device->GrabInput = NULL;
124 	device->GetWMInfo = NULL;
125 	device->InitOSKeymap = DC_InitOSKeymap;
126 	device->PumpEvents = DC_PumpEvents;
127 
128 	device->free = DC_DeleteDevice;
129 
130 	return device;
131 }
132 
133 VideoBootStrap DC_bootstrap = {
134 	"dcvideo", "Dreamcast Video",
135 	DC_Available, DC_CreateDevice
136 };
137 
138 
DC_VideoInit(_THIS,SDL_PixelFormat * vformat)139 int DC_VideoInit(_THIS, SDL_PixelFormat *vformat)
140 {
141 	/* Determine the screen depth (use default 16-bit depth) */
142 	/* we change this during the SDL_SetVideoMode implementation... */
143 	vformat->BitsPerPixel = 16;
144 	vformat->Rmask = 0x0000f800;
145 	vformat->Gmask = 0x000007e0;
146 	vformat->Bmask = 0x0000001f;
147 
148 	/* We're done! */
149 	return(0);
150 }
151 
152 const static SDL_Rect
153 	RECT_800x600 = {0,0,800,600},
154 	RECT_640x480 = {0,0,640,480},
155 	RECT_320x240 = {0,0,320,240};
156 const static SDL_Rect *vid_modes[] = {
157 	&RECT_800x600,
158 	&RECT_640x480,
159 	&RECT_320x240,
160 	NULL
161 };
162 
DC_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)163 SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
164 {
165 	switch(format->BitsPerPixel) {
166 	case 15:
167 	case 16:
168 		return &vid_modes;
169 	case 32:
170 		if (!(flags & SDL_OPENGL))
171 		return &vid_modes;
172 	default:
173 		return NULL;
174 	}
175 //	return (SDL_Rect **) -1;
176 }
177 
178 pvr_init_params_t params = {
179         /* Enable opaque and translucent polygons with size 16 */
180         { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16 },
181 
182         /* Vertex buffer size */
183         512*1024
184 };
185 
186 #if SDL_VIDEO_OPENGL
187 static int pvr_inited;
188 #endif
189 
DC_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)190 SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current,
191 				int width, int height, int bpp, Uint32 flags)
192 {
193 	int disp_mode,pixel_mode,pitch;
194 	Uint32 Rmask, Gmask, Bmask;
195 
196 	if (width==320 && height==240) disp_mode=DM_320x240;
197 	else if (width==640 && height==480) disp_mode=DM_640x480;
198 	else if (width==800 && height==600) disp_mode=DM_800x608;
199 	else {
200 		SDL_SetError("Couldn't find requested mode in list");
201 		return(NULL);
202 	}
203 
204 	switch(bpp) {
205 	case 15: pixel_mode = PM_RGB555; pitch = width*2;
206 		/* 5-5-5 */
207 		Rmask = 0x00007c00;
208 		Gmask = 0x000003e0;
209 		Bmask = 0x0000001f;
210 		break;
211 	case 16: pixel_mode = PM_RGB565; pitch = width*2;
212 		/* 5-6-5 */
213 		Rmask = 0x0000f800;
214 		Gmask = 0x000007e0;
215 		Bmask = 0x0000001f;
216 		break;
217 	case 24: bpp = 32;
218 	case 32: pixel_mode = PM_RGB888; pitch = width*4;
219 		Rmask = 0x00ff0000;
220 		Gmask = 0x0000ff00;
221 		Bmask = 0x000000ff;
222 #if SDL_VIDEO_OPENGL
223 		if (!(flags & SDL_OPENGL))
224 #endif
225 		break;
226 	default:
227 		SDL_SetError("Couldn't find requested mode in list");
228 		return(NULL);
229 	}
230 
231 //  if ( bpp != current->format->BitsPerPixel ) {
232 	if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) {
233 		return(NULL);
234 	}
235 //  }
236 
237 	/* Set up the new mode framebuffer */
238 	current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);
239 	current->w = width;
240 	current->h = height;
241 	current->pitch = pitch;
242 
243 #if SDL_VIDEO_OPENGL
244 	if (pvr_inited) {
245 		pvr_inited = 0;
246 		pvr_shutdown();
247 	}
248 #endif
249 
250 	vid_set_mode(disp_mode,pixel_mode);
251 
252 	current->pixels = vram_s;
253 
254 #if SDL_VIDEO_OPENGL
255 	if (flags & SDL_OPENGL) {
256 		this->gl_config.driver_loaded = 1;
257 		current->flags = SDL_FULLSCREEN | SDL_OPENGL;
258 		current->pixels = NULL;
259 		pvr_inited = 1;
260 		pvr_init(&params);
261 		glKosInit();
262 		glKosBeginFrame();
263 	} else
264 #endif
265 	if (flags | SDL_DOUBLEBUF) {
266 		current->flags |= SDL_DOUBLEBUF;
267 		current->pixels = (void*)((int)current->pixels | 0x400000);
268 	}
269 
270 	/* We're done */
271 	return(current);
272 }
273 
274 /* We don't actually allow hardware surfaces other than the main one */
DC_AllocHWSurface(_THIS,SDL_Surface * surface)275 static int DC_AllocHWSurface(_THIS, SDL_Surface *surface)
276 {
277 	return(-1);
278 }
DC_FreeHWSurface(_THIS,SDL_Surface * surface)279 static void DC_FreeHWSurface(_THIS, SDL_Surface *surface)
280 {
281 	return;
282 }
283 
284 /* We need to wait for vertical retrace on page flipped displays */
DC_LockHWSurface(_THIS,SDL_Surface * surface)285 static int DC_LockHWSurface(_THIS, SDL_Surface *surface)
286 {
287 	return(0);
288 }
289 
DC_UnlockHWSurface(_THIS,SDL_Surface * surface)290 static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface)
291 {
292 	return;
293 }
294 
DC_FlipHWSurface(_THIS,SDL_Surface * surface)295 static int DC_FlipHWSurface(_THIS, SDL_Surface *surface)
296 {
297 	if (surface->flags & SDL_DOUBLEBUF) {
298 		vid_set_start((int)surface->pixels & 0xffffff);
299 		surface->pixels = (void*)((int)surface->pixels ^ 0x400000);
300 	}
301 	return(0);
302 }
303 
DC_UpdateRects(_THIS,int numrects,SDL_Rect * rects)304 static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
305 {
306 	/* do nothing. */
307 }
308 
DC_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)309 static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
310 {
311 	/* do nothing of note. */
312 	return(1);
313 }
314 
315 /* Note:  If we are terminated, this could be called in the middle of
316    another SDL video routine -- notably UpdateRects.
317 */
DC_VideoQuit(_THIS)318 static void DC_VideoQuit(_THIS)
319 {
320 #if SDL_VIDEO_OPENGL
321 	if (pvr_inited) {
322 		pvr_inited = 0;
323 		pvr_shutdown();
324 	}
325 #endif
326 }
327 
328 #if SDL_VIDEO_OPENGL
329 
dmyfunc(void)330 void dmyfunc(void) {}
331 
332 typedef void (*funcptr)();
333 const static struct {
334 	char *name;
335 	funcptr addr;
336 } glfuncs[] = {
337 #define	DEF(func)	{#func,&func}
338 	DEF(glBegin),
339 	DEF(glBindTexture),
340 	DEF(glBlendFunc),
341 	DEF(glColor4f),
342 //	DEF(glCopyImageID),
343 	DEF(glDisable),
344 	DEF(glEnable),
345 	DEF(glEnd),
346 	DEF(glFlush),
347 	DEF(glGenTextures),
348 	DEF(glGetString),
349 	DEF(glLoadIdentity),
350 	DEF(glMatrixMode),
351 	DEF(glOrtho),
352 	DEF(glPixelStorei),
353 //	DEF(glPopAttrib),
354 //	DEF(glPopClientAttrib),
355 	{"glPopAttrib",&dmyfunc},
356 	{"glPopClientAttrib",&dmyfunc},
357 	DEF(glPopMatrix),
358 //	DEF(glPushAttrib),
359 //	DEF(glPushClientAttrib),
360 	{"glPushAttrib",&dmyfunc},
361 	{"glPushClientAttrib",&dmyfunc},
362 	DEF(glPushMatrix),
363 	DEF(glTexCoord2f),
364 	DEF(glTexEnvf),
365 	DEF(glTexImage2D),
366 	DEF(glTexParameteri),
367 	DEF(glTexSubImage2D),
368 	DEF(glVertex2i),
369 	DEF(glViewport),
370 #undef	DEF
371 };
372 
DC_GL_GetProcAddress(_THIS,const char * proc)373 static void *DC_GL_GetProcAddress(_THIS, const char *proc)
374 {
375 	void *ret;
376 	int i;
377 
378 	ret = glKosGetProcAddress(proc);
379 	if (ret) return ret;
380 
381 	for(i=0;i<sizeof(glfuncs)/sizeof(glfuncs[0]);i++) {
382 		if (SDL_strcmp(proc,glfuncs[i].name)==0) return glfuncs[i].addr;
383 	}
384 
385 	return NULL;
386 }
387 
DC_GL_LoadLibrary(_THIS,const char * path)388 static int DC_GL_LoadLibrary(_THIS, const char *path)
389 {
390 	this->gl_config.driver_loaded = 1;
391 
392 	return 0;
393 }
394 
DC_GL_GetAttribute(_THIS,SDL_GLattr attrib,int * value)395 static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
396 {
397 	GLenum mesa_attrib;
398 	int val;
399 
400 	switch(attrib) {
401 	case SDL_GL_RED_SIZE:
402 		val = 5;
403 		break;
404 	case SDL_GL_GREEN_SIZE:
405 		val = 6;
406 		break;
407 	case SDL_GL_BLUE_SIZE:
408 		val = 5;
409 		break;
410 	case SDL_GL_ALPHA_SIZE:
411 		val = 0;
412 		break;
413 	case SDL_GL_DOUBLEBUFFER:
414 		val = 1;
415 		break;
416 	case SDL_GL_DEPTH_SIZE:
417 		val = 16; /* or 32? */
418 		break;
419 	case SDL_GL_STENCIL_SIZE:
420 		val = 0;
421 		break;
422 	case SDL_GL_ACCUM_RED_SIZE:
423 		val = 0;
424 		break;
425 	case SDL_GL_ACCUM_GREEN_SIZE:
426 		val = 0;
427 	case SDL_GL_ACCUM_BLUE_SIZE:
428 		val = 0;
429 		break;
430 	case SDL_GL_ACCUM_ALPHA_SIZE:
431 		val = 0;
432 		break;
433 	default :
434 		return -1;
435 	}
436 	*value = val;
437 	return 0;
438 }
439 
DC_GL_SwapBuffers(_THIS)440 static void DC_GL_SwapBuffers(_THIS)
441 {
442 	glKosFinishFrame();
443 	glKosBeginFrame();
444 }
445 #endif
446