mirror of
https://github.com/libretro/beetle-lynx-libretro.git
synced 2024-11-23 08:10:55 +00:00
Merge pull request #44 from negativeExponent/mdfn_surface_cleanup
Add 16/32 color modes switching and cleanups
This commit is contained in:
commit
88c91e090b
@ -85,7 +85,6 @@ SOURCES_CXX += \
|
||||
$(MEDNAFEN_DIR)/mempatcher.cpp \
|
||||
$(MEDNAFEN_DIR)/md5.cpp \
|
||||
$(MEDNAFEN_DIR)/sound/Stereo_Buffer.cpp \
|
||||
$(MEDNAFEN_DIR)/video/surface.cpp \
|
||||
$(MEDNAFEN_DIR)/endian.cpp \
|
||||
$(CORE_DIR)/libretro.cpp
|
||||
|
||||
|
132
libretro.cpp
132
libretro.cpp
@ -46,6 +46,7 @@ std::string retro_base_name;
|
||||
std::string retro_save_directory;
|
||||
|
||||
static bool libretro_supports_input_bitmasks;
|
||||
static int system_color_depth = 16;
|
||||
|
||||
extern MDFNGI EmulatedLynx;
|
||||
MDFNGI *MDFNGameInfo = &EmulatedLynx;
|
||||
@ -135,12 +136,6 @@ void retro_init(void)
|
||||
retro_save_directory = retro_base_directory;
|
||||
}
|
||||
|
||||
#if defined(WANT_16BPP) && defined(FRONTEND_SUPPORTS_RGB565)
|
||||
enum retro_pixel_format rgb565 = RETRO_PIXEL_FORMAT_RGB565;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565) && log_cb)
|
||||
log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n");
|
||||
#endif
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb))
|
||||
perf_get_cpu_features_cb = perf_cb.get_cpu_features;
|
||||
else
|
||||
@ -231,6 +226,41 @@ static bool MDFNI_LoadGame(const uint8_t *data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_pix_format(void)
|
||||
{
|
||||
struct retro_variable var = { "lynx_pix_format", NULL };
|
||||
bool ret = true;
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
system_color_depth = atoi(var.value);
|
||||
}
|
||||
|
||||
if (system_color_depth == 32)
|
||||
{
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "Pixel format XRGB8888 not supported by platform.\n");
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret || system_color_depth == 16)
|
||||
{
|
||||
enum retro_pixel_format rgb565 = RETRO_PIXEL_FORMAT_RGB565;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565))
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n");
|
||||
system_color_depth = 16;
|
||||
}
|
||||
else
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool retro_load_game(const struct retro_game_info *info)
|
||||
{
|
||||
@ -253,26 +283,51 @@ bool retro_load_game(const struct retro_game_info *info)
|
||||
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
|
||||
|
||||
#ifdef WANT_32BPP
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_ERROR, "Pixel format XRGB8888 not supported by platform, cannot use %s.\n", MEDNAFEN_CORE_NAME);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
overscan = false;
|
||||
environ_cb(RETRO_ENVIRONMENT_GET_OVERSCAN, &overscan);
|
||||
|
||||
if (!init_pix_format())
|
||||
log_cb(RETRO_LOG_ERROR, "Unable to initialize pixel format. Aborting.\n");
|
||||
|
||||
if (!MDFNI_LoadGame((const uint8_t *)info->data, info->size))
|
||||
return false;
|
||||
|
||||
MDFN_PixelFormat pix_fmt(MDFN_COLORSPACE_RGB, 16, 8, 0, 24);
|
||||
last_pixel_format = MDFN_PixelFormat();
|
||||
surf = (MDFN_Surface*)calloc(1, sizeof(*surf));
|
||||
|
||||
if (!surf)
|
||||
return false;
|
||||
|
||||
surf->width = FB_WIDTH;
|
||||
surf->height = FB_HEIGHT;
|
||||
surf->pitch = FB_WIDTH;
|
||||
surf->bpp = system_color_depth;
|
||||
|
||||
surf = new MDFN_Surface(NULL, FB_WIDTH, FB_HEIGHT, FB_WIDTH, pix_fmt);
|
||||
if (system_color_depth == 32)
|
||||
{
|
||||
surf->pixels = (uint32_t*)calloc(4, FB_WIDTH * FB_HEIGHT);
|
||||
|
||||
if (!surf->pixels)
|
||||
{
|
||||
free(surf);
|
||||
surf = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (system_color_depth == 16)
|
||||
{
|
||||
surf->pixels16 = (uint16_t*)calloc(2, FB_WIDTH * FB_HEIGHT);
|
||||
|
||||
if (!surf->pixels16)
|
||||
{
|
||||
free(surf);
|
||||
surf = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
lynxie->DisplaySetAttributes(surf->bpp);
|
||||
|
||||
SetInput(0, "gamepad", (uint8_t*)&input_buf);
|
||||
|
||||
@ -428,13 +483,6 @@ void retro_run()
|
||||
spec.VideoFormatChanged = false;
|
||||
spec.SoundFormatChanged = false;
|
||||
|
||||
if (memcmp(&last_pixel_format, &spec.surface->format, sizeof(MDFN_PixelFormat)))
|
||||
{
|
||||
spec.VideoFormatChanged = true;
|
||||
|
||||
last_pixel_format = spec.surface->format;
|
||||
}
|
||||
|
||||
if (spec.SoundRate != last_sound_rate)
|
||||
{
|
||||
spec.SoundFormatChanged = true;
|
||||
@ -452,13 +500,16 @@ void retro_run()
|
||||
unsigned width = spec.DisplayRect.w;
|
||||
unsigned height = spec.DisplayRect.h;
|
||||
|
||||
#if defined(WANT_32BPP)
|
||||
const uint32_t *pix = surf->pixels;
|
||||
video_cb(pix, width, height, FB_WIDTH << 2);
|
||||
#elif defined(WANT_16BPP)
|
||||
const uint16_t *pix = surf->pixels16;
|
||||
video_cb(pix, width, height, FB_WIDTH << 1);
|
||||
#endif
|
||||
if (surf->bpp == 32)
|
||||
{
|
||||
const uint32_t *pix = surf->pixels;
|
||||
video_cb(pix, width, height, FB_WIDTH << 2);
|
||||
}
|
||||
else if (surf->bpp == 16)
|
||||
{
|
||||
const uint16_t *pix = surf->pixels16;
|
||||
video_cb(pix, width, height, FB_WIDTH << 1);
|
||||
}
|
||||
|
||||
audio_batch_cb(spec.SoundBuf, spec.SoundBufSize);
|
||||
|
||||
@ -494,8 +545,19 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
|
||||
void retro_deinit()
|
||||
{
|
||||
delete surf;
|
||||
surf = NULL;
|
||||
if (surf)
|
||||
{
|
||||
if (surf->pixels16)
|
||||
free(surf->pixels16);
|
||||
surf->pixels16 = NULL;
|
||||
|
||||
if (surf->pixels)
|
||||
free(surf->pixels);
|
||||
surf->pixels = NULL;
|
||||
|
||||
free (surf);
|
||||
surf = NULL;
|
||||
}
|
||||
|
||||
libretro_supports_input_bitmasks = false;
|
||||
}
|
||||
|
@ -63,7 +63,19 @@ struct retro_core_option_definition option_defs_us[] = {
|
||||
{ "disabled", NULL },
|
||||
{ NULL, NULL},
|
||||
},
|
||||
"enabled"
|
||||
"enabled",
|
||||
},
|
||||
|
||||
{
|
||||
"lynx_pix_format",
|
||||
"Color Format (Restart)",
|
||||
"",
|
||||
{
|
||||
{ "16", "16-Bit (RGB565)" },
|
||||
{ "32", "32-Bit (RGB8888)" },
|
||||
{ NULL, NULL},
|
||||
},
|
||||
"16",
|
||||
},
|
||||
|
||||
{ NULL, NULL, NULL, {{0}}, NULL },
|
||||
|
@ -1,6 +1,10 @@
|
||||
// Band-limited sound synthesis buffer
|
||||
// Various changes and hacks for use in Mednafen.
|
||||
|
||||
// Blip_Buffer 0.4.1
|
||||
#ifndef BLIP_BUFFER_H
|
||||
#define BLIP_BUFFER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define blip_inline inline __attribute__((always_inline))
|
||||
#else
|
||||
@ -10,10 +14,6 @@
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Blip_Buffer 0.4.1
|
||||
#ifndef BLIP_BUFFER_H
|
||||
#define BLIP_BUFFER_H
|
||||
|
||||
// Internal
|
||||
typedef int32_t blip_long;
|
||||
typedef uint32_t blip_ulong;
|
||||
|
@ -379,7 +379,7 @@ void CMikie::ComLynxTxCallback(void (*function)(int data,uint32 objref),uint32 o
|
||||
}
|
||||
|
||||
|
||||
void CMikie::DisplaySetAttributes(const MDFN_PixelFormat &format)
|
||||
void CMikie::DisplaySetAttributes(int32 bpp)
|
||||
{
|
||||
mpDisplayCurrent=NULL;
|
||||
|
||||
@ -394,41 +394,82 @@ void CMikie::DisplaySetAttributes(const MDFN_PixelFormat &format)
|
||||
uint8 g = ((Spot.Colours.Green * 15) + 30);
|
||||
uint8 b = ((Spot.Colours.Blue * 15) + 30);
|
||||
|
||||
mColourMap[Spot.Index]= format.MakeColor(r, g, b);
|
||||
switch (bpp)
|
||||
{
|
||||
case 16:
|
||||
mColourMap[Spot.Index] = MAKECOLOR_16(r, g, b, 0);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
mColourMap[Spot.Index] = MAKECOLOR_32(r, g, b, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void CMikie::CopyLineSurface(void)
|
||||
void CMikie::CopyLineSurface(int32 bpp)
|
||||
{
|
||||
T* bitmap_tmp = mpDisplayCurrent->pix<T>() + mpDisplayCurrentLine * mpDisplayCurrent->pitchinpix;
|
||||
|
||||
if(mpDisplayCurrentLine > 102)
|
||||
{
|
||||
printf("Lynx Line Overflow: %d\n", mpDisplayCurrentLine);
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32 loop = 0; loop < SCREEN_WIDTH / 2; loop++)
|
||||
switch (bpp)
|
||||
{
|
||||
uint32 source = mpRamPointer[(uint16)mLynxAddr];
|
||||
if(mDISPCTL_Flip)
|
||||
case 16:
|
||||
{
|
||||
uint16 *bitmap_tmp = mpDisplayCurrent->pixels16 + mpDisplayCurrentLine * mpDisplayCurrent->pitch;
|
||||
for (uint32 loop = 0; loop < SCREEN_WIDTH / 2; loop++)
|
||||
{
|
||||
mLynxAddr--;
|
||||
*bitmap_tmp=mColourMap[mPalette[source&0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp=mColourMap[mPalette[source>>4].Index];
|
||||
bitmap_tmp++;
|
||||
uint32 source = mpRamPointer[(uint16)mLynxAddr];
|
||||
if (mDISPCTL_Flip)
|
||||
{
|
||||
mLynxAddr--;
|
||||
*bitmap_tmp = mColourMap[mPalette[source & 0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source >> 4].Index];
|
||||
bitmap_tmp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLynxAddr++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source >> 4].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source & 0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
{
|
||||
uint32 *bitmap_tmp = mpDisplayCurrent->pixels + mpDisplayCurrentLine * mpDisplayCurrent->pitch;
|
||||
for (uint32 loop = 0; loop < SCREEN_WIDTH / 2; loop++)
|
||||
{
|
||||
mLynxAddr++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source>>4].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source&0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
uint32 source = mpRamPointer[(uint16)mLynxAddr];
|
||||
if (mDISPCTL_Flip)
|
||||
{
|
||||
mLynxAddr--;
|
||||
*bitmap_tmp = mColourMap[mPalette[source & 0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source >> 4].Index];
|
||||
bitmap_tmp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLynxAddr++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source >> 4].Index];
|
||||
bitmap_tmp++;
|
||||
*bitmap_tmp = mColourMap[mPalette[source & 0x0f].Index];
|
||||
bitmap_tmp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CMikie::DisplayRenderLine(void)
|
||||
@ -486,16 +527,7 @@ uint32 CMikie::DisplayRenderLine(void)
|
||||
// Assign the temporary pointer;
|
||||
if(!mpSkipFrame)
|
||||
{
|
||||
switch(mpDisplayCurrent->format.bpp)
|
||||
{
|
||||
case 16:
|
||||
CopyLineSurface<uint16>();
|
||||
break;
|
||||
|
||||
case 32:
|
||||
CopyLineSurface<uint32>();
|
||||
break;
|
||||
}
|
||||
CopyLineSurface(mpDisplayCurrent->bpp);
|
||||
|
||||
if(mpDisplayCurrentLine < 102)
|
||||
LynxLineDrawn[mpDisplayCurrentLine] = true;
|
||||
|
@ -201,7 +201,7 @@ class CMikie : public CLynxBase
|
||||
void ComLynxTxLoopback(int data);
|
||||
void ComLynxTxCallback(void (*function)(int data,uint32 objref),uint32 objref);
|
||||
|
||||
void DisplaySetAttributes(const MDFN_PixelFormat &format);
|
||||
void DisplaySetAttributes(int32 bpp);
|
||||
|
||||
void BlowOut(void);
|
||||
|
||||
@ -395,7 +395,7 @@ class CMikie : public CLynxBase
|
||||
uint32 mLynxLineDMACounter;
|
||||
uint32 mLynxAddr;
|
||||
|
||||
template<typename T> void CopyLineSurface(void);
|
||||
void CopyLineSurface(int32 bpp);
|
||||
};
|
||||
|
||||
|
||||
|
@ -256,7 +256,7 @@ void Emulate(EmulateSpecStruct *espec)
|
||||
espec->DisplayRect.h = 102;
|
||||
|
||||
if(espec->VideoFormatChanged)
|
||||
lynxie->DisplaySetAttributes(espec->surface->format); // FIXME, pitch
|
||||
lynxie->DisplaySetAttributes(espec->surface->bpp);
|
||||
|
||||
if(espec->SoundFormatChanged)
|
||||
{
|
||||
@ -286,32 +286,36 @@ void Emulate(EmulateSpecStruct *espec)
|
||||
}
|
||||
|
||||
{
|
||||
// FIXME, we should integrate this into mikie.*
|
||||
uint32 color_black = espec->surface->MakeColor(30, 30, 30);
|
||||
// FIXME, we should integrate this into mikie.*
|
||||
uint32 color_black;
|
||||
if (espec->surface->bpp == 16)
|
||||
{
|
||||
color_black = MAKECOLOR_16(30, 30, 30, 0);
|
||||
for (int y = 0; y < 102; y++)
|
||||
{
|
||||
uint16 *row = espec->surface->pixels16 + y * espec->surface->pitch;
|
||||
|
||||
for(int y = 0; y < 102; y++)
|
||||
{
|
||||
if(espec->surface->format.bpp == 16)
|
||||
{
|
||||
uint16 *row = espec->surface->pixels16 + y * espec->surface->pitchinpix;
|
||||
if (!LynxLineDrawn[y])
|
||||
{
|
||||
for (int x = 0; x < 160; x++)
|
||||
row[x] = color_black;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (espec->surface->bpp == 32)
|
||||
{
|
||||
color_black = MAKECOLOR_32(30, 30, 30, 0);
|
||||
for (int y = 0; y < 102; y++)
|
||||
{
|
||||
uint32 *row = espec->surface->pixels + y * espec->surface->pitch;
|
||||
|
||||
if(!LynxLineDrawn[y])
|
||||
{
|
||||
for(int x = 0; x < 160; x++)
|
||||
row[x] = color_black;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 *row = espec->surface->pixels + y * espec->surface->pitchinpix;
|
||||
|
||||
if(!LynxLineDrawn[y])
|
||||
{
|
||||
for(int x = 0; x < 160; x++)
|
||||
row[x] = color_black;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!LynxLineDrawn[y])
|
||||
{
|
||||
for (int x = 0; x < 160; x++)
|
||||
row[x] = color_black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
espec->MasterCycles = gSystemCycleCount - lynxie->mMikie->startTS;
|
||||
|
@ -187,7 +187,7 @@ class CSystem : public CSystemBase
|
||||
|
||||
// Mikey system interfacing
|
||||
|
||||
void DisplaySetAttributes(const MDFN_PixelFormat &format) { mMikie->DisplaySetAttributes(format); };
|
||||
void DisplaySetAttributes(int32 bpp) { mMikie->DisplaySetAttributes(bpp); };
|
||||
|
||||
void ComLynxCable(int status) { mMikie->ComLynxCable(status); };
|
||||
void ComLynxRxData(int data) { mMikie->ComLynxRxData(data); };
|
||||
|
@ -1,122 +0,0 @@
|
||||
/* Mednafen - Multi-system Emulator
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../mednafen.h"
|
||||
#include "surface.h"
|
||||
|
||||
MDFN_PixelFormat::MDFN_PixelFormat()
|
||||
{
|
||||
bpp = 0;
|
||||
colorspace = 0;
|
||||
|
||||
Rshift = 0;
|
||||
Gshift = 0;
|
||||
Bshift = 0;
|
||||
Ashift = 0;
|
||||
}
|
||||
|
||||
MDFN_PixelFormat::MDFN_PixelFormat(const unsigned int p_colorspace, const uint8 p_rs, const uint8 p_gs, const uint8 p_bs, const uint8 p_as)
|
||||
{
|
||||
#if defined(WANT_16BPP)
|
||||
bpp = 16;
|
||||
#else
|
||||
bpp = 32;
|
||||
#endif
|
||||
colorspace = p_colorspace;
|
||||
|
||||
Rshift = p_rs;
|
||||
Gshift = p_gs;
|
||||
Bshift = p_bs;
|
||||
Ashift = p_as;
|
||||
}
|
||||
|
||||
MDFN_Surface::MDFN_Surface()
|
||||
{
|
||||
format = MDFN_PixelFormat();
|
||||
|
||||
pixels = NULL;
|
||||
pixels16 = NULL;
|
||||
pitchinpix = 0;
|
||||
w = 0;
|
||||
h = 0;
|
||||
}
|
||||
|
||||
MDFN_Surface::MDFN_Surface(void *const p_pixels, const uint32 p_width, const uint32 p_height, const uint32 p_pitchinpix, const MDFN_PixelFormat &nf)
|
||||
{
|
||||
Init(p_pixels, p_width, p_height, p_pitchinpix, nf);
|
||||
}
|
||||
|
||||
void MDFN_Surface::Init(void *const p_pixels, const uint32 p_width, const uint32 p_height, const uint32 p_pitchinpix, const MDFN_PixelFormat &nf)
|
||||
{
|
||||
void *rpix = NULL;
|
||||
assert(nf.bpp == 16 || nf.bpp == 32);
|
||||
|
||||
format = nf;
|
||||
|
||||
pixels16 = NULL;
|
||||
pixels = NULL;
|
||||
#if defined(WANT_8BPP)
|
||||
palette = NULL;
|
||||
#endif
|
||||
|
||||
if(!(rpix = calloc(1, p_pitchinpix * p_height * (nf.bpp / 8))))
|
||||
throw(1);
|
||||
|
||||
#if defined(WANT_8BPP)
|
||||
//if(nf.bpp == 8)
|
||||
{
|
||||
pixels8 = (uint8 *)rpix;
|
||||
palette = (MDFN_PaletteEntry*)calloc(sizeof(MDFN_PaletteEntry), 256);
|
||||
}
|
||||
#elif defined(WANT_16BPP)
|
||||
//if(nf.bpp == 16)
|
||||
pixels16 = (uint16 *)rpix;
|
||||
#elif defined(WANT_32BPP)
|
||||
//else
|
||||
pixels = (uint32 *)rpix;
|
||||
#endif
|
||||
|
||||
w = p_width;
|
||||
h = p_height;
|
||||
|
||||
pitchinpix = p_pitchinpix;
|
||||
}
|
||||
|
||||
// When we're converting, only convert the w*h area(AKA leave the last part of the line, pitch32 - w, alone),
|
||||
// for places where we store auxillary information there(graphics viewer in the debugger), and it'll be faster
|
||||
// to boot.
|
||||
void MDFN_Surface::SetFormat(const MDFN_PixelFormat &nf, bool convert)
|
||||
{
|
||||
format = nf;
|
||||
}
|
||||
|
||||
MDFN_Surface::~MDFN_Surface()
|
||||
{
|
||||
#if defined(WANT_16BPP)
|
||||
if(pixels16)
|
||||
free(pixels16);
|
||||
#elif defined(WANT_32BPP)
|
||||
if(pixels)
|
||||
free(pixels);
|
||||
#elif defined(WANT_8BPP)
|
||||
pixels8 = NULL;
|
||||
if(palette)
|
||||
free(palette);
|
||||
palette = NULL;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,204 +1,61 @@
|
||||
#ifndef __MDFN_SURFACE_H
|
||||
#define __MDFN_SURFACE_H
|
||||
|
||||
#if defined(WANT_32BPP)
|
||||
#define RED_SHIFT 16
|
||||
#define GREEN_SHIFT 8
|
||||
#define BLUE_SHIFT 0
|
||||
#define ALPHA_SHIFT 24
|
||||
#define MAKECOLOR(r, g, b, a) ((r << RED_SHIFT) | (g << GREEN_SHIFT) | (b << BLUE_SHIFT) | (a << ALPHA_SHIFT))
|
||||
#elif defined(WANT_16BPP) && defined(FRONTEND_SUPPORTS_RGB565)
|
||||
/* 16bit color - RGB565 */
|
||||
#define RED_MASK 0xf800
|
||||
#define GREEN_MASK 0x7e0
|
||||
#define BLUE_MASK 0x1f
|
||||
#define RED_EXPAND 3
|
||||
#define GREEN_EXPAND 2
|
||||
#define BLUE_EXPAND 3
|
||||
#define RED_SHIFT 11
|
||||
#define GREEN_SHIFT 5
|
||||
#define BLUE_SHIFT 0
|
||||
#define MAKECOLOR(r, g, b, a) (((r >> RED_EXPAND) << RED_SHIFT) | ((g >> GREEN_EXPAND) << GREEN_SHIFT) | ((b >> BLUE_EXPAND) << BLUE_SHIFT))
|
||||
#elif defined(WANT_16BPP) && !defined(FRONTEND_SUPPORTS_RGB565)
|
||||
/* 16bit color - RGB555 */
|
||||
#define RED_MASK 0x7c00
|
||||
#define GREEN_MASK 0x3e0
|
||||
#define BLUE_MASK 0x1f
|
||||
#define RED_EXPAND 3
|
||||
#define GREEN_EXPAND 3
|
||||
#define BLUE_EXPAND 3
|
||||
#define RED_SHIFT 10
|
||||
#define GREEN_SHIFT 5
|
||||
#define BLUE_SHIFT 0
|
||||
#define MAKECOLOR(r, g, b, a) (((r >> RED_EXPAND) << RED_SHIFT) | ((g >> GREEN_EXPAND) << GREEN_SHIFT) | ((b >> BLUE_EXPAND) << BLUE_SHIFT))
|
||||
#endif
|
||||
#include "mednafen-types.h"
|
||||
|
||||
struct MDFN_PaletteEntry
|
||||
{
|
||||
uint8 r, g, b;
|
||||
};
|
||||
/* 32bit color - XRGB8888 */
|
||||
#define RED_SHIFT_32 16
|
||||
#define GREEN_SHIFT_32 8
|
||||
#define BLUE_SHIFT_32 0
|
||||
#define ALPHA_SHIFT_32 24
|
||||
#define MAKECOLOR_32(r, g, b, a) ((r << RED_SHIFT_32) | (g << GREEN_SHIFT_32) | (b << BLUE_SHIFT_32) | (a << ALPHA_SHIFT_32))
|
||||
|
||||
/* 16bit color - RGB565 */
|
||||
#define RED_MASK_16 0xf800
|
||||
#define GREEN_MASK_16 0x7e0
|
||||
#define BLUE_MASK_16 0x1f
|
||||
#define RED_EXPAND_16 3
|
||||
#define GREEN_EXPAND_16 2
|
||||
#define BLUE_EXPAND_16 3
|
||||
#define RED_SHIFT_16 11
|
||||
#define GREEN_SHIFT_16 5
|
||||
#define BLUE_SHIFT_16 0
|
||||
#define MAKECOLOR_16(r, g, b, a) (((r >> RED_EXPAND_16) << RED_SHIFT_16) | ((g >> GREEN_EXPAND_16) << GREEN_SHIFT_16) | ((b >> BLUE_EXPAND_16) << BLUE_SHIFT_16))
|
||||
|
||||
/* 16bit color - RGB555 */
|
||||
#define RED_MASK_15 0x7c00
|
||||
#define GREEN_MASK_15 0x3e0
|
||||
#define BLUE_MASK_15 0x1f
|
||||
#define RED_EXPAND_15 3
|
||||
#define GREEN_EXPAND_15 3
|
||||
#define BLUE_EXPAND_15 3
|
||||
#define RED_SHIFT_15 10
|
||||
#define GREEN_SHIFT_15 5
|
||||
#define BLUE_SHIFT_15 0
|
||||
#define MAKECOLOR_15(r, g, b, a) (((r >> RED_EXPAND_15) << RED_SHIFT_15) | ((g >> GREEN_EXPAND_15) << GREEN_SHIFT_15) | ((b >> BLUE_EXPAND_15) << BLUE_SHIFT_15))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32 x, y, w, h;
|
||||
} MDFN_Rect;
|
||||
|
||||
enum
|
||||
typedef struct
|
||||
{
|
||||
MDFN_COLORSPACE_RGB = 0,
|
||||
MDFN_COLORSPACE_YCbCr = 1,
|
||||
MDFN_COLORSPACE_YUV = 2, // TODO, maybe.
|
||||
};
|
||||
unsigned int colorspace;
|
||||
uint8 r_shift;
|
||||
uint8 g_shift;
|
||||
uint8 b_shift;
|
||||
uint8 a_shift;
|
||||
} MDFN_PixelFormat;
|
||||
|
||||
class MDFN_PixelFormat
|
||||
typedef struct
|
||||
{
|
||||
public:
|
||||
|
||||
MDFN_PixelFormat();
|
||||
MDFN_PixelFormat(const unsigned int p_colorspace, const uint8 p_rs, const uint8 p_gs, const uint8 p_bs, const uint8 p_as);
|
||||
|
||||
unsigned int bpp;
|
||||
unsigned int colorspace;
|
||||
|
||||
union
|
||||
{
|
||||
uint8 Rshift; // Bit position of the lowest bit of the red component
|
||||
uint8 Yshift;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
uint8 Gshift; // [...] green component
|
||||
uint8 Ushift;
|
||||
uint8 Cbshift;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
uint8 Bshift; // [...] blue component
|
||||
uint8 Vshift;
|
||||
uint8 Crshift;
|
||||
};
|
||||
|
||||
uint8 Ashift; // [...] alpha component.
|
||||
// Creates a color value for the surface corresponding to the 8-bit R/G/B/A color passed.
|
||||
INLINE uint32 MakeColor(uint8 r, uint8 g, uint8 b, uint8 a = 0) const
|
||||
{
|
||||
return MAKECOLOR(r, g, b, a);
|
||||
}
|
||||
|
||||
// Gets the R/G/B/A values for the passed 32-bit surface pixel value
|
||||
#if defined(WANT_32BPP)
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b, int &a) const
|
||||
{
|
||||
r = (value >> RED_SHIFT) & 0xFF;
|
||||
g = (value >> GREEN_SHIFT) & 0xFF;
|
||||
b = (value >> BLUE_SHIFT) & 0xFF;
|
||||
a = (value >> ALPHA_SHIFT) & 0xFF;
|
||||
}
|
||||
#elif defined(WANT_16BPP)
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b, int &a) const
|
||||
{
|
||||
r = (value & BLUE_MASK) << RED_SHIFT;
|
||||
g = (value & GREEN_MASK) << GREEN_SHIFT;
|
||||
b = (value & RED_MASK);
|
||||
}
|
||||
#endif
|
||||
|
||||
}; // MDFN_PixelFormat;
|
||||
|
||||
// Supports 32-bit RGBA
|
||||
// 16-bit is WIP
|
||||
class MDFN_Surface //typedef struct
|
||||
{
|
||||
public:
|
||||
|
||||
MDFN_Surface();
|
||||
MDFN_Surface(void *const p_pixels, const uint32 p_width, const uint32 p_height, const uint32 p_pitchinpix, const MDFN_PixelFormat &nf);
|
||||
|
||||
~MDFN_Surface();
|
||||
|
||||
uint16 *pixels16;
|
||||
uint32 *pixels;
|
||||
|
||||
private:
|
||||
INLINE void pix_(uint16*& z) const { z = pixels16; }
|
||||
INLINE void pix_(uint32*& z) const { z = pixels; }
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
INLINE const T* pix(void) const
|
||||
{
|
||||
T* ret;
|
||||
pix_(ret);
|
||||
return (const T*)ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
INLINE T* pix(void)
|
||||
{
|
||||
T* ret;
|
||||
pix_(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// w, h, and pitch32 should always be > 0
|
||||
int32 w;
|
||||
int32 h;
|
||||
|
||||
union
|
||||
{
|
||||
int32 pitch32; // In pixels, not in bytes.
|
||||
int32 pitchinpix; // New name, new code should use this.
|
||||
};
|
||||
|
||||
MDFN_PaletteEntry *palette;
|
||||
|
||||
MDFN_PixelFormat format;
|
||||
|
||||
void SetFormat(const MDFN_PixelFormat &new_format, bool convert);
|
||||
|
||||
// Creates a value for the surface corresponding to the R/G/B/A color passed.
|
||||
INLINE uint32 MakeColor(uint8 r, uint8 g, uint8 b, uint8 a = 0) const
|
||||
{
|
||||
return MAKECOLOR(r, g, b, a);
|
||||
}
|
||||
|
||||
#if defined(WANT_32BPP)
|
||||
// Gets the R/G/B/A values for the passed 32-bit surface pixel value
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b, int &a) const
|
||||
{
|
||||
r = (value >> RED_SHIFT) & 0xFF;
|
||||
g = (value >> GREEN_SHIFT) & 0xFF;
|
||||
b = (value >> BLUE_SHIFT) & 0xFF;
|
||||
a = (value >> ALPHA_SHIFT) & 0xFF;
|
||||
}
|
||||
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b) const
|
||||
{
|
||||
r = (value >> RED_SHIFT) & 0xFF;
|
||||
g = (value >> GREEN_SHIFT) & 0xFF;
|
||||
b = (value >> BLUE_SHIFT) & 0xFF;
|
||||
}
|
||||
#elif defined(WANT_16BPP)
|
||||
|
||||
// Gets the R/G/B/A values for the passed 32-bit surface pixel value
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b, int &a) const
|
||||
{
|
||||
r = (value & BLUE_MASK) << RED_SHIFT;
|
||||
g = (value & GREEN_MASK) << GREEN_SHIFT;
|
||||
b = (value & RED_MASK);
|
||||
}
|
||||
|
||||
INLINE void DecodeColor(uint32 value, int &r, int &g, int &b) const
|
||||
{
|
||||
r = (value & BLUE_MASK) << RED_SHIFT;
|
||||
g = (value & GREEN_MASK) << GREEN_SHIFT;
|
||||
b = (value & RED_MASK);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
void Init(void *const p_pixels, const uint32 p_width, const uint32 p_height, const uint32 p_pitchinpix, const MDFN_PixelFormat &nf);
|
||||
};
|
||||
uint16 *pixels16;
|
||||
uint32 *pixels;
|
||||
int32 width;
|
||||
int32 height;
|
||||
int32 pitch;
|
||||
int32 bpp;
|
||||
} MDFN_Surface;
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user