PS2: support for different gfx modes
This commit is contained in:
parent
ca2f0f0067
commit
beee456c68
4 changed files with 202 additions and 46 deletions
|
@ -44,12 +44,49 @@ enum Buffers {
|
|||
PRINTF
|
||||
};
|
||||
|
||||
/*
|
||||
Supported modes:
|
||||
|
||||
Mode #1 = SDTV progressive (NTSC: 224p / PAL: 256p)
|
||||
Mode #2 = SDTV interlaced (NTSC: 448i / PAL: 512i) <- default
|
||||
Mode #3 = EDTV progressive (NTSC: 480p / PAL: 576p)
|
||||
Mode #4 = HDTV progressive (720p)
|
||||
Mode #5 = HDTV interlaced (1080i)
|
||||
Mode #6 = VESA (640x480@60)
|
||||
Mode #7 = VESA (800x600@60)
|
||||
Mode #8 = VESA (1024x768@60)
|
||||
*/
|
||||
|
||||
static ps2_mode_t ps2_mode[] = {
|
||||
|
||||
// -> w, h, interlaced, pitch, mode, vck, magh, magv, dx, dy
|
||||
|
||||
/* #1 : SDTV - progressive */
|
||||
{ 640, 224, 0, 640, 0x02, 2560, 4, 0, 160 /*158*/, 25 /*22*/ }, /* NTSC */
|
||||
{ 640, 256, 0, 640, 0x03, 2560, 4, 0, 170 /*163*/, 35 /*36*/ }, /* PAL */
|
||||
|
||||
/* #2 : SDTV - interlaced */
|
||||
{ 640, 448, 1, 640, 0x02, 2560, 4, 0, 156 /*158*/, 50 /*45*/ }, /* NTSC */
|
||||
{ 640, 512, 1, 640, 0x03, 2560, 4, 0, 170 /*163*/, 70 /*72*/ }, /* PAL */
|
||||
|
||||
/* #3 : EDTV */
|
||||
{ 720, 480, 0, 768, 0x50, 1440, 2, 0, 58, 35 }, /* NTSC */
|
||||
/* { 720, 576, 0, 768, 0x53, 1440, 2, 0, 62, 45 }, */ /* PAL : full */
|
||||
/* { 656, 576, 0, 704, 0x53, 1312, 2, 0, 62, 45 }, */ /* PAL : redux @ (0,0) */
|
||||
{ 656, 576, 0, 704, 0x53, 1312, 2, 0, 78 /*314*/, 45 }, /* PAL : redux @ center'd */
|
||||
|
||||
/* #4/#5 : HDTV */
|
||||
{ 1280, 720, 0, 1280, 0x52, 1280, 1, 0, 76 /*302*/, 24 },
|
||||
{ 1920, 1080, 1, 1920, 0x51, 1920, 1, 0, 60 /*236*/ /*238*/, 40 },
|
||||
|
||||
/* #6/#7/#8 : VESA 4:3 @ 60Hz */
|
||||
{ 640, 480, 0, 640, 0x1A, 1280, 2, 0, 70 /*276*/, 34 },
|
||||
{ 800, 600, 0, 832, 0x2B, 1600, 2, 0, 105 /*420*/, 26 },
|
||||
{ 1024, 768, 0, 1024, 0x3B, 2048, 2, 0, 144 /*580*/, 34 }
|
||||
};
|
||||
|
||||
#define ANIM_STACK_SIZE (1024 * 32)
|
||||
|
||||
#define DEFAULT_PAL_X 175
|
||||
#define DEFAULT_PAL_Y 72 // 60
|
||||
#define DEFAULT_NTSC_X 165
|
||||
#define DEFAULT_NTSC_Y 45
|
||||
#define ORG_X 256
|
||||
#define ORG_Y 256
|
||||
#define ORIGIN_X (ORG_X << 4)
|
||||
|
@ -103,7 +140,8 @@ int vblankEndHandler(int cause) {
|
|||
|
||||
void createAnimThread(Gs2dScreen *screen);
|
||||
|
||||
Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
||||
Gs2dScreen::Gs2dScreen(uint16 width, uint16 height) {
|
||||
|
||||
_systemQuit = false;
|
||||
ee_sema_t newSema;
|
||||
newSema.init_count = 1;
|
||||
|
@ -131,7 +169,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
|||
_pitch = (width + 127) & ~127;
|
||||
|
||||
_screenBuf = (uint8 *)memalign(64, _width * _height);
|
||||
_overlayBuf = (uint16 *)memalign(64, _width * _height * 2);
|
||||
_overlayBuf = (uint16 *)memalign(64, _pitch * _height * 2);
|
||||
_clut = (uint32 *)memalign(64, 256 * 4);
|
||||
|
||||
memset(_screenBuf, 0, _width * _height);
|
||||
|
@ -139,32 +177,102 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
|||
_clut[1] = GS_RGBA(0xC0, 0xC0, 0xC0, 0);
|
||||
clearOverlay();
|
||||
|
||||
if (mode == TV_DONT_CARE) {
|
||||
#if 1
|
||||
char romver[8];
|
||||
uint16 biosver;
|
||||
int fd = fioOpen("rom0:ROMVER", O_RDONLY);
|
||||
fioRead(fd, &romver, 8);
|
||||
fioClose(fd);
|
||||
biosver=atoi(romver);
|
||||
printf("ROMVER = %s\n", romver);
|
||||
printf("ver = %d\n", atoi(romver));
|
||||
|
||||
if (romver[4] == 'E')
|
||||
_tvMode = TV_PAL;
|
||||
else
|
||||
_tvMode = TV_NTSC;
|
||||
#else
|
||||
if (PAL_NTSC_FLAG == 'E')
|
||||
_tvMode = TV_PAL;
|
||||
if (!_tvMode) { // determine TV standard first
|
||||
if (ConfMan.hasKey("tv_mode", "PlayStation2")) {
|
||||
const char *tvname = ConfMan.get("tv_mode", "PlayStation2").c_str();
|
||||
|
||||
if (strcmp("ntsc", tvname) == 0) {
|
||||
_tvMode = 2;
|
||||
}
|
||||
else if (strcmp("pal", tvname) == 0) {
|
||||
_tvMode = 1;
|
||||
}
|
||||
else
|
||||
_tvMode = 0;
|
||||
}
|
||||
|
||||
if (!_tvMode) {
|
||||
if (romver[4] == 'E')
|
||||
_tvMode = TV_PAL;
|
||||
else
|
||||
_tvMode = TV_NTSC;
|
||||
|
||||
printf("Auto-detect TV mode: PSX:%c PS2:%c\n", *(char *)(0x1FC7FF52), romver[4]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 mode;
|
||||
if (!_gfxMode) { // determine GFX mode next
|
||||
if (ConfMan.hasKey("gfx_mode", "PlayStation2")) {
|
||||
_gfxMode = ConfMan.getInt("gfx_mode", "PlayStation2");
|
||||
// TODO: free more video mem to support these modes
|
||||
if (_gfxMode == 4 || _gfxMode == 5) {
|
||||
printf("Not enough video mem: using EDTV (3)\n");
|
||||
_gfxMode = 3;
|
||||
}
|
||||
else
|
||||
if (_gfxMode == 7 || _gfxMode == 8) {
|
||||
printf("Not enough video mem: using VGA (6)\n");
|
||||
_gfxMode = 6;
|
||||
}
|
||||
|
||||
if (_gfxMode < 1 || _gfxMode > 8) _gfxMode = 2;
|
||||
else
|
||||
if (_gfxMode == 4 || _gfxMode == 5) _tvMode = TV_HDTV;
|
||||
else
|
||||
if (_gfxMode > 5) _tvMode = TV_VESA;
|
||||
}
|
||||
else
|
||||
_tvMode = TV_NTSC;
|
||||
#endif
|
||||
} else
|
||||
_tvMode = mode;
|
||||
_gfxMode = 2;
|
||||
}
|
||||
|
||||
// _tvMode = TV_NTSC;
|
||||
printf("Setting up %s mode\n", (_tvMode == TV_PAL) ? "PAL" : "NTSC");
|
||||
// Remap Mode Index
|
||||
mode = _gfxMode;
|
||||
if (_tvMode == TV_NTSC) {
|
||||
mode = (mode * 2) - 1;
|
||||
}
|
||||
else if (_tvMode == TV_PAL) {
|
||||
mode = (mode * 2);
|
||||
}
|
||||
else if (_tvMode == TV_HDTV) {
|
||||
mode += 3;
|
||||
}
|
||||
else /* VESA */ {
|
||||
_tvMode = TV_VESA;
|
||||
mode += 3;
|
||||
}
|
||||
mode--;
|
||||
|
||||
switch (_tvMode) {
|
||||
case TV_NTSC:
|
||||
printf("Setting up TV mode: NTSC\n");
|
||||
break;
|
||||
case TV_PAL:
|
||||
printf("Setting up TV mode: PAL\n");
|
||||
break;
|
||||
case TV_HDTV:
|
||||
printf("Setting up TV mode: HDTV\n");
|
||||
break;
|
||||
case TV_VESA:
|
||||
printf("Setting up TV mode: VESA\n");
|
||||
break;
|
||||
}
|
||||
|
||||
_tvWidth = ps2_mode[mode].w;
|
||||
_tvHeight = ps2_mode[mode].h;
|
||||
_tvPitch = ps2_mode[mode].pitch;
|
||||
|
||||
printf("Setting up GFX mode: %d x %d\n", _tvWidth, _tvHeight);
|
||||
|
||||
// set screen size, 640x512 for pal, 640x448 for ntsc
|
||||
_tvWidth = 640;
|
||||
_tvHeight = ((_tvMode == TV_PAL) ? 512 /*544*/ : 448);
|
||||
kFullScreen[0].z = kFullScreen[1].z = 0;
|
||||
kFullScreen[0].x = ORIGIN_X;
|
||||
kFullScreen[0].y = ORIGIN_Y;
|
||||
|
@ -177,7 +285,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
|||
_texCoords[1].u = SCALE(_width);
|
||||
_texCoords[1].v = SCALE(_height);
|
||||
|
||||
uint32 tvFrameSize = _tvWidth * _tvHeight * 4; // 32 bits per pixel
|
||||
uint32 tvFrameSize = _tvPitch * _tvHeight * 4; // 32 bits per pixel
|
||||
|
||||
// setup frame buffer pointers
|
||||
_frameBufPtr[0] = 0;
|
||||
|
@ -216,22 +324,39 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
|||
GS_CSR = 0;
|
||||
GsPutIMR(0x7F00);
|
||||
|
||||
uint16 dispPosX, dispPosY;
|
||||
|
||||
if (_tvMode == TV_PAL) {
|
||||
SetGsCrt(GS_INTERLACED, 3, 0);
|
||||
dispPosX = DEFAULT_PAL_X;
|
||||
dispPosY = DEFAULT_PAL_Y;
|
||||
} else {
|
||||
SetGsCrt(GS_INTERLACED, 2, 0);
|
||||
dispPosX = DEFAULT_NTSC_X;
|
||||
dispPosY = DEFAULT_NTSC_Y;
|
||||
if (biosver < 220 && ps2_mode[mode].mode == 0x53) { // EDTV PAL : mode not in BIOS < 2.20
|
||||
// no worries... we work in magic ;-)
|
||||
/* 720x576p */
|
||||
asm ("di");
|
||||
asm ("sync.l; sync.p");
|
||||
GS_PMODE = 0;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SMODE1 = 0x1742890504;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SMODE2 = 0;
|
||||
GS_SYNCH1 = 0x402E02003C827;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SYNCH2 = 0x19CA67;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SYNCV = 0xA9000002700005;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SRFSH = 4;
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SMODE1 = 0x1742880504;
|
||||
asm ("sync.l; sync.p");
|
||||
asm ("sync.l; sync.p");
|
||||
GS_SMODE2 = 0;
|
||||
asm("ei");
|
||||
}
|
||||
else { // BIOS
|
||||
SetGsCrt(ps2_mode[mode].interlaced, ps2_mode[mode].mode, 0); // ps2_mode[mode].interlaced);
|
||||
}
|
||||
|
||||
asm("di");
|
||||
GS_PMODE = GS_SET_PMODE(1, 0, 1, 1, 0, 255);
|
||||
GS_BGCOLOUR = GS_RGBA(0, 0, 0, 0);
|
||||
GS_DISPLAY1 = GS_SET_DISPLAY(_tvWidth, _tvHeight, dispPosX, dispPosY);
|
||||
GS_DISPLAY1 = GS_SET_DISPLAY_MODE(ps2_mode[mode]);
|
||||
asm("ei");
|
||||
|
||||
_curDrawBuf = 0;
|
||||
|
@ -239,7 +364,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode mode) {
|
|||
_dmaPipe->setOrigin(ORIGIN_X, ORIGIN_Y);
|
||||
_dmaPipe->setConfig(1, 0, 1);
|
||||
_dmaPipe->setScissorRect(0, 0, _tvWidth - 1, _tvHeight - 1);
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvWidth, GS_PSMCT24, 0);
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvPitch, GS_PSMCT24, 0);
|
||||
_dmaPipe->flush();
|
||||
|
||||
_clutChanged = _screenChanged = _overlayChanged = true;
|
||||
|
@ -507,10 +632,10 @@ void Gs2dScreen::updateScreen(void) {
|
|||
WaitSema(g_DmacSema); // wait for dma transfer, if there's one running
|
||||
WaitSema(g_VblankSema); // wait if there's already an image waiting for vblank
|
||||
|
||||
g_DmacCmd = GS_SET_DISPFB(_frameBufPtr[_curDrawBuf], _tvWidth, GS_PSMCT24); // put it here for dmac/vblank handler
|
||||
g_DmacCmd = GS_SET_DISPFB(_frameBufPtr[_curDrawBuf], _tvPitch, GS_PSMCT24); // put it here for dmac/vblank handler
|
||||
_dmaPipe->flush();
|
||||
_curDrawBuf ^= 1;
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvWidth, GS_PSMCT24, 0);
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvPitch, GS_PSMCT24, 0);
|
||||
} else
|
||||
_dmaPipe->flush();
|
||||
SignalSema(_screenSema);
|
||||
|
@ -752,10 +877,10 @@ void Gs2dScreen::playAnim(void) {
|
|||
|
||||
drawY += LINE_SPACE;
|
||||
}
|
||||
g_DmacCmd = GS_SET_DISPFB(_frameBufPtr[_curDrawBuf], _tvWidth, GS_PSMCT24); // put it here for dmac/vblank handler
|
||||
g_DmacCmd = GS_SET_DISPFB(_frameBufPtr[_curDrawBuf], _tvPitch, GS_PSMCT24); // put it here for dmac/vblank handler
|
||||
_dmaPipe->flush();
|
||||
_curDrawBuf ^= 1;
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvWidth, GS_PSMCT24, 0);
|
||||
_dmaPipe->setDrawBuffer(_frameBufPtr[_curDrawBuf], _tvPitch, GS_PSMCT24, 0);
|
||||
_dmaPipe->setAlphaBlend(DEST_COLOR, ZERO_COLOR, SOURCE_ALPHA, SOURCE_COLOR, 0);
|
||||
|
||||
SignalSema(_screenSema);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue