Beginning of support for multiple resolutions.

Makes Zak256 inventory scrolling work.

svn-id: r4227
This commit is contained in:
James Brown 2002-05-07 18:44:34 +00:00
parent e2df4d2b3b
commit 705f304004
5 changed files with 69 additions and 43 deletions

16
gfx.cpp
View file

@ -28,22 +28,22 @@ void Scumm::getGraphicsPerformance()
int i; int i;
for (i = 10; i != 0; i--) { for (i = 10; i != 0; i--) {
initScreens(0, 0, 320, 200); initScreens(0, 0, _realWidth, _realHeight); //ender
} }
_vars[VAR_PERFORMANCE_1] = 0; //_scummTimer; _vars[VAR_PERFORMANCE_1] = 0; //_scummTimer;
for (i = 10; i != 0; i--) { for (i = 10; i != 0; i--) {
setDirtyRange(0, 0, 200); setDirtyRange(0, 0, _realHeight); //ender
drawDirtyScreenParts(); drawDirtyScreenParts();
} }
_vars[VAR_PERFORMANCE_2] = 0; //_scummTimer; _vars[VAR_PERFORMANCE_2] = 0; //_scummTimer;
if (_gameId == GID_DIG) if (_gameId == GID_DIG)
initScreens(0, 0, 320, 200); initScreens(0, 0, _realWidth, _realHeight);
else else
initScreens(0, 16, 320, 144); initScreens(0, 16, _realWidth, 144);
} }
void Scumm::initScreens(int a, int b, int w, int h) void Scumm::initScreens(int a, int b, int w, int h)
@ -56,11 +56,11 @@ void Scumm::initScreens(int a, int b, int w, int h)
} }
if (!getResourceAddress(rtBuffer, 4)) { if (!getResourceAddress(rtBuffer, 4)) {
initVirtScreen(3, 0, 80, 320, 13, false, false); initVirtScreen(3, 0, 80, _realWidth, 13, false, false);
} }
initVirtScreen(0, 0, b, 320, h - b, true, true); initVirtScreen(0, 0, b, _realWidth, h - b, true, true);
initVirtScreen(1, 0, 0, 320, b, false, false); initVirtScreen(1, 0, 0, _realWidth, b, false, false);
initVirtScreen(2, 0, h, 320, 200 - h, false, false); initVirtScreen(2, 0, h, _realWidth, _realHeight - h, false, false); //ender
_screenB = b; _screenB = b;
_screenH = h; _screenH = h;

View file

@ -931,7 +931,8 @@ public:
/* Should be in Verb class */ /* Should be in Verb class */
uint16 _verbMouseOver; uint16 _verbMouseOver;
int _inventoryOffset;
void redrawVerbs(); void redrawVerbs();
void checkExecVerbs(); void checkExecVerbs();
void verbMouseOver(int verb); void verbMouseOver(int verb);
@ -1129,7 +1130,7 @@ public:
/* Should be in Graphics class? */ /* Should be in Graphics class? */
uint16 _screenB, _screenH; uint16 _screenB, _screenH;
int _scrHeight, _scrWidth; int _scrHeight, _scrWidth, _realHeight, _realWidth;
VirtScreen virtscr[4]; // Virtual screen areas VirtScreen virtscr[4]; // Virtual screen areas
CameraData camera; // 'Camera' - viewport CameraData camera; // 'Camera' - viewport
ColorCycle _colorCycle[16]; // Palette cycles ColorCycle _colorCycle[16]; // Palette cycles

View file

@ -876,7 +876,7 @@ void Scumm::processKbd()
} else if (_lastKeyHit == 93) { // ], eg volume down } else if (_lastKeyHit == 93) { // ], eg volume down
_sound_volume_master+=5; _sound_volume_master+=5;
if (_sound_volume_master > 128) if (_sound_volume_master > 128)
_sound_volume_master = 128; _sound_volume_master = 128;
_imuse->set_master_volume(_sound_volume_master); _imuse->set_master_volume(_sound_volume_master);
} else if (_lastKeyHit == 45) { // -, eg text speed down } else if (_lastKeyHit == 45) { // -, eg text speed down
_defaultTalkDelay+=5; _defaultTalkDelay+=5;
@ -905,12 +905,12 @@ int Scumm::getKeyInput(int a)
if (mouse.x < 0) if (mouse.x < 0)
mouse.x = 0; mouse.x = 0;
if (mouse.x > 319) if (mouse.x > _realWidth-1)
mouse.x = 319; mouse.x = _realWidth-1;
if (mouse.y < 0) if (mouse.y < 0)
mouse.y = 0; mouse.y = 0;
if (mouse.y > 199) if (mouse.y > _realHeight-1)
mouse.y = 199; mouse.y = _realHeight-1;
if (_leftBtnPressed & msClicked && _rightBtnPressed & msClicked) { if (_leftBtnPressed & msClicked && _rightBtnPressed & msClicked) {
_mouseButStat = 0; _mouseButStat = 0;
@ -1372,8 +1372,17 @@ Scumm *Scumm::createFromDetector(GameDetector *detector, OSystem *syst)
scumm->_system = syst; scumm->_system = syst;
if (detector->_gameId == GID_ZAK256) { // FmTowns is 320x240
scumm->_realWidth = 320;
scumm->_realHeight = 240;
} else {
scumm->_realWidth = 320;
scumm->_realHeight = 200;
}
/* This initializes SDL */ /* This initializes SDL */
syst->init_size(320,200); syst->init_size(scumm->_realWidth, scumm->_realHeight);
prop.cd_num = detector->_cdrom; prop.cd_num = detector->_cdrom;
syst->property(OSystem::PROP_OPEN_CD, &prop); syst->property(OSystem::PROP_OPEN_CD, &prop);

58
sdl.cpp
View file

@ -127,15 +127,16 @@ private:
enum { enum {
NUM_DIRTY_RECT = 100, NUM_DIRTY_RECT = 100,
SCREEN_WIDTH = 320, //SCREEN_WIDTH = 320,
SCREEN_HEIGHT = 200, //SCREEN_HEIGHT = 240,
CKSUM_NUM = (SCREEN_WIDTH*SCREEN_HEIGHT/(8*8)), //CKSUM_NUM = (SCREEN_WIDTH*SCREEN_HEIGHT/(8*8)),
MAX_MOUSE_W = 40, MAX_MOUSE_W = 40,
MAX_MOUSE_H = 40, MAX_MOUSE_H = 40,
MAX_SCALING = 3, MAX_SCALING = 3,
}; };
int SCREEN_WIDTH, SCREEN_HEIGHT, CKSUM_NUM;
SDL_Rect *dirty_rect_list; SDL_Rect *dirty_rect_list;
int num_dirty_rects; int num_dirty_rects;
uint32 *dirty_checksums; uint32 *dirty_checksums;
@ -302,15 +303,15 @@ normal_mode:;
break; break;
} }
sdl_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 8, 0, 0, 0, 0); sdl_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 8, 0, 0, 0, 0);
if (sdl_screen == NULL) if (sdl_screen == NULL)
error("sdl_screen failed failed"); error("sdl_screen failed failed");
if (_sai_func) { if (_sai_func) {
uint16 *tmp_screen = (uint16*)calloc((320+3)*(200+3),sizeof(uint16)); uint16 *tmp_screen = (uint16*)calloc((SCREEN_WIDTH+3)*(SCREEN_HEIGHT+3),sizeof(uint16));
_mode_flags = DF_FORCE_FULL_ON_PALETTE | DF_WANT_RECT_OPTIM | DF_2xSAI | DF_SEPARATE_TEMPSCREEN | DF_UPDATE_EXPAND_1_PIXEL; _mode_flags = DF_FORCE_FULL_ON_PALETTE | DF_WANT_RECT_OPTIM | DF_2xSAI | DF_SEPARATE_TEMPSCREEN | DF_UPDATE_EXPAND_1_PIXEL;
sdl_hwscreen = SDL_SetVideoMode(320 * scaling, 200 * scaling, 16, sdl_hwscreen = SDL_SetVideoMode(SCREEN_WIDTH * scaling, SCREEN_HEIGHT * scaling, 16,
_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
); );
if (sdl_hwscreen == NULL) if (sdl_hwscreen == NULL)
@ -322,7 +323,7 @@ normal_mode:;
else else
Init_2xSaI(565); Init_2xSaI(565);
sdl_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen, sdl_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen,
320 + 3, 200 + 3, 16, (320 + 3)*2, SCREEN_WIDTH + 3, SCREEN_HEIGHT + 3, 16, (SCREEN_WIDTH + 3)*2,
sdl_hwscreen->format->Rmask, sdl_hwscreen->format->Rmask,
sdl_hwscreen->format->Gmask, sdl_hwscreen->format->Gmask,
sdl_hwscreen->format->Bmask, sdl_hwscreen->format->Bmask,
@ -347,7 +348,7 @@ normal_mode:;
_mode_flags = DF_WANT_RECT_OPTIM; _mode_flags = DF_WANT_RECT_OPTIM;
sdl_hwscreen = SDL_SetVideoMode(320 * scaling, 200 * scaling, 8, sdl_hwscreen = SDL_SetVideoMode(SCREEN_WIDTH * scaling, SCREEN_HEIGHT * scaling, 8,
_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE _full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
); );
if (sdl_hwscreen == NULL) if (sdl_hwscreen == NULL)
@ -373,9 +374,12 @@ void OSystem_SDL::unload_gfx_mode() {
} }
void OSystem_SDL::init_size(uint w, uint h) { void OSystem_SDL::init_size(uint w, uint h) {
if (w != SCREEN_WIDTH && h != SCREEN_HEIGHT) //if (w != SCREEN_WIDTH && h != SCREEN_HEIGHT)
error("320x200 is the only game resolution supported"); // error("320x200 is the only game resolution supported");
SCREEN_WIDTH = w;
SCREEN_HEIGHT = h;
CKSUM_NUM = (SCREEN_WIDTH*SCREEN_HEIGHT/(8*8));
/* allocate palette, it needs to be persistent across /* allocate palette, it needs to be persistent across
* driver changes, so i'll alloc it here */ * driver changes, so i'll alloc it here */
_cur_pal = (SDL_Color*)calloc(sizeof(SDL_Color), 256); _cur_pal = (SDL_Color*)calloc(sizeof(SDL_Color), 256);
@ -417,10 +421,10 @@ void OSystem_SDL::copy_rect(const byte *buf, int pitch, int x, int y, int w, int
if (SDL_LockSurface(sdl_screen) == -1) if (SDL_LockSurface(sdl_screen) == -1)
error("SDL_LockSurface failed: %s.\n", SDL_GetError()); error("SDL_LockSurface failed: %s.\n", SDL_GetError());
byte *dst = (byte *)sdl_screen->pixels + y * 320 + x; byte *dst = (byte *)sdl_screen->pixels + y * SCREEN_WIDTH + x;
do { do {
memcpy(dst, buf, w); memcpy(dst, buf, w);
dst += 320; dst += SCREEN_WIDTH;
buf += pitch; buf += pitch;
} while (--h); } while (--h);
@ -463,14 +467,14 @@ void OSystem_SDL::add_dirty_rect(int x, int y, int w, int h) {
#define DOLINE(x) a ^= ((uint32*)buf)[0+(x)*(SCREEN_WIDTH/4)]; b ^= ((uint32*)buf)[1+(x)*(SCREEN_WIDTH/4)] #define DOLINE(x) a ^= ((uint32*)buf)[0+(x)*(SCREEN_WIDTH/4)]; b ^= ((uint32*)buf)[1+(x)*(SCREEN_WIDTH/4)]
void OSystem_SDL::mk_checksums(const byte *buf) { void OSystem_SDL::mk_checksums(const byte *buf) {
uint32 *sums = dirty_checksums; uint32 *sums = dirty_checksums;
uint x,y; int x,y;
/* the 8x8 blocks in buf are enumerated starting in the top left corner and /* the 8x8 blocks in buf are enumerated starting in the top left corner and
* reading each line at a time from left to right */ * reading each line at a time from left to right */
for(y=0; y!=SCREEN_HEIGHT/8; y++,buf+=SCREEN_WIDTH*(8-1)) for(y=0; y!=SCREEN_HEIGHT/8; y++,buf+=SCREEN_WIDTH*(8-1))
for(x=0; x!=SCREEN_WIDTH/8; x++,buf+=8) { for(x=0; x!=SCREEN_WIDTH/8; x++,buf+=8) {
uint32 a = x; int32 a = x;
uint32 b = y; int32 b = y;
DOLINE(0); ROL(a,13); ROL(b,11); DOLINE(0); ROL(a,13); ROL(b,11);
DOLINE(2); ROL(a,13); ROL(b,11); DOLINE(2); ROL(a,13); ROL(b,11);
@ -508,7 +512,7 @@ void OSystem_SDL::add_dirty_rgn_auto(const byte *buf) {
and add all dirty rectangles to a list. try to combine small rectangles and add all dirty rectangles to a list. try to combine small rectangles
into bigger ones in a simple way */ into bigger ones in a simple way */
if (!force_full) { if (!force_full) {
uint x,y,w; int x,y,w;
uint32 *ck = dirty_checksums; uint32 *ck = dirty_checksums;
for(y=0; y!=SCREEN_HEIGHT/8; y++) { for(y=0; y!=SCREEN_HEIGHT/8; y++) {
@ -827,7 +831,7 @@ void OSystem_SDL::get_320x200_image(byte *buf) {
if (SDL_LockSurface(sdl_screen) == -1) if (SDL_LockSurface(sdl_screen) == -1)
error("SDL_LockSurface failed: %s.\n", SDL_GetError()); error("SDL_LockSurface failed: %s.\n", SDL_GetError());
memcpy(buf, sdl_screen->pixels, 320*200); memcpy(buf, sdl_screen->pixels, SCREEN_WIDTH*SCREEN_HEIGHT);
SDL_UnlockSurface(sdl_screen); SDL_UnlockSurface(sdl_screen);
} }
@ -838,7 +842,7 @@ void OSystem_SDL::hotswap_gfx_mode() {
* then draw that to the new screen right after it's setup. * then draw that to the new screen right after it's setup.
*/ */
byte *bak_mem = (byte*)malloc(320*200); byte *bak_mem = (byte*)malloc(SCREEN_WIDTH*SCREEN_HEIGHT);
get_320x200_image(bak_mem); get_320x200_image(bak_mem);
@ -851,7 +855,7 @@ void OSystem_SDL::hotswap_gfx_mode() {
SDL_SetColors(sdl_palscreen, _cur_pal, 0, 256); SDL_SetColors(sdl_palscreen, _cur_pal, 0, 256);
/* blit image */ /* blit image */
OSystem_SDL::copy_rect(bak_mem, 320, 0, 0, 320, 200); OSystem_SDL::copy_rect(bak_mem, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
free(bak_mem); free(bak_mem);
OSystem_SDL::update_screen(); OSystem_SDL::update_screen();
@ -937,12 +941,12 @@ void OSystem_SDL::draw_mouse() {
_ms_old.x = xdraw; _ms_old.x = xdraw;
_ms_old.y = ydraw; _ms_old.y = ydraw;
dst = (byte *)sdl_screen->pixels + ydraw * 320 + xdraw; dst = (byte *)sdl_screen->pixels + ydraw * SCREEN_WIDTH + xdraw;
for (y = 0; y < h; y++, dst += 320, bak += MAX_MOUSE_W, buf += w) { for (y = 0; y < h; y++, dst += SCREEN_WIDTH, bak += MAX_MOUSE_W, buf += w) {
if ((uint) (ydraw + y) < 200) { if ((ydraw + y) < SCREEN_HEIGHT) {
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
if ((uint) (xdraw + x) < 320) { if ((xdraw + x) < SCREEN_WIDTH) {
bak[x] = dst[x]; bak[x] = dst[x];
if ((color = buf[x]) != 0xFF) { if ((color = buf[x]) != 0xFF) {
dst[x] = color; dst[x] = color;
@ -972,12 +976,12 @@ void OSystem_SDL::undraw_mouse() {
const int old_mouse_h = _ms_old.h; const int old_mouse_h = _ms_old.h;
int x,y; int x,y;
dst = (byte *)sdl_screen->pixels + old_mouse_y * 320 + old_mouse_x; dst = (byte *)sdl_screen->pixels + old_mouse_y * SCREEN_WIDTH + old_mouse_x;
for (y = 0; y < old_mouse_h; y++, bak += MAX_MOUSE_W, dst += 320) { for (y = 0; y < old_mouse_h; y++, bak += MAX_MOUSE_W, dst += SCREEN_WIDTH) {
if ((uint) (old_mouse_y + y) < 200) { if ((old_mouse_y + y) < SCREEN_HEIGHT) {
for (x = 0; x < old_mouse_w; x++) { for (x = 0; x < old_mouse_w; x++) {
if ((uint) (old_mouse_x + x) < 320) { if ((old_mouse_x + x) < SCREEN_WIDTH) {
dst[x] = bak[x]; dst[x] = bak[x];
} }
} }

View file

@ -63,6 +63,12 @@ void Scumm::checkExecVerbs()
runInputScript(2, 0, code); runInputScript(2, 0, code);
} else { } else {
over = checkMouseOver(mouse.x, mouse.y); over = checkMouseOver(mouse.x, mouse.y);
// FIXME For the future: Indy3 and under inv scrolling
/*
if (over >= 31 && over <= 36)
over += _inventoryOffset;
*/
runInputScript(1, over != 0 ? _verbs[over].verbid : 0, code); runInputScript(1, over != 0 ? _verbs[over].verbid : 0, code);
} }
} }
@ -138,6 +144,12 @@ void Scumm::drawVerb(int vrb, int mode)
if (vs->curmode == 2) if (vs->curmode == 2)
string[4].color = vs->dimcolor; string[4].color = vs->dimcolor;
// FIXME For the future: Indy3 and under inv scrolling
/*
if (vrb >= 31 && vrb <= 36)
vrb += _inventoryOffset;
*/
_messagePtr = getResourceAddress(rtVerb, vrb); _messagePtr = getResourceAddress(rtVerb, vrb);
assert(_messagePtr); assert(_messagePtr);