proper code to change video modes

This commit is contained in:
dborth 2009-09-16 07:53:18 +00:00
parent 2c662616c5
commit 100263673a
2 changed files with 72 additions and 77 deletions

View File

@ -32,13 +32,12 @@ int FDSSwitchRequested;
/*** External 2D Video ***/ /*** External 2D Video ***/
/*** 2D Video Globals ***/ /*** 2D Video Globals ***/
static GXRModeObj *vmode; // Graphics Mode Object static GXRModeObj *vmode = NULL; // Graphics Mode Object
static unsigned int *xfb[2]; // Framebuffers static unsigned int *xfb[2] = { NULL, NULL }; // Framebuffers
static int whichfb = 0; // Frame buffer toggle static int whichfb = 0; // Frame buffer toggle
int screenheight; int screenheight = 480;
int screenwidth; int screenwidth = 640;
bool progressive = false; bool progressive = false;
static int currentVideoMode = -1; // -1 - not set, 0 - automatic, 1 - NTSC (480i), 2 - Progressive (480p), 3 - PAL (50Hz), 4 - PAL (60Hz)
static int oldRenderMode = -1; // set to GCSettings.render when changing (temporarily) to another mode static int oldRenderMode = -1; // set to GCSettings.render when changing (temporarily) to another mode
/*** 3D GX ***/ /*** 3D GX ***/
@ -459,50 +458,49 @@ UpdateScaling()
} }
/**************************************************************************** /****************************************************************************
* SetupVideoMode * FindVideoMode
* *
* Finds the optimal video mode, or uses the user-specified one * Finds the optimal video mode, or uses the user-specified one
* Also configures original video modes * Also configures original video modes
***************************************************************************/ ***************************************************************************/
static void SetupVideoMode() static GXRModeObj * FindVideoMode()
{ {
if(currentVideoMode == GCSettings.videomode) GXRModeObj * mode;
return; // no need to do anything
// choose the desired video mode // choose the desired video mode
switch(GCSettings.videomode) switch(GCSettings.videomode)
{ {
case 1: // NTSC (480i) case 1: // NTSC (480i)
vmode = &TVNtsc480IntDf; mode = &TVNtsc480IntDf;
break; break;
case 2: // Progressive (480p) case 2: // Progressive (480p)
vmode = &TVNtsc480Prog; mode = &TVNtsc480Prog;
break; break;
case 3: // PAL (50Hz) case 3: // PAL (50Hz)
vmode = &TVPal574IntDfScale; mode = &TVPal574IntDfScale;
break; break;
case 4: // PAL (60Hz) case 4: // PAL (60Hz)
vmode = &TVEurgb60Hz480IntDf; mode = &TVEurgb60Hz480IntDf;
break; break;
default: default:
vmode = VIDEO_GetPreferredMode(NULL); mode = VIDEO_GetPreferredMode(NULL);
#ifdef HW_DOL #ifdef HW_DOL
/* we have component cables, but the preferred mode is interlaced /* we have component cables, but the preferred mode is interlaced
* why don't we switch into progressive? * why don't we switch into progressive?
* on the Wii, the user can do this themselves on their Wii Settings */ * on the Wii, the user can do this themselves on their Wii Settings */
if(VIDEO_HaveComponentCable()) if(VIDEO_HaveComponentCable())
vmode = &TVNtsc480Prog; mode = &TVNtsc480Prog;
#endif #endif
// use hardware vertical scaling to fill screen // use hardware vertical scaling to fill screen
if(vmode->viTVMode >> 2 == VI_PAL) if(mode->viTVMode >> 2 == VI_PAL)
vmode = &TVPal574IntDfScale; mode = &TVPal574IntDfScale;
break; break;
} }
// configure original modes // configure original modes
switch (vmode->viTVMode >> 2) switch (mode->viTVMode >> 2)
{ {
case VI_PAL: case VI_PAL:
// 576 lines (PAL 50Hz) // 576 lines (PAL 50Hz)
@ -531,14 +529,14 @@ static void SetupVideoMode()
// Original Video modes (forced to PAL 60Hz) // Original Video modes (forced to PAL 60Hz)
// set video signal mode // set video signal mode
PAL_240p.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_NON_INTERLACE); PAL_240p.viTVMode = VI_TVMODE(mode->viTVMode >> 2, VI_NON_INTERLACE);
PAL_240p.viYOrigin = (VI_MAX_HEIGHT_NTSC - 480)/2; PAL_240p.viYOrigin = (VI_MAX_HEIGHT_NTSC - 480)/2;
NTSC_240p.viTVMode = VI_TVMODE(vmode->viTVMode >> 2, VI_NON_INTERLACE); NTSC_240p.viTVMode = VI_TVMODE(mode->viTVMode >> 2, VI_NON_INTERLACE);
break; break;
} }
// check for progressive scan // check for progressive scan
if (vmode->viTVMode == VI_TVMODE_NTSC_PROG) if (mode->viTVMode == VI_TVMODE_NTSC_PROG)
progressive = true; progressive = true;
else else
progressive = false; progressive = false;
@ -547,11 +545,51 @@ static void SetupVideoMode()
// widescreen fix // widescreen fix
if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) if(CONF_GetAspectRatio() == CONF_ASPECT_16_9)
{ {
vmode->viWidth = VI_MAX_WIDTH_PAL; mode->viWidth = VI_MAX_WIDTH_PAL;
} }
#endif #endif
currentVideoMode = GCSettings.videomode; return mode;
}
/****************************************************************************
* SetupVideoMode
*
* Sets up the given video mode
***************************************************************************/
static void SetupVideoMode(GXRModeObj * mode)
{
if(vmode == mode)
return;
VIDEO_SetPostRetraceCallback (NULL);
copynow = GX_FALSE;
VIDEO_Configure (mode);
VIDEO_Flush();
// Allocate the video buffers
if(xfb[0]) free(MEM_K1_TO_K0(xfb[0]));
if(xfb[1]) free(MEM_K1_TO_K0(xfb[1]));
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (mode));
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (mode));
// Clear framebuffers etc.
VIDEO_ClearFrameBuffer (mode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer (mode, xfb[1], COLOR_BLACK);
VIDEO_SetNextFramebuffer (xfb[0]);
VIDEO_SetBlack (FALSE);
VIDEO_Flush ();
VIDEO_WaitVSync ();
if (mode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else
while (VIDEO_GetNextField())
VIDEO_WaitVSync();
VIDEO_SetPostRetraceCallback ((VIRetraceCallback)copy_to_xfb);
vmode = mode;
} }
/**************************************************************************** /****************************************************************************
@ -563,41 +601,11 @@ static void SetupVideoMode()
void void
InitGCVideo () InitGCVideo ()
{ {
SetupVideoMode(); GXRModeObj *rmode = FindVideoMode();
SetupVideoMode(rmode);
// configure VI
VIDEO_Configure (vmode);
screenheight = 480;
screenwidth = 640;
// Allocate the video buffers
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
// A console is always useful while debugging.
//console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight, vmode->fbWidth * 2);
// Clear framebuffers etc.
VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
VIDEO_SetNextFramebuffer (xfb[0]);
// video callbacks
VIDEO_SetPostRetraceCallback ((VIRetraceCallback)copy_to_xfb);
VIDEO_SetBlack (FALSE);
VIDEO_Flush ();
VIDEO_WaitVSync ();
if (vmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync ();
copynow = GX_FALSE;
StartGX (); StartGX ();
InitLUTs(); // init LUTs for hq2x InitLUTs(); // init LUTs for hq2x
InitVideoThread (); InitVideoThread ();
// Finally, the video is up and ready for use :)
} }
/**************************************************************************** /****************************************************************************
@ -608,24 +616,16 @@ InitGCVideo ()
void void
ResetVideo_Emu () ResetVideo_Emu ()
{ {
SetupVideoMode(); GXRModeObj *rmode;
GXRModeObj *rmode = vmode; // same mode as menu
Mtx44 p; Mtx44 p;
// change current VI mode if using original render mode // change current VI mode if using original render mode
if (GCSettings.render == 0) if (GCSettings.render == 0)
rmode = tvmodes[GCSettings.timing]; rmode = tvmodes[GCSettings.timing];
// reconfigure VI
VIDEO_Configure (rmode);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else else
while (VIDEO_GetNextField()) rmode = FindVideoMode();
VIDEO_WaitVSync();
SetupVideoMode(rmode); // reconfigure VI
VIDEO_SetPreRetraceCallback(NULL); VIDEO_SetPreRetraceCallback(NULL);
GXColor background = {0, 0, 0, 255}; GXColor background = {0, 0, 0, 255};
@ -864,17 +864,9 @@ ResetVideo_Menu ()
Mtx44 p; Mtx44 p;
f32 yscale; f32 yscale;
u32 xfbHeight; u32 xfbHeight;
GXRModeObj * rmode = FindVideoMode();
SetupVideoMode(); SetupVideoMode(rmode); // reconfigure VI
VIDEO_Configure (vmode);
VIDEO_Flush();
VIDEO_WaitVSync();
if (vmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
else
while (VIDEO_GetNextField())
VIDEO_WaitVSync();
VIDEO_SetPreRetraceCallback((VIRetraceCallback)UpdatePads); VIDEO_SetPreRetraceCallback((VIRetraceCallback)UpdatePads);
// clears the bg to color and clears the z buffer // clears the bg to color and clears the z buffer

View File

@ -2,6 +2,9 @@
Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net> Copyright (c) 2008 Francisco Muñoz 'Hermes' <www.elotrolado.net>
All rights reserved. All rights reserved.
Proper (standard) vorbis usage by Tantric, 2009
Threading modifications/corrections by Tantric, 2009
Redistribution and use in source and binary forms, with or without modification, are Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met: permitted provided that the following conditions are met: