Skip to content

Commit a8af8b7

Browse files
committed
Improve palette support with SDL framebuffers
1 parent 9d8f83f commit a8af8b7

2 files changed

Lines changed: 82 additions & 56 deletions

File tree

SDL/fb.c

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,15 @@
3535
static SDL_Surface *screen = NULL;
3636
static SDL_Surface *sdd_surface = NULL;
3737
static 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
3842
static SDL_Rect mouse_rect;
43+
static int palette_offset = 0;
3944

4045
static uint32_t GetColour(ARMul_State *state,unsigned int col);
46+
static SDL_Color GetColourStruct(ARMul_State *state,unsigned int col);
4147
static void SetupScreen(ARMul_State *state,int *width,int *height,int bpp);
4248
static 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

301306
static 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

309322
static 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

444455
static 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

543551
static 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

575601
static 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;

SDL/platform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern SDL_Window *window;
2020
#if SDL_VERSION_ATLEAST(2, 0, 0)
2121
#define SDL_RenderTexture SDL_RenderCopyF
2222
#define SDL_CreateSurface(w, h, f) SDL_CreateRGBSurfaceWithFormat(0, w, h, SDL_BITSPERPIXEL(f), f)
23+
#define SDL_CreatePalette SDL_AllocPalette
2324

2425
static inline bool SDL_SetSurfaceColorKey(SDL_Surface *surface, bool enabled, Uint32 key) {
2526
return (SDL_SetColorKey(surface, enabled ? SDL_TRUE : 0, key) == 0);

0 commit comments

Comments
 (0)