Skip to content

Commit

Permalink
ZVISION: Change screen resolution for the hires DVD videos to 800x600
Browse files Browse the repository at this point in the history
Also, this hooks up the MPEG-PS decoder, but only if libmpeg2 is
compiled in. The DVD videos are still disabled until AC3 audio support
is implemented.
The hires DVD videos are encoded a 720x480 resolution, with double the
frame rate of the lowres ones (29.97FPS up from 15FPS)
  • Loading branch information
bluegr committed Jan 10, 2015
1 parent 616b34e commit 899cf48
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 70 deletions.
57 changes: 35 additions & 22 deletions engines/zvision/graphics/render_manager.cpp
Expand Up @@ -42,28 +42,25 @@ namespace ZVision {
RenderManager::RenderManager(ZVision *engine, uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow, const Graphics::PixelFormat pixelFormat, bool doubleFPS)
: _engine(engine),
_system(engine->_system),
_workingWidth(workingWindow.width()),
_workingHeight(workingWindow.height()),
_screenCenterX(_workingWidth / 2),
_screenCenterY(_workingHeight / 2),
_screenCenterX(_workingWindow.width() / 2),
_screenCenterY(_workingWindow.height() / 2),
_workingWindow(workingWindow),
_pixelFormat(pixelFormat),
_backgroundWidth(0),
_backgroundHeight(0),
_backgroundOffset(0),
_renderTable(_workingWidth, _workingHeight),
_doubleFPS(doubleFPS) {
_renderTable(_workingWindow.width(), _workingWindow.height()),
_doubleFPS(doubleFPS),
_subid(0) {

_backgroundSurface.create(_workingWidth, _workingHeight, _pixelFormat);
_effectSurface.create(_workingWidth, _workingHeight, _pixelFormat);
_warpedSceneSurface.create(_workingWidth, _workingHeight, _pixelFormat);
_backgroundSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
_effectSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
_warpedSceneSurface.create(_workingWindow.width(), _workingWindow.height(), _pixelFormat);
_menuSurface.create(windowWidth, workingWindow.top, _pixelFormat);
_subtitleSurface.create(windowWidth, windowHeight - workingWindow.bottom, _pixelFormat);


_menuArea = Common::Rect(0, 0, windowWidth, workingWindow.top);
_subtitleArea = Common::Rect(0, workingWindow.bottom, windowWidth, windowHeight);

_subid = 0;
initSubArea(windowWidth, windowHeight, workingWindow);
}

RenderManager::~RenderManager() {
Expand All @@ -83,7 +80,7 @@ void RenderManager::renderSceneToScreen() {
// If we have graphical effects, we apply them using a temporary buffer
if (!_effects.empty()) {
bool copied = false;
Common::Rect windowRect(_workingWidth, _workingHeight);
Common::Rect windowRect(_workingWindow.width(), _workingWindow.height());

for (EffectsList::iterator it = _effects.begin(); it != _effects.end(); it++) {
Common::Rect rect = (*it)->getRegion();
Expand Down Expand Up @@ -121,7 +118,7 @@ void RenderManager::renderSceneToScreen() {
if (!_backgroundSurfaceDirtyRect.isEmpty()) {
_renderTable.mutateImage(&_warpedSceneSurface, in);
out = &_warpedSceneSurface;
outWndDirtyRect = Common::Rect(_workingWidth, _workingHeight);
outWndDirtyRect = Common::Rect(_workingWindow.width(), _workingWindow.height());
}
} else {
out = in;
Expand Down Expand Up @@ -590,7 +587,7 @@ void RenderManager::prepareBackground() {

if (state == RenderTable::PANORAMA) {
// Calculate the visible portion of the background
Common::Rect viewPort(_workingWidth, _workingHeight);
Common::Rect viewPort(_workingWindow.width(), _workingWindow.height());
viewPort.translate(-(_screenCenterX - _backgroundOffset), 0);
Common::Rect drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
Expand Down Expand Up @@ -635,7 +632,7 @@ void RenderManager::prepareBackground() {
}
} else if (state == RenderTable::TILT) {
// Tilt doesn't allow wrapping, so we just do a simple clip
Common::Rect viewPort(_workingWidth, _workingHeight);
Common::Rect viewPort(_workingWindow.width(), _workingWindow.height());
viewPort.translate(0, -(_screenCenterY - _backgroundOffset));
Common::Rect drawRect = _backgroundDirtyRect;
drawRect.clip(viewPort);
Expand All @@ -655,7 +652,7 @@ void RenderManager::prepareBackground() {
// Clear the dirty rect since everything is clean now
_backgroundDirtyRect = Common::Rect();

_backgroundSurfaceDirtyRect.clip(_workingWidth, _workingHeight);
_backgroundSurfaceDirtyRect.clip(_workingWindow.width(), _workingWindow.height());
}

void RenderManager::clearMenuSurface() {
Expand Down Expand Up @@ -687,6 +684,15 @@ void RenderManager::renderMenuToScreen() {
}
}

void RenderManager::initSubArea(uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow) {
_workingWindow = workingWindow;

_subtitleSurface.free();

_subtitleSurface.create(windowWidth, windowHeight - workingWindow.bottom, _pixelFormat);
_subtitleArea = Common::Rect(0, workingWindow.bottom, windowWidth, windowHeight);
}

uint16 RenderManager::createSubArea(const Common::Rect &area) {
_subid++;

Expand Down Expand Up @@ -791,8 +797,8 @@ Common::Rect RenderManager::transformBackgroundSpaceRectToScreenSpace(const Comm

if (state == RenderTable::PANORAMA) {
if (_backgroundOffset < _screenCenterX) {
Common::Rect rScreen(_screenCenterX + _backgroundOffset, _workingHeight);
Common::Rect lScreen(_workingWidth - rScreen.width(), _workingHeight);
Common::Rect rScreen(_screenCenterX + _backgroundOffset, _workingWindow.height());
Common::Rect lScreen(_workingWindow.width() - rScreen.width(), _workingWindow.height());
lScreen.translate(_backgroundWidth - lScreen.width(), 0);
lScreen.clip(src);
rScreen.clip(src);
Expand All @@ -802,8 +808,8 @@ Common::Rect RenderManager::transformBackgroundSpaceRectToScreenSpace(const Comm
tmp.translate(_screenCenterX - _backgroundOffset, 0);
}
} else if (_backgroundWidth - _backgroundOffset < _screenCenterX) {
Common::Rect rScreen(_screenCenterX - (_backgroundWidth - _backgroundOffset), _workingHeight);
Common::Rect lScreen(_workingWidth - rScreen.width(), _workingHeight);
Common::Rect rScreen(_screenCenterX - (_backgroundWidth - _backgroundOffset), _workingWindow.height());
Common::Rect lScreen(_workingWindow.width() - rScreen.width(), _workingWindow.height());
lScreen.translate(_backgroundWidth - lScreen.width(), 0);
lScreen.clip(src);
rScreen.clip(src);
Expand Down Expand Up @@ -1172,4 +1178,11 @@ void RenderManager::rotateTo(int16 _toPos, int16 _time) {
_engine->startClock();
}

void RenderManager::upscaleRect(Common::Rect &rect) {
rect.top = rect.top * HIRES_WINDOW_HEIGHT / WINDOW_HEIGHT;
rect.left = rect.left * HIRES_WINDOW_WIDTH / WINDOW_WIDTH;
rect.bottom = rect.bottom * HIRES_WINDOW_HEIGHT / WINDOW_HEIGHT;
rect.right = rect.right * HIRES_WINDOW_WIDTH / WINDOW_WIDTH;
}

} // End of namespace ZVision
10 changes: 5 additions & 5 deletions engines/zvision/graphics/render_manager.h
Expand Up @@ -73,12 +73,8 @@ class RenderManager {
* are given in this coordinate space. Also, all images are clipped to the
* edges of this Rectangle
*/
const Common::Rect _workingWindow;
Common::Rect _workingWindow;

// Width of the working window. Saved to prevent extraneous calls to _workingWindow.width()
const int _workingWidth;
// Height of the working window. Saved to prevent extraneous calls to _workingWindow.height()
const int _workingHeight;
// Center of the screen in the x direction
const int _screenCenterX;
// Center of the screen in the y direction
Expand Down Expand Up @@ -241,6 +237,8 @@ class RenderManager {

// Subtitles methods

void initSubArea(uint32 windowWidth, uint32 windowHeight, const Common::Rect workingWindow);

// Create subtitle area and return ID
uint16 createSubArea(const Common::Rect &area);
uint16 createSubArea();
Expand Down Expand Up @@ -334,6 +332,8 @@ class RenderManager {
void checkBorders();
void rotateTo(int16 to, int16 time);
void updateRotation();

void upscaleRect(Common::Rect &rect);
};

} // End of namespace ZVision
Expand Down
50 changes: 33 additions & 17 deletions engines/zvision/scripting/actions.cpp
Expand Up @@ -912,44 +912,60 @@ ActionStreamVideo::ActionStreamVideo(ZVision *engine, int32 slotkey, const Commo
bool ActionStreamVideo::execute() {
Video::VideoDecoder *decoder;
Common::Rect destRect = Common::Rect(_x1, _y1, _x2 + 1, _y2 + 1);
Common::String subname = _fileName;
subname.setChar('s', subname.size() - 3);
subname.setChar('u', subname.size() - 2);
subname.setChar('b', subname.size() - 1);
bool subtitleExists = _engine->getSearchManager()->hasFile(subname);
bool switchToHires = false;

// NOTE: We only show the hires MPEG2 videos when libmpeg2 is compiled in,
// otherwise we fall back to the lowres ones
#ifdef USE_MPEG2
Common::String hiresFileName = _fileName;
hiresFileName.setChar('d', hiresFileName.size() - 8);
hiresFileName.setChar('v', hiresFileName.size() - 3);
hiresFileName.setChar('o', hiresFileName.size() - 2);
hiresFileName.setChar('b', hiresFileName.size() - 1);

if (_engine->getScriptManager()->getStateValue(StateKey_MPEGMovies) == 1 &&_engine->getSearchManager()->hasFile(hiresFileName))
// TODO: Enable once VOB + AC3 support is implemented
//_fileName = hiresFileName;
if (_engine->getScriptManager()->getStateValue(StateKey_MPEGMovies) == 1 &&_engine->getSearchManager()->hasFile(hiresFileName)) {
// TODO: Enable once AC3 support is implemented
if (!_engine->getSearchManager()->hasFile(_fileName)) // Check for the regular video
return true;
warning("The hires videos of the DVD version of ZGI aren't supported yet, using lowres");
#endif

Common::String subname = _fileName;
subname.setChar('s', subname.size() - 3);
subname.setChar('u', subname.size() - 2);
subname.setChar('b', subname.size() - 1);

//_fileName = hiresFileName;
//switchToHires = true;
} else if (!_engine->getSearchManager()->hasFile(_fileName))
return true;
#else
if (!_engine->getSearchManager()->hasFile(_fileName))
return true;
#endif

decoder = _engine->loadAnimation(_fileName);
Subtitle *sub = (subtitleExists) ? new Subtitle(_engine, subname, switchToHires) : NULL;

_engine->getCursorManager()->showMouse(false);

Subtitle *sub = NULL;

if (_engine->getSearchManager()->hasFile(subname))
sub = new Subtitle(_engine, subname);
if (switchToHires) {
_engine->initHiresScreen();
destRect = Common::Rect(40, -40, 760, 440);
Common::Rect workingWindow = _engine->_workingWindow;
workingWindow.translate(0, -40);
_engine->getRenderManager()->initSubArea(HIRES_WINDOW_WIDTH, HIRES_WINDOW_HEIGHT, workingWindow);
}

_engine->playVideo(*decoder, destRect, _skippable, sub);
delete decoder;

if (switchToHires) {
_engine->initScreen();
_engine->getRenderManager()->initSubArea(WINDOW_WIDTH, WINDOW_HEIGHT, _engine->_workingWindow);
}

_engine->getCursorManager()->showMouse(true);

if (sub)
delete sub;
delete decoder;
delete sub;

return true;
}
Expand Down
9 changes: 8 additions & 1 deletion engines/zvision/text/subtitles.cpp
Expand Up @@ -27,7 +27,7 @@

namespace ZVision {

Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
Subtitle::Subtitle(ZVision *engine, const Common::String &subname, bool upscaleToHires) :
_engine(engine),
_areaId(-1),
_subId(-1) {
Expand All @@ -44,6 +44,8 @@ Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
int32 x1, y1, x2, y2;
sscanf(str.c_str(), "%*[^:]:%d %d %d %d", &x1, &y1, &x2, &y2);
Common::Rect rct = Common::Rect(x1, y1, x2, y2);
if (upscaleToHires)
_engine->getRenderManager()->upscaleRect(rct);
_areaId = _engine->getRenderManager()->createSubArea(rct);
} else if (str.matchString("*TextFile*", true)) {
char filename[64];
Expand All @@ -67,6 +69,11 @@ Subtitle::Subtitle(ZVision *engine, const Common::String &subname) :
int32 sb;
if (sscanf(str.c_str(), "%*[^:]:(%d,%d)=%d", &st, &en, &sb) == 3) {
if (sb <= (int32)_subs.size()) {
if (upscaleToHires) {
// Convert from 15FPS (AVI) to 29.97FPS (VOB)
st = st * 29.97 / 15;
en = en * 29.97 / 15;
}
_subs[sb].start = st;
_subs[sb].stop = en;
}
Expand Down
2 changes: 1 addition & 1 deletion engines/zvision/text/subtitles.h
Expand Up @@ -31,7 +31,7 @@ class ZVision;

class Subtitle {
public:
Subtitle(ZVision *engine, const Common::String &subname);
Subtitle(ZVision *engine, const Common::String &subname, bool upscaleToHires = false);
~Subtitle();

void process(int32 time);
Expand Down
8 changes: 2 additions & 6 deletions engines/zvision/video/video.cpp
Expand Up @@ -23,9 +23,7 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "video/video_decoder.h"
// TODO: Enable once VOB + AC3 support is implemented
#if 0
//#ifdef USE_MPEG2
#ifdef USE_MPEG2
#include "video/mpegps_decoder.h"
#endif
#include "engines/util.h"
Expand All @@ -50,9 +48,7 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
animation = new RLFDecoder();
else if (tmpFileName.hasSuffix(".avi"))
animation = new ZorkAVIDecoder();
// TODO: Enable once VOB + AC3 support is implemented
#if 0
//#ifdef USE_MPEG2
#ifdef USE_MPEG2
else if (tmpFileName.hasSuffix(".vob"))
animation = new Video::MPEGPSDecoder();
#endif
Expand Down
6 changes: 6 additions & 0 deletions engines/zvision/zvision.cpp
Expand Up @@ -360,4 +360,10 @@ void ZVision::initScreen() {
initGraphics(WINDOW_WIDTH, WINDOW_HEIGHT, true, &_screenPixelFormat);
}

void ZVision::initHiresScreen() {
_renderManager->upscaleRect(_workingWindow);

initGraphics(HIRES_WINDOW_WIDTH, HIRES_WINDOW_HEIGHT, true, &_screenPixelFormat);
}

} // End of namespace ZVision
40 changes: 22 additions & 18 deletions engines/zvision/zvision.h
Expand Up @@ -67,6 +67,27 @@ class TextRenderer;
class Subtitle;
class MidiManager;

enum {
WINDOW_WIDTH = 640,
WINDOW_HEIGHT = 480,

HIRES_WINDOW_WIDTH = 800,
HIRES_WINDOW_HEIGHT = 600,

// Zork nemesis working window sizes
ZNM_WORKING_WINDOW_WIDTH = 512,
ZNM_WORKING_WINDOW_HEIGHT = 320,

// ZGI working window sizes
ZGI_WORKING_WINDOW_WIDTH = 640,
ZGI_WORKING_WINDOW_HEIGHT = 344,

ROTATION_SCREEN_EDGE_OFFSET = 60,
MAX_ROTATION_SPEED = 400, // Pixels per second

KEYBUF_SIZE = 20
};

class ZVision : public Engine {
public:
ZVision(OSystem *syst, const ZVisionGameDescription *gameDesc);
Expand All @@ -83,24 +104,6 @@ class ZVision : public Engine {
const Graphics::PixelFormat _screenPixelFormat;

private:
enum {
WINDOW_WIDTH = 640,
WINDOW_HEIGHT = 480,

// Zork nemesis working window sizes
ZNM_WORKING_WINDOW_WIDTH = 512,
ZNM_WORKING_WINDOW_HEIGHT = 320,

// ZGI working window sizes
ZGI_WORKING_WINDOW_WIDTH = 640,
ZGI_WORKING_WINDOW_HEIGHT = 344,

ROTATION_SCREEN_EDGE_OFFSET = 60,
MAX_ROTATION_SPEED = 400, // Pixels per second

KEYBUF_SIZE = 20
};

Console *_console;
const ZVisionGameDescription *_gameDescription;

Expand Down Expand Up @@ -195,6 +198,7 @@ class ZVision : public Engine {
}

void initScreen();
void initHiresScreen();

/**
* Play a video until it is finished. This is a blocking call. It will call
Expand Down

0 comments on commit 899cf48

Please sign in to comment.