mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-04 23:07:46 -04:00
sms, basic gamegear support
This commit is contained in:
parent
0df7401c02
commit
466fa07953
16 changed files with 451 additions and 214 deletions
104
pico/draw.c
104
pico/draw.c
|
@ -135,7 +135,7 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat)
|
|||
for (; n; n--)
|
||||
*pd++ = (unsigned char) (*ps++ | pat);
|
||||
}
|
||||
#define blockcpy memcpy
|
||||
#define blockcpy memmove
|
||||
#endif
|
||||
|
||||
#define TileNormMaker_(pix_func,ret) \
|
||||
|
@ -1642,21 +1642,28 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
|
|||
|
||||
PicoDrawUpdateHighPal();
|
||||
|
||||
if (Pico.video.reg[12]&1) {
|
||||
len = 320;
|
||||
} else {
|
||||
len = 256;
|
||||
}
|
||||
if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x3) == 0x3)
|
||||
len = 160;
|
||||
else if (Pico.video.reg[12]&1) len = 320;
|
||||
else len = 256;
|
||||
|
||||
if ((*est->PicoOpt & POPT_EN_SOFTSCALE) && len == 256) {
|
||||
switch (PicoIn.filter) {
|
||||
case 3: h_upscale_bl4_4_5(pd, 320, ps, 256, 256, f_pal); break;
|
||||
case 2: h_upscale_bl2_4_5(pd, 320, ps, 256, 256, f_pal); break;
|
||||
case 1: h_upscale_snn_4_5(pd, 320, ps, 256, 256, f_pal); break;
|
||||
default: h_upscale_nn_4_5(pd, 320, ps, 256, 256, f_pal); break;
|
||||
}
|
||||
if ((*est->PicoOpt & POPT_EN_SOFTSCALE) && len < 320) {
|
||||
if (len == 256)
|
||||
switch (PicoIn.filter) {
|
||||
case 3: h_upscale_bl4_4_5(pd, 320, ps, 256, len, f_pal); break;
|
||||
case 2: h_upscale_bl2_4_5(pd, 320, ps, 256, len, f_pal); break;
|
||||
case 1: h_upscale_snn_4_5(pd, 320, ps, 256, len, f_pal); break;
|
||||
default: h_upscale_nn_4_5(pd, 320, ps, 256, len, f_pal); break;
|
||||
}
|
||||
else if (len == 160)
|
||||
switch (PicoIn.filter) {
|
||||
case 3:
|
||||
case 2: h_upscale_bl2_1_2(pd, 320, ps, 160, len, f_pal); break;
|
||||
default: h_upscale_nn_1_2(pd, 320, ps, 160, len, f_pal); break;
|
||||
}
|
||||
} else {
|
||||
if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len == 256) pd += 32;
|
||||
if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)
|
||||
pd += (320-len) / 2;
|
||||
#if 1
|
||||
h_copy(pd, 320, ps, 320, len, f_pal);
|
||||
#else
|
||||
|
@ -1670,9 +1677,10 @@ void FinalizeLine555(int sh, int line, struct PicoEState *est)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
|
||||
void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
|
||||
{
|
||||
unsigned char *pd = est->DrawLineDest;
|
||||
unsigned char *ps = est->HighCol+8;
|
||||
int len;
|
||||
static int dirty_line;
|
||||
|
||||
|
@ -1680,8 +1688,8 @@ static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
|
|||
{
|
||||
// a hack for mid-frame palette changes
|
||||
if (!(est->rendstatus & PDRAW_SONIC_MODE) | (line - dirty_line > 4)) {
|
||||
// store a maximum of 2 additional palettes in SonicPal
|
||||
if (est->SonicPalCount < 2)
|
||||
// store a maximum of 3 additional palettes in SonicPal
|
||||
if (est->SonicPalCount < 3)
|
||||
est->SonicPalCount ++;
|
||||
dirty_line = line;
|
||||
est->rendstatus |= PDRAW_SONIC_MODE;
|
||||
|
@ -1690,35 +1698,33 @@ static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)
|
|||
Pico.m.dirtyPal = 2;
|
||||
}
|
||||
|
||||
if (Pico.video.reg[12]&1) {
|
||||
len = 320;
|
||||
} else {
|
||||
len = 256;
|
||||
}
|
||||
if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x3) == 0x3)
|
||||
len = 160;
|
||||
else if (Pico.video.reg[12]&1) len = 320;
|
||||
else len = 256;
|
||||
|
||||
if ((PicoIn.opt & POPT_EN_SOFTSCALE) && len == 256) {
|
||||
unsigned char *ps = est->HighCol+8;
|
||||
if (DrawLineDestIncrement == 0)
|
||||
pd = est->HighCol+8;
|
||||
|
||||
if ((PicoIn.opt & POPT_EN_SOFTSCALE) && len < 320) {
|
||||
unsigned char pal = 0;
|
||||
|
||||
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))
|
||||
pal = est->SonicPalCount*0x40;
|
||||
if (DrawLineDestIncrement == 0)
|
||||
pd = est->HighCol+8;
|
||||
// Smoothing can't be used with CLUT, hence it's always Nearest Neighbour.
|
||||
// use reverse version since src and dest ptr may be the same.
|
||||
rh_upscale_nn_4_5(pd, 320, ps, 256, len, f_or);
|
||||
} else if (DrawLineDestIncrement == 0) {
|
||||
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))
|
||||
blockcpy_or(est->HighCol+8, est->HighCol+8, len, est->SonicPalCount*0x40);
|
||||
if (len == 256)
|
||||
// use reverse version since src and dest ptr may be the same.
|
||||
rh_upscale_nn_4_5(pd, 320, ps, 256, len, f_or);
|
||||
else
|
||||
rh_upscale_nn_1_2(pd, 320, ps, 256, len, f_or);
|
||||
} else {
|
||||
if (!(PicoIn.opt & POPT_DIS_32C_BORDER))
|
||||
pd += 32;
|
||||
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE)) {
|
||||
if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)
|
||||
pd += (320-len) / 2;
|
||||
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))
|
||||
// select active backup palette
|
||||
blockcpy_or(pd, est->HighCol+8, len, est->SonicPalCount*0x40);
|
||||
} else {
|
||||
blockcpy(pd, est->HighCol+8, len);
|
||||
}
|
||||
blockcpy_or(pd, ps, len, est->SonicPalCount*0x40);
|
||||
else if (pd != ps)
|
||||
blockcpy(pd, ps, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1893,8 +1899,15 @@ PICO_INTERNAL void PicoFrameStart(void)
|
|||
|
||||
static void DrawBlankedLine(int line, int offs, int sh, int bgc)
|
||||
{
|
||||
if (PicoScanBegin != NULL)
|
||||
PicoScanBegin(line + offs);
|
||||
int skip = skip_next_line;
|
||||
|
||||
if (PicoScanBegin != NULL && skip == 0)
|
||||
skip = PicoScanBegin(line + offs);
|
||||
|
||||
if (skip) {
|
||||
skip_next_line = skip - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
BackFill(bgc, sh, &Pico.est);
|
||||
|
||||
|
@ -1902,7 +1915,7 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
|
|||
FinalizeLine(sh, line, &Pico.est);
|
||||
|
||||
if (PicoScanEnd != NULL)
|
||||
PicoScanEnd(line + offs);
|
||||
skip_next_line = PicoScanEnd(line + offs);
|
||||
|
||||
Pico.est.HighCol += HighColIncrement;
|
||||
Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;
|
||||
|
@ -1910,15 +1923,10 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc)
|
|||
|
||||
static void PicoLine(int line, int offs, int sh, int bgc)
|
||||
{
|
||||
int skip = 0;
|
||||
|
||||
if (skip_next_line > 0) {
|
||||
skip_next_line--;
|
||||
return;
|
||||
}
|
||||
int skip = skip_next_line;
|
||||
|
||||
Pico.est.DrawScanline = line;
|
||||
if (PicoScanBegin != NULL)
|
||||
if (PicoScanBegin != NULL && skip == 0)
|
||||
skip = PicoScanBegin(line + offs);
|
||||
|
||||
if (skip) {
|
||||
|
|
193
pico/draw_arm.S
193
pico/draw_arm.S
|
@ -1642,27 +1642,42 @@ FinalizeLine555:
|
|||
add r3, r10, #OFS_EST_HighPal
|
||||
|
||||
mov lr, #0xff
|
||||
|
||||
ldr r1, [r10, #OFS_EST_HighCol]
|
||||
ldr r0, [r10, #OFS_EST_DrawLineDest]
|
||||
add r1, r1, #8
|
||||
|
||||
ldrb r12, [r8, #OFS_Pico_video_reg+12]
|
||||
mov lr, lr, lsl #1
|
||||
|
||||
tst r12, #1
|
||||
movne r2, #320/8 @ len
|
||||
bne .fl_no32colRGB555
|
||||
ldr r5, [r10, #OFS_EST_PicoOpt]
|
||||
mov r2, #256/8
|
||||
ldr r1, [r10, #OFS_EST_HighCol]
|
||||
ldr r0, [r10, #OFS_EST_DrawLineDest]
|
||||
ldr r4, [r5]
|
||||
tst r4, #0x4000
|
||||
bne .fl_32scale_RGB555
|
||||
tst r4, #0x0100
|
||||
addeq r0, r0, #32*2
|
||||
ldr r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]
|
||||
ldrb r12,[r8, #OFS_Pico_video_reg+12]
|
||||
ldr r2, [r8, #OFS_Pico_m_hardware]
|
||||
add r1, r1, #8
|
||||
|
||||
tst r7, #0x10
|
||||
beq .fl_no20colRGB555
|
||||
and r7, r2, #0x3
|
||||
cmp r7, #0x3 @ Game Gear, LCD?
|
||||
bne .fl_no20colRGB555
|
||||
|
||||
mov r2, #160/8 @ len = 160
|
||||
tst r4, #0x4000 @ EN_SOFTSCALE?
|
||||
bne .fl_20scale_RGB555 @ scale 160->320
|
||||
beq .fl_checkborder
|
||||
|
||||
.fl_no20colRGB555:
|
||||
tst r12, #1 @ h32?
|
||||
movne r2, #320/8 @ len = 320
|
||||
bne .fl_no32colRGB555
|
||||
moveq r2, #256/8 @ len = 256
|
||||
tst r4, #0x4000 @ EN_SOFTSCALE?
|
||||
bne .fl_32scale_RGB555 @ scale 256->320
|
||||
|
||||
.fl_checkborder:
|
||||
tst r4, #0x0100 @ DIS_32C_BORDER?
|
||||
rsbeq r4, r2, #320/8 @ pd += (320-len)/2
|
||||
addeq r0, r0, r4, lsl #3
|
||||
|
||||
.fl_no32colRGB555:
|
||||
|
||||
#ifdef UNALIGNED_DRAWLINEDEST
|
||||
@ this is basically for Gizmondo, which has unaligned odd lines in the framebuffer
|
||||
tst r0, #2
|
||||
|
@ -1715,9 +1730,9 @@ FinalizeLine555:
|
|||
bne .fl_32scale_RGB555u
|
||||
#endif
|
||||
|
||||
ands r5, r5, #0x3
|
||||
addne pc, pc, r5, lsl #2
|
||||
b .fl_32scale_nn
|
||||
and r5, r5, #0x3
|
||||
add pc, pc, r5, lsl #2
|
||||
nop
|
||||
b .fl_32scale_nn
|
||||
b .fl_32scale_snn
|
||||
b .fl_32scale_bl2
|
||||
|
@ -1866,6 +1881,9 @@ FinalizeLine555:
|
|||
ldmfd sp!, {r4-r10,pc}
|
||||
|
||||
.fl_32scale_bl4:
|
||||
// TODO this should reflect the bl4 C algorithm, but it doesn't, it's bln.
|
||||
and r9, r9, r9, lsl #1 @ nuke 2 LSBs to avoid spilling for n/4
|
||||
.fl_32loop_bl4:
|
||||
ldr r12, [r1], #4
|
||||
ldr r7, [r1], #4
|
||||
|
||||
|
@ -1926,10 +1944,147 @@ FinalizeLine555:
|
|||
subs r2, r2, #1
|
||||
|
||||
stmia r0!, {r4,r5,r6,r8,r10}
|
||||
bne .fl_32scale_bl4
|
||||
bne .fl_32loop_bl4
|
||||
|
||||
ldmfd sp!, {r4-r10,pc}
|
||||
|
||||
.fl_20scale_RGB555:
|
||||
ldr r5, [r5, #OFS_PicoIn_filter-OFS_PicoIn_opt]
|
||||
|
||||
mov r9, #0xf700 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007
|
||||
orr r9, r9, #0x00de
|
||||
|
||||
#ifdef UNALIGNED_DRAWLINEDEST
|
||||
tst r0, #2
|
||||
bne .fl_20scale_RGB555u
|
||||
#endif
|
||||
|
||||
and r5, r5, #0x2
|
||||
add pc, pc, r5, lsl #1
|
||||
nop
|
||||
b .fl_20scale_nn
|
||||
b .fl_20scale_bl2
|
||||
|
||||
.fl_20scale_nn:
|
||||
ldr r12, [r1], #4
|
||||
ldr r7, [r1], #4
|
||||
|
||||
and r4, lr, r12, lsl #1
|
||||
ldrh r4, [r3, r4]
|
||||
and r5, lr, r12, lsr #7
|
||||
ldrh r5, [r3, r5]
|
||||
and r6, lr, r12, lsr #15
|
||||
ldrh r6, [r3, r6]
|
||||
and r8 ,lr, r12, lsr #23
|
||||
ldrh r8 ,[r3, r8 ]
|
||||
|
||||
orr r4, r4, r4, lsl #16
|
||||
orr r5, r5, r5, lsl #16
|
||||
orr r6, r6, r6, lsl #16
|
||||
orr r8, r8, r8, lsl #16
|
||||
stmia r0!, {r4,r5,r6,r8}
|
||||
|
||||
and r4, lr, r7, lsl #1
|
||||
ldrh r4, [r3, r4]
|
||||
and r5, lr, r7, lsr #7
|
||||
ldrh r5, [r3, r5]
|
||||
and r6 ,lr, r7, lsr #15
|
||||
ldrh r6 ,[r3, r6]
|
||||
and r8, lr, r7, lsr #23
|
||||
ldrh r8, [r3, r8]
|
||||
|
||||
orr r4, r4, r4, lsl #16
|
||||
orr r5, r5, r5, lsl #16
|
||||
orr r6, r6, r6, lsl #16
|
||||
orr r8, r8, r8, lsl #16
|
||||
stmia r0!, {r4,r5,r6,r8}
|
||||
|
||||
subs r2, r2, #1
|
||||
bne .fl_20scale_nn
|
||||
|
||||
ldmfd sp!, {r4-r10,pc}
|
||||
|
||||
|
||||
.fl_20scale_bl2:
|
||||
ldr r8, [r1]
|
||||
and r8, lr, r8, lsl #1
|
||||
ldrh r8, [r3, r8]
|
||||
and r8, r8, r9
|
||||
lsl r8, r8, #16
|
||||
|
||||
.fl_20loop_bl2:
|
||||
ldr r12, [r1], #4
|
||||
ldr r7, [r1], #4
|
||||
|
||||
and r4, lr, r12, lsl #1
|
||||
ldrh r4, [r3, r4]
|
||||
and r5, lr, r12, lsr #7
|
||||
ldrh r5, [r3, r5]
|
||||
and r6, lr, r12, lsr #15
|
||||
ldrh r6, [r3, r6]
|
||||
|
||||
and r4, r4, r9
|
||||
add r10,r4, r8, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r4, r10,r4, lsl #16 @ (px-1+px0)/2 | px0
|
||||
|
||||
and r8 ,lr, r12, lsr #23
|
||||
ldrh r8 ,[r3, r8]
|
||||
|
||||
and r5, r5, r9
|
||||
add r10,r5, r4, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r5, r10,r5, lsl #16 @ (px0 +px1)/2 | px1
|
||||
|
||||
and r6, r6, r9
|
||||
add r10,r6, r5, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r6, r10,r6, lsl #16 @ (px1 +px2)/2 | px2
|
||||
|
||||
and r8, r8, r9
|
||||
add r10,r8, r6, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r8, r10,r8, lsl #16 @ (px2 +px3)/2 | px3
|
||||
|
||||
stmia r0!, {r4,r5,r6,r8}
|
||||
|
||||
and r4, lr, r7, lsl #1
|
||||
ldrh r4, [r3, r4]
|
||||
and r5, lr, r7, lsr #7
|
||||
ldrh r5, [r3, r5]
|
||||
and r6, lr, r7, lsr #15
|
||||
ldrh r6, [r3, r6]
|
||||
|
||||
and r4, r4, r9
|
||||
add r10,r4, r8, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r4, r10,r4, lsl #16 @ (px-1+px0)/2 | px0
|
||||
|
||||
and r8 ,lr, r7, lsr #23
|
||||
ldrh r8 ,[r3, r8]
|
||||
|
||||
and r5, r5, r9
|
||||
add r10,r5, r4, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r5, r10,r5, lsl #16 @ (px0 +px1)/2 | px1
|
||||
|
||||
and r6, r6, r9
|
||||
add r10,r6, r5, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r6, r10,r6, lsl #16 @ (px1 +px2)/2 | px2
|
||||
|
||||
and r8, r8, r9
|
||||
add r10,r8, r6, lsr #16
|
||||
mov r10,r10,lsr #1
|
||||
orr r8, r10,r8, lsl #16 @ (px2 +px3)/2 | px3
|
||||
|
||||
subs r2, r2, #1
|
||||
stmia r0!, {r4,r5,r6,r8}
|
||||
bne .fl_20loop_bl2
|
||||
|
||||
ldmfd sp!, {r4-r10,pc}
|
||||
|
||||
|
||||
#ifdef UNALIGNED_DRAWLINEDEST
|
||||
@ unaligned versions of loops
|
||||
@ warning: starts drawing 2bytes before dst
|
||||
|
|
12
pico/media.c
12
pico/media.c
|
@ -248,7 +248,6 @@ enum media_type_e PicoLoadMedia(const char *filename,
|
|||
}
|
||||
}
|
||||
else if (media_type == PM_MARK3) {
|
||||
lprintf("detected SMS ROM\n");
|
||||
PicoIn.AHW = PAHW_SMS;
|
||||
}
|
||||
|
||||
|
@ -297,9 +296,18 @@ enum media_type_e PicoLoadMedia(const char *filename,
|
|||
goto out;
|
||||
}
|
||||
rom_data = NULL; // now belongs to PicoCart
|
||||
Pico.m.ncart_in = 0;
|
||||
|
||||
// simple test for GG. Do this here since m.hardware is nulled in Insert
|
||||
if (PicoIn.AHW & PAHW_SMS) {
|
||||
if (strstr(filename,".gg")) {
|
||||
Pico.m.hardware |= 0x1;
|
||||
lprintf("detected GG ROM\n");
|
||||
} else
|
||||
lprintf("detected SMS ROM\n");
|
||||
}
|
||||
|
||||
// insert CD if it was detected
|
||||
Pico.m.ncart_in = 0;
|
||||
if (cd_img_type != CT_UNKNOWN) {
|
||||
ret = cdd_load(filename, cd_img_type);
|
||||
if (ret != 0) {
|
||||
|
|
117
pico/mode4.c
117
pico/mode4.c
|
@ -141,6 +141,8 @@ static void DrawSpritesM4(int scanline)
|
|||
if (pv->reg[0] & 8)
|
||||
xoff = 0;
|
||||
xoff += line_offset;
|
||||
if ((Pico.m.hardware & 0x3) == 0x3)
|
||||
xoff -= 48; // GG LCD, adjust to center 160 px
|
||||
|
||||
sat = (u8 *)PicoMem.vram + ((pv->reg[5] & 0x7e) << 7);
|
||||
if (pv->reg[1] & 2) {
|
||||
|
@ -164,10 +166,12 @@ static void DrawSpritesM4(int scanline)
|
|||
break;
|
||||
}
|
||||
|
||||
sprites_x[s] = xoff + sat[MEM_LE2(0x80 + i*2)];
|
||||
sprites_addr[s] = sprite_base + ((sat[MEM_LE2(0x80 + i*2 + 1)] & addr_mask) << (5-1)) +
|
||||
((scanline - y) >> zoomed << (2-1));
|
||||
s++;
|
||||
if (xoff + sat[MEM_LE2(0x80 + i*2)] >= 0) {
|
||||
sprites_x[s] = xoff + sat[MEM_LE2(0x80 + i*2)];
|
||||
sprites_addr[s] = sprite_base + ((sat[MEM_LE2(0x80 + i*2 + 1)] & addr_mask) << (5-1)) +
|
||||
((scanline - y) >> zoomed << (2-1));
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
// really half-assed but better than nothing
|
||||
|
@ -296,9 +300,12 @@ static void DrawDisplayM4(int scanline)
|
|||
|
||||
// low priority tiles
|
||||
if (!(pv->debug_p & PVD_KILL_B)) {
|
||||
if (pv->reg[0] & 0x80) {
|
||||
if ((Pico.m.hardware & 0x3) == 0x3) {
|
||||
// on GG render only the center 160 px
|
||||
DrawStripLowM4(nametab , dx | ((cells-12)<< 16),(tilex+6) | (ty << 16));
|
||||
} else if (pv->reg[0] & 0x80) {
|
||||
// vscroll disabled for rightmost 8 columns (e.g. Gauntlet)
|
||||
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline & 7;
|
||||
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline&7;
|
||||
DrawStripLowM4(nametab, dx | ((cells-8) << 16), tilex | (ty << 16));
|
||||
DrawStripLowM4(nametab2, dx2 | (8 << 16), tilex2 | (ty2 << 17));
|
||||
} else
|
||||
|
@ -311,8 +318,10 @@ static void DrawDisplayM4(int scanline)
|
|||
|
||||
// high priority tiles (use virtual layer switch just for fun)
|
||||
if (!(pv->debug_p & PVD_KILL_A)) {
|
||||
if (pv->reg[0] & 0x80) {
|
||||
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline & 7;
|
||||
if ((Pico.m.hardware & 0x3) == 0x3) {
|
||||
DrawStripHighM4(nametab , dx | ((cells-12)<< 16),(tilex+6) | (ty << 16));
|
||||
} else if (pv->reg[0] & 0x80) {
|
||||
int dx2 = dx + (cells-8)*8, tilex2 = tilex + (cells-8), ty2 = scanline&7;
|
||||
DrawStripHighM4(nametab, dx | ((cells-8) << 16), tilex | (ty << 16));
|
||||
DrawStripHighM4(nametab2, dx2 | (8 << 16), tilex2 | (ty2 << 17));
|
||||
} else
|
||||
|
@ -451,20 +460,21 @@ static void DrawSpritesM2(int scanline)
|
|||
|
||||
// now draw all sprites backwards
|
||||
for (--s; s >= 0; s--) {
|
||||
int x, w = (zoomed ? 16: 8);
|
||||
int x, c, w = (zoomed ? 16: 8);
|
||||
i = sprites_x[s];
|
||||
x = sat[MEM_LE2(i+1)] + xoff;
|
||||
if (sat[MEM_LE2(i+3)] & 0x80)
|
||||
x -= 32;
|
||||
c = sat[MEM_LE2(i+3)] & 0x0f;
|
||||
if (x > 0) {
|
||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s])];
|
||||
if (zoomed) TileDoubleSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||
else TileNormSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||
if (zoomed) TileDoubleSprM2(x, pack, c);
|
||||
else TileNormSprM2(x, pack, c);
|
||||
}
|
||||
if((pv->reg[1] & 0x2) && (x+=w) > 0) {
|
||||
pack = PicoMem.vramb[MEM_LE2(sprites_addr[s]+0x10)];
|
||||
if (zoomed) TileDoubleSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||
else TileNormSprM2(x, pack, sat[MEM_LE2(i+3)] & 0xf);
|
||||
if (zoomed) TileDoubleSprM2(x, pack, c);
|
||||
else TileNormSprM2(x, pack, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -524,34 +534,45 @@ static void FinalizeLineRGB555SMS(int line);
|
|||
|
||||
void PicoFrameStartSMS(void)
|
||||
{
|
||||
int lines = 192, columns = 256, coffs;
|
||||
int lines = 192, columns = 256, loffs, coffs;
|
||||
skip_next_line = 0;
|
||||
screen_offset = 24;
|
||||
loffs = screen_offset = 24; // 192 lines is really 224 with top/bottom bars
|
||||
Pico.est.rendstatus = PDRAW_32_COLS;
|
||||
|
||||
switch ((Pico.video.reg[0]&0x06) | (Pico.video.reg[1]&0x18)) {
|
||||
// Copy LCD enable flag for easier handling
|
||||
Pico.m.hardware &= ~0x2;
|
||||
if (PicoIn.opt & POPT_EN_GG_LCD)
|
||||
Pico.m.hardware |= 0x2;
|
||||
|
||||
if ((Pico.m.hardware & 0x3) == 0x3) {
|
||||
// GG LCD always has 160x144 regardless of settings
|
||||
screen_offset = 24; // nonetheless the vdp timing has 224 lines
|
||||
loffs = 48;
|
||||
lines = 144;
|
||||
columns = 160;
|
||||
} else switch ((Pico.video.reg[0]&0x06) | (Pico.video.reg[1]&0x18)) {
|
||||
// SMS2 only 224/240 line modes, e.g. Micro Machines
|
||||
case 0x06|0x08:
|
||||
screen_offset = 0;
|
||||
loffs = screen_offset = 0;
|
||||
lines = 240;
|
||||
break;
|
||||
case 0x06|0x10:
|
||||
screen_offset = 8;
|
||||
loffs = screen_offset = 8;
|
||||
lines = 224;
|
||||
break;
|
||||
}
|
||||
if (PicoIn.opt & POPT_EN_SOFTSCALE) {
|
||||
line_offset = 0;
|
||||
coffs = 0;
|
||||
columns = 320;
|
||||
} else
|
||||
line_offset = PicoIn.opt & POPT_DIS_32C_BORDER ? 0 : 32;
|
||||
coffs = PicoIn.opt & POPT_DIS_32C_BORDER ? 0:(320-columns)/2;
|
||||
line_offset = (PicoIn.opt & POPT_ALT_RENDERER ? coffs : 0);
|
||||
|
||||
coffs = line_offset;
|
||||
if (FinalizeLineSMS == FinalizeLineRGB555SMS)
|
||||
line_offset = 0 /* done in FinalizeLine */;
|
||||
|
||||
if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) {
|
||||
emu_video_mode_change(screen_offset, lines, coffs, columns);
|
||||
emu_video_mode_change(loffs, lines, coffs, columns);
|
||||
rendstatus_old = Pico.est.rendstatus;
|
||||
rendlines = lines;
|
||||
}
|
||||
|
@ -562,14 +583,20 @@ void PicoFrameStartSMS(void)
|
|||
|
||||
void PicoLineSMS(int line)
|
||||
{
|
||||
if (skip_next_line > 0) {
|
||||
skip_next_line--;
|
||||
int skip = skip_next_line;
|
||||
|
||||
// GG LCD, render only visible part of screen
|
||||
if ((Pico.m.hardware & 0x3) == 0x3 && (line < 24 || line >= 24+144))
|
||||
goto norender;
|
||||
|
||||
if (PicoScanBegin != NULL && skip == 0)
|
||||
skip = PicoScanBegin(line + screen_offset);
|
||||
|
||||
if (skip) {
|
||||
skip_next_line = skip - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PicoScanBegin != NULL)
|
||||
skip_next_line = PicoScanBegin(line + screen_offset);
|
||||
|
||||
// Draw screen:
|
||||
BackFill(Pico.video.reg[7] & 0x0f, 0, &Pico.est);
|
||||
if (Pico.video.reg[1] & 0x40) {
|
||||
|
@ -583,19 +610,21 @@ void PicoLineSMS(int line)
|
|||
if (PicoScanEnd != NULL)
|
||||
skip_next_line = PicoScanEnd(line + screen_offset);
|
||||
|
||||
norender:
|
||||
Pico.est.HighCol += HighColIncrement;
|
||||
Pico.est.DrawLineDest = (char *)Pico.est.DrawLineDest + DrawLineDestIncrement;
|
||||
}
|
||||
|
||||
/* Fixed palette for TMS9918 modes */
|
||||
static u16 tmspal[32] = {
|
||||
0x00,0x00,0x08,0x0c,0x10,0x30,0x01,0x3c,0x02,0x03,0x05,0x0f,0x04,0x33,0x15,0x3f
|
||||
0x0000, 0x0000, 0x00a0, 0x00f0, 0x0500, 0x0f00, 0x0005, 0x0ff0,
|
||||
0x000a, 0x000f, 0x0055, 0x00ff, 0x0050, 0x0f0f, 0x0555, 0x0fff,
|
||||
};
|
||||
|
||||
void PicoDoHighPal555SMS(void)
|
||||
{
|
||||
unsigned int *spal=(void *)PicoMem.cram;
|
||||
unsigned int *dpal=(void *)Pico.est.HighPal;
|
||||
u32 *spal=(void *)PicoMem.cram;
|
||||
u32 *dpal=(void *)Pico.est.HighPal;
|
||||
unsigned int t;
|
||||
int i;
|
||||
|
||||
|
@ -603,21 +632,9 @@ void PicoDoHighPal555SMS(void)
|
|||
if (!(Pico.video.reg[0] & 0x4))
|
||||
spal = (u32 *)tmspal;
|
||||
|
||||
/* cram is always stored as shorts, even though real hardware probably uses bytes */
|
||||
if (PicoIn.AHW & PAHW_SMS) for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
||||
t = *spal;
|
||||
#if defined(USE_BGR555)
|
||||
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9);
|
||||
t |= (t >> 2) | ((t >> 4) & 0x04210421);
|
||||
#elif defined(USE_BGR565)
|
||||
t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)<<10);
|
||||
t |= (t >> 2) | ((t >> 4) & 0x08610861);
|
||||
#else
|
||||
t = ((t & 0x00030003)<<14) | ((t & 0x000c000c)<<7) | ((t & 0x00300030)>>1);
|
||||
t |= (t >> 2) | ((t >> 4) & 0x08610861);
|
||||
#endif
|
||||
*dpal = t;
|
||||
} else for (i = 0x20/2; i > 0; i--, spal++, dpal++) { // GG palette 4 bit/col
|
||||
/* SMS 6 bit cram data was already converted to MD/GG format by vdp write,
|
||||
* hence GG/SMS/TMS can all be handled the same here */
|
||||
for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
|
||||
t = *spal;
|
||||
#if defined(USE_BGR555)
|
||||
t = ((t & 0x000f000f)<< 1) | ((t & 0x00f000f0)<<2) | ((t & 0x0f000f00)<<3);
|
||||
|
@ -646,15 +663,7 @@ static void FinalizeLineRGB555SMS(int line)
|
|||
|
||||
static void FinalizeLine8bitSMS(int line)
|
||||
{
|
||||
u8 *pd = Pico.est.DrawLineDest + line_offset;
|
||||
u8 *ps = Pico.est.HighCol + line_offset + 8;
|
||||
|
||||
if (DrawLineDestIncrement) {
|
||||
if (PicoIn.opt & POPT_EN_SOFTSCALE)
|
||||
rh_upscale_nn_4_5(pd, 320, ps, 256, 256, f_nop);
|
||||
else if (pd != ps)
|
||||
memcpy(pd, ps, 256);
|
||||
}
|
||||
FinalizeLine8bit(0, line, &Pico.est);
|
||||
}
|
||||
|
||||
void PicoDrawSetOutputSMS(pdso_t which)
|
||||
|
|
|
@ -64,7 +64,7 @@ extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s;
|
|||
#define POPT_EN_MCD_PCM (1<<10)
|
||||
#define POPT_EN_MCD_CDDA (1<<11)
|
||||
#define POPT_EN_MCD_GFX (1<<12) // 00 x000
|
||||
// unused (1<<13)
|
||||
#define POPT_EN_GG_LCD (1<<13)
|
||||
#define POPT_EN_SOFTSCALE (1<<14)
|
||||
#define POPT_EN_MCD_RAMCART (1<<15)
|
||||
#define POPT_DIS_VDP_FIFO (1<<16) // 0x 0000
|
||||
|
|
|
@ -670,6 +670,7 @@ PICO_INTERNAL void PicoFrameStart(void);
|
|||
void PicoDrawSync(int to, int blank_last_line);
|
||||
void BackFill(int reg7, int sh, struct PicoEState *est);
|
||||
void FinalizeLine555(int sh, int line, struct PicoEState *est);
|
||||
void FinalizeLine8bit(int sh, int line, struct PicoEState *est);
|
||||
void PicoDrawSetOutBufMD(void *dest, int increment);
|
||||
extern int (*PicoScanBegin)(unsigned int num);
|
||||
extern int (*PicoScanEnd)(unsigned int num);
|
||||
|
|
15
pico/sms.c
15
pico/sms.c
|
@ -52,8 +52,17 @@ static void vdp_data_write(unsigned char d)
|
|||
struct PicoVideo *pv = &Pico.video;
|
||||
|
||||
if (pv->type == 3) {
|
||||
if (PicoMem.cram[pv->addr & 0x1f] != d) Pico.m.dirtyPal = 1;
|
||||
PicoMem.cram[pv->addr & 0x1f] = d;
|
||||
if (Pico.m.hardware & 0x1) { // GG, same layout as MD
|
||||
unsigned a = pv->addr & 0x3f;
|
||||
if (a & 0x1) d &= 0x0f;
|
||||
if (((u8 *)PicoMem.cram)[MEM_LE2(a)] != d) Pico.m.dirtyPal = 1;
|
||||
((u8 *)PicoMem.cram)[MEM_LE2(a)] = d;
|
||||
} else { // SMS, convert to MD layout (00BbGgRr to 0000BbBbGgGgRrRr)
|
||||
unsigned a = pv->addr & 0x1f;
|
||||
u16 c = (d&0x30)*0x40 + (d&0x0c)*0x10 + (d&0x03)*0x04;
|
||||
if (PicoMem.cram[a] != (c | (c>>2))) Pico.m.dirtyPal = 1;
|
||||
PicoMem.cram[a] = c | (c>>2);
|
||||
}
|
||||
} else {
|
||||
PicoMem.vramb[MEM_LE2(pv->addr)] = d;
|
||||
}
|
||||
|
@ -130,7 +139,7 @@ static unsigned char z80_sms_in(unsigned short a)
|
|||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
d = 0xff;
|
||||
d = 0xff & ~(PicoIn.pad[0] & 0x80);
|
||||
break;
|
||||
|
||||
case 0x40: /* V counter */
|
||||
|
|
|
@ -58,9 +58,6 @@
|
|||
.endif
|
||||
|
||||
orr r2, r2, r2, lsr #3
|
||||
.if \sh == 1
|
||||
str r2, [r0, #0x40*2*4]
|
||||
.endif
|
||||
str r2, [r0], #4
|
||||
.endm
|
||||
|
||||
|
@ -101,10 +98,10 @@ bgr444_to_rgb32_sh:
|
|||
subs r12, r12, #1
|
||||
|
||||
ldmia r1!, {r4-r7}
|
||||
convRGB32_2 r4, 1
|
||||
convRGB32_2 r5, 1
|
||||
convRGB32_2 r6, 1
|
||||
convRGB32_2 r7, 1
|
||||
convRGB32_2 r4, 2
|
||||
convRGB32_2 r5, 2
|
||||
convRGB32_2 r6, 2
|
||||
convRGB32_2 r7, 2
|
||||
bgt .loopRGB32sh
|
||||
|
||||
mov r12, #0x40>>3 @ repeats
|
||||
|
@ -112,10 +109,10 @@ bgr444_to_rgb32_sh:
|
|||
|
||||
.loopRGB32hi:
|
||||
ldmia r1!, {r4-r7}
|
||||
convRGB32_2 r4, 2
|
||||
convRGB32_2 r5, 2
|
||||
convRGB32_2 r6, 2
|
||||
convRGB32_2 r7, 2
|
||||
convRGB32_2 r4, 1
|
||||
convRGB32_2 r5, 1
|
||||
convRGB32_2 r6, 1
|
||||
convRGB32_2 r7, 1
|
||||
|
||||
subs r12, r12, #1
|
||||
bgt .loopRGB32hi
|
||||
|
|
|
@ -326,6 +326,8 @@ static void system_announce(void)
|
|||
|
||||
if (PicoIn.AHW & PAHW_SMS) {
|
||||
sys_name = "Master System";
|
||||
if (Pico.m.hardware & 0x1)
|
||||
sys_name = "Game Gear";
|
||||
#ifdef NO_SMS
|
||||
extra = " [no support]";
|
||||
#endif
|
||||
|
@ -587,7 +589,7 @@ void emu_prep_defconfig(void)
|
|||
memset(&defaultConfig, 0, sizeof(defaultConfig));
|
||||
defaultConfig.EmuOpt = EOPT_EN_SRAM | EOPT_EN_SOUND | EOPT_16BPP |
|
||||
EOPT_EN_CD_LEDS | EOPT_GZIP_SAVES | 0x10/*?*/;
|
||||
defaultConfig.s_PicoOpt = POPT_EN_SNDFILTER|POPT_EN_YM2413|
|
||||
defaultConfig.s_PicoOpt = POPT_EN_SNDFILTER|POPT_EN_YM2413|POPT_EN_GG_LCD |
|
||||
POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80 |
|
||||
POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_MCD_GFX |
|
||||
POPT_EN_DRC|POPT_ACC_SPRITES |
|
||||
|
|
|
@ -42,7 +42,7 @@ static const char *rom_exts[] = {
|
|||
"bin", "smd", "gen", "md",
|
||||
"iso", "cso", "cue", "chd",
|
||||
"32x",
|
||||
"sms",
|
||||
"sms", "gg",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -536,6 +536,7 @@ static menu_entry e_menu_adv_options[] =
|
|||
mee_onoff ("Disable YM2612 SSG-EG", MA_OPT2_DISABLE_YM_SSG,PicoIn.opt, POPT_DIS_FM_SSGEG),
|
||||
mee_onoff ("Emulate SN76496 (PSG)", MA_OPT2_ENABLE_SN76496,PicoIn.opt, POPT_EN_PSG),
|
||||
mee_onoff ("Emulate YM2413 (FM)", MA_OPT2_ENABLE_YM2413 ,PicoIn.opt, POPT_EN_YM2413),
|
||||
mee_onoff ("Emulate Game Gear LCD", MA_OPT2_ENABLE_GGLCD ,PicoIn.opt, POPT_EN_GG_LCD),
|
||||
mee_onoff ("Disable idle loop patching",MA_OPT2_NO_IDLE_LOOPS,PicoIn.opt, POPT_DIS_IDLE_DET),
|
||||
mee_onoff ("Disable frame limiter", MA_OPT2_NO_FRAME_LIMIT,currentConfig.EmuOpt, EOPT_NO_FRMLIMIT),
|
||||
mee_onoff ("Enable dynarecs", MA_OPT2_DYNARECS, PicoIn.opt, POPT_EN_DRC),
|
||||
|
|
|
@ -52,6 +52,7 @@ typedef enum
|
|||
MA_OPT2_DISABLE_YM_SSG,
|
||||
MA_OPT2_ENABLE_SN76496,
|
||||
MA_OPT2_ENABLE_YM2413,
|
||||
MA_OPT2_ENABLE_GGLCD,
|
||||
MA_OPT2_NO_LAST_ROM,
|
||||
MA_OPT2_RAMTIMINGS, /* gp2x */
|
||||
MA_OPT2_NO_FRAME_LIMIT, /* psp */
|
||||
|
|
|
@ -35,12 +35,20 @@
|
|||
*/
|
||||
#include <pico/pico_types.h>
|
||||
|
||||
|
||||
/* LSB of all colors in a pixel */
|
||||
#if defined(USE_BGR555)
|
||||
#define PXLSB 0x0421
|
||||
#else
|
||||
#define PXLSB 0x0821
|
||||
#endif
|
||||
|
||||
/* RGB565 pixel mixing, see https://www.compuphase.com/graphic/scale3.htm and
|
||||
http://blargg.8bitalley.com/info/rgb_mixing.html */
|
||||
/* 2-level mixing */
|
||||
//#define p_05(d,p1,p2) d=(((p1)+(p2) + ( ((p1)^(p2))&0x0821))>>1) // round up
|
||||
//#define p_05(d,p1,p2) d=(((p1)+(p2) - ( ((p1)^(p2))&0x0821))>>1) // round down
|
||||
#define p_05(d,p1,p2) d=(((p1)&(p2)) + ((((p1)^(p2))&~0x0821)>>1))
|
||||
//#define p_05(d,p1,p2) d=(((p1)+(p2) + ( ((p1)^(p2))&PXLSB))>>1) // round up
|
||||
//#define p_05(d,p1,p2) d=(((p1)+(p2) - ( ((p1)^(p2))&PXLSB))>>1) // round down
|
||||
#define p_05(d,p1,p2) d=(((p1)&(p2)) + ((((p1)^(p2))&~PXLSB)>>1))
|
||||
/* 4-level mixing, 2 times slower */
|
||||
// 1/4*p1 + 3/4*p2 = 1/2*(1/2*(p1+p2) + p2)
|
||||
#define p_025(d,p1,p2) p_05(t, p1, p2); p_05( d, t, p2)
|
||||
|
@ -322,6 +330,21 @@ scalers h:
|
|||
si += ss - w; \
|
||||
} while (0)
|
||||
|
||||
// reverse version for overlapping buffers
|
||||
#define rh_upscale_nn_1_2(di,ds,si,ss,w,f) do { \
|
||||
int i; \
|
||||
di += w*2; \
|
||||
si += w; \
|
||||
for (i = w/2; i > 0; i--, si -= 2, di -= 4) { \
|
||||
di[-1] = f(si[-1]); \
|
||||
di[-2] = f(si[-1]); \
|
||||
di[-3] = f(si[-2]); \
|
||||
di[-4] = f(si[-2]); \
|
||||
} \
|
||||
di += ds; \
|
||||
si += ss; \
|
||||
} while (0)
|
||||
|
||||
#define h_upscale_bl2_1_2(di,ds,si,ss,w,f) do { \
|
||||
int i; uint p = f(si[0]); \
|
||||
for (i = w/2; i > 0; i--, si += 2, di += 4) { \
|
||||
|
@ -514,11 +537,12 @@ scalers v:
|
|||
} else { \
|
||||
int j; \
|
||||
l = 0; \
|
||||
di -= 4*ds; \
|
||||
di -= 3*ds; \
|
||||
for (j = 0; j < 2; j++) { \
|
||||
v_copy(&di[0], &di[-ds], w, f_nop); \
|
||||
di += 2*ds; \
|
||||
} \
|
||||
di -= ds; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -528,11 +552,12 @@ scalers v:
|
|||
} else { \
|
||||
int j; \
|
||||
l = 0; \
|
||||
di -= 4*ds; \
|
||||
di -= 3*ds; \
|
||||
for (j = 0; j < 2; j++) { \
|
||||
v_mix(&di[0], &di[-ds], &di[ds], w, p_05, f_nop); \
|
||||
di += 2*ds; \
|
||||
} \
|
||||
di -= ds; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ static void change_renderer(int diff)
|
|||
}
|
||||
|
||||
#define is_16bit_mode() \
|
||||
(currentConfig.renderer == RT_16BIT || (PicoIn.AHW & PAHW_32X))
|
||||
(currentConfig.renderer == RT_16BIT || (PicoIn.AHW & PAHW_32X) || doing_bg_frame)
|
||||
|
||||
static void (*osd_text)(int x, int y, const char *text);
|
||||
|
||||
|
@ -248,7 +248,7 @@ static int EmuScanEnd8_rot(unsigned int num)
|
|||
|
||||
/* line doublers */
|
||||
static unsigned int ld_counter;
|
||||
static int ld_left, ld_lines;
|
||||
static int ld_left, ld_lines; // numbers in Q1 format
|
||||
|
||||
static int EmuScanBegin16_ld(unsigned int num)
|
||||
{
|
||||
|
@ -271,9 +271,9 @@ static int EmuScanEnd16_ld(unsigned int num)
|
|||
emu_scan_end(ld_counter);
|
||||
|
||||
ld_counter++;
|
||||
ld_left--;
|
||||
ld_left -= 2;
|
||||
if (ld_left <= 0) {
|
||||
ld_left = ld_lines;
|
||||
ld_left += ld_lines;
|
||||
|
||||
EmuScanBegin16_ld(num);
|
||||
memcpy(Pico.est.DrawLineDest, oldline, 320 * gp2x_current_bpp / 8);
|
||||
|
@ -313,6 +313,7 @@ static int make_local_pal_md(int fast_mode)
|
|||
else if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode
|
||||
bgr444_to_rgb32(localPal, Pico.est.SonicPal);
|
||||
bgr444_to_rgb32_sh(localPal, Pico.est.SonicPal);
|
||||
memcpy(localPal+0xc0, localPal, 0x40*4); // for spr prio mess
|
||||
}
|
||||
else {
|
||||
bgr444_to_rgb32(localPal, Pico.est.SonicPal);
|
||||
|
@ -331,18 +332,7 @@ static int make_local_pal_md(int fast_mode)
|
|||
|
||||
static int make_local_pal_sms(int fast_mode)
|
||||
{
|
||||
unsigned short *spal = PicoMem.cram;
|
||||
unsigned int *dpal = (void *)localPal;
|
||||
unsigned int i, t;
|
||||
|
||||
for (i = 0x40; i > 0; i--) {
|
||||
t = *spal++;
|
||||
t = ((t & 0x0003) << 22) | ((t & 0x000c) << 12) | ((t & 0x0030) << 2);
|
||||
t |= t >> 2;
|
||||
t |= t >> 4;
|
||||
*dpal++ = t;
|
||||
}
|
||||
|
||||
bgr444_to_rgb32(localPal, PicoMem.cram);
|
||||
Pico.m.dirtyPal = 0;
|
||||
return 0x40;
|
||||
}
|
||||
|
@ -486,6 +476,9 @@ static void vid_reset_mode(void)
|
|||
int gp2x_mode = 16;
|
||||
int renderer = get_renderer();
|
||||
|
||||
if (doing_bg_frame)
|
||||
renderer = RT_16BIT;
|
||||
|
||||
PicoIn.opt &= ~POPT_ALT_RENDERER;
|
||||
emu_scan_begin = NULL;
|
||||
emu_scan_end = NULL;
|
||||
|
@ -557,11 +550,13 @@ static void vid_reset_mode(void)
|
|||
|
||||
Pico.m.dirtyPal = 1;
|
||||
|
||||
PicoIn.opt &= ~POPT_EN_SOFTSCALE;
|
||||
PicoIn.opt &= ~(POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE);
|
||||
if (currentConfig.scaling == EOPT_SCALE_SW) {
|
||||
PicoIn.opt |= POPT_EN_SOFTSCALE;
|
||||
PicoIn.filter = EOPT_FILTER_BILINEAR2;
|
||||
}
|
||||
} else if (currentConfig.scaling == EOPT_SCALE_HW && is_16bit_mode())
|
||||
// hw scaling, render without any padding
|
||||
PicoIn.opt |= POPT_DIS_32C_BORDER;
|
||||
|
||||
// palette converters for 8bit modes
|
||||
make_local_pal = (PicoIn.AHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md;
|
||||
|
@ -572,6 +567,12 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
|
|||
int scalex = 320, scaley = 240;
|
||||
int ln_offs = 0;
|
||||
|
||||
/* line doubling for swscaling, also needed for bg frames */
|
||||
if (currentConfig.vscaling == EOPT_SCALE_SW && line_count < 240) {
|
||||
ld_lines = ld_left = 2*line_count / (240 - line_count);
|
||||
PicoDrawSetCallbacks(EmuScanBegin16_ld, EmuScanEnd16_ld);
|
||||
}
|
||||
|
||||
if (doing_bg_frame)
|
||||
return;
|
||||
|
||||
|
@ -579,10 +580,8 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
|
|||
osd_y = 232;
|
||||
|
||||
/* set up hwscaling here */
|
||||
PicoIn.opt &= ~POPT_DIS_32C_BORDER;
|
||||
if (col_count < 320 && currentConfig.scaling == EOPT_SCALE_HW) {
|
||||
scalex = col_count;
|
||||
PicoIn.opt |= POPT_DIS_32C_BORDER;
|
||||
osd_fps_x = col_count - (320-OSD_FPS_X);
|
||||
}
|
||||
|
||||
|
@ -594,11 +593,6 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
|
|||
|
||||
gp2x_video_RGB_setscaling(ln_offs, scalex, scaley);
|
||||
|
||||
/* line doubling */
|
||||
if (currentConfig.vscaling == EOPT_SCALE_SW && line_count < 240) {
|
||||
ld_lines = ld_left = line_count / (240 - line_count);
|
||||
PicoDrawSetCallbacks(EmuScanBegin16_ld, EmuScanEnd16_ld);
|
||||
}
|
||||
|
||||
// clear whole screen in all buffers
|
||||
if (!is_16bit_mode())
|
||||
|
@ -731,6 +725,8 @@ void pemu_forced_frame(int no_scale, int do_emu)
|
|||
doing_bg_frame = 1;
|
||||
PicoDrawSetCallbacks(NULL, NULL);
|
||||
Pico.m.dirtyPal = 1;
|
||||
PicoIn.opt &= ~POPT_DIS_32C_BORDER;
|
||||
gp2x_current_bpp = 16;
|
||||
|
||||
if (!no_scale)
|
||||
no_scale = currentConfig.scaling == EOPT_SCALE_NONE;
|
||||
|
@ -749,6 +745,7 @@ void plat_video_loop_prepare(void)
|
|||
// make sure we are in correct mode
|
||||
change_renderer(0);
|
||||
vid_reset_mode();
|
||||
rendstatus_old = -1;
|
||||
}
|
||||
|
||||
void pemu_loop_prep(void)
|
||||
|
|
|
@ -89,8 +89,8 @@ static retro_audio_sample_batch_t audio_batch_cb;
|
|||
#define INITIAL_SND_RATE 44100
|
||||
|
||||
static const float VOUT_PAR = 0.0;
|
||||
static const float VOUT_4_3 = (224.0f * (4.0f / 3.0f));
|
||||
static const float VOUT_CRT = (224.0f * 1.29911f);
|
||||
static const float VOUT_4_3 = (4.0f / 3.0f);
|
||||
static const float VOUT_CRT = (1.29911f);
|
||||
|
||||
static bool show_overscan = false;
|
||||
static bool old_show_overscan = false;
|
||||
|
@ -746,7 +746,7 @@ void retro_get_system_info(struct retro_system_info *info)
|
|||
#define _GIT_VERSION "-" GIT_VERSION
|
||||
#endif
|
||||
info->library_version = VERSION _GIT_VERSION;
|
||||
info->valid_extensions = "bin|gen|smd|md|32x|cue|iso|chd|sms";
|
||||
info->valid_extensions = "bin|gen|smd|md|32x|cue|iso|chd|sms|gg";
|
||||
info->need_fullpath = true;
|
||||
}
|
||||
|
||||
|
@ -899,7 +899,7 @@ typedef struct patch
|
|||
} patch;
|
||||
|
||||
extern void decode(char *buff, patch *dest);
|
||||
extern uint16_t m68k_read16(uint32_t a);
|
||||
extern uint32_t m68k_read16(uint32_t a);
|
||||
extern void m68k_write16(uint32_t a, uint16_t d);
|
||||
|
||||
void retro_cheat_reset(void)
|
||||
|
@ -1494,12 +1494,13 @@ static void update_variables(bool first_run)
|
|||
var.value = NULL;
|
||||
var.key = "picodrive_aspect";
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
|
||||
int height = vout_height >= 192 && vout_height <= 224 ? 224 : vout_height;
|
||||
if (strcmp(var.value, "4/3") == 0)
|
||||
user_vout_width = VOUT_4_3;
|
||||
user_vout_width = VOUT_4_3 * height;
|
||||
else if (strcmp(var.value, "CRT") == 0)
|
||||
user_vout_width = VOUT_CRT;
|
||||
user_vout_width = VOUT_CRT * height;
|
||||
else
|
||||
user_vout_width = VOUT_PAR;
|
||||
user_vout_width = VOUT_PAR * height;
|
||||
}
|
||||
|
||||
if (user_vout_width != old_user_vout_width)
|
||||
|
@ -1801,7 +1802,8 @@ void retro_init(void)
|
|||
sceBlock = getVMBlock();
|
||||
#endif
|
||||
|
||||
PicoIn.opt = POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80|POPT_EN_YM2413
|
||||
PicoIn.opt = POPT_EN_STEREO|POPT_EN_FM
|
||||
| POPT_EN_PSG|POPT_EN_Z80|POPT_EN_YM2413|POPT_EN_GG_LCD
|
||||
| POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_MCD_GFX
|
||||
| POPT_EN_32X|POPT_EN_PWM
|
||||
| POPT_ACC_SPRITES|POPT_DIS_32C_BORDER;
|
||||
|
|
|
@ -95,7 +95,7 @@ static void draw_cd_leds(void)
|
|||
* for display isn't always possible.
|
||||
*/
|
||||
|
||||
static u16 *screen_buffer(u16 *buf)
|
||||
static inline u16 *screen_buffer(u16 *buf)
|
||||
{
|
||||
return buf + screen_y * g_screen_ppitch + screen_x -
|
||||
(out_y * g_screen_ppitch + out_x);
|
||||
|
@ -105,34 +105,46 @@ void screen_blit(u16 *pd, int pp, u8* ps, int ss, u16 *pal)
|
|||
{
|
||||
typedef void (*upscale_t)
|
||||
(u16 *di,int ds, u8 *si,int ss, int w,int h, u16 *pal);
|
||||
upscale_t upscale_hv[] = {
|
||||
static const upscale_t upscale_256_224_hv[] = {
|
||||
upscale_rgb_nn_x_4_5_y_16_17, upscale_rgb_snn_x_4_5_y_16_17,
|
||||
upscale_rgb_bl2_x_4_5_y_16_17, upscale_rgb_bl4_x_4_5_y_16_17,
|
||||
};
|
||||
upscale_t upscale_h[] = {
|
||||
static const upscale_t upscale_256_224_h[] = {
|
||||
upscale_rgb_nn_x_4_5, upscale_rgb_snn_x_4_5,
|
||||
upscale_rgb_bl2_x_4_5, upscale_rgb_bl4_x_4_5,
|
||||
};
|
||||
upscale_t upscale_v[] = {
|
||||
static const upscale_t upscale_256_224_v[] = {
|
||||
upscale_rgb_nn_y_16_17, upscale_rgb_snn_y_16_17,
|
||||
upscale_rgb_bl2_y_16_17, upscale_rgb_bl4_y_16_17,
|
||||
};
|
||||
upscale_t *upscale;
|
||||
static const upscale_t upscale_160_144_hv[] = {
|
||||
upscale_rgb_nn_x_1_2_y_3_5, upscale_rgb_nn_x_1_2_y_3_5,
|
||||
upscale_rgb_bl2_x_1_2_y_3_5, upscale_rgb_bl4_x_1_2_y_3_5,
|
||||
};
|
||||
static const upscale_t upscale_160_144_h[] = {
|
||||
upscale_rgb_nn_x_1_2, upscale_rgb_nn_x_1_2,
|
||||
upscale_rgb_bl2_x_1_2, upscale_rgb_bl2_x_1_2,
|
||||
};
|
||||
static const upscale_t upscale_160_144_v[] = {
|
||||
upscale_rgb_nn_y_3_5, upscale_rgb_nn_y_3_5,
|
||||
upscale_rgb_bl2_y_3_5, upscale_rgb_bl4_y_3_5,
|
||||
};
|
||||
const upscale_t *upscale;
|
||||
int y;
|
||||
|
||||
// handle software upscaling
|
||||
upscale = NULL;
|
||||
if (currentConfig.scaling == EOPT_SCALE_SW && out_w == 256) {
|
||||
if (currentConfig.vscaling == EOPT_SCALE_SW && out_h <= 224)
|
||||
// h+v scaling
|
||||
upscale = upscale_hv;
|
||||
else
|
||||
// h scaling
|
||||
upscale = upscale_h;
|
||||
} else if (currentConfig.vscaling == EOPT_SCALE_SW && out_h <= 224) {
|
||||
// v scaling
|
||||
upscale = upscale_v;
|
||||
} else {
|
||||
if (currentConfig.scaling == EOPT_SCALE_SW) {
|
||||
if (currentConfig.vscaling == EOPT_SCALE_SW && out_h <= 224)
|
||||
// h+v scaling
|
||||
upscale = out_w == 256 ? upscale_256_224_hv: upscale_160_144_hv;
|
||||
else
|
||||
// h scaling
|
||||
upscale = out_w == 256 ? upscale_256_224_h : upscale_160_144_h;
|
||||
} else if (currentConfig.vscaling == EOPT_SCALE_SW && out_h <= 224)
|
||||
// v scaling
|
||||
upscale = out_w == 256 ? upscale_256_224_v : upscale_160_144_v;
|
||||
if (!upscale) {
|
||||
// no scaling
|
||||
for (y = 0; y < out_h; y++)
|
||||
h_copy(pd, pp, ps, 328, out_w, f_pal);
|
||||
|
@ -280,16 +292,16 @@ static int vscale_state;
|
|||
|
||||
static int cb_vscaling_begin(unsigned int line)
|
||||
{
|
||||
static int prevline = 999;
|
||||
|
||||
// at start of new frame?
|
||||
if (line < prevline) {
|
||||
// set y frame offset (see emu_change_video_mode)
|
||||
if (line <= out_y) {
|
||||
// set y frame offset (see emu_video_mode_change)
|
||||
Pico.est.DrawLineDest = screen_buffer(g_screen_ptr) +
|
||||
(out_y * g_screen_ppitch + out_x);
|
||||
(out_y * g_screen_ppitch /*+ out_x*/);
|
||||
vscale_state = 0;
|
||||
}
|
||||
prevline = line;
|
||||
return out_y - line;
|
||||
} else if (line > out_y + out_h)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -301,16 +313,25 @@ static int cb_vscaling_nop(unsigned int line)
|
|||
static int cb_vscaling_end(unsigned int line)
|
||||
{
|
||||
u16 *dest = Pico.est.DrawLineDest;
|
||||
switch (currentConfig.filter) {
|
||||
case 3: v_upscale_bl4_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
case 2: v_upscale_bl2_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
case 1: v_upscale_snn_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
default: v_upscale_nn_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_h == 144)
|
||||
switch (currentConfig.filter) {
|
||||
case 0: v_upscale_nn_3_5(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
default: v_upscale_snn_3_5(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (currentConfig.filter) {
|
||||
case 3: v_upscale_bl4_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
case 2: v_upscale_bl2_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
case 1: v_upscale_snn_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
default: v_upscale_nn_16_17(dest, g_screen_ppitch, 320, vscale_state);
|
||||
break;
|
||||
}
|
||||
Pico.est.DrawLineDest = dest;
|
||||
return 0;
|
||||
}
|
||||
|
@ -337,10 +358,10 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
|
|||
}
|
||||
switch (currentConfig.vscaling) {
|
||||
case EOPT_SCALE_HW:
|
||||
screen_h = (out_h < 224 ? 224 : out_h);
|
||||
screen_h = (out_h < 224 && out_h > 144 ? 224 : out_h);
|
||||
screen_y = 0;
|
||||
// NTSC always has 224 visible lines, anything smaller has bars
|
||||
if (out_h < 224)
|
||||
if (out_h < 224 && out_h > 144)
|
||||
screen_y += (224 - out_h)/2;
|
||||
// handle vertical centering for 16 bit mode
|
||||
if (is_16bit_mode())
|
||||
|
@ -349,7 +370,7 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
|
|||
case EOPT_SCALE_SW:
|
||||
screen_y = (screen_h - 240)/2;
|
||||
// NTSC always has 224 visible lines, anything smaller has bars
|
||||
if (out_h < 224)
|
||||
if (out_h < 224 && out_h > 144)
|
||||
screen_y += (224 - out_h)/2;
|
||||
// in 16 bit mode sw scaling is divided between core and platform
|
||||
if (is_16bit_mode() && out_h < 240)
|
||||
|
|
|
@ -136,6 +136,7 @@ get_define OFS_Pico_ Pico est ; echo "$line" >>$fn
|
|||
|
||||
get_define OFS_PicoIn_ PicoInterface opt ; echo "$line" >>$fn
|
||||
get_define OFS_PicoIn_ PicoInterface filter ; echo "$line" >>$fn
|
||||
get_define OFS_PicoIn_ PicoInterface AHW ; echo "$line" >>$fn
|
||||
|
||||
get_define OFS_EST_ PicoEState DrawScanline ; echo "$line" >>$fn
|
||||
get_define OFS_EST_ PicoEState rendstatus ; echo "$line" >>$fn
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue