Option "desired_screen_aspect_ratio" for fullscreen mode in the SDL backend

Shortcoming: the picture is not centered

svn-id: r43214
This commit is contained in:
Bertrand Augereau 2009-08-10 18:03:54 +00:00
parent 19d5aa25dc
commit 10b74c336b
4 changed files with 94 additions and 5 deletions

View file

@ -358,6 +358,50 @@ void OSystem_SDL::initSize(uint w, uint h) {
_dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32)); _dirtyChecksums = (uint32 *)calloc(_cksumNum * 2, sizeof(uint32));
} }
static void fixupResolutionForAspectRatio(AspectRatio desiredAspectRatio, int &width, int &height) {
assert(&width != &height);
if (desiredAspectRatio.isAuto())
return;
int kw = desiredAspectRatio.kw();
int kh = desiredAspectRatio.kh();
const int w = width;
const int h = height;
SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_SWSURFACE); //TODO : Maybe specify a pixel format
assert(availableModes);
const SDL_Rect *bestMode = NULL;
uint bestMetric = (uint)-1; // Metric is wasted space
while (const SDL_Rect *mode = *availableModes++) {
if (mode->w < w)
continue;
if (mode->h < h)
continue;
if (mode->h * kw != mode->w * kh)
continue;
//printf("%d %d\n", mode->w, mode->h);
uint metric = mode->w * mode->h - w * h;
if (metric > bestMetric)
continue;
bestMetric = metric;
bestMode = mode;
}
if (!bestMode) {
warning("Unable to enforce the desired aspect ratio!");
return;
}
//printf("%d %d\n", bestMode->w, bestMode->h);
width = bestMode->w;
height = bestMode->h;
}
bool OSystem_SDL::loadGFXMode() { bool OSystem_SDL::loadGFXMode() {
assert(_inited); assert(_inited);
_forceFull = true; _forceFull = true;
@ -374,11 +418,11 @@ bool OSystem_SDL::loadGFXMode() {
if (_videoMode.aspectRatioCorrection) if (_videoMode.aspectRatioCorrection)
_videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight); _videoMode.overlayHeight = real2Aspect(_videoMode.overlayHeight);
hwW = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.hardwareWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
hwH = effectiveScreenHeight(); _videoMode.hardwareHeight = effectiveScreenHeight();
#else #else
hwW = _videoMode.overlayWidth; _videoMode.hardwareWidth = _videoMode.overlayWidth;
hwH = _videoMode.overlayHeight; _videoMode.hardwareHeight = _videoMode.overlayHeight;
#endif #endif
// //
@ -392,7 +436,11 @@ bool OSystem_SDL::loadGFXMode() {
// Create the surface that contains the scaled graphics in 16 bit mode // Create the surface that contains the scaled graphics in 16 bit mode
// //
_hwscreen = SDL_SetVideoMode(hwW, hwH, 16, if(_videoMode.fullscreen) {
fixupResolutionForAspectRatio(_videoMode.desiredAspectRatio, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
}
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16,
_videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE _videoMode.fullscreen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
); );
if (_hwscreen == NULL) { if (_hwscreen == NULL) {

View file

@ -85,6 +85,31 @@ static Uint32 timer_handler(Uint32 interval, void *param) {
return interval; return interval;
} }
AspectRatio::AspectRatio(int w, int h) {
// TODO : Validation and so on...
// Currently, we just ensure the program don't instantiate non-supported aspect ratios
_kw = w;
_kh = h;
}
static const size_t AR_COUNT = 4;
static const char* desiredAspectRatioAsStrings[AR_COUNT] = { "auto", "4/3", "16/9", "16/10" };
static const AspectRatio desiredAspectRatios[AR_COUNT] = { AspectRatio(0, 0), AspectRatio(4,3), AspectRatio(16,9), AspectRatio(16,10) };
static AspectRatio getDesiredAspectRatio() {
//TODO : We could parse an arbitrary string, if we code enough proper validation
Common::String desiredAspectRatio = ConfMan.get("desired_screen_aspect_ratio");
for (size_t i = 0; i < AR_COUNT; i++) {
assert(desiredAspectRatioAsStrings[i] != NULL);
if (!scumm_stricmp(desiredAspectRatio.c_str(), desiredAspectRatioAsStrings[i])) {
return desiredAspectRatios[i];
}
}
// TODO : Report a warning
return AspectRatio(0, 0);
}
void OSystem_SDL::initBackend() { void OSystem_SDL::initBackend() {
assert(!_inited); assert(!_inited);
@ -124,6 +149,7 @@ void OSystem_SDL::initBackend() {
_videoMode.mode = GFX_DOUBLESIZE; _videoMode.mode = GFX_DOUBLESIZE;
_videoMode.scaleFactor = 2; _videoMode.scaleFactor = 2;
_videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio"); _videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio");
_videoMode.desiredAspectRatio = getDesiredAspectRatio();
_scalerProc = Normal2x; _scalerProc = Normal2x;
#else // for small screen platforms #else // for small screen platforms
_videoMode.mode = GFX_NORMAL; _videoMode.mode = GFX_NORMAL;

View file

@ -70,6 +70,18 @@ enum {
GFX_DOTMATRIX = 11 GFX_DOTMATRIX = 11
}; };
class AspectRatio {
int _kw, _kh;
public:
AspectRatio() { _kw = _kh = 0; }
AspectRatio(int w, int h);
bool isAuto() const { return (_kw | _kh) == 0; }
int kw() const { return _kw; }
int kh() const { return _kh; }
};
class OSystem_SDL : public BaseBackend { class OSystem_SDL : public BaseBackend {
public: public:
@ -268,12 +280,14 @@ protected:
bool fullscreen; bool fullscreen;
bool aspectRatioCorrection; bool aspectRatioCorrection;
AspectRatio desiredAspectRatio;
int mode; int mode;
int scaleFactor; int scaleFactor;
int screenWidth, screenHeight; int screenWidth, screenHeight;
int overlayWidth, overlayHeight; int overlayWidth, overlayHeight;
int hardwareWidth, hardwareHeight;
}; };
VideoState _videoMode, _oldVideoMode; VideoState _videoMode, _oldVideoMode;

View file

@ -157,6 +157,7 @@ void registerDefaults() {
ConfMan.registerDefault("aspect_ratio", false); ConfMan.registerDefault("aspect_ratio", false);
ConfMan.registerDefault("gfx_mode", "normal"); ConfMan.registerDefault("gfx_mode", "normal");
ConfMan.registerDefault("render_mode", "default"); ConfMan.registerDefault("render_mode", "default");
ConfMan.registerDefault("desired_screen_aspect_ratio", "auto");
// Sound & Music // Sound & Music
ConfMan.registerDefault("music_volume", 192); ConfMan.registerDefault("music_volume", 192);