• 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 <nds.h>
25 #include <nds/registers_alt.h>
26 #include "SDL.h"
27 #include "SDL_error.h"
28 #include "SDL_video.h"
29 #include "SDL_mouse.h"
30 #include "../SDL_sysvideo.h"
31 #include "../SDL_pixels_c.h"
32 #include "../../events/SDL_events_c.h"
33 
34 #include "SDL_ndsvideo.h"
35 #include "SDL_ndsevents_c.h"
36 #include "SDL_ndsmouse_c.h"
37 
38 #define NDSVID_DRIVER_NAME "nds"
39 
40 /* Initialization/Query functions */
41 static int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat);
42 static SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
43 static SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
44 static int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
45 static void NDS_VideoQuit(_THIS);
46 
47 /* Hardware surface functions */
48 static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface);
49 static int NDS_LockHWSurface(_THIS, SDL_Surface *surface);
50 static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface);
51 static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface);
52 static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface);
53 
54 /* etc. */
55 static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
56 
57 /* NDS driver bootstrap functions */
58 
NDS_Available(void)59 static int NDS_Available(void)
60 {
61 	return(1);
62 }
63 
NDS_DeleteDevice(SDL_VideoDevice * device)64 static void NDS_DeleteDevice(SDL_VideoDevice *device)
65 {
66 	SDL_free(device->hidden);
67 	SDL_free(device);
68 }
69 
on_irq_vblank()70 void on_irq_vblank()
71 {
72   // Disable interrupts
73   //REG_IME = 0;
74   scanKeys();
75 
76   //  VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK;
77   //  REG_IF |= IRQ_VBLANK;
78   //REG_IF = REG_IF;
79 
80   // Enable interrupts
81   //REG_IME = 1;
82 }
83 
HWAccelBlit(SDL_Surface * src,SDL_Rect * srcrect,SDL_Surface * dst,SDL_Rect * dstrect)84 static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
85                         SDL_Surface *dst, SDL_Rect *dstrect)
86  {
87 	return 0;
88  }
89 
CheckHWBlit(_THIS,SDL_Surface * src,SDL_Surface * dst)90 static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
91 {
92  	if (src->flags & SDL_SRCALPHA) return false;
93  	if (src->flags & SDL_SRCCOLORKEY) return false;
94  	if (src->flags & SDL_HWPALETTE ) return false;
95  	if (dst->flags & SDL_SRCALPHA) return false;
96  	if (dst->flags & SDL_SRCCOLORKEY) return false;
97  	if (dst->flags & SDL_HWPALETTE ) return false;
98 
99  	if (src->format->BitsPerPixel != dst->format->BitsPerPixel) return false;
100  	if (src->format->BytesPerPixel != dst->format->BytesPerPixel) return false;
101 
102         src->map->hw_blit = HWAccelBlit;
103         return true;
104 }
105 
NDS_CreateDevice(int devindex)106 static SDL_VideoDevice *NDS_CreateDevice(int devindex)
107 {
108 	SDL_VideoDevice *device=0;
109 
110 
111 	/* Initialize all variables that we clean on shutdown */
112 	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
113 	if ( device ) {
114 		SDL_memset(device, 0, (sizeof *device));
115 		device->hidden = (struct SDL_PrivateVideoData *)
116 				SDL_malloc((sizeof *device->hidden));
117 	}
118 	if ( (device == NULL) || (device->hidden == NULL) ) {
119 		SDL_OutOfMemory();
120 		if ( device ) {
121 			SDL_free(device);
122 		}
123 		return(0);
124 	}
125 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
126 
127 	/* Set the function pointers */
128 	device->VideoInit = NDS_VideoInit;
129 	device->ListModes = NDS_ListModes;
130 	device->SetVideoMode = NDS_SetVideoMode;
131 	device->CreateYUVOverlay = NULL;
132 	device->SetColors = NDS_SetColors;
133 	device->UpdateRects = NDS_UpdateRects;
134 	device->VideoQuit = NDS_VideoQuit;
135 	device->AllocHWSurface = NDS_AllocHWSurface;
136 	device->CheckHWBlit = CheckHWBlit;
137 	device->FillHWRect = NULL;
138 	device->SetHWColorKey = NULL;
139 	device->SetHWAlpha = NULL;
140 	device->LockHWSurface = NDS_LockHWSurface;
141 	device->UnlockHWSurface = NDS_UnlockHWSurface;
142 	device->FlipHWSurface = NDS_FlipHWSurface;
143 	device->FreeHWSurface = NDS_FreeHWSurface;
144 	device->SetCaption = NULL;
145 	device->SetIcon = NULL;
146 	device->IconifyWindow = NULL;
147 	device->GrabInput = NULL;
148 	device->GetWMInfo = NULL;
149 	device->InitOSKeymap = NDS_InitOSKeymap;
150 	device->PumpEvents = NDS_PumpEvents;
151 	device->info.blit_hw=1;
152 
153 	device->free = NDS_DeleteDevice;
154 	return device;
155 }
156 
157 VideoBootStrap NDS_bootstrap = {
158 	NDSVID_DRIVER_NAME, "SDL NDS video driver",
159 	NDS_Available, NDS_CreateDevice
160 };
161 
162 	u16* frontBuffer;// = (u16*)(0x06000000);
163 	u16* backBuffer;// =  (u16*)(0x06000000 + 256 * 256 * 2);
NDS_VideoInit(_THIS,SDL_PixelFormat * vformat)164 int NDS_VideoInit(_THIS, SDL_PixelFormat *vformat)
165 {
166 	//printf("WARNING: You are using the SDL NDS video driver!\n");
167 
168 	/* Determine the screen depth (use default 8-bit depth) */
169 	/* we change this during the SDL_SetVideoMode implementation... */
170 	vformat->BitsPerPixel = 16;	// mode 3
171 	vformat->BytesPerPixel = 2;
172 	vformat->Rmask = 0x0000f800;
173 	vformat->Gmask = 0x000007e0;
174 	vformat->Bmask = 0x0000001f;
175     powerON(POWER_ALL);
176 	irqInit();
177 	irqSet(IRQ_VBLANK, on_irq_vblank);
178 	irqEnable(IRQ_VBLANK);
179 
180     //set the mode for 2 text layers and two extended background layers
181 	//videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
182 	videoSetMode(MODE_6_2D| DISPLAY_BG2_ACTIVE);
183 
184 	//set the sub background up for text display (we could just print to one
185 	//of the main display text backgrounds just as easily
186 	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE); //sub bg 0 will be used to print text
187 
188     //set the first two banks as background memory and the third as sub background memory
189     //D is not used..if you need a bigger background then you will need to map
190     //more vram banks consecutivly (VRAM A-D are all 0x20000 bytes in size)
191     //vramSetMainBanks(VRAM_A_MAIN_BG_0x6000000, VRAM_B_MAIN_BG_0x6020000,VRAM_C_SUB_BG , VRAM_D_LCD);
192 	vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG);
193 	//vramSetBankA(VRAM_A_MAIN_BG);
194 	//vramSetBankB(VRAM_B_MAIN_BG);
195 	//vramSetBankC(VRAM_C_MAIN_BG);
196 	//vramSetBankD(VRAM_D_MAIN_BG);
197 	//vramSetBankE(VRAM_E_MAIN_BG);
198 	//vramSetBankF(VRAM_F_MAIN_BG);
199 	//vramSetBankG(VRAM_G_MAIN_BG);
200 	vramSetBankH(VRAM_H_SUB_BG);
201 	vramSetBankI(VRAM_I_LCD);
202 
203 	////////////////set up text background for text/////////////////////
204     SUB_BG0_CR = BG_MAP_BASE(8);
205 
206 	BG_PALETTE_SUB[255] = RGB15(31,31,31);//by default font will be rendered with color 255
207 	///////////////set up our bitmap background///////////////////////
208 
209 	//BG3_CR = BG_BMP16_512x512;
210 
211 	//these are rotation backgrounds so you must set the rotation attributes:
212     //these are fixed point numbers with the low 8 bits the fractional part
213     //this basicaly gives it a 1:1 translation in x and y so you get a nice flat bitmap
214       /*  BG3_XDX = 1<<8;
215         BG3_XDY = 0;
216         BG3_YDX = 0;
217         BG3_YDY = 1<<8;
218     //our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2
219         BG3_CX = 0;
220         BG3_CY = 0;
221 		*/
222 	//consoleInit() is a lot more flexible but this gets you up and running quick
223 	consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(8), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
224 
225 
226 	frontBuffer =(u16*)(0x06000000);
227 	//backBuffer  =(u16*)(0x06000000 + 1024 * 512*2);
228 
229 	//lcdSwap();
230 	/* We're done! */
231 	return(0);
232 }
233 
NDS_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)234 SDL_Rect **NDS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
235 {
236 	return (SDL_Rect **) -1;
237 }
238 
NDS_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)239 SDL_Surface *NDS_SetVideoMode(_THIS, SDL_Surface *current,
240 				int width, int height, int bpp, Uint32 flags)
241 {
242 	Uint32 Rmask, Gmask, Bmask, Amask;
243 
244 	//if(width > 1024 || height > 512 || bpp > 16)
245 	//	return(NULL);
246 
247 	if(bpp >8) {
248 		bpp=16;
249  		Rmask = 0x0000001F;
250 		Gmask = 0x000003E0;
251 		Bmask = 0x00007C00;
252 		Amask = 0x00008000;
253 
254 		videoSetMode(MODE_5_2D| DISPLAY_BG2_ACTIVE);
255 
256 		vramSetMainBanks(VRAM_A_MAIN_BG,VRAM_B_MAIN_BG,VRAM_C_MAIN_BG,VRAM_D_MAIN_BG);
257 
258 		BG2_CR = BG_BMP16_512x512;
259 	    BG2_XDX = ((width / 256) << 8) | (width % 256) ;
260         BG2_XDY = 0;
261         BG2_YDX = 0;
262         BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ;
263         BG2_CX = 0;
264         BG2_CY = 0;
265 //        for (i=0;i<256*192;i++)
266 //	        frontBuffer[i] = RGB15(31,0,0)|BIT(15);
267 	}
268 	else
269 	if(bpp <= 8) {
270 		bpp=8;
271 		Rmask = 0x00000000;
272 		Gmask = 0x00000000;
273 		Bmask = 0x00000000;
274 		BG2_CR = BG_BMP8_1024x512;
275         BG2_XDX = ((width / 256) << 8) | (width % 256) ;
276         BG2_XDY = 0;
277         BG2_YDX = 0;
278         BG2_YDY = ((height / 192) << 8) | ((height % 192) + (height % 192) / 3) ;
279 
280 	}
281 	else
282 		if(bpp < 15) bpp=15;
283 	if(width<=256) width=256;
284 	else
285 		if(width<256) width=256;
286 	if(height<=192) height=192;
287 	else
288 		if(height<192) height=192;
289 
290 	if(bpp==8)
291 	{
292 		if(width<256) width=256;
293 		if(height<192) height=192;
294 		this->hidden->ndsmode=4;
295 	}
296 
297 	if(bpp==15)
298 	{
299 		if(width<256) this->hidden->ndsmode=5;
300 		else this->hidden->ndsmode=3;
301 	}
302 
303 	this->hidden->buffer= frontBuffer;//NDS_VRAM_BASE;
304 
305 	//NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2;
306 
307  	//fprintf(stderr,"Setting mode %dx%d (ndsmode %d)\n", width, height,this->hidden->ndsmode);
308 
309 	// FIXME: How do I tell that 15 bits mode is 555?
310 
311 	SDL_memset(this->hidden->buffer, 0, 1024 * 512* ((this->hidden->ndsmode==4 || this->hidden->ndsmode==5) ? 2 : 1 ) * ((bpp+7) / 8));
312 
313 	/* Allocate the new pixel format for the screen */
314 	if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, Amask) ) {
315 		this->hidden->buffer = NULL;
316 		SDL_SetError("Couldn't allocate new pixel format for requested mode");
317 		return(NULL);
318 	}
319 
320 	/* Set up the new mode framebuffer */
321 	current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | (this->hidden->ndsmode > 0 ? SDL_DOUBLEBUF : 0);
322 	this->hidden->w = current->w = width;
323 	this->hidden->h = current->h = height;
324 	current->pixels = frontBuffer;
325 
326 	if (flags & SDL_DOUBLEBUF) {
327 		this->hidden->secondbufferallocd=1;
328 		backBuffer=(u16*)SDL_malloc(1024*512*2);
329 		current->pixels = backBuffer;
330 	}
331 	if(bpp==8)
332 		current->pitch =1024;
333 	else
334 		current->pitch =512*2;
335 
336 	/* We're done */
337 	return(current);
338 }
339 
NDS_AllocHWSurface(_THIS,SDL_Surface * surface)340 static int NDS_AllocHWSurface(_THIS, SDL_Surface *surface)
341 {
342 	if(this->hidden->secondbufferallocd) {
343 		//printf("double double buffer alloc\n");
344 		return -1;
345 	}
346 	//if(this->hidden->ndsmode==3)
347 	//{
348 	//	printf("no 2nd buffer in mode3\n");
349 	//	return -1;
350 	//}
351 	//printf("second buffer\n");
352 	//this->hidden->secondbufferallocd=1;
353 	//backBuffer=(u16*)malloc(1024*512*2);
354 	//surface->pixels = backBuffer;
355 
356 	return(0);
357 }
NDS_FreeHWSurface(_THIS,SDL_Surface * surface)358 static void NDS_FreeHWSurface(_THIS, SDL_Surface *surface)
359 {
360 	//free(backBuffer);
361 	this->hidden->secondbufferallocd=0;
362 }
363 int z=0;
364 /* We need to wait for vertical retrace on page flipped displays */
NDS_LockHWSurface(_THIS,SDL_Surface * surface)365 static int NDS_LockHWSurface(_THIS, SDL_Surface *surface)
366 {
367 /*
368 	uint8* a = surface->pixels;
369   int i,j;
370   a += 5 * SCREEN_WIDTH + 5;
371   for( i = 0; i < 195; ++i) {
372     uint16* line = a + (SCREEN_WIDTH * i);
373     for( j = 0; j < 158; ++j) {
374       *line++ = RGB15(155,155,25);
375     }
376   }
377 */
378 	//if (z <256)
379 	// BG_PALETTE[z++]=RGB15(255-z,z,255-z);
380 
381 
382 	return(0);
383 }
384 
NDS_UnlockHWSurface(_THIS,SDL_Surface * surface)385 static void NDS_UnlockHWSurface(_THIS, SDL_Surface *surface)
386 {
387 	return;
388 }
389 
NDS_FlipHWSurface(_THIS,SDL_Surface * surface)390 static int NDS_FlipHWSurface(_THIS, SDL_Surface *surface)
391 {
392 	if(this->hidden->secondbufferallocd){
393 		while(DISP_Y!=192);
394 	    while(DISP_Y==192);
395 		//printf("flip");
396 
397 		dmaCopyAsynch(backBuffer,frontBuffer,1024*512);
398 	}
399 		//printf("flip\n");
400         //u16* temp = surface->pixels;
401         //surface->pixels = frontBuffer;
402         //frontBuffer = temp;
403 	/*	u8* vram=BG_GFX;
404 	int x,y;
405 	for(y = 0; y < 512; y++)
406 		dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512);
407 	//unsigned char buf;
408 
409 	//printf("NDS_FlipHWSurface\n");
410 	//printf("ptr now: 0x%x\n",surface->pixels);
411 
412 	    while(DISP_Y!=192);
413 	    while(DISP_Y==192);
414         //swap
415         u16* temp = frontBuffer;
416         frontBuffer = backBuffer;
417         backBuffer = temp;
418 
419         //flip
420         //base is 16KB and screen size is 256x256x2 (128KB)
421         BG2_CR ^= BG_BMP_BASE( 512 / 16 ); */
422 /*
423 	if(surface->pixels == frontBuffer)//NDS_VRAM_BASE)
424 	{
425 			while(DISP_Y!=192);
426 	while(DISP_Y==192);
427         //swap
428         u16* temp = backBuffer;
429         backBuffer = frontBuffer;
430         frontBuffer = temp;
431 
432         //flip
433         //base is 16KB and screen size is 256x256x2 (128KB)
434         BG3_CR ^= BG_BMP_BASE( 128 / 16 );
435 	}
436 	else
437 	{
438 
439 		while(DISP_Y!=192);
440 	while(DISP_Y==192);
441         //swap
442         u16* temp = frontBuffer;
443         frontBuffer = backBuffer;
444         backBuffer = temp;
445 
446         //flip
447         //base is 16KB and screen size is 256x256x2 (128KB)
448         BG3_CR ^= BG_BMP_BASE( 128 / 16 );
449 
450 	}
451 	*/
452 	//printf("ptr then: 0x%x\n",surface->pixels);
453 
454 	//printf("setting dispcnt to 0x%x\n",NDS_DISPCNT = NDS_DISP_MODE(this->hidden->ndsmode)|NDS_DISP_BG2| buf);
455 	return(0);
456 }
457 
NDS_UpdateRects(_THIS,int numrects,SDL_Rect * rects)458 static void NDS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
459 {
460 	//fprintf(stderr,"update\n");
461 	/* do nothing. */
462 	//dmaCopy(frontBuffer,BG_GFX,512*512);
463 	 /*
464 	u8* vram=(u8*)BG_GFX;
465 	int x,y;
466 	for(y = 0; y < 512; y++)
467 		dmaCopy(&frontBuffer[y*rects->w], &vram[y*512],512);
468 	 */
469 
470 }
471 
NDS_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)472 int NDS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
473 {
474 	//printf("SetColors\n");
475 	short r,g,b;
476 
477 	if(this->hidden->ndsmode != 4)
478 	{
479 		printf("This is not a palettized mode\n");
480 		return -1;
481 	}
482 
483 	int i,j=firstcolor+ncolors;
484 	for(i=firstcolor;i<j;i++)
485 	{
486 		r=colors[i].r>>3;
487 		g=colors[i].g>>3;
488 		b=colors[i].b>>3;
489 		BG_PALETTE[i]=RGB15(r, g, b);
490 	}
491 
492 	return(0);
493 }
494 
495 /* Note:  If we are terminated, this could be called in the middle of
496    another SDL video routine -- notably UpdateRects.
497 */
NDS_VideoQuit(_THIS)498 void NDS_VideoQuit(_THIS)
499 {
500 }
501