mirror of
https://github.com/libretro/mame2003-plus-libretro.git
synced 2026-11-07 04:16:07 -10:00
ST-V: faster VDP2 and VDP1 drawing, SH-2 polling loops skipped, FTCSR as in MAME
VDP2 tiles: - vdp2_drawgfx_alpha drew every pixel through vdp2_window_process; with a window it now draws the runs of each line the windows show, from the line cache of vdp2_drawgfx_transpen (same pixels), and with no window it copies without checks. Both work out the window key once per tile and check the cached line inline. - Each decoded element keeps two masks of its rows (a pixel other than pen 0; no pen 0). With transparency vdp2_drawgfx_transpen skips tiles and rows of pen 0 only and copies whole the rows without it. VDP1 sprites: without color calculation draw_sprites walks the window runs of the line instead of calling vdp2_window_process for every pixel. SH-2: - Only a read that includes FRC resyncs it (MAME frc_r); TIER and FTCSR reads (MAME ftcsr_r) do not. - The recompiler skips the iterations of polling loops that only read, as it already did for the SGL idle loop: a block that starts with a short loop back to itself which leaves every register as it found it and read only RAM or TIER/FTCSR repeats the same iteration until the end of the timeslice, so those iterations are counted at once. Makefile (unix): -fvisibility=hidden, only retro_* leaves the library. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013Vje3pEtpLHubqCGwCgoQX
This commit is contained in:
4 files changed
+246
-27
No files matched your search
@@ -100,7 +100,9 @@ endif
|
||||
ifeq ($(platform), unix)
|
||||
TARGET = $(TARGET_NAME)_libretro.so
|
||||
fpic = -fPIC
|
||||
CFLAGS += $(fpic)
|
||||
# only the retro_* entry points (RETRO_API) leave the library: the rest is
|
||||
# reached directly instead of through the GOT and PLT
|
||||
CFLAGS += $(fpic) -fvisibility=hidden
|
||||
LDFLAGS += $(fpic) -shared -Wl,--version-script=link.T
|
||||
|
||||
# Linux Portable
|
||||
|
||||
+5
-1
@@ -2893,7 +2893,11 @@ READ32_HANDLER( sh2_internal_r )
|
||||
switch( offset )
|
||||
{
|
||||
case 0x04: /* TIER, FTCSR, FRC*/
|
||||
sh2_timer_resync();
|
||||
/* only a read of FRC brings it up to date, as in current MAME (frc_r):
|
||||
reading TIER or FTCSR does not (a slave CPU waiting for its input
|
||||
capture flag reads FTCSR tens of thousands of times a frame) */
|
||||
if ((mem_mask & 0xffff) != 0xffff)
|
||||
sh2_timer_resync();
|
||||
return (sh2.m[4] & 0xffff0000) | sh2.frc;
|
||||
case 0x05: /* OCRx, TCR, TOCR*/
|
||||
if(sh2.m[5] & 0x10)
|
||||
|
||||
+95
-1
@@ -84,6 +84,7 @@ struct jit_block
|
||||
UINT8 valid;
|
||||
UINT8 len; /* instructions */
|
||||
UINT8 idle; /* the SGL idle counting loop starts here (see jit_idle_skip) */
|
||||
UINT8 spin; /* a polling loop that only reads: see jit_spin_skip */
|
||||
UINT16 op0; /* first opcode, to retry an untranslatable block once it changes */
|
||||
};
|
||||
|
||||
@@ -1269,11 +1270,18 @@ static void jit_emit_mem_access(struct sljit_compiler *C, UINT16 op, const struc
|
||||
*/
|
||||
static sljit_u32 jit_slow_break;
|
||||
|
||||
static int jit_spin_io; /* a read of the spin check went to a device (see jit_spin_skip) */
|
||||
|
||||
static sljit_s32 SLJIT_FUNC jit_slow_read(sljit_u32 ea, sljit_u32 size)
|
||||
{
|
||||
int before = sh2_icount;
|
||||
INT32 v;
|
||||
|
||||
/* only TIER and FTCSR read the same all through a timeslice without side
|
||||
effects; any other device read stops a spin from being skipped */
|
||||
if (!((size == 1 && (ea == 0xfffffe10 || ea == 0xfffffe11)) || (size == 2 && ea == 0xfffffe10)))
|
||||
jit_spin_io = 1;
|
||||
|
||||
jit_in_block = 1;
|
||||
if (size == 1)
|
||||
v = (INT8)RB(ea);
|
||||
@@ -1893,6 +1901,86 @@ static void jit_idle_skip(void)
|
||||
sh2_icount -= k * cost;
|
||||
}
|
||||
|
||||
/*
|
||||
Polling loops: a block that starts with a short loop back to its own
|
||||
start with BT or BF, which in between only reads memory (no
|
||||
post-increment), moves, tests and compares, for example the Winter Heat
|
||||
slave waiting for its input capture flag:
|
||||
|
||||
loop: MOV.B @R1,R0 ; FTCSR
|
||||
TST #0x80,R0
|
||||
BT loop
|
||||
|
||||
As for the SGL idle loop, nothing it reads can change within a
|
||||
timeslice: if one iteration leaves every register as it found it and
|
||||
read only RAM (or TIER/FTCSR), every later iteration of the timeslice
|
||||
is the same, so they are counted at once. A whole iteration and the
|
||||
part of one that ends the timeslice are left to the code.
|
||||
*/
|
||||
#define JIT_SPIN_MAX 8
|
||||
|
||||
static int jit_spin_op(UINT16 op)
|
||||
{
|
||||
switch (op >> 12)
|
||||
{
|
||||
case 0x0: return op == 0x0009; /* NOP */
|
||||
case 0x2: { int k = op & 15; return k >= 8 && k <= 0xc; } /* TST AND XOR OR CMP/STR */
|
||||
case 0x3: { int k = op & 15; return k == 0 || k == 2 || k == 3 || k == 6 || k == 7; } /* CMP/xx */
|
||||
case 0x4: return (op & 0xff) == 0x11 || (op & 0xff) == 0x15; /* CMP/PZ CMP/PL */
|
||||
case 0x5: return 1; /* MOV.L @(disp,Rm),Rn */
|
||||
case 0x6: { int k = op & 15; return k <= 3 || k >= 7; } /* loads, MOV, NOT, SWAP, NEG(C), EXT */
|
||||
case 0x8: { int k = (op >> 8) & 15; return k == 4 || k == 5 || k == 8; } /* MOV.B/W @(disp,Rm),R0, CMP/EQ #imm */
|
||||
case 0x9: return 1; /* MOV.W @(disp,PC),Rn */
|
||||
case 0xc: { int k = (op >> 8) & 15; return (k >= 4 && k <= 6) || (k >= 8 && k <= 0xb); } /* GBR loads, TST AND XOR OR #imm */
|
||||
case 0xd: return 1; /* MOV.L @(disp,PC),Rn */
|
||||
case 0xe: return 1; /* MOV #imm,Rn */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jit_spin_block(const UINT16 *ops, UINT32 count, UINT32 pc)
|
||||
{
|
||||
UINT32 i;
|
||||
/* the loop: from the start to a BT or BF back to it; the rest of the
|
||||
block only runs once the loop is left */
|
||||
for (i = 0; i < count && i < JIT_SPIN_MAX; i++)
|
||||
{
|
||||
UINT16 op = ops[i];
|
||||
if ((op & 0xfd00) == 0x8900) /* BT or BF, no delay slot */
|
||||
return i > 0 && pc + i * 2 + 4 + (INT8)(op & 0xff) * 2 == pc;
|
||||
if (!jit_spin_op(op))
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct { UINT32 r[16], sr, gbr, mach, macl, pr; } jit_spin_regs;
|
||||
|
||||
static void jit_spin_save(void)
|
||||
{
|
||||
memcpy(jit_spin_regs.r, sh2.r, sizeof(jit_spin_regs.r));
|
||||
jit_spin_regs.sr = sh2.sr;
|
||||
jit_spin_regs.gbr = sh2.gbr;
|
||||
jit_spin_regs.mach = sh2.mach;
|
||||
jit_spin_regs.macl = sh2.macl;
|
||||
jit_spin_regs.pr = sh2.pr;
|
||||
jit_spin_io = 0;
|
||||
}
|
||||
|
||||
/* after one iteration from 'before' cycles: counts the iterations the rest of the timeslice would repeat */
|
||||
static void jit_spin_skip(const struct jit_block *block, int before)
|
||||
{
|
||||
int cost = before - sh2_icount, k;
|
||||
if (cost <= 0 || jit_spin_io || sh2.pc != block->pc || sh2.delay || sh2.test_irq
|
||||
|| memcmp(jit_spin_regs.r, sh2.r, sizeof(jit_spin_regs.r)) || jit_spin_regs.sr != sh2.sr
|
||||
|| jit_spin_regs.gbr != sh2.gbr || jit_spin_regs.mach != sh2.mach || jit_spin_regs.macl != sh2.macl
|
||||
|| jit_spin_regs.pr != sh2.pr)
|
||||
return;
|
||||
k = (sh2_icount - 1) / cost - 1;
|
||||
if (k > 0)
|
||||
sh2_icount -= k * cost;
|
||||
}
|
||||
|
||||
static void jit_compile(struct jit_block *block, UINT32 pc)
|
||||
{
|
||||
static struct jit_ctx ctx;
|
||||
@@ -1911,6 +1999,7 @@ static void jit_compile(struct jit_block *block, UINT32 pc)
|
||||
block->code = NULL;
|
||||
block->entry = NULL;
|
||||
block->idle = 0;
|
||||
block->spin = 0;
|
||||
block->op0 = jit_fetch(pc);
|
||||
|
||||
/* code must sit in one fast RAM region, below the special areas */
|
||||
@@ -1951,6 +2040,7 @@ static void jit_compile(struct jit_block *block, UINT32 pc)
|
||||
}
|
||||
if (count == 0)
|
||||
return;
|
||||
block->spin = jit_spin_block(ops, count, pc);
|
||||
|
||||
/* cycles the block takes before each instruction, and at most in all */
|
||||
ctx.pre[0] = 0;
|
||||
@@ -2021,7 +2111,7 @@ static void jit_compile(struct jit_block *block, UINT32 pc)
|
||||
{
|
||||
sljit_uw n_entry = sljit_get_label_addr(entry);
|
||||
/* the idle loop goes through the dispatcher, where it is skipped */
|
||||
block->entry = block->idle ? NULL : (void *)n_entry;
|
||||
block->entry = (block->idle || block->spin) ? NULL : (void *)n_entry;
|
||||
jit_code_bytes += sljit_get_generated_code_size(C);
|
||||
}
|
||||
sljit_free_compiler(C);
|
||||
@@ -2093,11 +2183,15 @@ static INLINE int sh2_jit_run(void)
|
||||
jit_idle_skip();
|
||||
if (block->cost > sh2_icount)
|
||||
return sh2_icount != before; /* the iterations skipped, if any: the rest steps */
|
||||
if (block->spin)
|
||||
jit_spin_save();
|
||||
#ifdef SH2JIT_VERIFY
|
||||
sh2.pc = jit_verify_block(block);
|
||||
#else
|
||||
sh2.pc = ((jit_func)block->code)();
|
||||
#endif
|
||||
if (block->spin)
|
||||
jit_spin_skip(block, before);
|
||||
if (jit_flush_pending)
|
||||
{
|
||||
jit_flush_pending = 0;
|
||||
|
||||
+143
-24
@@ -198,6 +198,8 @@ struct stv_gfx
|
||||
int colors; /* palette banks */
|
||||
UINT8 *cache;
|
||||
UINT8 *dirty;
|
||||
UINT16 *rows_any; /* per element, a bit per row: the row has a pixel other than 0 */
|
||||
UINT16 *rows_full; /* per element, a bit per row: the row has no pixel 0 */
|
||||
};
|
||||
|
||||
static struct stv_gfx stv_gfx[4];
|
||||
@@ -217,6 +219,8 @@ static void gfx_setup(struct stv_gfx *g, int width, int height, int bpp, int inc
|
||||
g->cache = auto_malloc(g->elements * width * height);
|
||||
g->dirty = auto_malloc(g->elements);
|
||||
memset(g->dirty, 1, g->elements);
|
||||
g->rows_any = auto_malloc(g->elements * sizeof(UINT16));
|
||||
g->rows_full = auto_malloc(g->elements * sizeof(UINT16));
|
||||
}
|
||||
|
||||
/* a VRAM byte at addr changed: the elements that contain it are stale */
|
||||
@@ -238,6 +242,7 @@ static void gfx_decode_element(struct stv_gfx *g, int code)
|
||||
{
|
||||
const UINT8 *src = vdp2_gfx_source + code * g->inc;
|
||||
UINT8 *dst = g->cache + code * g->width * g->height;
|
||||
UINT32 any = 0, full = 0;
|
||||
int x, y;
|
||||
|
||||
/* the 16x16 tiles are four 8x8 cells: left top, right top, left bottom, right bottom */
|
||||
@@ -262,6 +267,21 @@ static void gfx_decode_element(struct stv_gfx *g, int code)
|
||||
}
|
||||
*dst++ = pix;
|
||||
}
|
||||
|
||||
/* which rows have something to draw, and which are drawn whole */
|
||||
dst = g->cache + code * g->width * g->height;
|
||||
for (y = 0; y < g->height; y++, dst += g->width)
|
||||
{
|
||||
int n0 = 0;
|
||||
for (x = 0; x < g->width; x++)
|
||||
n0 += (dst[x] == 0);
|
||||
if (n0 < g->width)
|
||||
any |= 1 << y;
|
||||
if (n0 == 0)
|
||||
full |= 1 << y;
|
||||
}
|
||||
g->rows_any[code] = (UINT16)any;
|
||||
g->rows_full[code] = (UINT16)full;
|
||||
}
|
||||
|
||||
#ifdef STV_VIDEO_THREADS
|
||||
@@ -712,6 +732,8 @@ static void vdp2_drawgfxzoom_rgb555( struct mame_bitmap *dest_bmp,const struct r
|
||||
static void vdp2_drawgfx_rgb555(struct mame_bitmap *dest_bmp, const struct rectangle *clip, UINT32 code, int flipx, int flipy, int sx, int sy, int transparency, int alpha);
|
||||
static void vdp2_drawgfx_rgb888( struct mame_bitmap *dest_bmp, const struct rectangle *clip, UINT32 code, int flipx, int flipy, int sx, int sy, int transparency, int alpha);
|
||||
static void vdp2_drawgfx_alpha(struct mame_bitmap *dest_bmp,const struct rectangle *clip,gfx_element *gfx, UINT32 code,UINT32 color, int flipx,int flipy,int offsx,int offsy, int transparency, int alpha);
|
||||
static void vdp2_drawgfx_alpha_spans(struct mame_bitmap *dest_bmp, const pen_t *pal, const UINT8 *source_base, int width,
|
||||
int x_index_base, int y_index, int xinc, int yinc, int sx, int sy, int ex, int ey, int opaque, int alpha);
|
||||
static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rectangle *clip,gfx_element *gfx, UINT32 code,UINT32 color, int flipx,int flipy,int offsx,int offsy, int transparency);
|
||||
static void draw_4bpp_bitmap(struct mame_bitmap *bitmap, const struct rectangle *cliprect);
|
||||
static void draw_8bpp_bitmap(struct mame_bitmap *bitmap, const struct rectangle *cliprect);
|
||||
@@ -5901,26 +5923,31 @@ static void vdp2_drawgfx_alpha(struct mame_bitmap *dest_bmp,const struct rectang
|
||||
}
|
||||
|
||||
/* skip if inner loop doesn't draw anything */
|
||||
if (ex > sx)
|
||||
{
|
||||
for (y = sy; y < ey; y++)
|
||||
{
|
||||
UINT8 const *const source = source_base + y_index*gfx->width;
|
||||
UINT32 *const dest = BMP32(dest_bmp, y);
|
||||
int x_index = x_index_base;
|
||||
for (x = sx; x < ex; x++)
|
||||
{
|
||||
if(vdp2_window_process(x,y))
|
||||
{
|
||||
int c = (source[x_index]);
|
||||
if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0))
|
||||
dest[x] = stv_alpha_blend_r32( dest[x], pal[c], alpha );
|
||||
}
|
||||
if (ex <= sx)
|
||||
return;
|
||||
|
||||
x_index += xinc;
|
||||
}
|
||||
y_index += yinc;
|
||||
/* a window on this layer: only the runs of each line it shows */
|
||||
if (current_tilemap.window_control.enabled[0] || current_tilemap.window_control.enabled[1])
|
||||
{
|
||||
vdp2_drawgfx_alpha_spans(dest_bmp, pal, source_base, gfx->width, x_index_base, y_index,
|
||||
xinc, yinc, sx, sy, ex, ey, (transparency & STV_TRANSPARENCY_NONE) ? 1 : 0, alpha);
|
||||
return;
|
||||
}
|
||||
|
||||
for (y = sy; y < ey; y++)
|
||||
{
|
||||
UINT8 const *const source = source_base + y_index*gfx->width;
|
||||
UINT32 *const dest = BMP32(dest_bmp, y);
|
||||
int x_index = x_index_base;
|
||||
for (x = sx; x < ex; x++)
|
||||
{
|
||||
int c = (source[x_index]);
|
||||
if ((transparency & STV_TRANSPARENCY_NONE) || (c != 0))
|
||||
dest[x] = stv_alpha_blend_r32( dest[x], pal[c], alpha );
|
||||
|
||||
x_index += xinc;
|
||||
}
|
||||
y_index += yinc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6023,6 +6050,64 @@ static const struct vdp2_window_span *vdp2_window_spans_get(int y)
|
||||
return sp;
|
||||
}
|
||||
|
||||
/* the settings of the windows of the current layer, as the key of the cache */
|
||||
static INLINE int vdp2_window_spans_key(void)
|
||||
{
|
||||
return (current_tilemap.window_control.enabled[0] ? 1 : 0)
|
||||
| (current_tilemap.window_control.enabled[1] ? 2 : 0)
|
||||
| (current_tilemap.window_control.area[0] ? 0 : 4)
|
||||
| (current_tilemap.window_control.area[1] ? 0 : 8)
|
||||
| ((current_tilemap.window_control.logic & 1) ? 16 : 0);
|
||||
}
|
||||
|
||||
/* vdp2_window_spans_get for a line, with the key of the layer worked out by
|
||||
the caller once per tile: the cached line is checked here, inline */
|
||||
static INLINE const struct vdp2_window_span *vdp2_window_spans_line(int y, int key)
|
||||
{
|
||||
if (y >= 0 && y < VDP2_WINDOW_LINES)
|
||||
{
|
||||
const struct vdp2_window_span *sp = &vdp2_window_spans[y];
|
||||
if (sp->gen == vdp2_window_cache_gen && sp->key == key)
|
||||
return sp;
|
||||
}
|
||||
return vdp2_window_spans_get(y);
|
||||
}
|
||||
|
||||
/* vdp2_drawgfx_alpha with a window: the runs of pixels each line shows, from
|
||||
the cache of the line, as vdp2_drawgfx_transpen (same pixels as
|
||||
vdp2_window_process for each one) */
|
||||
static void vdp2_drawgfx_alpha_spans(struct mame_bitmap *dest_bmp, const pen_t *pal, const UINT8 *source_base, int width,
|
||||
int x_index_base, int y_index, int xinc, int yinc, int sx, int sy, int ex, int ey, int opaque, int alpha)
|
||||
{
|
||||
const int key = vdp2_window_spans_key();
|
||||
int x, y;
|
||||
|
||||
for (y = sy; y < ey; y++)
|
||||
{
|
||||
UINT8 const *const source = source_base + y_index*width;
|
||||
UINT32 *const dest = BMP32(dest_bmp, y);
|
||||
const struct vdp2_window_span *sp = vdp2_window_spans_line(y, key);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sp->n; i++)
|
||||
{
|
||||
int a = sp->a[i], b = sp->b[i], x_index;
|
||||
if (a < sx) a = sx;
|
||||
if (b > ex) b = ex;
|
||||
if (a >= b)
|
||||
continue;
|
||||
x_index = x_index_base + (a - sx) * xinc;
|
||||
for (x = a; x < b; x++, x_index += xinc)
|
||||
{
|
||||
const int c = source[x_index];
|
||||
if (opaque || c != 0)
|
||||
dest[x] = stv_alpha_blend_r32(dest[x], pal[c], alpha);
|
||||
}
|
||||
}
|
||||
y_index += yinc;
|
||||
}
|
||||
}
|
||||
|
||||
static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rectangle *clip,gfx_element *gfx,
|
||||
UINT32 code,UINT32 color, int flipx,int flipy,int offsx,int offsy,
|
||||
int transparency)
|
||||
@@ -6031,6 +6116,8 @@ static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rect
|
||||
int x;
|
||||
const pen_t *pal = &PEN(0 + gfx->granularity * (color % gfx->colors));
|
||||
const UINT8 *source_base = gfx_get_data(gfx, code % gfx->elements);
|
||||
const UINT32 rows_any = gfx->rows_any[code % gfx->elements];
|
||||
const UINT32 rows_full = gfx->rows_full[code % gfx->elements];
|
||||
int x_index_base, y_index, sx, sy, ex, ey;
|
||||
int xinc, yinc;
|
||||
|
||||
@@ -6076,6 +6163,9 @@ static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rect
|
||||
/* skip if inner loop doesn't draw anything */
|
||||
if (ex <= sx)
|
||||
return;
|
||||
/* a tile with nothing but pen 0 draws nothing */
|
||||
if (!(transparency & STV_TRANSPARENCY_NONE) && !rows_any)
|
||||
return;
|
||||
|
||||
/* no window on this layer: plain copy loops (the RBG0 cache is drawn this way) */
|
||||
if (!current_tilemap.window_control.enabled[0] && !current_tilemap.window_control.enabled[1])
|
||||
@@ -6089,7 +6179,13 @@ static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rect
|
||||
UINT32 *dest = BMP32(dest_bmp, y) + sx;
|
||||
int n;
|
||||
|
||||
if (opaque)
|
||||
/* rows of pen 0 only are skipped, rows without it copied whole */
|
||||
if (!opaque && !((rows_any >> y_index) & 1))
|
||||
{
|
||||
y_index += yinc;
|
||||
continue;
|
||||
}
|
||||
if (opaque || ((rows_full >> y_index) & 1))
|
||||
{
|
||||
for (n = 0; n < width; n++, source += xinc)
|
||||
dest[n] = pal[*source];
|
||||
@@ -6134,13 +6230,23 @@ static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rect
|
||||
the line (vdp2_window_spans) */
|
||||
{
|
||||
const int opaque = (transparency & STV_TRANSPARENCY_NONE) ? 1 : 0;
|
||||
const int key = vdp2_window_spans_key();
|
||||
|
||||
for (y = sy; y < ey; y++)
|
||||
{
|
||||
UINT8 const *const source = source_base + y_index*gfx->width;
|
||||
UINT32 *const dest = BMP32(dest_bmp, y);
|
||||
const struct vdp2_window_span *sp = vdp2_window_spans_get(y);
|
||||
int i;
|
||||
const struct vdp2_window_span *sp;
|
||||
int i, whole;
|
||||
|
||||
/* rows of pen 0 only are skipped, rows without it copied whole */
|
||||
if (!opaque && !((rows_any >> y_index) & 1))
|
||||
{
|
||||
y_index += yinc;
|
||||
continue;
|
||||
}
|
||||
whole = opaque || ((rows_full >> y_index) & 1);
|
||||
sp = vdp2_window_spans_line(y, key);
|
||||
|
||||
for (i = 0; i < sp->n; i++)
|
||||
{
|
||||
@@ -6150,7 +6256,7 @@ static void vdp2_drawgfx_transpen(struct mame_bitmap *dest_bmp,const struct rect
|
||||
if (a >= b)
|
||||
continue;
|
||||
x_index = x_index_base + (a - sx) * xinc;
|
||||
if (opaque)
|
||||
if (whole)
|
||||
{
|
||||
for (x = a; x < b; x++, x_index += xinc)
|
||||
dest[x] = pal[source[x_index]];
|
||||
@@ -9675,9 +9781,16 @@ static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cli
|
||||
{
|
||||
if ( alpha_enabled == 0 )
|
||||
{
|
||||
/* the window: the runs of each line it shows (vdp2_window_spans), walked
|
||||
along the line instead of vdp2_window_process for every pixel */
|
||||
const int win = current_tilemap.window_control.enabled[0] || current_tilemap.window_control.enabled[1];
|
||||
const int wkey = vdp2_window_spans_key();
|
||||
|
||||
for ( y = cliprect->min_y; y <= cliprect->max_y; y++ )
|
||||
{
|
||||
int x0 = cliprect->min_x, x1 = cliprect->max_x;
|
||||
const struct vdp2_window_span *wsp;
|
||||
int wi = 0;
|
||||
if ( vdp1_sprite_priorities_usage_valid )
|
||||
{
|
||||
if (vdp1_sprite_priorities_in_fb_line[y][pri] == 0)
|
||||
@@ -9689,6 +9802,7 @@ static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cli
|
||||
|
||||
framebuffer_line = vdp1.framebuffer_display_lines[y];
|
||||
bitmap_line = BMP32(bitmap, y);
|
||||
wsp = win ? vdp2_window_spans_line(y, wkey) : NULL;
|
||||
|
||||
for ( x = x0; x <= x1; x++ )
|
||||
{
|
||||
@@ -9707,8 +9821,13 @@ static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cli
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(!vdp2_window_process(x,y))
|
||||
continue;
|
||||
if (wsp)
|
||||
{
|
||||
while (wi < wsp->n && x >= wsp->b[wi])
|
||||
wi++;
|
||||
if (wi >= wsp->n || x < wsp->a[wi])
|
||||
continue;
|
||||
}
|
||||
|
||||
/* pukunpa, no alpha no framebuffer bumps */
|
||||
if(sprite_window && pix == 0x8000)
|
||||
|
||||
Reference in new issue
Block a user