3535static SDL_Surface * screen = NULL ;
3636static SDL_Surface * sdd_surface = NULL ;
3737static SDL_Surface * mouse_surface = NULL ;
38+ #if SDL_VERSION_ATLEAST (2 , 0 , 0 )
39+ static SDL_Palette * sdd_palette = NULL ;
40+ static SDL_Palette * mouse_palette = NULL ;
41+ #endif
3842static SDL_Rect mouse_rect ;
43+ static int palette_offset = 0 ;
3944
4045static uint32_t GetColour (ARMul_State * state ,unsigned int col );
46+ static SDL_Color GetColourStruct (ARMul_State * state ,unsigned int col );
4147static void SetupScreen (ARMul_State * state ,int * width ,int * height ,int bpp );
4248static void PollDisplay (ARMul_State * state ,int XScale ,int YScale );
4349
@@ -271,8 +277,6 @@ static void SDD_Name(Host_PollDisplay)(ARMul_State *state) {
271277
272278/* ------------------------------------------------------------------ */
273279
274- #if !SDL_VERSION_ATLEAST (2 , 0 , 0 )
275-
276280/* Palettised display code */
277281#define PDD_Name (x ) pdd_##x
278282
@@ -289,21 +293,30 @@ static void PDD_Name(Host_SetPaletteEntry)(ARMul_State *state,int i,uint_fast16_
289293
290294 UNUSED_VAR (state );
291295
292- /* Convert to 8-bit component values */
293- col .r = (phys & 0xf )* 0x11 ;
294- col .g = ((phys >>4 ) & 0xf )* 0x11 ;
295- col .b = ((phys >>8 ) & 0xf )* 0x11 ;
296+ col = GetColourStruct (state , phys );
296297
298+ #if SDL_VERSION_ATLEAST (2 , 0 , 0 )
299+ SDL_SetPaletteColors (sdd_palette , & col , i , 1 );
300+ #else
297301 SDL_SetColors (screen , & col , i , 1 );
298302 SDL_SetColors (sdd_surface , & col , i , 1 );
303+ #endif
299304}
300305
301306static void PDD_Name (Host_SetCursorPaletteEntry )(ARMul_State * state ,int i ,uint_fast16_t phys )
302307{
303- /* TODO */
304- UNUSED_VAR (state );
305- UNUSED_VAR (i );
306- UNUSED_VAR (phys );
308+ SDL_Color col ;
309+
310+ if (palette_offset > 0 && palette_offset < 256 )
311+ PDD_Name (Host_SetPaletteEntry )(state , palette_offset + i + 1 , phys );
312+
313+ col = GetColourStruct (state , phys );
314+
315+ #if SDL_VERSION_ATLEAST (2 , 0 , 0 )
316+ SDL_SetPaletteColors (mouse_palette , & col , i + 1 , 1 );
317+ #else
318+ SDL_SetColors (mouse_surface , & col , i + 1 , 1 );
319+ #endif
307320}
308321
309322static void PDD_Name (Host_SetBorderColour )(ARMul_State * state ,uint_fast16_t phys )
@@ -401,7 +414,7 @@ void PDD_Name(Host_ChangeMode)(ARMul_State *state,int width,int height,int depth
401414 HD .Width = width ;
402415 HD .Height = height ;
403416
404- SetupScreen (state ,& HD .Width ,& HD .Height ,8 );
417+ SetupScreen (state ,& HD .Width ,& HD .Height ,1 << depth );
405418
406419 /* Calculate expansion params */
407420 if ((depth == 3 ) && (HD .XScale == 1 ))
@@ -437,8 +450,6 @@ static void PDD_Name(Host_PollDisplay)(ARMul_State *state) {
437450 PollDisplay (state ,HD .XScale ,HD .YScale );
438451}
439452
440- #endif
441-
442453/* ------------------------------------------------------------------ */
443454
444455static uint32_t GetColour (ARMul_State * state ,unsigned int col )
@@ -453,64 +464,60 @@ static uint32_t GetColour(ARMul_State *state,unsigned int col)
453464 b = ((col >>8 ) & 0xf )* 0x11 ;
454465
455466#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
456- return SDL_MapRGB (SDL_GetPixelFormatDetails (screen -> format ), NULL , r , g , b );
467+ return SDL_MapRGB (SDL_GetPixelFormatDetails (screen -> format ), sdd_palette , r , g , b );
457468#else
458469 return SDL_MapRGB (screen -> format , r , g , b );
459470#endif
460471}
461472
473+ static SDL_Color GetColourStruct (ARMul_State * state ,unsigned int phys )
474+ {
475+ SDL_Color col ;
476+
477+ UNUSED_VAR (state );
478+
479+ /* Convert to 8-bit component values */
480+ col .r = ((phys >>0 ) & 0xf )* 0x11 ;
481+ col .g = ((phys >>4 ) & 0xf )* 0x11 ;
482+ col .b = ((phys >>8 ) & 0xf )* 0x11 ;
483+ #if SDL_VERSION_ATLEAST (2 , 0 , 0 )
484+ col .a = SDL_ALPHA_OPAQUE ;
485+ #endif
486+
487+ return col ;
488+ }
489+
462490#undef HD
463491
464492/* Refresh the mouse's image */
465- static void RefreshMouse (ARMul_State * state ,int XScale ,int YScale ) {
466- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
467- SDL_Palette * palette ;
468- #endif
493+ static bool RefreshMouse (ARMul_State * state ,int XScale ,int YScale ) {
469494 int x ,y ,offset , repeat ;
470495 int memptr ;
471496 int Height = ((int )VIDC .Vert_CursorEnd - (int )VIDC .Vert_CursorStart )* YScale ;
472- SDL_Color cursorPal [3 ];
473497 uint8_t * dst ;
474498
475499 /* TODO: Implement horizontal scaling */
476500 UNUSED_VAR (XScale );
477501
478- if (Height < 0 ) Height = 0 ;
502+ if (Height <= 0 ) return false ;
479503
480- if (mouse_surface && mouse_surface -> h != Height )
481- SDL_DestroySurface (mouse_surface ), mouse_surface = NULL ;
482- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
483- if (!mouse_surface ) {
484- mouse_surface = SDL_CreateSurface (32 , Height , SDL_PIXELFORMAT_INDEX8 );
485- palette = SDL_CreateSurfacePalette (mouse_surface );
486- } else {
487- palette = SDL_GetSurfacePalette (mouse_surface );
488- }
489- #else
490- if (!mouse_surface )
491- mouse_surface = SDL_CreateRGBSurface (SDL_SWSURFACE , 32 , Height , 8 , 0 , 0 , 0 , 0 );
492- #endif
493504 mouse_rect .w = 32 ;
494505 mouse_rect .h = Height ;
495506
496- /* Cursor palette */
497- for (x = 0 ; x < 3 ; x ++ ) {
498- uint_fast16_t phys = VIDC .CursorPalette [x ];
499- cursorPal [x ].r = (phys & 0xf )* 0x11 ;
500- cursorPal [x ].g = ((phys >>4 ) & 0xf )* 0x11 ;
501- cursorPal [x ].b = ((phys >>8 ) & 0xf )* 0x11 ;
507+ if (palette_offset == 0 ) {
508+ /* Cursor palette */
509+ SDL_Color cursorPal [3 ];
510+
511+ for (x = 0 ; x < 3 ; x ++ ) {
512+ cursorPal [x ] = GetColourStruct (state , VIDC .CursorPalette [x ]);
513+ }
514+
502515#if SDL_VERSION_ATLEAST (2 , 0 , 0 )
503- cursorPal [x ].a = SDL_ALPHA_OPAQUE ;
504- #endif
505- }
506- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
507- SDL_SetPaletteColors (palette , cursorPal , 1 , 3 );
508- #elif SDL_VERSION_ATLEAST (2 , 0 , 0 )
509- SDL_SetPaletteColors (mouse_surface -> format -> palette , cursorPal , 1 , 3 );
516+ SDL_SetPaletteColors (mouse_palette , cursorPal , 1 , 3 );
510517#else
511- SDL_SetColors (mouse_surface , cursorPal , 1 , 3 );
518+ SDL_SetColors (mouse_surface , cursorPal , 1 , 3 );
512519#endif
513- SDL_SetSurfaceColorKey ( mouse_surface , true, 0 );
520+ }
514521
515522 SDL_LockSurface (mouse_surface );
516523
@@ -529,7 +536,7 @@ static void RefreshMouse(ARMul_State *state,int XScale,int YScale) {
529536 dst [x ] = ((tmp [x /16 ]>>((x & 15 )* 2 )) & 3 );
530537 }; /* x */
531538 dst += mouse_surface -> pitch ;
532- } else return ;
539+ } else return true ;
533540 if (++ repeat == YScale ) {
534541 memptr += 8 ;
535542 offset += 8 ;
@@ -538,46 +545,66 @@ static void RefreshMouse(ARMul_State *state,int XScale,int YScale) {
538545 }; /* y */
539546
540547 SDL_UnlockSurface (mouse_surface );
548+ return true;
541549} /* RefreshMouse */
542550
543551static void SetupScreen (ARMul_State * state ,int * width ,int * height ,int bpp )
544552{
545553 UNUSED_VAR (state );
546- UNUSED_VAR (bpp );
547554
548- if (!sdd_surface )
549- SDL_DestroySurface (sdd_surface );
550555#if SDL_VERSION_ATLEAST (2 , 0 , 0 )
556+ if (!sdd_palette )
557+ sdd_palette = SDL_CreatePalette (256 );
558+ if (!mouse_palette )
559+ mouse_palette = SDL_CreatePalette (4 );
560+
551561 SDL_SetWindowSize (window , * width , * height );
552562 screen = SDL_GetWindowSurface (window );
563+ SDL_SetSurfacePalette (screen , sdd_palette );
553564#else
554565 screen = SDL_SetVideoMode (* width , * height , screen -> format -> BitsPerPixel ,
555566 SDL_SWSURFACE | SDL_HWPALETTE );
556567#endif
568+
569+ if (sdd_surface )
570+ SDL_DestroySurface (sdd_surface );
571+ if (mouse_surface )
572+ SDL_DestroySurface (mouse_surface );
573+
557574#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
558575 sdd_surface = SDL_CreateSurface (screen -> w , screen -> h , screen -> format );
576+ mouse_surface = SDL_CreateSurface (32 , screen -> h , SDL_PIXELFORMAT_INDEX8 );
559577#else
560578 sdd_surface = SDL_CreateRGBSurface (SDL_SWSURFACE , screen -> w , screen -> h ,
561579 screen -> format -> BitsPerPixel ,
562580 screen -> format -> Rmask ,
563581 screen -> format -> Gmask ,
564582 screen -> format -> Bmask ,
565583 screen -> format -> Amask );
584+ mouse_surface = SDL_CreateRGBSurface (SDL_SWSURFACE , 32 , screen -> h , 8 , 0 , 0 , 0 , 0 );
585+ #endif
586+ #if SDL_VERSION_ATLEAST (2 , 0 , 0 )
587+ SDL_SetSurfacePalette (sdd_surface , sdd_palette );
588+ SDL_SetSurfacePalette (mouse_surface , mouse_palette );
566589#endif
590+ SDL_SetSurfaceColorKey (mouse_surface , true, 0 );
567591
568592 /* Screen is expected to be cleared */
569593 SDL_FillSurfaceRect (sdd_surface , NULL , GetColour (state , 0 ));
570594
595+ palette_offset = (bpp > 8 ) ? 0 : (1 << bpp );
596+
571597 * width = screen -> w ;
572598 * height = screen -> h ;
573599}
574600
575601static void PollDisplay (ARMul_State * state ,int XScale ,int YScale )
576602{
577- RefreshMouse (state ,XScale ,YScale );
603+ bool has_mouse = RefreshMouse (state ,XScale ,YScale );
578604
579605 SDL_BlitSurface (sdd_surface , NULL , screen , NULL );
580- SDL_BlitSurface (mouse_surface , NULL , screen , & mouse_rect );
606+ if (has_mouse )
607+ SDL_BlitSurface (mouse_surface , NULL , screen , & mouse_rect );
581608
582609#if SDL_VERSION_ATLEAST (2 , 0 , 0 )
583610 SDL_UpdateWindowSurface (window );
@@ -614,10 +641,8 @@ bool DisplayDev_Init(ARMul_State *state)
614641 return DisplayDev_Set (state ,& SDD32_DisplayDev );
615642 } else if (bpp == 2 ) {
616643 return DisplayDev_Set (state ,& SDD16_DisplayDev );
617- #if !SDL_VERSION_ATLEAST (2 , 0 , 0 )
618644 } else if (bpp == 1 ) {
619645 return DisplayDev_Set (state ,& PDD_DisplayDev );
620- #endif
621646 } else {
622647 ControlPane_Error (false,"Unsupported bytes per pixel: %d" , bpp );
623648 return false;
0 commit comments