Added alpha support, gamma calculations, and preliminary rtg multithreading support

This commit is contained in:
Dimitris Panokostas 2018-11-25 18:45:51 +01:00
parent 69e51d3c57
commit eb8eab3165
10 changed files with 646 additions and 227 deletions

View file

@ -1497,6 +1497,9 @@ void cfgfile_save_options(struct zfile* f, struct uae_prefs* p, int type)
}
cfgfile_write(f, _T("z3mem_start"), _T("0x%x"), p->z3autoconfig_start);
cfgfile_write(f, _T("bogomem_size"), _T("%d"), p->bogomem_size / 0x40000);
cfgfile_write_bool(f, _T("gfxcard_hardware_vblank"), p->rtg_hardwareinterrupt);
cfgfile_write_bool(f, _T("gfxcard_hardware_sprite"), p->rtg_hardwaresprite);
cfgfile_write_bool(f, _T("gfxcard_multithread"), p->rtg_multithread);
for (int i = 0; i < MAX_RTG_BOARDS; i++)
{
struct rtgboardconfig* rbc = &p->rtgboards[i];
@ -3573,14 +3576,34 @@ static int cfgfile_parse_hardware(struct uae_prefs* p, const TCHAR* option, TCHA
if (cfgfile_yesno(option, value, _T("immediate_blits"), &p->immediate_blits)
|| cfgfile_yesno(option, value, _T("fast_copper"), &p->fast_copper)
|| cfgfile_yesno(option, value, _T("fpu_no_unimplemented"), &p->fpu_no_unimplemented)
|| cfgfile_yesno(option, value, _T("cpu_no_unimplemented"), &p->int_no_unimplemented)
|| cfgfile_yesno(option, value, _T("cd32cd"), &p->cs_cd32cd)
|| cfgfile_yesno(option, value, _T("cd32c2p"), &p->cs_cd32c2p)
|| cfgfile_yesno(option, value, _T("cd32nvram"), &p->cs_cd32nvram)
|| cfgfile_yesno(option, value, _T("cdtvcd"), &p->cs_cdtvcd)
|| cfgfile_yesno(option, value, _T("cdtv-cr"), &p->cs_cdtvcr)
|| cfgfile_yesno(option, value, _T("cdtvram"), &p->cs_cdtvram)
|| cfgfile_yesno(option, value, _T("a1000ram"), &p->cs_a1000ram)
|| cfgfile_yesno(option, value, _T("cia_overlay"), &p->cs_ciaoverlay)
|| cfgfile_yesno(option, value, _T("bogomem_fast"), &p->cs_slowmemisfast)
|| cfgfile_yesno(option, value, _T("ksmirror_e0"), &p->cs_ksmirror_e0)
|| cfgfile_yesno(option, value, _T("ksmirror_a8"), &p->cs_ksmirror_a8)
|| cfgfile_yesno(option, value, _T("resetwarning"), &p->cs_resetwarning)
|| cfgfile_yesno(option, value, _T("cia_todbug"), &p->cs_ciatodbug)
|| cfgfile_yesno(option, value, _T("denise_noehb"), &p->cs_denisenoehb)
|| cfgfile_yesno(option, value, _T("ics_agnus"), &p->cs_dipagnus)
|| cfgfile_yesno(option, value, _T("z3_autoconfig"), &p->cs_z3autoconfig)
|| cfgfile_yesno(option, value, _T("color_burst"), &p->cs_color_burst)
|| cfgfile_yesno(option, value, _T("toshiba_gary"), &p->cs_toshibagary)
|| cfgfile_yesno(option, value, _T("rom_is_slow"), &p->cs_romisslow)
|| cfgfile_yesno(option, value, _T("1mchipjumper"), &p->cs_1mchipjumper)
|| cfgfile_yesno(option, value, _T("agnus_bltbusybug"), &p->cs_agnusbltbusybug)
|| cfgfile_yesno(option, value, _T("gfxcard_hardware_vblank"), &p->rtg_hardwareinterrupt)
|| cfgfile_yesno(option, value, _T("gfxcard_hardware_sprite"), &p->rtg_hardwaresprite)
|| cfgfile_yesno(option, value, _T("gfxcard_multithread"), &p->rtg_multithread)
|| cfgfile_yesno(option, value, _T("synchronize_clock"), &p->tod_hack)
|| cfgfile_yesno(option, value, _T("keyboard_connected"), &p->keyboard_connected)
|| cfgfile_yesno(option, value, _T("lightpen_crosshair"), &p->lightpen_crosshair)
|| cfgfile_yesno(option, value, _T("ntsc"), &p->ntscmode)
|| cfgfile_yesno(option, value, _T("cpu_compatible"), &p->cpu_compatible)

View file

@ -5699,7 +5699,7 @@ static void vsync_handler_pre(void)
// GUI check here, must be after frame rendering
devices_vsync_pre();
if (!nodraw() || (picasso_on && picasso_rendered))
if (!nodraw() || picasso_on)
fpscounter(frameok);
handle_events();

View file

@ -76,6 +76,9 @@ void devices_hsync(void)
#endif
decide_blitter(-1);
#ifdef PICASSO96
picasso_handle_hsync();
#endif
DISK_hsync();
audio_hsync();
gayle_hsync();
@ -128,6 +131,7 @@ void do_leave_program(void)
#ifdef JIT
compiler_exit();
#endif
picasso_free();
graphics_leave();
inputdevice_close();
DISK_free();

View file

@ -3528,16 +3528,24 @@ void drawing_init(void)
int isvsync_chipset(void)
{
if (picasso_on)
if (picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0)
return 0;
return 1;
if (currprefs.gfx_apmode[0].gfx_vsyncmode == 0)
return 1;
if (currprefs.m68k_speed >= 0)
return -1;
return currprefs.cachesize ? -3 : -2;
}
int isvsync_rtg(void)
{
if (!picasso_on)
return 0;
return 1;
if (currprefs.gfx_apmode[1].gfx_vsyncmode == 0)
return 1;
if (currprefs.m68k_speed >= 0)
return -1;
return currprefs.cachesize ? -3 : -2;
}
int isvsync(void)

View file

@ -13,22 +13,24 @@
#include "rtgmodes.h"
#include "xwin.h"
#include <math.h>
#define RED 0
#define GRN 1
#define BLU 2
unsigned int doMask (int p, int bits, int shift)
unsigned int doMask(int p, int bits, int shift)
{
/* scale to 0..255, shift to align msb with mask, and apply mask */
uae_u32 val;
/* scale to 0..255, shift to align msb with mask, and apply mask */
uae_u32 val;
val = p << 24;
if (!bits)
return 0;
val >>= (32 - bits);
val <<= shift;
if (!bits)
return 0;
val >>= (32 - bits);
val <<= shift;
return val;
return val;
}
int bits_in_mask(unsigned long mask)
@ -53,36 +55,158 @@ int mask_shift(unsigned long mask)
return n;
}
unsigned int doMask256 (int p, int bits, int shift)
unsigned int doMask256(int p, int bits, int shift)
{
/* p is a value from 0 to 255 (Amiga color value)
* shift to align msb with mask, and apply mask */
/* p is a value from 0 to 255 (Amiga color value)
* shift to align msb with mask, and apply mask */
unsigned long val = p * 0x01010101UL;
unsigned long val = p * 0x01010101UL;
if (bits == 0)
return 0;
val >>= (32 - bits);
val <<= shift;
val >>= (32 - bits);
val <<= shift;
return val;
return val;
}
static unsigned int doColor(int i, int bits, int shift)
{
int shift2;
int shift2;
if(bits >= 8)
shift2 = 0;
else
shift2 = 8 - bits;
return (i >> shift2) << shift;
if (bits >= 8)
shift2 = 0;
else
shift2 = 8 - bits;
return (i >> shift2) << shift;
}
static uae_u32 lowbits (int v, int shift, int lsize)
static unsigned int doAlpha(int alpha, int bits, int shift)
{
v >>= shift;
v &= (1 << lsize) - 1;
return v;
return (alpha & ((1 << bits) - 1)) << shift;
}
static float video_gamma(float value, float gamma, float bri, float con)
{
double factor;
float ret;
value += bri;
value *= con;
if (value <= 0.0f)
return 0.0f;
factor = pow(255.0f, 1.0f - gamma);
ret = (float)(factor * pow(value, gamma));
if (ret < 0.0f)
ret = 0.0f;
return ret;
}
static uae_u32 gamma_value[256 * 3][3];
static int lf, hf;
static void video_calc_gammatable()
{
float bri, con, gam, gams[3];
bri = ((float)(currprefs.gfx_luminance)) * (128.0f / 1000.0f);
con = ((float)(currprefs.gfx_contrast + 1000)) / 1000.0f;
gam = ((float)(1000 - currprefs.gfx_gamma)) / 1000.0f - 1.0;
gams[0] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[0])) / 1000.0f;
gams[1] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[1])) / 1000.0f;
gams[2] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[2])) / 1000.0f;
lf = 64 * currprefs.gf[picasso_on].gfx_filter_blur / 1000;
hf = 256 - lf * 2;
for (int i = 0; i < (256 * 3); i++) {
for (int j = 0; j < 3; j++) {
float val = i - 256;
float v;
if (currprefs.gfx_threebitcolors == 2) {
val *= 2;
}
else if (currprefs.gfx_threebitcolors == 3) {
val = (val * 252.0) / 119.0;
}
else if (currprefs.gfx_threebitcolors == 1) {
val = (val * 252.0) / 238.0;
}
if (currprefs.gfx_luminance == 0 && currprefs.gfx_contrast == 0 && currprefs.gfx_gamma == 0 &&
currprefs.gfx_gamma_ch[0] == 0 && currprefs.gfx_gamma_ch[1] == 0 && currprefs.gfx_gamma_ch[2] == 0) {
v = val;
}
else {
v = video_gamma(val, gams[j], bri, con);
}
if (v < 0.0)
v = 0.0;
if (v > 255.0)
v = 255.0;
gamma_value[i][j] = (uae_u32)(v + 0.5);
}
}
}
static uae_u32 limit256(int monid, double v)
{
struct amigadisplay *ad = &adisplays[monid];
v = v * (double)(currprefs.gf[ad->picasso_on].gfx_filter_contrast + 1000) / 1000.0 + currprefs.gf[ad->picasso_on].gfx_filter_luminance / 10.0;
if (v < 0)
v = 0;
if (v > 255)
v = 255;
return ((uae_u32)v) & 0xff;
}
static uae_u32 limit256rb(int monid, double v)
{
struct amigadisplay *ad = &adisplays[monid];
v *= (double)(currprefs.gf[ad->picasso_on].gfx_filter_saturation + 1000) / 1000.0;
if (v < -128)
v = -128;
if (v > 127)
v = 127;
return ((uae_u32)v) & 0xff;
}
static double get_y(int r, int g, int b)
{
return 0.2989f * r + 0.5866f * g + 0.1145f * b;
}
static uae_u32 get_yh(int monid, int r, int g, int b)
{
return limit256(monid, get_y(r, g, b) * hf / 256);
}
static uae_u32 get_yl(int monid, int r, int g, int b)
{
return limit256(monid, get_y(r, g, b) * lf / 256);
}
static uae_u32 get_cb(int monid, int r, int g, int b)
{
return limit256rb(monid, -0.168736f * r - 0.331264f * g + 0.5f * b);
}
static uae_u32 get_cr(int monid, int r, int g, int b)
{
return limit256rb(monid, 0.5f * r - 0.418688f * g - 0.081312f * b);
}
extern uae_s32 tyhrgb[65536];
extern uae_s32 tylrgb[65536];
extern uae_s32 tcbrgb[65536];
extern uae_s32 tcrrgb[65536];
extern uae_u32 redc[3 * 256], grec[3 * 256], bluc[3 * 256];
static uae_u32 lowbits(int v, int shift, int lsize)
{
v >>= shift;
v &= (1 << lsize) - 1;
return v;
}
void alloc_colors_picasso(int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt)
@ -178,24 +302,35 @@ void alloc_colors_picasso(int rw, int gw, int bw, int rs, int gs, int bs, int rg
#endif
}
void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int byte_swap,
void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap,
uae_u32 *rc, uae_u32 *gc, uae_u32 *bc)
{
int bpp = rw + gw + bw;
int bpp = rw + gw + bw + aw;
int i;
for(i = 0; i < 256; i++) {
rc[i] = doColor (i, rw, rs);
gc[i] = doColor (i, gw, gs);
bc[i] = doColor (i, bw, bs);
for (i = 0; i < 256; i++) {
int j;
if (currprefs.gfx_blackerthanblack) {
j = i * 15 / 16 + 15;
}
else {
j = i;
}
j += 256;
rc[i] = doColor(gamma_value[j][0], rw, rs) | doAlpha(alpha, aw, as);
gc[i] = doColor(gamma_value[j][1], gw, gs) | doAlpha(alpha, aw, as);
bc[i] = doColor(gamma_value[j][2], bw, bs) | doAlpha(alpha, aw, as);
if (byte_swap) {
if (bpp <= 16) {
rc[i] = bswap_16 (rc[i]);
gc[i] = bswap_16 (gc[i]);
bc[i] = bswap_16 (bc[i]);
} else {
rc[i] = bswap_32 (rc[i]);
gc[i] = bswap_32 (gc[i]);
bc[i] = bswap_32 (bc[i]);
rc[i] = bswap_16(rc[i]);
gc[i] = bswap_16(gc[i]);
bc[i] = bswap_16(bc[i]);
}
else {
rc[i] = bswap_32(rc[i]);
gc[i] = bswap_32(gc[i]);
bc[i] = bswap_32(bc[i]);
}
}
if (bpp <= 16) {
@ -208,17 +343,21 @@ void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int byte_s
}
}
void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int byte_swap)
void alloc_colors64k(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, bool yuv)
{
int bpp = rw + gw + bw;
int i, j;
video_calc_gammatable();
j = 256;
for (i = 0; i < 4096; i++) {
int r = ((i >> 8) << 4) | (i >> 8);
int g = (((i >> 4) & 0xf) << 4) | ((i >> 4) & 0x0f);
int b = ((i & 0xf) << 4) | (i & 0x0f);
xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs);
r = gamma_value[r + j][0];
g = gamma_value[g + j][1];
b = gamma_value[b + j][2];
xcolors[i] = doMask(r, rw, rs) | doMask(g, gw, gs) | doMask(b, bw, bs) | doAlpha(alpha, aw, as);
if (byte_swap) {
if (bpp <= 16) {
xcolors[i] = bswap_16(xcolors[i]);
@ -233,5 +372,82 @@ void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int byte_s
xcolors[i] |= xcolors[i] * 0x00010001;
}
}
alloc_colors_rgb(rw, gw, bw, rs, gs, bs, byte_swap, xredcolors, xgreencolors, xbluecolors);
#if defined(AGA) || defined(GFXFILTER)
alloc_colors_rgb(rw, gw, bw, rs, gs, bs, aw, as, alpha, byte_swap, xredcolors, xgreencolors, xbluecolors);
/* copy original color table */
//for (i = 0; i < 256; i++) {
// redc[0 * 256 + i] = xredcolors[0];
// grec[0 * 256 + i] = xgreencolors[0];
// bluc[0 * 256 + i] = xbluecolors[0];
// redc[1 * 256 + i] = xredcolors[i];
// grec[1 * 256 + i] = xgreencolors[i];
// bluc[1 * 256 + i] = xbluecolors[i];
// redc[2 * 256 + i] = xredcolors[255];
// grec[2 * 256 + i] = xgreencolors[255];
// bluc[2 * 256 + i] = xbluecolors[255];
//}
#ifdef GFXFILTER
if (yuv) {
/* create internal 5:6:5 color tables */
for (i = 0; i < 256; i++) {
j = i + 256;
xredcolors[i] = doColor(gamma[j][0], 5, 11);
xgreencolors[i] = doColor(gamma[j][1], 6, 5);
xbluecolors[i] = doColor(gamma[j][2], 5, 0);
if (bpp <= 16) {
/* Fill upper 16 bits of each colour value with
* a copy of the colour. */
xredcolors[i] = xredcolors[i] * 0x00010001;
xgreencolors[i] = xgreencolors[i] * 0x00010001;
xbluecolors[i] = xbluecolors[i] * 0x00010001;
}
}
for (i = 0; i < 4096; i++) {
int r = ((i >> 8) << 4) | (i >> 8);
int g = (((i >> 4) & 0xf) << 4) | ((i >> 4) & 0x0f);
int b = ((i & 0xf) << 4) | (i & 0x0f);
r = gamma[r + 256][0];
g = gamma[g + 256][1];
b = gamma[b + 256][2];
xcolors[i] = doMask(r, 5, 11) | doMask(g, 6, 5) | doMask(b, 5, 0);
if (byte_swap) {
if (bpp <= 16)
xcolors[i] = bswap_16(xcolors[i]);
else
xcolors[i] = bswap_32(xcolors[i]);
}
if (bpp <= 16) {
/* Fill upper 16 bits of each colour value
* with a copy of the colour. */
xcolors[i] |= xcolors[i] * 0x00010001;
}
}
/* create RGB 5:6:5 -> YUV tables */
for (i = 0; i < 65536; i++) {
uae_u32 r, g, b;
r = (((i >> 11) & 31) << 3) | lowbits(i, 11, 3);
r = gamma[r + 256][0];
g = (((i >> 5) & 63) << 2) | lowbits(i, 5, 2);
g = gamma[g + 256][1];
b = (((i >> 0) & 31) << 3) | lowbits(i, 0, 3);
b = gamma[b + 256][2];
tyhrgb[i] = get_yh(monid, r, g, b) * 256 * 256;
tylrgb[i] = get_yl(monid, r, g, b) * 256 * 256;
tcbrgb[i] = ((uae_s8)get_cb(monid, r, g, b)) * 256;
tcrrgb[i] = ((uae_s8)get_cr(monid, r, g, b)) * 256;
}
}
#endif
#endif
//xredcolor_b = rw;
//xgreencolor_b = gw;
//xbluecolor_b = bw;
//xredcolor_s = rs;
//xgreencolor_s = gs;
//xbluecolor_s = bs;
//xredcolor_m = ((1 << rw) - 1) << xredcolor_s;
//xgreencolor_m = ((1 << gw) - 1) << xgreencolor_s;
//xbluecolor_m = ((1 << bw) - 1) << xbluecolor_s;
}

View file

@ -46,8 +46,8 @@ extern int bits_in_mask (unsigned long mask);
extern int mask_shift (unsigned long mask);
extern unsigned int doMask (int p, int bits, int shift);
extern unsigned int doMask256 (int p, int bits, int shift);
extern void alloc_colors64k (int, int, int, int, int, int, int);
extern void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int byte_swap,
extern void alloc_colors64k(int, int, int, int, int, int, int, int, int, int, bool);
extern void alloc_colors_rgb(int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap,
uae_u32 *rc, uae_u32 *gc, uae_u32 *bc);
extern void alloc_colors_picasso (int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt);
@ -67,19 +67,19 @@ extern void alloc_colors_picasso (int rw, int gw, int bw, int rs, int gs, int bs
*/
struct vidbuffer
{
uae_u8 *bufmem;
int rowbytes; /* Bytes per row in the memory pointed at by bufmem. */
int pixbytes; /* Bytes per pixel. */
/* size of max visible image */
int outwidth;
int outheight;
uae_u8 *bufmem;
int rowbytes; /* Bytes per row in the memory pointed at by bufmem. */
int pixbytes; /* Bytes per pixel. */
/* size of max visible image */
int outwidth;
int outheight;
};
extern int max_uae_width, max_uae_height;
struct vidbuf_description
{
struct vidbuffer drawbuffer;
struct vidbuffer drawbuffer;
};
extern struct vidbuf_description gfxvidinfo;

View file

@ -927,7 +927,10 @@ static int init_colors()
red_shift = mask_shift(screen->format->Rmask);
green_shift = mask_shift(screen->format->Gmask);
blue_shift = mask_shift(screen->format->Bmask);
alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, 0);
alpha_bits = 0;
alpha_shift = 0;
alloc_colors64k(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, alpha_bits, alpha_shift, alpha, 0, false);
notice_new_xcolors();
return 1;
@ -970,7 +973,7 @@ int GetSurfacePixelFormat()
: depth == 16 && unit == 16
? RGBFB_R5G6B5
: unit == 24
? RGBFB_B8G8R8
? RGBFB_R8G8B8
: unit == 32
? RGBFB_R8G8B8A8
: RGBFB_NONE;
@ -1384,6 +1387,7 @@ void gfx_set_picasso_modeinfo(uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbf
picasso_vidinfo.depth = screen->format->BitsPerPixel; // Native depth
picasso_vidinfo.extra_mem = 1;
picasso_vidinfo.pixbytes = screen->format->BytesPerPixel; // Native bytes
picasso_vidinfo.offset = 0;
if (screen_is_picasso)
{

View file

@ -41,6 +41,7 @@
#include "sysconfig.h"
#include "sysdeps.h"
#include "gfxboard.h"
#if defined(PICASSO96)
@ -69,11 +70,20 @@
static const int defaultHz = 60;
//TODO use the amigadisplay struct eventually
#ifdef AMIBERRY
bool pending_render;
#endif
static int picasso96_BT = BT_uaegfx;
static int picasso96_GCT = GCT_Unknown;
static int picasso96_PCT = PCT_Unknown;
bool have_done_picasso = true; /* For the JIT compiler */
static int p96syncrate;
static smp_comm_pipe *render_pipe;
static volatile int render_thread_state;
#define PICASSO_STATE_SETDISPLAY 1
#define PICASSO_STATE_SETPANNING 2
@ -105,8 +115,6 @@ struct picasso96_state_struct picasso96_state;
struct picasso_vidbuf_description picasso_vidinfo;
static struct PicassoResolution* newmodes = nullptr;
static int picasso_convert, host_mode;
/* These are the maximum resolutions... They are filled in by GetSupportedResolutions() */
/* have to fill this in, otherwise problems occur on the Amiga side P96 s/w which expects
/* data here. */
@ -122,8 +130,6 @@ uae_u32 p96rc[256], p96gc[256], p96bc[256];
static uaecptr boardinfo, ABI_interrupt;
static int interrupt_enabled;
double p96vblank;
static bool picasso_active;
static bool picasso_changed;
static int uaegfx_old, uaegfx_active;
static uae_u32 reserved_gfxmem;
@ -576,72 +582,99 @@ static void do_fillrect_frame_buffer (struct RenderInfo *ri, int X, int Y, int W
}
static int p96_framecnt;
static int doskip (void)
static int doskip(void)
{
if (p96_framecnt > currprefs.gfx_framerate)
p96_framecnt = 0;
return p96_framecnt > 0;
if (p96_framecnt > currprefs.gfx_framerate)
p96_framecnt = 0;
return p96_framecnt > 0;
}
void picasso_trigger_vblank (void)
void picasso_trigger_vblank(void)
{
TrapContext *ctx = NULL;
if (!ABI_interrupt || !uaegfx_base || !interrupt_enabled)
return;
if (!ABI_interrupt || !uaegfx_base || !interrupt_enabled)
return;
trap_put_long(ctx, uaegfx_base + CARD_IRQPTR, ABI_interrupt + PSSO_BoardInfo_SoftInterrupt);
trap_put_byte(ctx, uaegfx_base + CARD_IRQFLAG, 1);
}
static bool rtg_render (void)
static bool is_uaegfx_active(void)
{
bool flushed = false;
if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.rtgboards[0].rtgmem_size)
return false;
return true;
}
if (!doskip ())
flushed = picasso_flushpixels (gfxmem_banks[0]->start + regs.natmem_offset, picasso96_state.XYOffset - gfxmem_banks[0]->start);
return flushed;
static void rtg_render (void)
{
bool uaegfx_active = is_uaegfx_active();
int uaegfx_index = 0;
if (doskip ())
{
return;
}
else {
bool full = picasso_vidinfo.full_refresh > 0;
if (uaegfx_active) {
if (!currprefs.rtg_multithread) {
picasso_flushpixels(gfxmem_banks[0]->start + regs.natmem_offset, picasso96_state.XYOffset - gfxmem_banks[0]->start);
}
}
else {
if (picasso_vidinfo.full_refresh < 0)
picasso_vidinfo.full_refresh = 0;
if (picasso_vidinfo.full_refresh > 0)
picasso_vidinfo.full_refresh--;
}
//gfxboard_vsync_handler(full, true);
if (currprefs.rtg_multithread && uaegfx_active) {
if (pending_render) {
pending_render = false;
gfx_unlock_picasso(true);
}
write_comm_pipe_int(render_pipe, uaegfx_index, 0);
}
}
}
static void rtg_clear (void)
{
picasso_vidinfo.rtg_clear_flag = 4;
}
static int set_panning_called = 0;
enum {
/* DEST = RGBFB_B8G8R8A8,32 */
RGBFB_A8R8G8B8_32 = 1,
RGBFB_A8B8G8R8_32,
RGBFB_R8G8B8A8_32,
RGBFB_B8G8R8A8_32,
RGBFB_R8G8B8_32,
RGBFB_B8G8R8_32,
RGBFB_R5G6B5PC_32,
RGBFB_R5G5B5PC_32,
RGBFB_R5G6B5_32,
RGBFB_R5G5B5_32,
RGBFB_B5G6R5PC_32,
RGBFB_B5G5R5PC_32,
RGBFB_CLUT_RGBFB_32,
/* DEST = RGBFB_B8G8R8A8,32 */
RGBFB_A8R8G8B8_32 = 1,
RGBFB_A8B8G8R8_32,
RGBFB_R8G8B8A8_32,
RGBFB_B8G8R8A8_32,
RGBFB_R8G8B8_32,
RGBFB_B8G8R8_32,
RGBFB_R5G6B5PC_32,
RGBFB_R5G5B5PC_32,
RGBFB_R5G6B5_32,
RGBFB_R5G5B5_32,
RGBFB_B5G6R5PC_32,
RGBFB_B5G5R5PC_32,
RGBFB_CLUT_RGBFB_32,
/* DEST = RGBFB_R5G6B5PC,16 */
RGBFB_A8R8G8B8_16,
RGBFB_A8B8G8R8_16,
RGBFB_R8G8B8A8_16,
RGBFB_B8G8R8A8_16,
RGBFB_R8G8B8_16,
RGBFB_B8G8R8_16,
RGBFB_R5G6B5PC_16,
RGBFB_R5G5B5PC_16,
RGBFB_R5G6B5_16,
RGBFB_R5G5B5_16,
RGBFB_B5G6R5PC_16,
RGBFB_B5G5R5PC_16,
RGBFB_CLUT_RGBFB_16,
/* DEST = RGBFB_R5G6B5PC,16 */
RGBFB_A8R8G8B8_16,
RGBFB_A8B8G8R8_16,
RGBFB_R8G8B8A8_16,
RGBFB_B8G8R8A8_16,
RGBFB_R8G8B8_16,
RGBFB_B8G8R8_16,
RGBFB_R5G6B5PC_16,
RGBFB_R5G5B5PC_16,
RGBFB_R5G6B5_16,
RGBFB_R5G5B5_16,
RGBFB_B5G6R5PC_16,
RGBFB_B5G5R5PC_16,
RGBFB_CLUT_RGBFB_16,
/* DEST = RGBFB_CLUT,8 */
RGBFB_CLUT_8
/* DEST = RGBFB_CLUT,8 */
RGBFB_CLUT_8
};
static int getconvert (int rgbformat, int pixbytes)
@ -740,27 +773,26 @@ static int getconvert (int rgbformat, int pixbytes)
static void setconvert(void)
{
static int ohost_mode, orgbformat;
picasso_convert = getconvert(picasso96_state.RGBFormat, picasso_vidinfo.pixbytes);
host_mode = GetSurfacePixelFormat();
picasso_vidinfo.picasso_convert = getconvert(picasso96_state.RGBFormat, picasso_vidinfo.pixbytes);
picasso_vidinfo.host_mode = GetSurfacePixelFormat();
if (picasso_vidinfo.pixbytes == 4)
alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, p96rc, p96gc, p96bc);
alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc);
else
alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, p96rc, p96gc, p96bc);
alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc);
gfx_set_picasso_colors(picasso96_state.RGBFormat);
picasso_palette(picasso96_state.CLUT);
if (host_mode != ohost_mode || picasso96_state.RGBFormat != orgbformat) {
if (picasso_vidinfo.host_mode != picasso_vidinfo.ohost_mode || picasso96_state.RGBFormat != picasso_vidinfo.orgbformat) {
write_log(_T("RTG conversion: Depth=%d HostRGBF=%d P96RGBF=%d Mode=%d\n"),
picasso_vidinfo.pixbytes, host_mode, picasso96_state.RGBFormat, picasso_convert);
ohost_mode = host_mode;
orgbformat = picasso96_state.RGBFormat;
picasso_vidinfo.pixbytes, host_mode, picasso96_state.RGBFormat, picasso_vidinfo.picasso_convert);
picasso_vidinfo.ohost_mode = picasso_vidinfo.host_mode;
picasso_vidinfo.orgbformat = picasso96_state.RGBFormat;
}
picasso_vidinfo.full_refresh = 1;
}
bool picasso_is_active (void)
{
return picasso_active;
return picasso_vidinfo.picasso_active;
}
/* Clear our screen, since we've got a new Picasso screen-mode, and refresh with the proper contents
@ -769,40 +801,39 @@ bool picasso_is_active (void)
* 2. Picasso-->Picasso transition, via SetPanning().
* 3. whenever the graphics code notifies us that the screen contents have been lost.
*/
void picasso_refresh (void)
void picasso_refresh(void)
{
struct RenderInfo ri;
struct RenderInfo ri;
if (!picasso_on)
return;
setconvert ();
if (!picasso_on)
return;
picasso_vidinfo.full_refresh = 1;
setconvert();
rtg_clear();
/* Make sure that the first time we show a Picasso video mode, we don't blit any crap.
* We can do this by checking if we have an Address yet.
*/
if (picasso96_state.Address) {
/* blit the stuff from our static frame-buffer to the gfx-card */
ri.Memory = gfxmem_bank.baseaddr + (picasso96_state.Address - gfxmem_bank.start);
ri.BytesPerRow = picasso96_state.BytesPerRow;
ri.RGBFormat = (RGBFTYPE)picasso96_state.RGBFormat;
} else {
write_log (_T("ERROR - picasso_refresh() can't refresh!\n"));
}
/* Make sure that the first time we show a Picasso video mode, we don't blit any crap.
* We can do this by checking if we have an Address yet.
*/
if (picasso96_state.Address) {
/* blit the stuff from our static frame-buffer to the gfx-card */
ri.Memory = gfxmem_bank.baseaddr + (picasso96_state.Address - gfxmem_bank.start);
ri.BytesPerRow = picasso96_state.BytesPerRow;
ri.RGBFormat = (RGBFTYPE)picasso96_state.RGBFormat;
}
else {
write_log(_T("ERROR - picasso_refresh() can't refresh!\n"));
}
}
bool picasso_rendered = false;
void picasso_handle_vsync(void)
static void picasso_handle_vsync2()
{
static int vsynccnt;
if (currprefs.rtgboards[0].rtgmem_size == 0)
return;
if (!picasso_on) {
picasso_trigger_vblank ();
return;
}
int thisisvsync = 1;
int vsync = isvsync_rtg();
int mult;
bool rendered = false;
bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
bool uaegfx_active = is_uaegfx_active();
int state = picasso_state_change;
if (state & PICASSO_STATE_SETDAC) {
@ -812,7 +843,7 @@ void picasso_handle_vsync(void)
if (state & PICASSO_STATE_SETGC) {
atomic_and(&picasso_state_change, ~PICASSO_STATE_SETGC);
set_gc_called = 1;
picasso_changed = true;
picasso_vidinfo.picasso_changed = true;
init_picasso_screen();
init_hz_p96();
}
@ -821,27 +852,111 @@ void picasso_handle_vsync(void)
/* Do not switch immediately. Tell the custom chip emulation about the
* desired state, and wait for custom.c to call picasso_enablescreen
* whenever it is ready to change the screen state. */
if (picasso_on == picasso_requested_on && picasso_requested_on && picasso_changed) {
if (picasso_on == picasso_requested_on && picasso_requested_on && picasso_vidinfo.picasso_changed) {
picasso_requested_forced_on = true;
}
picasso_changed = false;
picasso_active = picasso_requested_on;
picasso_vidinfo.picasso_changed = false;
picasso_vidinfo.picasso_active = picasso_requested_on;
}
if (state & PICASSO_STATE_SETPANNING) {
atomic_and(&picasso_state_change, ~PICASSO_STATE_SETPANNING);
set_panning_called = 1;
picasso_vidinfo.full_refresh = 1;
picasso_vidinfo.set_panning_called = 1;
init_picasso_screen();
set_panning_called = 0;
picasso_vidinfo.set_panning_called = 0;
}
if (state & PICASSO_STATE_SETDISPLAY) {
atomic_and(&picasso_vidinfo.picasso_state_change, ~PICASSO_STATE_SETDISPLAY);
// do nothing
}
//getvsyncrate(mon->monitor_id, currprefs.chipset_refreshrate, &mult);
//if (vsync && mult < 0) {
// vsynccnt++;
// if (vsynccnt < 2)
// thisisvsync = 0;
// else
// vsynccnt = 0;
//}
p96_framecnt++;
if (!uaegfx && !picasso_on) {
rtg_render();
return;
}
if (!picasso_on)
return;
picasso_rendered = rtg_render();
if (thisisvsync) {
rtg_render();
}
picasso_trigger_vblank();
if (uaegfx) {
if (thisisvsync)
picasso_trigger_vblank();
}
}
static int p96hsync;
void picasso_handle_vsync(void)
{
bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
bool uaegfx_active = is_uaegfx_active();
if (currprefs.rtgboards[0].rtgmem_size == 0)
return;
if (!picasso_on && uaegfx) {
picasso_trigger_vblank ();
return;
}
//int vsync = isvsync_rtg();
//if (vsync < 0) {
p96hsync = 0;
picasso_handle_vsync2();
//}
}
void picasso_handle_hsync(void)
{
bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE;
bool uaegfx_active = is_uaegfx_active();
if (currprefs.rtgboards[0].rtgmem_size == 0)
return;
if (pending_render) {
pending_render = false;
gfx_unlock_picasso(true);
}
//int vsync = isvsync_rtg();
//if (vsync < 0) {
//p96hsync++;
if (p96hsync >= p96syncrate * 3) {
p96hsync = 0;
// kickstart vblank vsync_busywait stuff
picasso_handle_vsync();
}
//return;
//}
p96hsync++;
if (p96hsync >= p96syncrate) {
if (picasso_on) {
if (uaegfx) {
picasso_trigger_vblank();
}
}
else {
picasso_handle_vsync2();
}
p96hsync = 0;
}
}
#define BLT_SIZE 4
@ -1298,27 +1413,29 @@ static uae_u32 REGPARAM2 picasso_SetSprite (TrapContext *ctx)
* the MemoryBase, MemorySize and RegisterBase fields.
*/
static void picasso96_alloc2 (TrapContext *ctx);
static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx)
static uae_u32 REGPARAM2 picasso_FindCard(TrapContext *ctx)
{
uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0);
/* NOTES: See BoardInfo struct definition in Picasso96 dev info */
/* NOTES: See BoardInfo struct definition in Picasso96 dev info */
if (!uaegfx_active || !gfxmem_bank.start)
return 0;
return 0;
if (uaegfx_base) {
trap_put_long(ctx, uaegfx_base + CARD_BOARDINFO, AmigaBoardInfo);
} else if (uaegfx_old) {
picasso96_alloc2 (ctx);
}
boardinfo = AmigaBoardInfo;
else if (uaegfx_old) {
picasso96_alloc2(ctx);
}
boardinfo = AmigaBoardInfo;
if (gfxmem_bank.allocated_size && !picasso96_state_uaegfx.CardFound) {
/* Fill in MemoryBase, MemorySize */
if (gfxmem_bank.allocated_size && !picasso96_state_uaegfx.CardFound) {
/* Fill in MemoryBase, MemorySize */
trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemoryBase, gfxmem_bank.start);
trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemorySize, gfxmem_bank.allocated_size - reserved_gfxmem);
picasso96_state_uaegfx.CardFound = 1; /* mark our "card" as being found */
return -1;
} else
return 0;
picasso96_state_uaegfx.CardFound = 1; /* mark our "card" as being found */
return -1;
}
else
return 0;
}
static void FillBoardInfo(TrapContext *ctx, uaecptr amigamemptr, struct LibResolution *res, int width, int height, int depth)
@ -1837,8 +1954,12 @@ static uae_u32 REGPARAM2 picasso_SetSwitch(TrapContext *ctx)
void picasso_enablescreen(int on)
{
if (!init_picasso_screen_called)
init_picasso_screen();
bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size;
bool uaegfx_active = is_uaegfx_active();
if (uaegfx_active && uaegfx)
if (!init_picasso_screen_called)
init_picasso_screen();
setconvert();
picasso_refresh();
@ -1897,7 +2018,8 @@ static uae_u32 REGPARAM2 picasso_SetColorArray(TrapContext *ctx)
uaecptr clut = boardinfo + PSSO_BoardInfo_CLUT;
if (start > 256 || count > 256 || start + count > 256)
return 0;
updateclut(ctx, clut, start, count);
if (updateclut(ctx, clut, start, count))
picasso_vidinfo.full_refresh = 1;
P96TRACE_SETUP((_T("SetColorArray(%d,%d)\n"), start, count));
return 1;
}
@ -1922,7 +2044,7 @@ static uae_u32 REGPARAM2 picasso_SetDAC(TrapContext *ctx)
static void init_picasso_screen(void)
{
if (set_panning_called) {
if (picasso_vidinfo.set_panning_called) {
picasso96_state_uaegfx.Extent = picasso96_state_uaegfx.Address + picasso96_state_uaegfx.BytesPerRow * picasso96_state_uaegfx.VirtualHeight;
}
if (set_gc_called) {
@ -2805,6 +2927,11 @@ static uae_u32 REGPARAM2 picasso_SetDisplay(TrapContext *ctx)
void init_hz_p96(void)
{
p96vblank = vblank_hz;
if (p96vblank <= 0)
p96vblank = 60;
if (p96vblank >= 300)
p96vblank = 300;
p96syncrate = maxvpos_nom * vblank_hz / p96vblank;
}
/* NOTE: Watch for those planeptrs of 0x00000000 and 0xFFFFFFFF for all zero / all one bitmaps !!!! */
@ -3102,7 +3229,11 @@ static void picasso_statusline(uae_u8 *dst)
int dst_height, dst_width, pitch;
dst_height = picasso96_state.Height;
if (dst_height > picasso_vidinfo.height)
dst_height = picasso_vidinfo.height;
dst_width = picasso96_state.Width;
if (dst_width > picasso_vidinfo.width)
dst_width = picasso_vidinfo.width;
pitch = picasso_vidinfo.rowbytes;
for (y = 0; y < TD_TOTAL_HEIGHT; y++) {
int line = dst_height - TD_TOTAL_HEIGHT + y;
@ -3111,7 +3242,6 @@ static void picasso_statusline(uae_u8 *dst)
}
}
// TODO: Change this to use SDL2 native conversions
static void copyall(uae_u8 *src, uae_u8 *dst)
{
int bytes;
@ -3157,58 +3287,65 @@ static void copyall(uae_u8 *src, uae_u8 *dst)
}
}
#ifdef MULTITHREADED_COPYALL
static struct srcdst_t {
uae_u8 *src;
uae_u8 *dst;
} srcdst;
static int copyall_multithreaded_wrapper(void *ptr) {
copyall(srcdst.src, srcdst.dst);
if (currprefs.leds_on_screen)
picasso_statusline(srcdst.dst);
return 0;
}
static void copyall_multithreaded(uae_u8 *src, uae_u8 *dst)
{
srcdst.src = src; srcdst.dst = dst;
SDL_DetachThread(SDL_CreateThread(copyall_multithreaded_wrapper, "copyall_thread", nullptr));
}
#endif
bool picasso_flushpixels(uae_u8 *src, int off)
{
uae_u8 *src_start;
uae_u8 *src_end;
uae_u8 *dst = NULL;
uae_u8 *src_start;
uae_u8 *src_end;
uae_u8 *dst = NULL;
int pwidth = picasso96_state.Width > picasso96_state.VirtualWidth ? picasso96_state.VirtualWidth : picasso96_state.Width;
int pheight = picasso96_state.Height > picasso96_state.VirtualHeight ? picasso96_state.VirtualHeight : picasso96_state.Height;
src_start = src + off;
src_end = src + off + picasso96_state.BytesPerRow * pheight - 1;
if (!picasso_vidinfo.extra_mem || src_start >= src_end) {
return false;
}
src_start = src + off;
src_end = src + off + picasso96_state.BytesPerRow * pheight - 1;
if (!picasso_vidinfo.extra_mem || src_start >= src_end) {
return false;
}
if (picasso_vidinfo.full_refresh || picasso_vidinfo.rtg_clear_flag)
picasso_vidinfo.full_refresh = -1;
dst = gfx_lock_picasso();
if (dst == NULL)
return false;
#ifdef MULTITHREADED_COPYALL
copyall_multithreaded(src + off, dst);
#else
copyall(src + off, dst);
#endif
if (currprefs.leds_on_screen)
picasso_statusline(dst);
gfx_unlock_picasso(true);
if (dst) {
picasso_vidinfo.full_refresh = 0;
}
return true;
}
static void *render_thread(void *v)
{
render_thread_state = 1;
for (;;) {
int idx = read_comm_pipe_int_blocking(render_pipe);
if (idx == -1)
break;
idx &= 0xff;
//int monid = currprefs.rtgboards[idx].monitor_id;
//struct amigadisplay *ad = &adisplays[monid];
if (picasso_on && picasso_requested_on) {
//lockrtg();
if (picasso_requested_on) {
//struct picasso96_state_struct *state = &picasso96_state[monid];
picasso_flushpixels(gfxmem_banks[idx]->start + regs.natmem_offset, picasso96_state.XYOffset - gfxmem_banks[idx]->start);
pending_render = true;
}
//unlockrtg();
}
}
render_thread_state = -1;
return 0;
}
extern addrbank gfxmem_bank;
MEMORY_FUNCTIONS(gfxmem);
@ -3514,6 +3651,19 @@ static void inituaegfxfuncs(TrapContext *ctx, uaecptr start, uaecptr ABI)
void picasso_reset(void)
{
if (currprefs.rtg_multithread)
{
if(!render_pipe)
{
render_pipe = xmalloc(smp_comm_pipe, 1);
init_comm_pipe(render_pipe, 10, 1);
}
if (render_thread_state <= 0) {
render_thread_state = 0;
uae_start_thread(_T("rtg"), render_thread, NULL, NULL);
}
}
if (savestate_state != STATE_RESTORE) {
uaegfx_base = 0;
uaegfx_old = 0;
@ -3522,8 +3672,9 @@ void picasso_reset(void)
reserved_gfxmem = 0;
resetpalette();
InitPicasso96();
picasso_rendered = false;
}
picasso_requested_on = false;
}
void uaegfx_install_code(uaecptr start)
@ -3647,6 +3798,7 @@ static uaecptr uaegfx_card_install(TrapContext *ctx, uae_u32 extrasize)
write_log(_T("uaegfx.card %d.%d init @%08X\n"), UAEGFX_VERSION, UAEGFX_REVISION, uaegfx_base);
uaegfx_active = 1;
return uaegfx_base;
}
@ -3695,6 +3847,17 @@ uae_u32 picasso_demux(uae_u32 arg, TrapContext *ctx)
return 0;
}
void picasso_free(void)
{
if (render_thread_state > 0) {
write_comm_pipe_int(render_pipe, -1, 0);
while (render_thread_state >= 0) {
Sleep(10);
}
render_thread_state = 0;
}
}
void restore_p96_finish(void)
{
init_alloc(NULL, 0);
@ -3715,7 +3878,7 @@ uae_u8 *restore_p96(uae_u8 *src)
picasso_on = 0;
init_picasso_screen_called = 0;
set_gc_called = !!(flags & 2);
set_panning_called = !!(flags & 4);
picasso_vidinfo.set_panning_called = !!(flags & 4);
interrupt_enabled = !!(flags & 32);
changed_prefs.rtgboards[0].rtgmem_size = restore_u32();
picasso96_state_uaegfx.Address = restore_u32();
@ -3758,7 +3921,7 @@ uae_u8 *save_p96(int *len, uae_u8 *dstptr)
else
dstbak = dst = xmalloc(uae_u8, 1000);
save_u32(2);
save_u32((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (set_panning_called ? 4 : 0) |
save_u32((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (picasso_vidinfo.set_panning_called ? 4 : 0) |
(interrupt_enabled ? 32 : 0) | 64);
save_u32(currprefs.rtgboards[0].rtgmem_size);
save_u32(picasso96_state_uaegfx.Address);

View file

@ -594,22 +594,32 @@ extern struct picasso96_state_struct picasso96_state;
extern void picasso_enablescreen (int on);
extern void picasso_refresh (void);
extern void init_hz_p96 (void);
extern void picasso_handle_hsync(void);
extern void picasso_handle_vsync (void);
extern void picasso_trigger_vblank (void);
extern void picasso_reset (void);
extern bool picasso_is_active (void);
extern int picasso_palette (struct MyCLUTEntry *CLUT);
extern bool picasso_flushpixels (uae_u8 *src, int offset);
extern void picasso_free(void);
/* This structure describes the UAE-side framebuffer for the Picasso
* screen. */
struct picasso_vidbuf_description {
int width, height, depth;
int rowbytes, pixbytes;
int rowbytes, pixbytes, offset;
int extra_mem; /* nonzero if there's a second buffer that must be updated */
uae_u32 rgbformat;
RGBFTYPE selected_rgbformat;
uae_u32 clut[256];
int picasso_convert, host_mode;
int ohost_mode, orgbformat;
int full_refresh;
int set_panning_called;
int rtg_clear_flag;
bool picasso_active;
bool picasso_changed;
uae_atomic picasso_state_change;
};
extern struct picasso_vidbuf_description picasso_vidinfo;

View file

@ -30,7 +30,7 @@ static const char* numbers = {
"+++++++---+++-++++++++++++++----+++++++++++++++++--+++--++++++++++++++++++++-++++++-++++------------------------+++----++++++++++++++"
};
STATIC_INLINE uae_u32 ledcolor(uae_u32 c, uae_u32* rc, uae_u32* gc, uae_u32* bc, uae_u32* a)
STATIC_INLINE uae_u32 ledcolor(uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a)
{
uae_u32 v = rc[(c >> 16) & 0xff] | gc[(c >> 8) & 0xff] | bc[(c >> 0) & 0xff];
if (a)
@ -54,8 +54,7 @@ static void write_tdnumber(uae_u8* buf, int bpp, int x, int y, int num, uae_u32
}
}
void draw_status_line_single(uae_u8* buf, int bpp, int y, int totalwidth, uae_u32* rc, uae_u32* gc, uae_u32* bc,
uae_u32* alpha)
void draw_status_line_single(uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha)
{
int x_start, j, led, border;
uae_u32 c1, c2, cb;
@ -278,45 +277,37 @@ void draw_status_line_single(uae_u8* buf, int bpp, int y, int totalwidth, uae_u3
}
on_rgb |= 0x33000000;
off_rgb |= 0x33000000;
if (half > 0)
{
if (half > 0) {
c = ledcolor(on ? (y >= TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
}
else if (half < 0)
{
else if (half < 0) {
c = ledcolor(on ? (y < TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
}
else
{
else {
c = ledcolor(on ? on_rgb : off_rgb, rc, gc, bc, alpha);
}
border = 0;
if (y == 0 || y == TD_TOTAL_HEIGHT - 1)
{
if (y == 0 || y == TD_TOTAL_HEIGHT - 1) {
c = ledcolor(TD_BORDER, rc, gc, bc, alpha);
border = 1;
}
x = x_start + pos * TD_WIDTH;
if (!border)
putpixel(buf, nullptr, bpp, x - 1, cb, 0);
putpixel(buf, NULL, bpp, x - 1, cb, 0);
for (j = 0; j < TD_LED_WIDTH; j++)
putpixel(buf, nullptr, bpp, x + j, c, 0);
putpixel(buf, NULL, bpp, x + j, c, 0);
if (!border)
putpixel(buf, nullptr, bpp, x + j, cb, 0);
putpixel(buf, NULL, bpp, x + j, cb, 0);
if (y >= TD_PADY && y - TD_PADY < TD_NUM_HEIGHT)
{
if (num3 >= 0)
{
if (y >= TD_PADY && y - TD_PADY < TD_NUM_HEIGHT) {
if (num3 >= 0) {
x += (TD_LED_WIDTH - am * TD_NUM_WIDTH) / 2;
if (num1 > 0)
{
if (num1 > 0) {
write_tdnumber(buf, bpp, x, y - TD_PADY, num1, pen_rgb, c2);
x += TD_NUM_WIDTH;
}
if (num2 >= 0)
{
if (num2 >= 0) {
write_tdnumber(buf, bpp, x, y - TD_PADY, num2, pen_rgb, c2);
x += TD_NUM_WIDTH;
}