It's actually a fairly easy feature to implement. This is the field function to change resolution:
static void SetResolution()
{
// remove flickering
ClearFBuffer(0,0,FRAME2_W*2,FRAME2_H);
DrawSync(0);
// set resolution to 320x240
GsInitGraph2(FRAME_X,SCREEN_H,GsOFSGPU|GsNONINTER, 1, 0);
GsDefDispBuff(0,SCREEN_Y,FRAME_X,SCREEN_Y);
// lower resolution to 320x208
GsDISPENV.screen.y=user_data.screeny;
GsDISPENV.screen.h=SCREEN_H;
GsDISPENV.disp.y=0;
GsDISPENV.disp.h=FRAME_Y;
}SCREEN_Y is 16 and SCREEN_H is 208. All I need to do is replacing those two macros with variables that change depending on some bit flag. Resulting routine:
static void SetResolution()
{
int h, dh, y;
extern DRAWENV GsDRAWENV;
if(user_data.flags&FLAG_PANSCREEN)
{
// 16:9 mode, no black bands
h=SCREEN_H;
dh=SCREEN_H;
y=0;
}
else
{
// 4:3, retain black bands
h=SCREEN_H;
dh=FRAME_Y;
y=SCREEN_Y;
}
// remove flickering
ClearFBuffer(0,0,FRAME2_W*2,FRAME2_H);
DrawSync(0);
// set resolution to 320x208
GsInitGraph2(FRAME_X,h,GsOFSGPU|GsNONINTER, 1, 0);
GsDefDispBuff(0,y,FRAME_X,y);
// lower resolution to 320x208
GsDISPENV.screen.y=user_data.screeny;
GsDISPENV.screen.h=h;
GsDISPENV.disp.y=0;
GsDISPENV.disp.h=dh;
}
By the way, this change affects only the in-game mode. No menus or other screens are adapted to the 16:9-ish resolution, but considering most are just text and boring stuff you probably won't mind.