Automatic video mode switching when loading game

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
Gamester17 Offline
Team-XBMC Forum Moderator
Posts: 10,595
Joined: Sep 2003
Reputation: 9
Location: Sweden
Lightbulb    Post: #51
deluded Wrote:Can xbmc not just bash some new values into the video hardware registers to enable different video modes?
Not without restarting the xbe (Xbox executable) or loading a other xbe, and the Xbox can only run one executable/process at a time. You can read this topic thread and this other topic thread for more detailed explainations and some solution ideas and workaround suggestions. The XBMC source code is also of course a good source of information.

Maybe you could 'just' create a small xbe program with a matching .cfg file (or xml) which only quickly preforms video-mode switching on the EEPROM in RAM before launching a specific xbe, ...so kind of like how Team-XBMC's shortcut tool (source code available in the SVN) works but with the addition of on-the-fly video-mode switching. That way you could use that xbe to launch XBMC each time, and maybe even add an option to edit that cfg (or xml) file from XBMC settings in the GUI. (The source code from nkpatcher and/or cherry's videomode code could possible be of help, more information here)
Code:
<xbe>E:\Apps\XBMC\default.xbe</xbe>
<videomode>ntsc</videomode>
<resolution>720p</resolution>

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
find quote
deluded Offline
Junior Member
Posts: 5
Joined: Jan 2007
Reputation: 0
Post: #52
Right - I've sorted my problem...

Xbox is put in to NTSC, and 480p enabled. Xbox then put back to PAL.

Following blunder code added to CApplication::Create, just after the GetModes() command:

// See if we can go to 480p - RH
BYTE currentCableMode = 0;
HalReadSMBusValue(0x20, 0x4, 0, (LPBYTE)&currentCableMode);

if((currentCableMode == 1)/*AV_PACK_HDTV*/ && g_videoConfig.HasPAL())
{
// We're in PAL mode, but connected to HDTV so switch to NTSC for 480p
char temp[1024];
helper.GetXbePath(temp);
char temp2[1024];
char temp3[2];
temp3[0] = temp[0]; temp3[1] = '\0';
helper.GetPartition((LPCSTR)temp3,temp2);
CStdString strTemp(temp+2);
int iLastSlash = strTemp.rfind('\\');
strcat(temp2,strTemp.substr(0,iLastSlash).c_str());
Destroy();
CUtil::LaunchXbe(temp2,("D:\\"+strTemp.substr(iLastSlash+1)).c_str(),NULL,VIDEO_NTSCM,COUNTRY_USA);

}

Basically, each time xbmc starts, it check to see if the HD component lead is connected (or in my case, the switch on the HD / Scart box) and if so, quits and re-runs itself in NTSC.

Must admit that XBMC looks a lot better in 480p (my projectors native resolution) than normal PAL.

Big thanks to the XBMC guys for making the thing compile 1st first time, and actually documenting the code Smile
find quote
Gamester17 Offline
Team-XBMC Forum Moderator
Posts: 10,595
Joined: Sep 2003
Reputation: 9
Location: Sweden
Lightbulb  my 2 cents Post: #53
deluded Wrote:Basically, each time xbmc starts, it check to see if the HD component lead is connected (or in my case, the switch on the HD / Scart box) and if so, quits and re-runs itself in NTSC
hmm, I'm not a programmer myself but I still think it would be better to put the function into a separate XBE, like Team-XBMC's shortcut tool. That way you would not have to load the XBMC XBE twice, the XBMC XBE is much larger and thus takes much longer to load. I do however like the idea of the cable auto-detect feature you implemented.

How about this instead? Add on-the-fly video-mode switching of the EEPROM shadow-copy in RAM before launching a specific XBE to the Team-XBMC's shortcut tool, with the option of cable auto-detect (for both video and audio), configurable via a .cfg file (or xml). Maybe also add GetXbePath to is and make is pass that information along as a parameter to XBMC so if an option to edit that .cfg file (or xml) from XBMC's GUI was implemented then XBMC would automaticly know where that XBE and it's matching cfg file (or xml) is located. That XBE program would still be small and fast to load, and there would be no need to ever load the same XBE twice. The audio option would be nice if like myself use digital-audio when in NTSC-mode (connected to a Xbox HD cable-adapter and HDTV display-device) and analog-audio when in PAL mode (connected to a standard definition Xbox composite video cable and analog stereo to CRT TV built-in speakers).

Suggested .cfg file (or xml) example:
Code:
<!-- Xbox executable (xbe) to run !-->
<xbe>E:\Apps\XBMC\default.xbe</xbe>

<video>
<!-- Set to true to enable video-mode switching, false to disable !-->
   <videomodeswitching>true</videomodeswitching>
<!-- Set to true to try to detect cable-adapter and automaticly switch to NTSC-mode if high-definition cable and PAL-mode otherwise !-->
   <detectcable>true</detectcable>
<!-- Which video-mode to switch to if detectcable is set to false !-->
   <videomode>ntsc</videomode>
<!-- NTSC video-mode resolution options, 480p, 720p or 1080i !-->
   <resolutionntsc>720p</resolutionntsc>
</video>

<audio>
<!-- Set to true to enable audio-mode switching, false to disable !-->
   <audiomodeswitching>true</audiomodeswitching>
<!-- Set to true to try to detect cable-adapter and automaticly switch to digital-audio if high-definition cable and analog-audio otherwise !-->
   <detectcable>true</detectcable>
<!-- Which audio-mode to when use (digital or analog) in NTSC-mode if detectcable is set to false !-->
   <audiomodentsc>digital</audiomodentsc>
<!-- Set to true to enable Dolby Digital when digital-audio is enabled in NTSC-mode !-->
   <ddaudiontsc>true</ddaudiontsc>
<!-- Set to true to enable DTS when digital-audio is enabled in NTSC-mode !-->
   <dtsaudiontsc>false</dtsaudiontsc>
<!-- Use mono or stereo when analog-audio is enabled in NTSC-mode !-->
   <analogaudiontsc>stereo</analogaudiontsc>
<!-- Which audio-mode to when use (digital or analog) in PAL-mode if detectcable is set to false !-->
   <audiomodepal>analog</audiomodepal>
<!-- Set to true to enable Dolby Digital when digital-audio is enabled in PAL-mode !-->
   <ddaudiopal>false</ddaudiopal>
<!-- Set to true to enable DTS when digital-audio is enabled in PAL-mode !-->
   <dtsaudiopal>false</dtsaudiopal>
<!-- Use mono or stereo when analog-audio is enabled in PAL-mode !-->
   <analogaudiopal>mono</analogaudiopal>
</audio>
PS! Note that all this should only touch the EEPROM shadow-copy in RAM and never write to the EEPROM!
The EEPROM it's only capable of aprox. 1000 erase/write cycles so will get damaged if write to it too often.

Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
find quote
deluded Offline
Junior Member
Posts: 5
Joined: Jan 2007
Reputation: 0
Post: #54
Looks like a good idea.

Bizarely, the code I posted worked fine on Saturday, then failed to work on Sunday - it just constantly rebooted XBMC, suggesting that the NTSC shadow copy patch thing hadn't worked.

I'll try to get my code working reliably, then take a look at making it configurable. I like the idea of a config file, but I don't think it's possible to detect if digital audio is present - anyone confirm this??

loading XBMC twice is actually much quicker than you'd expect, and not really noticable.. I suspect XBMC spends most of it's time loading the graphics and other DLLs - my patch was run before all this was done.
find quote
deluded Offline
Junior Member
Posts: 5
Joined: Jan 2007
Reputation: 0
Post: #55
I've fixed the code a bit - it might be worth putting something like as a setting for people that swap between PAL and 480p etc.

Changes made in Application.cpp

Below the line g_graphicsContext.SetGUIResolution(initialResolution);


// See if we can go to 480p - RH
BYTE currentCableMode = 0;
HalReadSMBusValue(XKUtils::SMBDEV_PIC16L, XKUtils::PIC16L_CMD_AV_PACK, 0, (LPBYTE)&currentCableMode);

if((currentCableMode == XKUtils::AV_PACK_HDTV) && XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I)
{
// We're in PAL mode, but connected to HDTV so switch to NTSC for 480p
F_VIDEO ForceVideo = VIDEO_NTSCM;
F_COUNTRY ForceCountry = COUNTRY_USA;
char temp[1024];

helper.GetXbePath(temp);

char temp2[1024];
char temp3[2];
temp3[0] = temp[0]; temp3[1] = '\0';
helper.GetPartition((LPCSTR)temp3,temp2);
CStdString strTemp(temp+2);
int iLastSlash = strTemp.rfind('\\');
strcat(temp2,strTemp.substr(0,iLastSlash).c_str());

Destroy();
CUtil::LaunchXbe(temp2,("D:\\"+strTemp.substr(iLastSlash+1)).c_str(),NULL,ForceVideo,ForceCountry);
}



Following code

else if ((DWVideo == XKEEPROM::VIDEO_STANDARD::PAL_I) && ((XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_M) || (XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_J) || initialResolution < 6))
{
CLog::Log(LOGINFO, "Rebooting to change resolution from %s back to PAL_I", (XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_M) ? "NTSC_M" : "NTSC_J");
ForceVideo = VIDEO_PAL50;
ForceCountry = COUNTRY_EUR;
bNeedReboot = true;
fDoPatchTest = true;
}


changed to


else if ((DWVideo == XKEEPROM::VIDEO_STANDARD::PAL_I) && ((XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_M) || (XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_J) || initialResolution < 6))
{
// See if we can go to 480p - RH
BYTE currentCableMode = 0;
HalReadSMBusValue(XKUtils::SMBDEV_PIC16L, XKUtils::PIC16L_CMD_AV_PACK, 0, (LPBYTE)&currentCableMode);

if(currentCableMode == XKUtils::AV_PACK_HDTV)
{
// Do nothing
bNeedReboot = false;
fDoPatchTest = false;

}
else
{
CLog::Log(LOGINFO, "Rebooting to change resolution from %s back to PAL_I", (XGetVideoStandard() == XC_VIDEO_STANDARD_NTSC_M) ? "NTSC_M" : "NTSC_J");
ForceVideo = VIDEO_PAL50;
ForceCountry = COUNTRY_EUR;
bNeedReboot = true;
fDoPatchTest = true;
}
}
find quote
Post Reply