SCI: Merge new GUI code written by m_kiewitz.
This is a major rewrite of the graphics code. A slightly adapted version of the old code is still available and currently the default. The new code is selectable in sci.cpp, but is not yet finished. svn-id: r44565
This commit is contained in:
parent
f6de0b4ec9
commit
b9cdb1abb7
35 changed files with 5702 additions and 625 deletions
|
@ -92,6 +92,29 @@
|
||||||
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
|
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
|
||||||
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
|
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Name="gui">
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_dbllist.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_dbllist.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_font.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_font.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_screen.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_screen.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_view.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_view.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_windowmgr.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_windowmgr.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui32\gui32.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui32\gui32.cpp" />
|
||||||
|
</Filter>
|
||||||
<Filter Name="sfx">
|
<Filter Name="sfx">
|
||||||
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
||||||
<File RelativePath="..\..\engines\sci\sfx\core.h" />
|
<File RelativePath="..\..\engines\sci\sfx\core.h" />
|
||||||
|
|
|
@ -93,6 +93,29 @@
|
||||||
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
|
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
|
||||||
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
|
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Name="gui">
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_dbllist.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_dbllist.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_font.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_font.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_screen.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_screen.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_view.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_view.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_windowmgr.cpp" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui\gui_windowmgr.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui32\gui32.h" />
|
||||||
|
<File RelativePath="..\..\engines\sci\gui32\gui32.cpp" />
|
||||||
|
</Filter>
|
||||||
<Filter Name="sfx">
|
<Filter Name="sfx">
|
||||||
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
||||||
<File RelativePath="..\..\engines\sci\sfx\core.h" />
|
<File RelativePath="..\..\engines\sci\sfx\core.h" />
|
||||||
|
|
|
@ -332,18 +332,18 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
DEFUN("ShowMovie", kShowMovie, "..*"),
|
DEFUN("ShowMovie", kShowMovie, "..*"),
|
||||||
DEFUN("SetVideoMode", kSetVideoMode, "i"),
|
DEFUN("SetVideoMode", kSetVideoMode, "i"),
|
||||||
DEFUN("Platform", kPlatform, "i*"),
|
DEFUN("Platform", kPlatform, "i*"),
|
||||||
DEFUN("PalVary", kPalVary, "ii*"),
|
DEFUN("TextColors", kTextColors, ".*"),
|
||||||
|
DEFUN("TextFonts", kTextFonts, ".*"),
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Stub functions
|
// Stub functions
|
||||||
|
DEFUN("PalVary", kPalVary, "ii*"),
|
||||||
DEFUN("ShiftScreen", kShiftScreen, ".*"),
|
DEFUN("ShiftScreen", kShiftScreen, ".*"),
|
||||||
DEFUN("MemorySegment", kMemorySegment, ".*"),
|
DEFUN("MemorySegment", kMemorySegment, ".*"),
|
||||||
DEFUN("ListOps", kListOps, ".*"),
|
DEFUN("ListOps", kListOps, ".*"),
|
||||||
DEFUN("ATan", kATan, ".*"),
|
DEFUN("ATan", kATan, ".*"),
|
||||||
DEFUN("MergePoly", kMergePoly, ".*"),
|
DEFUN("MergePoly", kMergePoly, ".*"),
|
||||||
DEFUN("AssertPalette", kAssertPalette, ".*"),
|
DEFUN("AssertPalette", kAssertPalette, ".*"),
|
||||||
DEFUN("TextColors", kTextColors, ".*"),
|
|
||||||
DEFUN("TextFonts", kTextFonts, ".*"),
|
|
||||||
DEFUN("Record", kRecord, ".*"),
|
DEFUN("Record", kRecord, ".*"),
|
||||||
DEFUN("PlayBack", kPlayBack, ".*"),
|
DEFUN("PlayBack", kPlayBack, ".*"),
|
||||||
DEFUN("DbugStr", kDbugStr, ".*"),
|
DEFUN("DbugStr", kDbugStr, ".*"),
|
||||||
|
|
|
@ -454,7 +454,8 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv);
|
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kStrSplit(EngineState *s, int argc, reg_t *argv);
|
reg_t kStrSplit(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kPlatform(EngineState *s, int argc, reg_t *argv);
|
reg_t kPlatform(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kPalVary(EngineState *s, int argc, reg_t *argv);
|
reg_t kTextColors(EngineState *s, int argc, reg_t *argv);
|
||||||
|
reg_t kTextFonts(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
|
|
|
@ -206,11 +206,13 @@ reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) {
|
||||||
SegManager *segMan = s->segMan;
|
SegManager *segMan = s->segMan;
|
||||||
|
|
||||||
if (obj.segment) {
|
if (obj.segment) {
|
||||||
int x = GET_SEL32V(obj, x);
|
int16 x = GET_SEL32V(obj, x);
|
||||||
int y = GET_SEL32V(obj, y);
|
int16 y = GET_SEL32V(obj, y);
|
||||||
|
|
||||||
PUT_SEL32V(obj, x, x - s->port->zone.x);
|
s->gui->globalToLocal(&x, &y);
|
||||||
PUT_SEL32V(obj, y, y - s->port->zone.y);
|
|
||||||
|
PUT_SEL32V(obj, x, x);
|
||||||
|
PUT_SEL32V(obj, y, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
|
@ -222,11 +224,13 @@ reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv) {
|
||||||
SegManager *segMan = s->segMan;
|
SegManager *segMan = s->segMan;
|
||||||
|
|
||||||
if (obj.segment) {
|
if (obj.segment) {
|
||||||
int x = GET_SEL32V(obj, x);
|
int16 x = GET_SEL32V(obj, x);
|
||||||
int y = GET_SEL32V(obj, y);
|
int16 y = GET_SEL32V(obj, y);
|
||||||
|
|
||||||
PUT_SEL32V(obj, x, x + s->port->zone.x);
|
s->gui->localToGlobal(&x, &y);
|
||||||
PUT_SEL32V(obj, y, y + s->port->zone.y);
|
|
||||||
|
PUT_SEL32V(obj, x, x);
|
||||||
|
PUT_SEL32V(obj, y, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -131,7 +131,8 @@ reg_t kGetTime(EngineState *s, int argc, reg_t *argv) {
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case K_NEW_GETTIME_TICKS :
|
case K_NEW_GETTIME_TICKS :
|
||||||
retval = start_time * 60 / 1000;
|
retval = s->gui->getTimeTicks(); // FIXME
|
||||||
|
//retval = start_time * 60 / 1000;
|
||||||
debugC(2, kDebugLevelTime, "GetTime(elapsed) returns %d", retval);
|
debugC(2, kDebugLevelTime, "GetTime(elapsed) returns %d", retval);
|
||||||
break;
|
break;
|
||||||
case K_NEW_GETTIME_TIME_12HOUR :
|
case K_NEW_GETTIME_TIME_12HOUR :
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace Common {
|
||||||
#include "sci/engine/seg_manager.h"
|
#include "sci/engine/seg_manager.h"
|
||||||
#include "sci/gfx/gfx_system.h"
|
#include "sci/gfx/gfx_system.h"
|
||||||
#include "sci/sfx/core.h"
|
#include "sci/sfx/core.h"
|
||||||
|
#include "sci/gui/gui.h"
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
|
@ -175,6 +176,8 @@ public:
|
||||||
|
|
||||||
/* Non-VM information */
|
/* Non-VM information */
|
||||||
|
|
||||||
|
SciGUI *gui; /* Currently active GUI */
|
||||||
|
|
||||||
GfxState *gfx_state; /**< Graphics state and driver */
|
GfxState *gfx_state; /**< Graphics state and driver */
|
||||||
gfx_pixmap_t *old_screen; /**< Old screen content: Stored during kDrawPic() for kAnimate() */
|
gfx_pixmap_t *old_screen; /**< Old screen content: Stored during kDrawPic() for kAnimate() */
|
||||||
|
|
||||||
|
@ -319,6 +322,12 @@ private:
|
||||||
*/
|
*/
|
||||||
PaletteEntry get_pic_color(EngineState *s, int color);
|
PaletteEntry get_pic_color(EngineState *s, int color);
|
||||||
|
|
||||||
|
/* Functions used in gui32\gui32.cpp */
|
||||||
|
reg_t graph_save_box(EngineState *s, rect_t area);
|
||||||
|
void graph_restore_box(EngineState *s, reg_t handle);
|
||||||
|
void assert_primary_widget_lists(EngineState *s);
|
||||||
|
void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport);
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
||||||
#endif // SCI_INCLUDE_ENGINE_H
|
#endif // SCI_INCLUDE_ENGINE_H
|
||||||
|
|
|
@ -248,4 +248,19 @@ void GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) {
|
||||||
cursorData = 0;
|
cursorData = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GfxDriver::animatePalette(int fromColor, int toColor, int stepCount) {
|
||||||
|
int i;
|
||||||
|
PaletteEntry firstColor = _mode->palette->getColor(fromColor);
|
||||||
|
PaletteEntry loopColor;
|
||||||
|
for (i=fromColor+1; i<=toColor; i++) {
|
||||||
|
loopColor = _mode->palette->getColor(i);
|
||||||
|
loopColor.r = 0;
|
||||||
|
loopColor.g = 0;
|
||||||
|
loopColor.b = 0;
|
||||||
|
_mode->palette->makeSystemColor(i-1, loopColor); // loopColor.r, loopColor.g, loopColor.b);
|
||||||
|
}
|
||||||
|
// _mode->palette->setColor(toColor, firstColor.r, firstColor.g, firstColor.b);
|
||||||
|
_mode->palette->makeSystemColor(toColor, firstColor);
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -228,6 +228,11 @@ public:
|
||||||
gfx_mode_t *getMode() { return _mode; }
|
gfx_mode_t *getMode() { return _mode; }
|
||||||
byte *getVisual0() { return _visual[0]; }
|
byte *getVisual0() { return _visual[0]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates palette
|
||||||
|
*/
|
||||||
|
void animatePalette(int fromColor, int toColor, int stepCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gfx_pixmap_t *_priority[2];
|
gfx_pixmap_t *_priority[2];
|
||||||
byte *_visual[2];
|
byte *_visual[2];
|
||||||
|
|
|
@ -365,6 +365,12 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SCI1:
|
||||||
|
// [LoopCount:WORD] [MirrorMask:WORD] [??:WORD] [PaletteOffset:WORD] [LoopOffset0:WORD] [LoopOffset1:WORD]...
|
||||||
|
// Loop-data:
|
||||||
|
// [CellCount:WORD] [Unknown:WORD] [CellOffset0:WORD] [CellOffset1:WORD]...
|
||||||
|
// SCI11:
|
||||||
|
// [HeaderSize:WORD] [LoopCount:BYTE] [Unknown:BYTE] [??:WORD] [??:WORD] [PaletteOffset:WORD]
|
||||||
gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType) {
|
gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType) {
|
||||||
uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + ((viewType == kViewVga11) ? 2 : 0));
|
uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + ((viewType == kViewVga11) ? 2 : 0));
|
||||||
uint16 headerSize = (viewType == kViewVga11) ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0;
|
uint16 headerSize = (viewType == kViewVga11) ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0;
|
||||||
|
|
330
engines/sci/gui/gui.cpp
Normal file
330
engines/sci/gui/gui.cpp
Normal file
|
@ -0,0 +1,330 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_screen.h"
|
||||||
|
#include "sci/gui/gui_gfx.h"
|
||||||
|
#include "sci/gui/gui_windowmgr.h"
|
||||||
|
#include "sci/gui/gui_memmgr.h"
|
||||||
|
#include "sci/gui/gui_view.h"
|
||||||
|
|
||||||
|
#include "sci/gfx/operations.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUI::SciGUI(OSystem *system, EngineState *state)
|
||||||
|
: _system(system), _s(state) {
|
||||||
|
_screen = new SciGUIscreen(_system, _s);
|
||||||
|
_gfx = new SciGUIgfx(_system, _s, _screen);
|
||||||
|
_windowMgr = new SciGUIwindowMgr(_s, _gfx);
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUI::SciGUI() {
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUI::~SciGUI() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::init(bool oldGfxFunctions) {
|
||||||
|
_usesOldGfxFunctions = oldGfxFunctions;
|
||||||
|
|
||||||
|
/* Set default SCI0 palette */
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUI::getTimeTicks() {
|
||||||
|
return _gfx->_sysTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::wait(int16 ticks) {
|
||||||
|
uint32 waitto = _gfx->_sysTicks + ticks;
|
||||||
|
do {
|
||||||
|
//eventMgr->pollEvents();
|
||||||
|
_system->delayMillis(_gfx->_sysSpeed >> 11);
|
||||||
|
} while (_gfx->_sysTicks < waitto);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::setPort(uint16 portPtr) {
|
||||||
|
switch (portPtr) {
|
||||||
|
case 0: _gfx->SetPort(_windowMgr->_wmgrPort); break;
|
||||||
|
case 0xFFFF: _gfx->SetPort(_gfx->_menuPort); break;
|
||||||
|
default:
|
||||||
|
_gfx->SetPort((sciPort *)heap2Ptr(portPtr));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft) {
|
||||||
|
_windowMgr->_picWind->rect = rect;
|
||||||
|
_windowMgr->_picWind->top = picTop;
|
||||||
|
_windowMgr->_picWind->left = picLeft;
|
||||||
|
//if (argc >= 7)
|
||||||
|
//InitPri(42,190);
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI::getPort() {
|
||||||
|
return make_reg(0, ptr2heap((byte *)_gfx->GetPort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::globalToLocal(int16 *x, int16 *y) {
|
||||||
|
sciPort *curPort = _gfx->GetPort();
|
||||||
|
*x = *x - curPort->left;
|
||||||
|
*y = *y - curPort->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::localToGlobal(int16 *x, int16 *y) {
|
||||||
|
sciPort *curPort = _gfx->GetPort();
|
||||||
|
*x = *x + curPort->left;
|
||||||
|
*y = *y + curPort->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI::newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) {
|
||||||
|
sciWnd *wnd = NULL;
|
||||||
|
|
||||||
|
if (rect2.top != 0 && rect2.left != 0 && rect2.height() != 0 && rect2.width() != 0)
|
||||||
|
wnd = _windowMgr->NewWindow(&rect1, &rect2, "", style, priority, 0);
|
||||||
|
else
|
||||||
|
wnd = _windowMgr->NewWindow(&rect1, NULL, "", style, priority, 0);
|
||||||
|
wnd->penClr = colorPen;
|
||||||
|
wnd->backClr = colorBack;
|
||||||
|
_windowMgr->DrawWindow(wnd);
|
||||||
|
return make_reg(0, ptr2heap((byte *)wnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::disposeWindow(uint16 windowPtr, int16 arg2) {
|
||||||
|
sciWnd *wnd = (sciWnd *)heap2Ptr(windowPtr);
|
||||||
|
_windowMgr->DisposeWindow(wnd, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::display(const char *text, int argc, reg_t *argv) {
|
||||||
|
int displayArg;
|
||||||
|
sciPort oldPort;
|
||||||
|
int16 align = 0;
|
||||||
|
int16 bgcolor = -1, width = 0xFFFF, bRedraw = 1;
|
||||||
|
byte bSaveUnder = false;
|
||||||
|
Common::Rect rect, *orect = &((sciWnd *)_gfx->GetPort())->rect0;
|
||||||
|
|
||||||
|
memcpy(&oldPort, _gfx->GetPort(), sizeof(sciPort));
|
||||||
|
// setting defaults
|
||||||
|
_gfx->PenMode(0);
|
||||||
|
_gfx->PenColor(0);
|
||||||
|
_gfx->TextFace(0);
|
||||||
|
// processing codes in argv
|
||||||
|
while (argc > 0) {
|
||||||
|
displayArg = argv[0].toUint16();
|
||||||
|
argc--; argv++;
|
||||||
|
switch (displayArg - 100) {
|
||||||
|
case 0:
|
||||||
|
_gfx->MoveTo(argv[0].toUint16(), argv[1].toUint16());
|
||||||
|
argc -= 2; argv += 2;
|
||||||
|
break;// move pen
|
||||||
|
case 1:
|
||||||
|
align = argv[0].toUint16();
|
||||||
|
argc--; argv++;
|
||||||
|
break;// set alignment
|
||||||
|
case 2:
|
||||||
|
_gfx->PenColor(argv[0].toUint16());
|
||||||
|
argc--; argv++;
|
||||||
|
break;// set pen color
|
||||||
|
case 3:
|
||||||
|
bgcolor = argv[0].toUint16();
|
||||||
|
argc--; argv++;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
_gfx->TextFace(argv[0].toUint16());
|
||||||
|
argc--; argv++;
|
||||||
|
break;// set text grayout flag
|
||||||
|
case 5:
|
||||||
|
_gfx->SetFont(argv[0].toUint16());
|
||||||
|
argc--; argv++;
|
||||||
|
break;// set font
|
||||||
|
case 6:
|
||||||
|
width = argv[0].toUint16();
|
||||||
|
argc--; argv++;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
bSaveUnder = 1;
|
||||||
|
break;
|
||||||
|
case 8: // restore under
|
||||||
|
// if (hunk2Ptr(*pArgs)) {
|
||||||
|
// memcpy(&rect, hunk2Ptr(*pArgs), sizeof(Common::Rect));
|
||||||
|
// // rect is now absolute. Have to move it to be port-relative
|
||||||
|
// rect.translate(-_gfx->RGetPort()->left, -_gfx->RGetPort()->top);
|
||||||
|
// _gfx->RestoreBits(*pArgs);
|
||||||
|
// ReAnimate(&rect);
|
||||||
|
// }
|
||||||
|
// finishing loop
|
||||||
|
argc = 0;
|
||||||
|
break;
|
||||||
|
case 0x15:
|
||||||
|
bRedraw = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning("Unknown kDisplay argument %X", displayArg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now drawing the text
|
||||||
|
_gfx->TextSize(rect, text, -1, width);
|
||||||
|
_gfx->Move((orect->left <= 320 ? 0 : 320 - orect->left), (orect->top <= 200 ? 0 : 200 - orect->top)); // move port to (0,0)
|
||||||
|
rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop);
|
||||||
|
// if (bSaveUnder)
|
||||||
|
// _acc = _gfx->SaveBits(rect, 1);
|
||||||
|
if (bgcolor != -1)
|
||||||
|
_gfx->FillRect(rect, 1, bgcolor, 0, 0);
|
||||||
|
_gfx->TextBox(text, 0, rect, align, 0xFFFF);
|
||||||
|
// if (_picNotValid == 0 && bRedraw)
|
||||||
|
// _gfx->ShowBits(rect, 1);
|
||||||
|
// restoring port and cursor pos
|
||||||
|
sciPort *currport = _gfx->GetPort();
|
||||||
|
uint16 tTop = currport->curTop;
|
||||||
|
uint16 tLeft = currport->curLeft;
|
||||||
|
memcpy(currport, &oldPort, sizeof(sciPort));
|
||||||
|
currport->curTop = tTop;
|
||||||
|
currport->curLeft = tLeft;
|
||||||
|
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
|
||||||
|
Common::Rect rect(0, 0, *textWidth, *textHeight);
|
||||||
|
_gfx->TextSize(rect, text, font, maxWidth);
|
||||||
|
*textWidth = rect.width(); *textHeight = rect.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used SCI1+ for text codes
|
||||||
|
void SciGUI::textFonts(int argc, reg_t *argv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used SCI1+ for text codes
|
||||||
|
void SciGUI::textColors(int argc, reg_t *argv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::drawPicture(sciResourceId pictureId, uint16 style, uint16 flags, int16 EGApaletteNo) {
|
||||||
|
bool addToFlag = flags ? true : false;
|
||||||
|
|
||||||
|
sciPort *oldPort = _gfx->SetPort((sciPort *)_windowMgr->_picWind);
|
||||||
|
|
||||||
|
if (_windowMgr->isFrontWindow(_windowMgr->_picWind)) {
|
||||||
|
_gfx->drawPicture(pictureId, style, addToFlag, EGApaletteNo);
|
||||||
|
} else {
|
||||||
|
_windowMgr->BeginUpdate(_windowMgr->_picWind);
|
||||||
|
_gfx->drawPicture(pictureId, style, addToFlag, EGApaletteNo);
|
||||||
|
_windowMgr->EndUpdate(_windowMgr->_picWind);
|
||||||
|
}
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
|
||||||
|
_gfx->SetPort(oldPort);
|
||||||
|
_s->pic_not_valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo) {
|
||||||
|
_gfx->drawCell(viewId, loopNo, cellNo, leftPos, topPos, priority, paletteNo);
|
||||||
|
_gfx->SetCLUT(&_gfx->_sysPalette);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse) {
|
||||||
|
rect.grow(1);
|
||||||
|
_gfx->EraseRect(rect);
|
||||||
|
_gfx->FrameRect(rect);
|
||||||
|
rect.grow(-2);
|
||||||
|
_gfx->TextFace(style & 1 ? 0 : 1);
|
||||||
|
_gfx->TextBox(text, 0, rect, 1, fontId);
|
||||||
|
_gfx->TextFace(0);
|
||||||
|
if (style & 8) { // selected
|
||||||
|
rect.grow(1);
|
||||||
|
_gfx->FrameRect(rect);
|
||||||
|
}
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse) {
|
||||||
|
rect.grow(1);
|
||||||
|
_gfx->EraseRect(rect);
|
||||||
|
rect.grow(-1);
|
||||||
|
_gfx->TextBox(text, 0, rect, mode, fontId);
|
||||||
|
if (style & 8) { // selected
|
||||||
|
_gfx->FrameRect(rect);
|
||||||
|
}
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::graphFillBoxForeground(Common::Rect rect) {
|
||||||
|
_gfx->PaintRect(rect);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::graphFillBoxBackground(Common::Rect rect) {
|
||||||
|
_gfx->EraseRect(rect);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control) {
|
||||||
|
_gfx->FillRect(rect, colorMask, color, priority, control);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control) {
|
||||||
|
_gfx->Draw_Line(rect.left, rect.top, rect.right, rect.bottom, color, priority, control);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI::graphSaveBox(Common::Rect rect, uint16 flags) {
|
||||||
|
return _gfx->SaveBits(rect, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::graphRestoreBox(reg_t handle) {
|
||||||
|
_gfx->RestoreBits(handle);
|
||||||
|
_screen->UpdateWhole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::paletteSet(int resourceNo, int flags) {
|
||||||
|
_gfx->SetResPalette(resourceNo, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUI::paletteFind(int r, int g, int b) {
|
||||||
|
return _gfx->MatchColor(&_gfx->_sysPalette, r, g, b) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::paletteAnimate(int fromColor, int toColor, int speed) {
|
||||||
|
_gfx->animatePalette(fromColor, toColor, speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI::moveCursor(int16 x, int16 y) {
|
||||||
|
Common::Point newPos;
|
||||||
|
sciPort *curPort = _gfx->GetPort();
|
||||||
|
|
||||||
|
x += _windowMgr->_picWind->rect.left;
|
||||||
|
y += _windowMgr->_picWind->rect.top;
|
||||||
|
newPos.x = CLIP<int16> (x, _windowMgr->_picWind->rect.left, _windowMgr->_picWind->rect.right - 1);
|
||||||
|
newPos.y = CLIP<int16> (y, _windowMgr->_picWind->rect.top, _windowMgr->_picWind->rect.bottom - 1);
|
||||||
|
|
||||||
|
gfxop_set_pointer_position(_s->gfx_state, newPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Sci
|
86
engines/sci/gui/gui.h
Normal file
86
engines/sci/gui/gui.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/gui/gui_helpers.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
class SciGUIscreen;
|
||||||
|
class SciGUIgfx;
|
||||||
|
class SciGUIresources;
|
||||||
|
class SciGUIwindowMgr;
|
||||||
|
class SciGUI {
|
||||||
|
public:
|
||||||
|
SciGUI(OSystem *system, EngineState *s);
|
||||||
|
SciGUI();
|
||||||
|
~SciGUI();
|
||||||
|
|
||||||
|
virtual void init(bool oldGfxFunctions);
|
||||||
|
|
||||||
|
virtual int16 getTimeTicks();
|
||||||
|
virtual void wait(int16 ticks);
|
||||||
|
virtual void setPort(uint16 portPtr);
|
||||||
|
virtual void setPortPic(Common::Rect rect, int16 picTop, int16 picLeft);
|
||||||
|
virtual reg_t getPort();
|
||||||
|
virtual void globalToLocal(int16 *x, int16 *y);
|
||||||
|
virtual void localToGlobal(int16 *x, int16 *y);
|
||||||
|
virtual reg_t newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title);
|
||||||
|
virtual void disposeWindow(uint16 windowPtr, int16 arg2);
|
||||||
|
|
||||||
|
virtual void display(const char *text, int argc, reg_t *argv);
|
||||||
|
|
||||||
|
virtual void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
|
||||||
|
virtual void textFonts(int argc, reg_t *argv);
|
||||||
|
virtual void textColors(int argc, reg_t *argv);
|
||||||
|
|
||||||
|
virtual void drawPicture(sciResourceId pictureId, uint16 showStyle, uint16 flags, int16 EGApaletteNo);
|
||||||
|
virtual void drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo);
|
||||||
|
virtual void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse);
|
||||||
|
virtual void drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse);
|
||||||
|
|
||||||
|
virtual void graphFillBoxForeground(Common::Rect rect);
|
||||||
|
virtual void graphFillBoxBackground(Common::Rect rect);
|
||||||
|
virtual void graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control);
|
||||||
|
virtual void graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control);
|
||||||
|
virtual reg_t graphSaveBox(Common::Rect rect, uint16 flags);
|
||||||
|
virtual void graphRestoreBox(reg_t handle);
|
||||||
|
|
||||||
|
virtual void paletteSet(int resourceNo, int flags);
|
||||||
|
virtual int16 paletteFind(int r, int g, int b);
|
||||||
|
virtual void paletteAnimate(int fromColor, int toColor, int speed);
|
||||||
|
|
||||||
|
virtual void moveCursor(int16 x, int16 y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIscreen *_screen;
|
||||||
|
SciGUIgfx *_gfx;
|
||||||
|
SciGUIresources *_resources;
|
||||||
|
SciGUIwindowMgr *_windowMgr;
|
||||||
|
bool _usesOldGfxFunctions;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Sci
|
257
engines/sci/gui/gui_dbllist.cpp
Normal file
257
engines/sci/gui/gui_dbllist.cpp
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/gui/gui_helpers.h"
|
||||||
|
#include "sci/gui/gui_memmgr.h"
|
||||||
|
#include "sci/gui/gui_dbllist.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
DblList::DblList() {
|
||||||
|
_hFirst = 0;
|
||||||
|
_hLast = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DblList::DblList(HEAPHANDLE heap) {
|
||||||
|
byte *ptr = heap2Ptr(heap);
|
||||||
|
_hFirst = READ_UINT16(ptr);
|
||||||
|
_hLast = READ_UINT16(ptr + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DblList::~DblList(void) {
|
||||||
|
}
|
||||||
|
//--------------------------------------
|
||||||
|
// Prints all list contents
|
||||||
|
void DblList::Dump(char*caption) {
|
||||||
|
debug("DumpList %s:", caption);
|
||||||
|
debug(" First: %04X Last: %04X", _hFirst, _hLast);
|
||||||
|
HEAPHANDLE node = _hFirst;
|
||||||
|
while (node) {
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
debug(" %04X key=%04X prev=%04X next=%04X add.data=%db", node,
|
||||||
|
pNode->key, pNode->prev, pNode->next, heapGetDataSize(node) - 6);
|
||||||
|
node = pNode->next;
|
||||||
|
}
|
||||||
|
debug("End of list");
|
||||||
|
}
|
||||||
|
//--------------------------------------
|
||||||
|
// Add a new node to front of the list
|
||||||
|
HEAPHANDLE DblList::AddToFront(HEAPHANDLE node, uint16 key) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::AddToFront !",
|
||||||
|
node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
pNode->key = key;
|
||||||
|
if (_hFirst) { // we already have a 1st node
|
||||||
|
sciNode *pnext = (sciNode *)heap2Ptr(_hFirst);
|
||||||
|
pnext->prev = node;
|
||||||
|
pNode->next = _hFirst;
|
||||||
|
} else { // list is empty, to passed node becames 1st one
|
||||||
|
_hLast = node;
|
||||||
|
pNode->next = 0;
|
||||||
|
}
|
||||||
|
_hFirst = node;
|
||||||
|
pNode->prev = 0;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
//
|
||||||
|
HEAPHANDLE DblList::AddToEnd(HEAPHANDLE node, uint16 key) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::AddToEnd !", node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
if (_hFirst) { // list is not empty
|
||||||
|
sciNode *plast = (sciNode *)heap2Ptr(_hLast);
|
||||||
|
plast->next = node;
|
||||||
|
pNode->prev = _hLast;
|
||||||
|
} else { // list is empty, so the node becames 1st one
|
||||||
|
_hFirst = node;
|
||||||
|
pNode->prev = 0;
|
||||||
|
}
|
||||||
|
_hLast = node;
|
||||||
|
pNode->next = 0;
|
||||||
|
pNode->key = key;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------
|
||||||
|
// returns node that contains the key
|
||||||
|
HEAPHANDLE DblList::FindKey(uint16 key) {
|
||||||
|
HEAPHANDLE node = _hFirst;
|
||||||
|
while (node) {
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
if (pNode->key == key)
|
||||||
|
break;
|
||||||
|
node = pNode->next;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
// detaches node with specified key and returning the node
|
||||||
|
HEAPHANDLE DblList::DeleteKey(uint16 key) {
|
||||||
|
HEAPHANDLE node = FindKey(key);
|
||||||
|
if (node)
|
||||||
|
DeleteNode(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
// detaches specified node from list
|
||||||
|
byte DblList::DeleteNode(HEAPHANDLE node) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::AddToEnd !", node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
// updating the links
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
if (pNode->prev) {
|
||||||
|
sciNode *pprev = (sciNode *)heap2Ptr(pNode->prev);
|
||||||
|
pprev->next = pNode->next;
|
||||||
|
}
|
||||||
|
if (pNode->next) {
|
||||||
|
sciNode *pnext = (sciNode *)heap2Ptr(pNode->next);
|
||||||
|
pnext->prev = pNode->prev;
|
||||||
|
}
|
||||||
|
// updating list head if needed
|
||||||
|
if (_hFirst == node)
|
||||||
|
_hFirst = pNode->next;
|
||||||
|
if (_hLast == node)
|
||||||
|
_hLast = pNode->prev;
|
||||||
|
pNode->prev = 0;
|
||||||
|
pNode->next = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
// Moves node to the end of the list
|
||||||
|
HEAPHANDLE DblList::MoveToEnd(HEAPHANDLE node) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::MoveToEnd !", node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
if (pNode->next) { // node is not the last one in list
|
||||||
|
DeleteNode(node);
|
||||||
|
AddToEnd(node, pNode->key);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
// Moves node to the front of the list
|
||||||
|
HEAPHANDLE DblList::MoveToFront(HEAPHANDLE node) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::MoveToFront !",
|
||||||
|
node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
if (pNode->prev) { // node is not 1st one in list
|
||||||
|
DeleteNode(node);
|
||||||
|
AddToFront(node, pNode->key);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
HEAPHANDLE DblList::AddAfter(HEAPHANDLE ref, HEAPHANDLE node, uint16 key) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::AddAfter !", node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
sciNode *pref = (sciNode *)heap2Ptr(ref);
|
||||||
|
pNode->key = key;
|
||||||
|
if (pref->next == 0) { // ref node is the last one
|
||||||
|
pNode->next = 0;
|
||||||
|
_hLast = node;
|
||||||
|
} else {
|
||||||
|
sciNode *pnext = (sciNode *)heap2Ptr(pref->next);
|
||||||
|
pNode->next = pref->next;
|
||||||
|
pnext->prev = node;
|
||||||
|
}
|
||||||
|
pref->next = node;
|
||||||
|
pNode->prev = ref;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
//
|
||||||
|
HEAPHANDLE DblList::AddBefore(HEAPHANDLE ref, HEAPHANDLE node, uint16 key) {
|
||||||
|
if (!node) {
|
||||||
|
warning("Bad node handler (%04X) passed to DblList::AddBefore !", node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
sciNode *pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
sciNode *pref = (sciNode *)heap2Ptr(ref);
|
||||||
|
pNode->key = key;
|
||||||
|
if (pref->prev == 0) { // ref node is the 1st one
|
||||||
|
pNode->prev = 0;
|
||||||
|
_hFirst = node;
|
||||||
|
} else {
|
||||||
|
sciNode*pprev = (sciNode *)heap2Ptr(pref->prev);
|
||||||
|
pNode->prev = pref->prev;
|
||||||
|
pprev->next = node;
|
||||||
|
}
|
||||||
|
pref->prev = node;
|
||||||
|
pNode->next = ref;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
void DblList::toHeap(HEAPHANDLE heap) {
|
||||||
|
byte *ptr = heap2Ptr(heap);
|
||||||
|
WRITE_UINT16(ptr, _hFirst);
|
||||||
|
WRITE_UINT16(ptr + 2, _hLast);
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
void DblList::DeleteList() {
|
||||||
|
HEAPHANDLE node = getFirst(), next;
|
||||||
|
sciNode *pNode;
|
||||||
|
while (node) {
|
||||||
|
pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
next = pNode->next;
|
||||||
|
heapDisposePtr(node);
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
_hFirst = _hLast = 0;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
uint16 DblList::getSize() {
|
||||||
|
uint16 cnt = 0;
|
||||||
|
HEAPHANDLE node = getFirst();
|
||||||
|
sciNode *pNode;
|
||||||
|
while (node) {
|
||||||
|
pNode = (sciNode *)heap2Ptr(node);
|
||||||
|
node = pNode->next;
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
//------------------------------------------------
|
||||||
|
} // end of namespace
|
74
engines/sci/gui/gui_dbllist.h
Normal file
74
engines/sci/gui/gui_dbllist.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Each node contains handles to next and previous node and an optional key for searching
|
||||||
|
Head node contains handles to first and last node
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
typedef uint16 HEAPHANDLE;
|
||||||
|
|
||||||
|
class DblList {
|
||||||
|
public:
|
||||||
|
DblList();
|
||||||
|
DblList(HEAPHANDLE heap);
|
||||||
|
~DblList(void);
|
||||||
|
protected:
|
||||||
|
HEAPHANDLE _hFirst, _hLast;
|
||||||
|
public:
|
||||||
|
// Add a new node to front of the list
|
||||||
|
HEAPHANDLE AddToFront(HEAPHANDLE node, uint16 key = 0);
|
||||||
|
HEAPHANDLE AddToEnd(HEAPHANDLE node, uint16 key = 0);
|
||||||
|
HEAPHANDLE MoveToEnd(HEAPHANDLE node);
|
||||||
|
HEAPHANDLE MoveToFront(HEAPHANDLE node);
|
||||||
|
HEAPHANDLE AddAfter(HEAPHANDLE ref, HEAPHANDLE node, uint16 key = 0);
|
||||||
|
HEAPHANDLE AddBefore(HEAPHANDLE ref, HEAPHANDLE node, uint16 key = 0);
|
||||||
|
|
||||||
|
HEAPHANDLE FindKey(uint16 key);
|
||||||
|
HEAPHANDLE DeleteKey(uint16 key);
|
||||||
|
byte DeleteNode(HEAPHANDLE node);
|
||||||
|
void DeleteList();
|
||||||
|
void Dump(char*caption = ""); // for debug
|
||||||
|
HEAPHANDLE getFirst() {
|
||||||
|
return _hFirst;
|
||||||
|
}
|
||||||
|
HEAPHANDLE getLast() {
|
||||||
|
return _hLast;
|
||||||
|
}
|
||||||
|
void toHeap(HEAPHANDLE heap);
|
||||||
|
bool isEmpty() {
|
||||||
|
return (_hFirst == 0 && _hLast == 0);
|
||||||
|
}
|
||||||
|
uint16 getSize();
|
||||||
|
void set(HEAPHANDLE first, HEAPHANDLE last){
|
||||||
|
_hFirst = first;
|
||||||
|
_hLast = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace
|
100
engines/sci/gui/gui_font.cpp
Normal file
100
engines/sci/gui/gui_font.cpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_screen.h"
|
||||||
|
#include "sci/gui/gui_font.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUIfont::SciGUIfont(OSystem *system, EngineState *state, SciGUIscreen *screen, sciResourceId resourceId)
|
||||||
|
: _system(system), _s(state), _screen(screen), _resourceId(resourceId) {
|
||||||
|
assert(resourceId != -1);
|
||||||
|
initData(resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUIfont::~SciGUIfont() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIfont::initData(sciResourceId resourceId) {
|
||||||
|
Resource *fontResource = _s->resMan->findResource(ResourceId(kResourceTypeFont, resourceId), false);
|
||||||
|
if (!fontResource) {
|
||||||
|
error("font resource %d not found", resourceId);
|
||||||
|
}
|
||||||
|
_resourceData = fontResource->data;
|
||||||
|
|
||||||
|
mCharMax = READ_LE_UINT16(_resourceData + 2);
|
||||||
|
mFontH = READ_LE_UINT16(_resourceData + 4);
|
||||||
|
mChars = new charinfo[mCharMax];
|
||||||
|
// filling info for every char
|
||||||
|
for (int16 i = 0; i < mCharMax; i++) {
|
||||||
|
mChars[i].offset = READ_LE_UINT16(_resourceData + 6 + i * 2);
|
||||||
|
mChars[i].w = _resourceData[mChars[i].offset];
|
||||||
|
mChars[i].h = _resourceData[mChars[i].offset + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sciResourceId SciGUIfont::getResourceId() {
|
||||||
|
return _resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIfont::getHeight() {
|
||||||
|
return mFontH;
|
||||||
|
}
|
||||||
|
byte SciGUIfont::getCharWidth(byte chr) {
|
||||||
|
return chr < mCharMax ? mChars[chr].w : 0;
|
||||||
|
}
|
||||||
|
byte SciGUIfont::getCharHeight(byte chr) {
|
||||||
|
return chr < mCharMax ? mChars[chr].h : 0;
|
||||||
|
}
|
||||||
|
byte *SciGUIfont::getCharData(byte chr) {
|
||||||
|
return chr < mCharMax ? _resourceData + mChars[chr].offset + 2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIfont::draw(int16 chr, int16 top, int16 left, byte color, byte textface) {
|
||||||
|
int charWidth = MIN<int>(getCharWidth(chr), _screen->_width - left);
|
||||||
|
int charHeight = MIN<int>(getCharHeight(chr), 200 - top);
|
||||||
|
byte b = 0, mask = 0xFF;
|
||||||
|
int pitch = _screen->_width;
|
||||||
|
int y = top;
|
||||||
|
|
||||||
|
byte *pIn = getCharData(chr);
|
||||||
|
for (int i = 0; i < charHeight; i++, y++) {
|
||||||
|
if (textface & 1) // "grayed" output
|
||||||
|
mask = top++ % 2 ? 0xAA : 0x55;
|
||||||
|
for (int done = 0; done < charWidth; done++) {
|
||||||
|
if ((done & 7) == 0) // fetching next data byte
|
||||||
|
b = *(pIn++) & mask;
|
||||||
|
if (b & 0x80) // if MSB is set - paint it
|
||||||
|
_screen->Put_Pixel(left + done, y, 1, color, 0, 0);
|
||||||
|
b = b << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
59
engines/sci/gui/gui_font.h
Normal file
59
engines/sci/gui/gui_font.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
class SciGUIfont {
|
||||||
|
public:
|
||||||
|
SciGUIfont(OSystem *system, EngineState *state, SciGUIscreen *screen, sciResourceId resourceId);
|
||||||
|
~SciGUIfont();
|
||||||
|
|
||||||
|
sciResourceId getResourceId();
|
||||||
|
byte getHeight();
|
||||||
|
byte getCharWidth(byte chr);
|
||||||
|
byte getCharHeight(byte chr);
|
||||||
|
byte *getCharData(byte chr);
|
||||||
|
void draw(int16 chr, int16 top, int16 left, byte color, byte textface);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initData(sciResourceId resourceId);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIscreen *_screen;
|
||||||
|
|
||||||
|
sciResourceId _resourceId;
|
||||||
|
byte *_resourceData;
|
||||||
|
|
||||||
|
struct charinfo {
|
||||||
|
byte w, h;
|
||||||
|
int16 offset;
|
||||||
|
};
|
||||||
|
byte mFontH;
|
||||||
|
uint16 mCharMax;
|
||||||
|
charinfo* mChars;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
1194
engines/sci/gui/gui_gfx.cpp
Normal file
1194
engines/sci/gui/gui_gfx.cpp
Normal file
File diff suppressed because it is too large
Load diff
150
engines/sci/gui/gui_gfx.h
Normal file
150
engines/sci/gui/gui_gfx.h
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
#define SCI_PATTERN_CODE_RECTANGLE 0x10
|
||||||
|
#define SCI_PATTERN_CODE_USE_TEXTURE 0x20
|
||||||
|
#define SCI_PATTERN_CODE_PENSIZE 0x07
|
||||||
|
|
||||||
|
class SciGUIscreen;
|
||||||
|
class SciGUIfont;
|
||||||
|
class SciGUIpicture;
|
||||||
|
class SciGUIview;
|
||||||
|
class SciGUIgfx {
|
||||||
|
public:
|
||||||
|
SciGUIgfx(OSystem *system, EngineState *state, SciGUIscreen *screen);
|
||||||
|
~SciGUIgfx();
|
||||||
|
|
||||||
|
void init(void);
|
||||||
|
void initPalette();
|
||||||
|
virtual void initTimer();
|
||||||
|
static void timerHandler(void*ref);
|
||||||
|
|
||||||
|
sciPort *mallocPort ();
|
||||||
|
byte *GetSegment(byte seg);
|
||||||
|
void ResetScreen();
|
||||||
|
void SetEGApalette();
|
||||||
|
void CreatePaletteFromData(byte *paletteData, sciPalette *paletteOut);
|
||||||
|
bool SetResPalette(int16 resourceNo, int16 flag);
|
||||||
|
void SetPalette(sciPalette *sciPal, int16 flag);
|
||||||
|
void MergePalettes(sciPalette*pFrom, sciPalette*pTo, uint16 flag);
|
||||||
|
uint16 MatchColor(sciPalette*pPal, byte r, byte g, byte b);
|
||||||
|
void SetCLUT(sciPalette*pal);
|
||||||
|
void GetCLUT(sciPalette*pal);
|
||||||
|
|
||||||
|
sciPort *SetPort(sciPort *port);
|
||||||
|
sciPort *GetPort();
|
||||||
|
void SetOrigin(int16 left, int16 top);
|
||||||
|
void MoveTo(int16 left, int16 top);
|
||||||
|
void Move(int16 left, int16 top);
|
||||||
|
void SetFont(int16 fontId);
|
||||||
|
void OpenPort(sciPort *port);
|
||||||
|
void PenColor(int16 color);
|
||||||
|
void PenMode(int16 mode);
|
||||||
|
void TextFace(int16 textFace);
|
||||||
|
int16 GetPointSize(void);
|
||||||
|
int16 GetFontId();
|
||||||
|
SciGUIfont *GetFont();
|
||||||
|
|
||||||
|
void ClearScreen(byte color = 255);
|
||||||
|
void InvertRect(const Common::Rect &rect);
|
||||||
|
void EraseRect(const Common::Rect &rect);
|
||||||
|
void PaintRect(const Common::Rect &rect);
|
||||||
|
void FillRect(const Common::Rect &rect, int16 arg2, byte clrPen, byte clrBack = 0, byte bControl = 0);
|
||||||
|
void FrameRect(const Common::Rect &rect);
|
||||||
|
void OffsetRect(Common::Rect &r);
|
||||||
|
|
||||||
|
byte CharHeight(int16 ch);
|
||||||
|
byte CharWidth(int16 ch);
|
||||||
|
int16 TextWidth(const char*text, int16 from, int16 len);
|
||||||
|
int16 StringWidth(const char*str) {
|
||||||
|
return TextWidth(str, 0, (int16)strlen(str));
|
||||||
|
}
|
||||||
|
void ClearChar(int16 chr);
|
||||||
|
void DrawChar(int16 chr);
|
||||||
|
void StdChar(int16 chr);
|
||||||
|
SCILanguage getSCILanguage();
|
||||||
|
char* StrSplit(char*buff, const char*msg, const char*fmt);
|
||||||
|
char* getIntlString(char*buff, const char*msg, const char*fmt, SCILanguage lang, SCILanguage prop);
|
||||||
|
int16 TextSize(Common::Rect &rect, const char *str, int16 fontId, int16 maxwidth);
|
||||||
|
int16 GetLongest(const char *str, int16 maxwidth);
|
||||||
|
void DrawText(const char *str, int16 from, int16 len);
|
||||||
|
void ShowText(const char *str, int16 from, int16 len);
|
||||||
|
void ShowString(const char *str) {
|
||||||
|
ShowText(str, 0, (int16)strlen(str));
|
||||||
|
}
|
||||||
|
void DrawString(const char *str) {
|
||||||
|
DrawText(str, 0, (int16)strlen(str));
|
||||||
|
}
|
||||||
|
void TextBox(const char *str, int16 bshow, const Common::Rect &rect, int16 align, int16 fontId);
|
||||||
|
void ShowBits(const Common::Rect &r, uint16 flags);
|
||||||
|
sciMemoryHandle SaveBits(const Common::Rect &rect, byte screenFlags);
|
||||||
|
void RestoreBits(sciMemoryHandle memoryHandle);
|
||||||
|
|
||||||
|
void Draw_Line(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control);
|
||||||
|
void Draw_Horiz(int16 left, int16 right, int16 top, byte flag, byte color, byte prio, byte control);
|
||||||
|
void Draw_Vert(int16 top, int16 bottom, int16 left, byte flag, byte color, byte prio, byte control);
|
||||||
|
void Draw_Box(Common::Rect box, byte color, byte prio, byte control);
|
||||||
|
void Draw_TexturedBox(Common::Rect box, byte color, byte prio, byte control, byte texture);
|
||||||
|
void Draw_Circle(Common::Rect box, byte size, byte color, byte prio, byte control);
|
||||||
|
void Draw_TexturedCircle(Common::Rect box, byte size, byte color, byte prio, byte control, byte texture);
|
||||||
|
void Draw_Pattern(int16 x, int16 y, byte pic_color, byte pic_priority, byte pic_control, byte code, byte texture);
|
||||||
|
void Pic_Fill(int16 x, int16 y, byte color, byte prio, byte control);
|
||||||
|
|
||||||
|
void drawPicture(sciResourceId pictureId, uint16 style, bool addToFlag, sciResourceId paletteId);
|
||||||
|
void drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, byte priority, uint16 paletteNo);
|
||||||
|
|
||||||
|
void animatePalette(byte fromColor, byte toColor, int speed);
|
||||||
|
|
||||||
|
sciPort *_menuPort;
|
||||||
|
uint32 _sysTicks;
|
||||||
|
int32 _sysSpeed; // ticker timer in ms
|
||||||
|
sciPalette _sysPalette;
|
||||||
|
|
||||||
|
uint16 _resolutionWidth;
|
||||||
|
uint16 _resolutionHeight;
|
||||||
|
uint _resolutionPixels;
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIscreen *_screen;
|
||||||
|
|
||||||
|
Common::Rect _bounds;
|
||||||
|
sciPort *_mainPort;
|
||||||
|
sciPort *_curPort;
|
||||||
|
// byte *_visualScreen;
|
||||||
|
// byte *_pcSeg;
|
||||||
|
uint16 _clrPowers[256];
|
||||||
|
|
||||||
|
byte bMapColors;
|
||||||
|
sciPalette *pPicPal;
|
||||||
|
Common::Array<sciPalSched> _palSchedules;
|
||||||
|
|
||||||
|
SciGUIfont *_font;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
150
engines/sci/gui/gui_helpers.h
Normal file
150
engines/sci/gui/gui_helpers.h
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/rect.h"
|
||||||
|
#include "sci/engine/vm_types.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
typedef int sciResourceId; // is a resource-number and -1 means no parameter given
|
||||||
|
typedef reg_t sciMemoryHandle;
|
||||||
|
typedef uint16 SCIHANDLE;
|
||||||
|
|
||||||
|
struct sciNode {
|
||||||
|
SCIHANDLE next; // heap handle to next node
|
||||||
|
SCIHANDLE prev; // heap handle to data
|
||||||
|
uint16 key; // maybe also a heap handle
|
||||||
|
};
|
||||||
|
struct sciNode1 : sciNode {
|
||||||
|
uint16 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// sciPort and sciWnd need to be binary identical, so if you change anything in one, you have to change it in the other one
|
||||||
|
// as well!
|
||||||
|
struct sciPort {
|
||||||
|
sciNode node; // node struct for list operations
|
||||||
|
int16 top, left;
|
||||||
|
Common::Rect rect;
|
||||||
|
int16 curTop, curLeft;
|
||||||
|
int16 fontH;
|
||||||
|
sciResourceId fontId;
|
||||||
|
int16 textFace, penClr, backClr;
|
||||||
|
int16 penMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciWnd {
|
||||||
|
// begins like sciPort (needs to be binary identical!!)
|
||||||
|
sciNode node; // node struct for list operations
|
||||||
|
int16 top, left;
|
||||||
|
Common::Rect rect;
|
||||||
|
int16 curTop, curLeft;
|
||||||
|
int16 fontH;
|
||||||
|
sciResourceId fontId;
|
||||||
|
int16 textFace, penClr, backClr;
|
||||||
|
int16 penMode;
|
||||||
|
// window specific members
|
||||||
|
Common::Rect rect0; // client area of window
|
||||||
|
Common::Rect rect1; // total area of window including borders
|
||||||
|
uint16 wndStyle;
|
||||||
|
uint16 uSaveFlag;
|
||||||
|
reg_t hSaved1;
|
||||||
|
reg_t hSaved2;
|
||||||
|
SCIHANDLE hTitle;
|
||||||
|
bool bDrawed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciCast {
|
||||||
|
sciNode node;
|
||||||
|
uint16 view;
|
||||||
|
uint16 loop;
|
||||||
|
uint16 cel;
|
||||||
|
uint16 z;
|
||||||
|
uint16 pal;
|
||||||
|
SCIHANDLE hSaved;
|
||||||
|
Common::Rect rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciColor {
|
||||||
|
byte used;
|
||||||
|
byte r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciPalette {
|
||||||
|
byte mapping[256];
|
||||||
|
uint32 timestamp;
|
||||||
|
sciColor colors[256];
|
||||||
|
byte intencity[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciPalSched {
|
||||||
|
byte from;
|
||||||
|
uint32 schedule;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STUB(str) debug("STUB: '%s' at file %s line %d",str,__FILE__,__LINE__)
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: The following feature enums and macros should be reconsidered.
|
||||||
|
// The way they are done right now is highly error prone.
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FTR_WINDOWMGR_SCI0 = (0<<0), // SCI0 based window manager
|
||||||
|
FTR_WINDOWMGR_SCI1 = (1<<0), // SCI1 based window manager
|
||||||
|
FTR_CAN_BEHERE = (0<<1), // Kernel77 is kCanBeHere (SCI0)
|
||||||
|
FTR_CANT_BEHERE = (1<<1), // Kernel77 is kCantBeHere(SCI1)
|
||||||
|
FTR_SOUND_SCI0 = (0<<2), // SCI0 Sound functions
|
||||||
|
FTR_SOUND_SCI01 = (1<<2), // SCI0+ Sound functions
|
||||||
|
FTR_SOUND_SCI1 = (2<<2), // SCI1 Sound functions
|
||||||
|
FTR_SHOWPIC_SCI0 = (0<<4), // SCI0 ShowPic (44 effect codes)
|
||||||
|
FTR_SHOWPIC_SCI1 = (1<<4), // SCI1 ShowPic (15 effect codes)
|
||||||
|
FTR_GL_ANIMATE = (1<<5) // Animate can be paused by global flag
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GETFTR_WINDOWMGR(x) (x & 0x00000001)
|
||||||
|
#define GETFTR_CANBEHERE(x) (x & 0x00000002)
|
||||||
|
#define GETFTR_SOUND(x) (x & 0x0000000C)
|
||||||
|
#define GETFTR_SHOWPIC(x) (x & 0x00000010)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GFX_STOPUPDATE = 0x01,
|
||||||
|
GFX_VIEWUPDATED = 0x02,
|
||||||
|
GFX_NOUPDATE = 0x04,
|
||||||
|
GFX_HIDDEN = 0x08,
|
||||||
|
GFX_FIXEDPRIO=0x10,
|
||||||
|
GFX_ALWAYSUPDATE = 0x20,
|
||||||
|
GFX_FORCEUPDATE = 0x40,
|
||||||
|
GFX_REMOVEVIEW = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SCILanguage{
|
||||||
|
kLangNone = 0,
|
||||||
|
kLangEnglish = 1,
|
||||||
|
kLangFrench = 33,
|
||||||
|
kLangSpanish = 34,
|
||||||
|
kLangItalian = 39,
|
||||||
|
kLangGerman = 49
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
373
engines/sci/gui/gui_memmgr.cpp
Normal file
373
engines/sci/gui/gui_memmgr.cpp
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/gui/gui_helpers.h"
|
||||||
|
#include "sci/gui/gui_memmgr.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
static tagHandle *pHandles = 0;
|
||||||
|
static int16 nHandles = 0;
|
||||||
|
static byte *_heap = 0;
|
||||||
|
SCIHANDLE _firstfree = 0;
|
||||||
|
Common::HashMap<HEAPHANDLE, tagHeapInfo> heapInfo;
|
||||||
|
#define HEAP_BOTTOM 1000
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
void FreeMem(void) {
|
||||||
|
// deleting handles
|
||||||
|
if (pHandles) {
|
||||||
|
for (uint16 i = 0; i < nHandles; i++)
|
||||||
|
hunkDisposeHandle(i);
|
||||||
|
delete[] pHandles;
|
||||||
|
pHandles = 0;
|
||||||
|
}
|
||||||
|
// deleting heap
|
||||||
|
if (_heap) {
|
||||||
|
delete[] _heap;
|
||||||
|
_heap = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
bool InitMem(int16 max_handles) {
|
||||||
|
// heap
|
||||||
|
_heap = new byte[HEAP_SIZE];
|
||||||
|
memset(_heap, 0x55, HEAP_SIZE);
|
||||||
|
_firstfree = HEAP_START;
|
||||||
|
heapSetBlockSize(_firstfree, HEAP_SIZE - 1 - HEAP_START);
|
||||||
|
heapSetBlockNext(_firstfree, (SCIHANDLE)(HEAP_SIZE - 1));
|
||||||
|
//hunk
|
||||||
|
pHandles = new tagHandle[max_handles];
|
||||||
|
if (pHandles) {
|
||||||
|
nHandles = max_handles;
|
||||||
|
memset(pHandles, 0, sizeof(tagHandle) * max_handles); // zerofy all
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
SCIHANDLE hunkNeedHandle(uint16 size, uint32 resId) {
|
||||||
|
SCIHANDLE newh = 0;
|
||||||
|
// see if there is an empty handle available
|
||||||
|
for (int16 i = 1; i < nHandles; i++)
|
||||||
|
if (pHandles[i].ptr == 0) {
|
||||||
|
newh = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if unused handle was found - allocate memory and return it
|
||||||
|
if (newh == nHandles)
|
||||||
|
return 0;
|
||||||
|
pHandles[newh].ptr = (byte*)malloc(size);
|
||||||
|
assert(pHandles[newh].ptr);
|
||||||
|
if (pHandles[newh].ptr) {
|
||||||
|
pHandles[newh].size = size;
|
||||||
|
pHandles[newh].resId = resId;
|
||||||
|
debug(
|
||||||
|
5,
|
||||||
|
" MemMgr: Requested %6db for res %08X, allocated handle %04X",
|
||||||
|
size, resId, newh);
|
||||||
|
return newh;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
void hunkDisposeHandle(SCIHANDLE handle) {
|
||||||
|
// if (handle > 0 && handle < nHandles && pHandles[handle].ptr) {
|
||||||
|
// debug(
|
||||||
|
// 5,
|
||||||
|
// " MemMgr: disposing handle 0x%04X, size=%8db, associated res %08X",
|
||||||
|
// handle, pHandles[handle].size, pHandles[handle].resId);
|
||||||
|
// free(pHandles[handle].ptr);
|
||||||
|
// pHandles[handle].ptr = 0;
|
||||||
|
// // deleting associated resource handler
|
||||||
|
// // Check that this don't fail on delete as ResGetLoaded could return 0;
|
||||||
|
// if (pHandles[handle].resId != 0xFFFFFFFF)
|
||||||
|
// delete g_sci->ResMgr.ResGetLoaded(pHandles[handle].resId);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
byte *hunk2Ptr(SCIHANDLE handle) {
|
||||||
|
if (handle > 0 && handle < nHandles && pHandles[handle].ptr)
|
||||||
|
return (byte *)pHandles[handle].ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
SCIHANDLE ptr2hunk(byte *ptr) {
|
||||||
|
for (int i = 0; i < nHandles; i++) {
|
||||||
|
if (ptr >= pHandles[i].ptr && ptr <= pHandles[i].ptr + pHandles[i].size)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
uint32 hunkHandleSize(SCIHANDLE handle) {
|
||||||
|
if (handle > 0 && handle < nHandles && pHandles[handle].ptr)
|
||||||
|
return pHandles[handle].size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
// int16 hunkResourceNum(SCIHANDLE handle) {
|
||||||
|
// if (handle > 0 && handle < nHandles && pHandles[handle].ptr)
|
||||||
|
// return RES_ID2NUM(pHandles[handle].resId);
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
void hunkDump() {
|
||||||
|
debug("\nMemMgr: Hunk dump:");
|
||||||
|
uint32 size = 0;
|
||||||
|
for (int i = 0; i < nHandles; i++)
|
||||||
|
if (pHandles[i].ptr) {
|
||||||
|
debug(" %04X, size=%8db, associated res %08X", i,
|
||||||
|
pHandles[i].size, pHandles[i].resId);
|
||||||
|
size += pHandles[i].size;
|
||||||
|
}
|
||||||
|
debug("Total memory allocated: %db", size);
|
||||||
|
debug("End dump");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 hunkUsed() {
|
||||||
|
uint32 size = 0;
|
||||||
|
for (int i = 0; i < nHandles; i++)
|
||||||
|
if (pHandles[i].ptr)
|
||||||
|
size += pHandles[i].size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
//----------------------
|
||||||
|
// HEAP
|
||||||
|
//----------------------
|
||||||
|
//---------------------------------------------
|
||||||
|
// TODO : make sure that STRING, STACK and SCRIPT DATA is never allocated below HEAP_BOTTOM=1000
|
||||||
|
// otherwise it will cause problems with kernel string fuctions that assumes that anything below 1000 is res number
|
||||||
|
HEAPHANDLE heapNewPtr(uint16 size, kDataType type, const char *info) {
|
||||||
|
if (size == 0)
|
||||||
|
warning("Zero Heap Allocation Request!");
|
||||||
|
|
||||||
|
HEAPHANDLE ptr, prev, next;
|
||||||
|
ptr = prev = _firstfree;
|
||||||
|
// 2 bytes block header header + block size must be odd
|
||||||
|
size += 2 + (size & 1);
|
||||||
|
// looking for an empty block to use
|
||||||
|
uint16 blocksize;
|
||||||
|
bool bBottomSafe = !(type == kDataString || type == kDataUnknown);
|
||||||
|
|
||||||
|
while (ptr < HEAP_SIZE - 1) {
|
||||||
|
blocksize = heapGetBlockSize(ptr);
|
||||||
|
next = heapGetBlockNext(ptr);
|
||||||
|
if (blocksize >= size) {
|
||||||
|
if (bBottomSafe || (!bBottomSafe && ptr > HEAP_BOTTOM)) {
|
||||||
|
if (blocksize <= size + 4) { // use all block
|
||||||
|
size = blocksize;
|
||||||
|
heapSetBlockNext(prev, next);
|
||||||
|
} else { // split block in 2 blocks
|
||||||
|
HEAPHANDLE newblock = ptr + size;
|
||||||
|
heapSetBlockNext(prev, newblock);
|
||||||
|
heapSetBlockSize(newblock, blocksize - size);
|
||||||
|
heapSetBlockNext(newblock, next);
|
||||||
|
next = newblock;
|
||||||
|
}
|
||||||
|
// setting allocated block
|
||||||
|
heapSetBlockSize(ptr, size);
|
||||||
|
// updating firstfree pointer
|
||||||
|
if (ptr == _firstfree)
|
||||||
|
_firstfree = next;
|
||||||
|
setHeapInfo(ptr, type, info);
|
||||||
|
return ptr;
|
||||||
|
} //if (bBottomSafe || (!bBottomSafe && ptr>HEAP_BOTTOM))
|
||||||
|
else { // !bottomsafe && ptr < HEAP_BOTTOM
|
||||||
|
if (blocksize + ptr - HEAP_BOTTOM >= size) {
|
||||||
|
// splitting the block into 3 parts
|
||||||
|
// [2][ptr...999] [2][1002...1000+size-1] [2][1002+size...ptr+blocksize]
|
||||||
|
// free returned free
|
||||||
|
heapSetBlockSize(ptr, HEAP_BOTTOM-ptr + 2);
|
||||||
|
heapSetBlockSize(HEAP_BOTTOM+2, size);
|
||||||
|
heapSetBlockSize(HEAP_BOTTOM+2 + size, blocksize - size
|
||||||
|
- (HEAP_BOTTOM-ptr + 2));
|
||||||
|
|
||||||
|
heapSetBlockNext(HEAP_BOTTOM+2 + size, next);
|
||||||
|
heapSetBlockNext(ptr, HEAP_BOTTOM+2 + size);
|
||||||
|
setHeapInfo(HEAP_BOTTOM+2, type, info);
|
||||||
|
return HEAP_BOTTOM + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // if (blocksize >= size)
|
||||||
|
// block too small - moving to next one
|
||||||
|
prev = ptr;
|
||||||
|
ptr = next;
|
||||||
|
}
|
||||||
|
// allocation error - out of heap
|
||||||
|
warning("Out of heap space");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//--------------------------------------------
|
||||||
|
void heapDisposePtr(HEAPHANDLE handle) {
|
||||||
|
HEAPHANDLE prev, next;
|
||||||
|
prev = next = _firstfree;
|
||||||
|
// searching for prev and next free blocks (before & after deleted block)
|
||||||
|
while (next < handle) {
|
||||||
|
prev = next;
|
||||||
|
next = heapGetBlockNext(prev);
|
||||||
|
}
|
||||||
|
// if deleted block is before 1st free space then it'll be 1st free space
|
||||||
|
if (handle < _firstfree) {
|
||||||
|
next = _firstfree;
|
||||||
|
_firstfree = handle;
|
||||||
|
} else
|
||||||
|
heapSetBlockNext(prev, handle);
|
||||||
|
|
||||||
|
heapSetBlockNext(handle, next);
|
||||||
|
//Try to merge with previous
|
||||||
|
if (prev + heapGetBlockSize(prev) == handle) {
|
||||||
|
heapSetBlockSize(prev, heapGetBlockSize(prev)
|
||||||
|
+ heapGetBlockSize(handle));
|
||||||
|
heapSetBlockNext(prev, next);
|
||||||
|
handle = prev;
|
||||||
|
}
|
||||||
|
//Try to merge with next
|
||||||
|
if (handle + heapGetBlockSize(handle) == next && next != (HEAP_SIZE - 1)) {
|
||||||
|
heapSetBlockSize(handle, heapGetBlockSize(handle) + heapGetBlockSize(
|
||||||
|
next));
|
||||||
|
heapSetBlockNext(handle, heapGetBlockNext(next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//-------------------------------------
|
||||||
|
uint16 heapFreeSize() {
|
||||||
|
HEAPHANDLE free = _firstfree;
|
||||||
|
uint16 szFree = 0;
|
||||||
|
while (free < HEAP_SIZE - 1) {
|
||||||
|
int size = heapGetBlockSize(free);
|
||||||
|
free = heapGetBlockNext(free);
|
||||||
|
szFree += size;
|
||||||
|
}
|
||||||
|
return szFree;
|
||||||
|
}
|
||||||
|
//-------------------------------------
|
||||||
|
uint16 heapLargestFreeSize() {
|
||||||
|
HEAPHANDLE free = _firstfree;
|
||||||
|
uint16 maxFree = 0;
|
||||||
|
while (free < HEAP_SIZE - 1) {
|
||||||
|
int size = heapGetBlockSize(free);
|
||||||
|
free = heapGetBlockNext(free);
|
||||||
|
if (size > maxFree)
|
||||||
|
maxFree = size;
|
||||||
|
}
|
||||||
|
return maxFree ? maxFree - 2 : 0;
|
||||||
|
}
|
||||||
|
//-------------------------------------
|
||||||
|
void heapDump() {
|
||||||
|
debug("\nMemMgr:Heap dump:");
|
||||||
|
HEAPHANDLE ptr = HEAP_START;
|
||||||
|
HEAPHANDLE free = _firstfree;
|
||||||
|
|
||||||
|
uint16 szFree = 0, szUsed = 0;
|
||||||
|
while (ptr < HEAP_SIZE - 1) {
|
||||||
|
int size = heapGetBlockSize(ptr);
|
||||||
|
if (ptr == free) {
|
||||||
|
free = heapGetBlockNext(free);
|
||||||
|
debug(" %04X %6u size:%6d FREE next=%04X", ptr, ptr,
|
||||||
|
heapGetDataSize(ptr), free);
|
||||||
|
szFree += size;
|
||||||
|
} else {
|
||||||
|
debug(" %04X %6u size:%6d USED", ptr, ptr, heapGetDataSize(ptr));
|
||||||
|
szUsed += size;
|
||||||
|
}
|
||||||
|
ptr += size;
|
||||||
|
}
|
||||||
|
debug("Total %db used, %db free\nEnd Dump", szUsed, szFree);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
inline byte *heap2Ptr(HEAPHANDLE ptr) {
|
||||||
|
return (ptr >= HEAP_START) ? (byte *)(_heap + ptr) : NULL;
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
HEAPHANDLE ptr2heap(byte *ptr) {
|
||||||
|
return ptr > _heap && ptr < (_heap + HEAP_SIZE) ? (HEAPHANDLE)(ptr - _heap)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
uint16 heapGetBlockSize(HEAPHANDLE ptr) {
|
||||||
|
return READ_UINT16(_heap + ptr - 2);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
uint16 heapGetDataSize(HEAPHANDLE ptr) {
|
||||||
|
return heapGetBlockSize(ptr) - 2;
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
void heapFillPtr(HEAPHANDLE ptr, byte filler) {
|
||||||
|
memset(heap2Ptr(ptr), filler, heapGetDataSize(ptr));
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
void heapClearPtr(HEAPHANDLE ptr) {
|
||||||
|
heapFillPtr(ptr, 0);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
void heapSetBlockSize(HEAPHANDLE ptr, uint16 nbytes) {
|
||||||
|
WRITE_UINT16(_heap + ptr - 2, nbytes);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
HEAPHANDLE heapGetBlockNext(HEAPHANDLE ptr) {
|
||||||
|
return READ_UINT16(_heap + ptr);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
void heapSetBlockNext(HEAPHANDLE ptr, SCIHANDLE next) {
|
||||||
|
WRITE_UINT16(_heap + ptr, next);
|
||||||
|
}
|
||||||
|
//----------------------------
|
||||||
|
void heapDisposePtr(byte *ptr) {
|
||||||
|
heapDisposePtr(ptr - _heap);
|
||||||
|
}
|
||||||
|
//---------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
void setHeapInfo(HEAPHANDLE hnd, kDataType type, const char *szinfo) {
|
||||||
|
tagHeapInfo info = { kDataUnknown, 0 };
|
||||||
|
info.type = type;
|
||||||
|
if (szinfo)
|
||||||
|
strncpy(info.info, szinfo, 20);
|
||||||
|
heapInfo.setVal(hnd, info);
|
||||||
|
}
|
||||||
|
//--------------------------------
|
||||||
|
bool saveMemState(Common::OutSaveFile *pFile) {
|
||||||
|
pFile->writeString("MEMORY\n");
|
||||||
|
// saving heap
|
||||||
|
pFile->write(_heap, HEAP_SIZE);
|
||||||
|
pFile->writeUint16LE(_firstfree);
|
||||||
|
// TODO : process and write hunk handles
|
||||||
|
//pFile->writeString("HUNK\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//--------------------------------
|
||||||
|
bool restoreMemState(Common::InSaveFile *pFile) {
|
||||||
|
if (pFile->readLine() != "MEMORY")
|
||||||
|
return false;
|
||||||
|
pFile->read(_heap, HEAP_SIZE);
|
||||||
|
_firstfree = pFile->readUint16LE();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
}// end of namespace SCI
|
123
engines/sci/gui/gui_memmgr.h
Normal file
123
engines/sci/gui/gui_memmgr.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCI_MEMMGR_H
|
||||||
|
#define SCI_MEMMGR_H
|
||||||
|
|
||||||
|
#include "common/savefile.h"
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "common/hashmap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Memory management functions for SCI engine;
|
||||||
|
All fuctions are simplified as there is no 16-bit limitations as in
|
||||||
|
original SCI. Although it may cause problems.
|
||||||
|
|
||||||
|
SCI Heap functionality.
|
||||||
|
Heap size is limited to 65535 bytes to be consistent with SCI scripts
|
||||||
|
Free block header is [wBlockSize][wNextFree]
|
||||||
|
Used block header is [wBlockSize][data.....]
|
||||||
|
^-----returned HEAPHANDLE
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
typedef uint16 SCIHANDLE;
|
||||||
|
typedef uint16 HEAPHANDLE;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HEAP_SIZE = 0x10000l,
|
||||||
|
HEAP_START = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tagHandle {
|
||||||
|
byte *ptr; // data pointer
|
||||||
|
uint32 size; // memory block size
|
||||||
|
uint32 resId; // associated resource
|
||||||
|
};
|
||||||
|
//---------------------------------------------
|
||||||
|
// for debugger
|
||||||
|
enum kDataType {
|
||||||
|
kDataUnknown = 0,
|
||||||
|
kDataClass,
|
||||||
|
kDataObject,
|
||||||
|
kDataRect,
|
||||||
|
kDataWindow,
|
||||||
|
kDataPort,
|
||||||
|
kDataString,
|
||||||
|
kDataListHdr,
|
||||||
|
kDataListNode,
|
||||||
|
kDataCast,
|
||||||
|
kDataPalette,
|
||||||
|
kDataScript,
|
||||||
|
kDataFile
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tagHeapInfo {
|
||||||
|
kDataType type;
|
||||||
|
char info[21];
|
||||||
|
};
|
||||||
|
|
||||||
|
void setHeapInfo(HEAPHANDLE hnd, kDataType type, const char *info = 0);
|
||||||
|
|
||||||
|
bool InitMem(int16 max_handles);
|
||||||
|
void FreeMem(void);
|
||||||
|
|
||||||
|
// hunk functions
|
||||||
|
SCIHANDLE hunkNeedHandle(uint16 size, uint32 resId = 0xFFFFFFFF);
|
||||||
|
void hunkDisposeHandle(SCIHANDLE handle);
|
||||||
|
|
||||||
|
byte *hunk2Ptr(SCIHANDLE handle);
|
||||||
|
SCIHANDLE ptr2hunk(byte *ptr);
|
||||||
|
uint32 hunkHandleSize(SCIHANDLE handle);
|
||||||
|
int16 hunkResourceNum(SCIHANDLE handle);
|
||||||
|
void hunkDump();
|
||||||
|
uint32 hunkUsed();
|
||||||
|
|
||||||
|
// heap functions
|
||||||
|
HEAPHANDLE heapNewPtr(uint16 size, kDataType type/*=kDataUnknown*/,
|
||||||
|
const char *info = 0);
|
||||||
|
void heapDisposePtr(HEAPHANDLE handle);
|
||||||
|
void heapDisposePtr(byte *ptr);
|
||||||
|
byte *heap2Ptr(HEAPHANDLE ptr);
|
||||||
|
HEAPHANDLE ptr2heap(byte *ptr);
|
||||||
|
uint16 heapGetBlockSize(HEAPHANDLE ptr);
|
||||||
|
uint16 heapGetDataSize(HEAPHANDLE ptr);
|
||||||
|
void heapFillPtr(HEAPHANDLE ptr, byte filler);
|
||||||
|
void heapClearPtr(HEAPHANDLE ptr);
|
||||||
|
void heapDump();
|
||||||
|
uint16 heapFreeSize();
|
||||||
|
uint16 heapLargestFreeSize();
|
||||||
|
|
||||||
|
void heapSetBlockSize(HEAPHANDLE ptr, uint16 nbytes);
|
||||||
|
HEAPHANDLE heapGetBlockNext(HEAPHANDLE ptr);
|
||||||
|
void heapSetBlockNext(HEAPHANDLE ptr, SCIHANDLE next);
|
||||||
|
|
||||||
|
bool saveMemState(Common::OutSaveFile *pFile);
|
||||||
|
bool restoreMemState(Common::InSaveFile *pFile);
|
||||||
|
|
||||||
|
} // end of namespace SCI
|
||||||
|
|
||||||
|
#endif
|
592
engines/sci/gui/gui_picture.cpp
Normal file
592
engines/sci/gui/gui_picture.cpp
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_screen.h"
|
||||||
|
#include "sci/gui/gui_gfx.h"
|
||||||
|
#include "sci/gui/gui_picture.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUIpicture::SciGUIpicture(OSystem *system, EngineState *state, SciGUIgfx *gfx, SciGUIscreen *screen, sciResourceId resourceId)
|
||||||
|
: _system(system), _s(state), _gfx(gfx), _screen(screen), _resourceId(resourceId) {
|
||||||
|
assert(resourceId != -1);
|
||||||
|
initData(resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUIpicture::~SciGUIpicture() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::initData(sciResourceId resourceId) {
|
||||||
|
_resource = _s->resMan->findResource(ResourceId(kResourceTypePic, resourceId), false);
|
||||||
|
if (!_resource) {
|
||||||
|
error("picture resource %d not found", resourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sciResourceId SciGUIpicture::getResourceId() {
|
||||||
|
return _resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PALETTE_SIZE 1284
|
||||||
|
#define CEL_HEADER_SIZE 7
|
||||||
|
#define EXTRA_MAGIC_SIZE 15
|
||||||
|
|
||||||
|
void SciGUIpicture::draw(uint16 style, bool addToFlag, int16 EGApaletteNo) {
|
||||||
|
_style = style;
|
||||||
|
_addToFlag = addToFlag;
|
||||||
|
_EGApaletteNo = EGApaletteNo;
|
||||||
|
_curPort = _gfx->GetPort();
|
||||||
|
_priority = 0;
|
||||||
|
|
||||||
|
if (READ_LE_UINT16(_resource->data) == 0x26) {
|
||||||
|
// SCI 1.1 picture
|
||||||
|
draw11();
|
||||||
|
} else {
|
||||||
|
// Just directly draw the vector data
|
||||||
|
_gfx->SetEGApalette();
|
||||||
|
drawVectorData(_resource->data, _resource->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::reset() {
|
||||||
|
int16 x, y;
|
||||||
|
for (y = _curPort->top; y < _screen->_height; y++) {
|
||||||
|
for (x = 0; x < _screen->_width; x++) {
|
||||||
|
_screen->Put_Pixel(x, y, SCI_SCREEN_MASK_ALL, 255, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::draw11() {
|
||||||
|
byte *inbuffer = _resource->data;
|
||||||
|
int size = _resource->size;
|
||||||
|
int has_view = READ_LE_UINT16(inbuffer + 4);
|
||||||
|
int vector_data_ptr = READ_LE_UINT16(inbuffer + 16);
|
||||||
|
int vector_size = size - vector_data_ptr;
|
||||||
|
int palette_data_ptr = READ_LE_UINT16(inbuffer + 28);
|
||||||
|
int view_data_ptr = READ_LE_UINT16(inbuffer + 32);
|
||||||
|
int view_size = palette_data_ptr - view_data_ptr;
|
||||||
|
int view_rle_ptr = READ_LE_UINT16(inbuffer + view_data_ptr + 24);
|
||||||
|
int view_pixel_ptr = READ_LE_UINT16(inbuffer + view_data_ptr + 28);
|
||||||
|
byte *view = NULL;
|
||||||
|
sciPalette palette;
|
||||||
|
|
||||||
|
// Create palette and set it
|
||||||
|
_gfx->CreatePaletteFromData(inbuffer + palette_data_ptr, &palette);
|
||||||
|
_gfx->SetPalette(&palette, 2);
|
||||||
|
// drawPalette11(inbuffer + palette_data_ptr);
|
||||||
|
|
||||||
|
// display Cel-data
|
||||||
|
if (has_view) {
|
||||||
|
view = (byte *)malloc(size*2); // is there a way to know how much decoded view-data there will be?
|
||||||
|
if (!view) return;
|
||||||
|
memcpy(view, inbuffer + view_data_ptr, 8);
|
||||||
|
decodeRLE(inbuffer + view_rle_ptr, inbuffer + view_pixel_ptr, view + 8, view_size - 8);
|
||||||
|
drawCel(0, 0, view, size * 2);
|
||||||
|
free(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process vector data
|
||||||
|
// ?? if we process vector data first some things in sq4 dont seem right, but this way we wont get _priority set
|
||||||
|
drawVectorData(inbuffer + vector_data_ptr, vector_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::drawPalette11(byte *data) {
|
||||||
|
int start_color = data[25];
|
||||||
|
int format = data[32];
|
||||||
|
byte *pal_data = &data[37];
|
||||||
|
int colors_nr = READ_LE_UINT16(data + 29);
|
||||||
|
int i;
|
||||||
|
sciPalette palette = {0};
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case SCI_PAL_FORMAT_VARIABLE_FLAGS:
|
||||||
|
for (i = start_color; i < start_color + colors_nr; i ++) {
|
||||||
|
palette.colors[i].used = pal_data[0];
|
||||||
|
palette.colors[i].r = pal_data[1];
|
||||||
|
palette.colors[i].g = pal_data[2];
|
||||||
|
palette.colors[i].b = pal_data[3];
|
||||||
|
pal_data += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCI_PAL_FORMAT_CONSTANT_FLAGS:
|
||||||
|
for (i = start_color; i < start_color + colors_nr; i ++) {
|
||||||
|
palette.colors[i].used = 1;
|
||||||
|
palette.colors[i].r = pal_data[0];
|
||||||
|
palette.colors[i].g = pal_data[1];
|
||||||
|
palette.colors[i].b = pal_data[2];
|
||||||
|
pal_data += 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_gfx->SetPalette(&palette, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::decodeRLE(byte *rledata, byte *pixeldata, byte *outbuffer, int size) {
|
||||||
|
int pos = 0;
|
||||||
|
byte nextbyte;
|
||||||
|
byte *rd = rledata;
|
||||||
|
byte *ob = outbuffer;
|
||||||
|
byte *pd = pixeldata;
|
||||||
|
|
||||||
|
while (pos < size) {
|
||||||
|
nextbyte = *(rd++);
|
||||||
|
*(ob++) = nextbyte;
|
||||||
|
pos ++;
|
||||||
|
switch (nextbyte&0xC0) {
|
||||||
|
case 0x40 :
|
||||||
|
case 0x00 :
|
||||||
|
memcpy(ob, pd, nextbyte);
|
||||||
|
pd += nextbyte;
|
||||||
|
ob += nextbyte;
|
||||||
|
pos += nextbyte;
|
||||||
|
break;
|
||||||
|
case 0xC0 :
|
||||||
|
break;
|
||||||
|
case 0x80 :
|
||||||
|
nextbyte = *(pd++);
|
||||||
|
*(ob++) = nextbyte;
|
||||||
|
pos ++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::drawCel(int16 x, int16 y, byte *pdata, int size) {
|
||||||
|
byte* pend = pdata + size;
|
||||||
|
uint16 width = READ_LE_UINT16(pdata + 0);
|
||||||
|
uint16 height = READ_LE_UINT16(pdata + 2);
|
||||||
|
signed char dx = *(pdata + 4);
|
||||||
|
signed char dy = *(pdata + 5);
|
||||||
|
byte priority = _addToFlag ? _priority : 0;
|
||||||
|
byte clr = *(pdata + 6);
|
||||||
|
if (dx || dy || width != 320)
|
||||||
|
debug("Warning: embedded picture cel has width=%d dx=%d dy=%d", width, dx, dy);
|
||||||
|
byte *ptr = pdata + 8; // offset to data
|
||||||
|
|
||||||
|
y += _curPort->top;
|
||||||
|
|
||||||
|
uint16 j = 0, lasty = MIN<int16>(height + y, _curPort->rect.bottom) + _curPort->top;
|
||||||
|
byte b, brun;
|
||||||
|
|
||||||
|
while (y < lasty && ptr < pend) {
|
||||||
|
b = *ptr++;
|
||||||
|
brun = b & 0x3F; // bytes run length on this step
|
||||||
|
switch (b & 0xC0) {
|
||||||
|
case 0: // copy bytes as-is but skip transparent ones
|
||||||
|
while (brun-- && y < lasty && ptr < pend) {
|
||||||
|
if ((b = *ptr++) != clr && priority >= _screen->Get_Priority(x, y)) {
|
||||||
|
_screen->Put_Pixel(x, y, 3, b, priority, 0);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
if (x >= _screen->_width) {
|
||||||
|
x -= _screen->_width; y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x80: // fill with color
|
||||||
|
b = *ptr++;
|
||||||
|
while (brun-- && y < lasty) {
|
||||||
|
if (priority >= _screen->Get_Priority(x, y)) {
|
||||||
|
_screen->Put_Pixel(x, y, 3, b, priority, 0);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
if (x >= _screen->_width) {
|
||||||
|
x -= _screen->_width; y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xC0: // fill with transparent - skip
|
||||||
|
x += brun;
|
||||||
|
if (x >= _screen->_width) {
|
||||||
|
x -= _screen->_width; y++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::drawCelAmiga(int16 x, int16 y, byte *pdata, int size) {
|
||||||
|
byte* pend = pdata + size;
|
||||||
|
uint16 width = READ_LE_UINT16(pdata + 0);
|
||||||
|
uint16 height = READ_LE_UINT16(pdata + 2);
|
||||||
|
signed char dx = *(pdata + 4);
|
||||||
|
signed char dy = *(pdata + 5);
|
||||||
|
byte priority = _addToFlag ? _priority : 0;
|
||||||
|
//byte clr = *(pdata + 8);
|
||||||
|
if (dx || dy || width != 320)
|
||||||
|
debug("Warning : cel have w=%d dx=%d dy=%d", width, dx, dy);
|
||||||
|
byte *ptr = pdata + 8; // offset to data
|
||||||
|
|
||||||
|
y += _curPort->top;
|
||||||
|
|
||||||
|
uint16 j = 0, lasty = MIN<int16>(height + y, _curPort->rect.bottom) + _curPort->top;
|
||||||
|
byte op, col, bytes;
|
||||||
|
while (y < lasty && ptr < pend) {
|
||||||
|
op = *ptr++;
|
||||||
|
if (op & 0x07) {
|
||||||
|
bytes = op & 0x07;
|
||||||
|
col = op >> 3;
|
||||||
|
while (bytes-- && y < lasty) {
|
||||||
|
if (priority >= _screen->Get_Priority(x, y)) {
|
||||||
|
_screen->Put_Pixel(x, y, 3, col, priority, 0);
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
if (x >= _screen->_width) {
|
||||||
|
x -= _screen->_width; y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bytes = op >> 3;
|
||||||
|
x += bytes;
|
||||||
|
if (x >= _screen->_width) {
|
||||||
|
x -= _screen->_width; y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PIC_OP_SET_COLOR = 0xf0,
|
||||||
|
PIC_OP_DISABLE_VISUAL = 0xf1,
|
||||||
|
PIC_OP_SET_PRIORITY = 0xf2,
|
||||||
|
PIC_OP_DISABLE_PRIORITY = 0xf3,
|
||||||
|
PIC_OP_SHORT_PATTERNS = 0xf4,
|
||||||
|
PIC_OP_MEDIUM_LINES = 0xf5,
|
||||||
|
PIC_OP_LONG_LINES = 0xf6,
|
||||||
|
PIC_OP_SHORT_LINES = 0xf7,
|
||||||
|
PIC_OP_FILL = 0xf8,
|
||||||
|
PIC_OP_SET_PATTERN = 0xf9,
|
||||||
|
PIC_OP_ABSOLUTE_PATTERN = 0xfa,
|
||||||
|
PIC_OP_SET_CONTROL = 0xfb,
|
||||||
|
PIC_OP_DISABLE_CONTROL = 0xfc,
|
||||||
|
PIC_OP_MEDIUM_PATTERNS = 0xfd,
|
||||||
|
PIC_OP_OPX = 0xfe,
|
||||||
|
PIC_OP_TERMINATE = 0xff
|
||||||
|
};
|
||||||
|
#define PIC_OP_FIRST PIC_OP_SET_COLOR
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PIC_OPX_SCI0_SET_PALETTE_ENTRIES = 0,
|
||||||
|
PIC_OPX_SCI0_SET_PALETTE = 1,
|
||||||
|
PIC_OPX_SCI0_MONO0 = 2,
|
||||||
|
PIC_OPX_SCI0_MONO1 = 3,
|
||||||
|
PIC_OPX_SCI0_MONO2 = 4,
|
||||||
|
PIC_OPX_SCI0_MONO3 = 5,
|
||||||
|
PIC_OPX_SCI0_MONO4 = 6,
|
||||||
|
PIC_OPX_SCI0_EMBEDDED_VIEW = 7,
|
||||||
|
PIC_OPX_SCI0_SET_PRIORITY_TABLE = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PIC_OPX_SCI1_SET_PALETTE_ENTRIES = 0,
|
||||||
|
PIC_OPX_SCI1_EMBEDDED_VIEW = 1,
|
||||||
|
PIC_OPX_SCI1_SET_PALETTE = 2,
|
||||||
|
PIC_OPX_SCI1_PRIORITY_TABLE_EQDIST = 3,
|
||||||
|
PIC_OPX_SCI1_PRIORITY_TABLE_EXPLICIT = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PIC_EGAPALETTE_COUNT 4
|
||||||
|
#define PIC_EGAPALETTE_SIZE 40
|
||||||
|
#define PIC_EGAPALETTE_TOTALSIZE PIC_EGAPALETTE_COUNT*PIC_EGAPALETTE_SIZE
|
||||||
|
|
||||||
|
const byte vector_defaultEGApalette[PIC_EGAPALETTE_SIZE] = {
|
||||||
|
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||||
|
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x88,
|
||||||
|
0x88, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88,
|
||||||
|
0x88, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||||
|
0x08, 0x91, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x88
|
||||||
|
};
|
||||||
|
|
||||||
|
void SciGUIpicture::drawVectorData(byte *data, int dataSize) {
|
||||||
|
byte pic_op;
|
||||||
|
byte pic_color = 0, pic_priority = 0x0F, pic_control = 0x0F;
|
||||||
|
int16 x = 0, y = 0, oldx, oldy;
|
||||||
|
byte EGApalette = 0;
|
||||||
|
byte EGAindex = 0;
|
||||||
|
byte EGApalettes[PIC_EGAPALETTE_TOTALSIZE] = {0};
|
||||||
|
bool EGAmapping = false;
|
||||||
|
int curPos = 0;
|
||||||
|
uint16 size;
|
||||||
|
byte byte;
|
||||||
|
int i;
|
||||||
|
sciPalette palette = {0};
|
||||||
|
int16 pattern_Code = 0, pattern_Texture = 0;
|
||||||
|
bool sci1 = false;
|
||||||
|
|
||||||
|
if (_EGApaletteNo >= PIC_EGAPALETTE_COUNT)
|
||||||
|
_EGApaletteNo = 0;
|
||||||
|
|
||||||
|
if (getSciVersion() >= SCI_VERSION_1_EGA)
|
||||||
|
sci1 = true;
|
||||||
|
|
||||||
|
for (i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE)
|
||||||
|
memcpy(&EGApalettes[i], &vector_defaultEGApalette, sizeof(vector_defaultEGApalette));
|
||||||
|
|
||||||
|
// Drawing
|
||||||
|
while (curPos < dataSize) {
|
||||||
|
warning("%X at %d", data[curPos], curPos);
|
||||||
|
switch (pic_op = data[curPos++]) {
|
||||||
|
case PIC_OP_SET_COLOR:
|
||||||
|
byte = data[curPos++];
|
||||||
|
pic_color = EGAmapping ? EGApalettes[byte] : byte;
|
||||||
|
break;
|
||||||
|
case PIC_OP_DISABLE_VISUAL:
|
||||||
|
pic_color = 0xFF;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_SET_PRIORITY:
|
||||||
|
pic_priority = data[curPos++];
|
||||||
|
break;
|
||||||
|
case PIC_OP_DISABLE_PRIORITY:
|
||||||
|
pic_priority = 255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_SET_CONTROL:
|
||||||
|
pic_control = data[curPos++];
|
||||||
|
break;
|
||||||
|
case PIC_OP_DISABLE_CONTROL:
|
||||||
|
pic_control = 255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_SHORT_LINES: // short line
|
||||||
|
vectorGetAbsCoords(data, curPos, oldx, oldy);
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetRelCoords(data, curPos, oldx, oldy, x, y);
|
||||||
|
warning("line %d %d -> %d %d", oldy, oldx, y, x);
|
||||||
|
_gfx->Draw_Line(oldx, oldy, x, y, pic_color, pic_priority, pic_control);
|
||||||
|
oldx = x; oldy = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OP_MEDIUM_LINES: // medium line
|
||||||
|
vectorGetAbsCoords(data, curPos, oldx, oldy);
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetRelCoordsMed(data, curPos, oldx, oldy, x, y);
|
||||||
|
warning("line %d %d -> %d %d", oldy, oldx, y, x);
|
||||||
|
_gfx->Draw_Line(oldx, oldy, x, y, pic_color, pic_priority, pic_control);
|
||||||
|
oldx = x; oldy = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OP_LONG_LINES: // long line
|
||||||
|
vectorGetAbsCoords(data, curPos, oldx, oldy);
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
warning("line %d %d -> %d %d", oldy, oldx, y, x);
|
||||||
|
_gfx->Draw_Line(oldx, oldy, x, y, pic_color, pic_priority, pic_control);
|
||||||
|
oldx = x; oldy = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_FILL: //fill
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
warning("fill %d %d", y, x);
|
||||||
|
_gfx->Pic_Fill(x, y, pic_color, pic_priority, pic_control);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_SET_PATTERN:
|
||||||
|
pattern_Code = data[curPos++];
|
||||||
|
break;
|
||||||
|
case PIC_OP_SHORT_PATTERNS:
|
||||||
|
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
warning("pattern %d %d", y, x);
|
||||||
|
_gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
|
||||||
|
vectorGetRelCoords(data, curPos, x, y, x, y);
|
||||||
|
warning("pattern %d %d", y, x);
|
||||||
|
_gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OP_MEDIUM_PATTERNS:
|
||||||
|
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
warning("pattern %d %d", y, x);
|
||||||
|
_gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
|
||||||
|
vectorGetRelCoordsMed(data, curPos, x, y, x, y);
|
||||||
|
warning("pattern %d %d", y, x);
|
||||||
|
_gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OP_ABSOLUTE_PATTERN:
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture);
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
warning("pattern %d %d", y, x);
|
||||||
|
//_gfx->Draw_Pattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PIC_OP_OPX: // Extended functions
|
||||||
|
if (sci1) {
|
||||||
|
warning("OPX SCI1 %X at %d", data[curPos], curPos);
|
||||||
|
switch (pic_op = data[curPos++]) {
|
||||||
|
case PIC_OPX_SCI1_SET_PALETTE_ENTRIES:
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
curPos++; // skip commands
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI1_SET_PALETTE:
|
||||||
|
curPos += 256 + 4; // Skip over mapping and timestamp
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
palette.colors[i].used = data[curPos++];
|
||||||
|
palette.colors[i].r = data[curPos++]; palette.colors[i].g = data[curPos++]; palette.colors[i].b = data[curPos++];
|
||||||
|
}
|
||||||
|
_gfx->SetPalette(&palette, 2);
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI1_EMBEDDED_VIEW: // draw cel
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
size = READ_LE_UINT16(data + curPos); curPos += 2;
|
||||||
|
drawCel(x, y, data + curPos, size);
|
||||||
|
curPos += size;
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI1_PRIORITY_TABLE_EQDIST:
|
||||||
|
//FIXME
|
||||||
|
//g_sci->InitPri(READ_LE_UINT16(ptr), READ_LE_UINT16(ptr + 2));
|
||||||
|
debug(5, "DrawPic::InitPri %d %d",
|
||||||
|
READ_LE_UINT16(data + curPos), READ_LE_UINT16(data + curPos + 2));
|
||||||
|
curPos += 4;
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI1_PRIORITY_TABLE_EXPLICIT:
|
||||||
|
//FIXME
|
||||||
|
//g_sci->PriBands(ptr);
|
||||||
|
curPos += 14;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unsupported sci1 extended pic-operation %X", pic_op);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (pic_op = data[curPos++]) {
|
||||||
|
case PIC_OPX_SCI0_SET_PALETTE_ENTRIES:
|
||||||
|
while (vectorIsNonOpcode(data[curPos])) {
|
||||||
|
byte = data[curPos++];
|
||||||
|
if (byte >= PIC_EGAPALETTE_TOTALSIZE) {
|
||||||
|
error("picture trying to write to invalid EGA-palette");
|
||||||
|
}
|
||||||
|
EGApalettes[byte] = data[curPos++];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_SET_PALETTE:
|
||||||
|
byte = data[curPos++];
|
||||||
|
if (EGApalette >= PIC_EGAPALETTE_COUNT) {
|
||||||
|
error("picture trying to write to invalid palette %d", EGApalette);
|
||||||
|
}
|
||||||
|
byte *= PIC_EGAPALETTE_SIZE;
|
||||||
|
for (i = 0; i < PIC_EGAPALETTE_SIZE; i++) {
|
||||||
|
EGApalettes[byte + i] = data[curPos++];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_MONO0:
|
||||||
|
curPos += 41;
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_MONO1:
|
||||||
|
case PIC_OPX_SCI0_MONO3:
|
||||||
|
curPos++;
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_MONO2:
|
||||||
|
case PIC_OPX_SCI0_MONO4:
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_EMBEDDED_VIEW:
|
||||||
|
vectorGetAbsCoords(data, curPos, x, y);
|
||||||
|
size = READ_LE_UINT16(data + curPos); curPos += 2;
|
||||||
|
drawCel(x, y, data + curPos, size);
|
||||||
|
curPos += size;
|
||||||
|
break;
|
||||||
|
case PIC_OPX_SCI0_SET_PRIORITY_TABLE:
|
||||||
|
//FIXME
|
||||||
|
//g_sci->PriBands(ptr);
|
||||||
|
curPos += 14;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unsupported sci1 extended pic-operation %X", pic_op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIC_OP_TERMINATE:
|
||||||
|
_priority = pic_priority;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
error("Unsupported pic-operation %X", pic_op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error("picture vector data without terminator");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SciGUIpicture::vectorIsNonOpcode(byte byte) {
|
||||||
|
if (byte >= PIC_OP_FIRST)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y) {
|
||||||
|
byte byte = data[curPos++];
|
||||||
|
x = data[curPos++] + ((byte & 0xF0) << 4);
|
||||||
|
y = data[curPos++] + ((byte & 0x0F) << 8);
|
||||||
|
if (_style & PIC_STYLE_MIRRORED) x = 319 - x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::vectorGetRelCoords(byte *data, int &curPos, int16 oldx, int16 oldy, int16 &x, int16 &y) {
|
||||||
|
byte byte = data[curPos++];
|
||||||
|
if (byte & 0x80) {
|
||||||
|
x = oldx - ((byte >> 4) & 7) * (_style & PIC_STYLE_MIRRORED ? -1 : 1);
|
||||||
|
} else {
|
||||||
|
x = oldx + (byte >> 4) * (_style & PIC_STYLE_MIRRORED ? -1 : 1);
|
||||||
|
}
|
||||||
|
if (byte & 0x08) {
|
||||||
|
y = oldy - (byte & 7);
|
||||||
|
} else {
|
||||||
|
y = oldy + (byte & 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::vectorGetRelCoordsMed(byte *data, int &curPos, int16 oldx, int16 oldy, int16 &x, int16 &y) {
|
||||||
|
byte byte = data[curPos++];
|
||||||
|
if (byte & 0x80) {
|
||||||
|
y = oldy - (byte & 0x7F);
|
||||||
|
} else {
|
||||||
|
y = oldy + byte;
|
||||||
|
}
|
||||||
|
byte = data[curPos++];
|
||||||
|
if (byte & 0x80) {
|
||||||
|
x = oldx - (128 - (byte & 0x7F)) * (_style & PIC_STYLE_MIRRORED ? -1 : 1);
|
||||||
|
} else {
|
||||||
|
x = oldx + byte * (_style & PIC_STYLE_MIRRORED ? -1 : 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIpicture::vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_Code, int16 &pattern_Texture) {
|
||||||
|
if (pattern_Code & SCI_PATTERN_CODE_USE_TEXTURE) {
|
||||||
|
pattern_Texture = (data[curPos++] >> 1) & 0x7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
71
engines/sci/gui/gui_picture.h
Normal file
71
engines/sci/gui/gui_picture.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
#define SCI_PAL_FORMAT_VARIABLE_FLAGS 0
|
||||||
|
#define SCI_PAL_FORMAT_CONSTANT_FLAGS 1
|
||||||
|
|
||||||
|
#define PIC_STYLE_MIRRORED 0x4000
|
||||||
|
|
||||||
|
class SciGUIpicture {
|
||||||
|
public:
|
||||||
|
SciGUIpicture(OSystem *system, EngineState *state, SciGUIgfx *gfx, SciGUIscreen *screen, sciResourceId resourceId);
|
||||||
|
~SciGUIpicture();
|
||||||
|
|
||||||
|
sciResourceId getResourceId();
|
||||||
|
void draw(uint16 style, bool addToFlag, int16 EGApaletteNo);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initData(sciResourceId resourceId);
|
||||||
|
void reset();
|
||||||
|
void draw11();
|
||||||
|
void decodeRLE(byte *rledata, byte *pixeldata, byte *outbuffer, int size);
|
||||||
|
void drawPalette11(byte *data);
|
||||||
|
void drawCel(int16 x, int16 y, byte *pdata, int size);
|
||||||
|
void drawCelAmiga(int16 x, int16 y, byte *pdata, int size);
|
||||||
|
void drawVectorData(byte *data, int size);
|
||||||
|
bool vectorIsNonOpcode(byte byte);
|
||||||
|
void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y);
|
||||||
|
void vectorGetRelCoords(byte *data, int &curPos, int16 oldx, int16 oldy, int16 &x, int16 &y);
|
||||||
|
void vectorGetRelCoordsMed(byte *data, int &curPos, int16 oldx, int16 oldy, int16 &x, int16 &y);
|
||||||
|
void vectorGetPatternTexture(byte *data, int &curPos, int16 pattern_Code, int16 &pattern_Texture);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIgfx *_gfx;
|
||||||
|
SciGUIscreen *_screen;
|
||||||
|
|
||||||
|
int16 _resourceId;
|
||||||
|
Resource *_resource;
|
||||||
|
|
||||||
|
sciPort *_curPort;
|
||||||
|
uint16 _style;
|
||||||
|
bool _addToFlag;
|
||||||
|
int16 _EGApaletteNo;
|
||||||
|
byte _priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
209
engines/sci/gui/gui_screen.cpp
Normal file
209
engines/sci/gui/gui_screen.cpp
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/timer.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_screen.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUIscreen::SciGUIscreen(OSystem *system, EngineState *state)
|
||||||
|
: _system(system), _s(state) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUIscreen::~SciGUIscreen() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::init() {
|
||||||
|
int i;
|
||||||
|
uint16 base = 0;
|
||||||
|
|
||||||
|
_width = 320;
|
||||||
|
_height = 200;
|
||||||
|
_pixels = _width * _height;
|
||||||
|
|
||||||
|
// if you want to do scaling, adjust Put_Pixel() accordingly
|
||||||
|
_displayWidth = 320;
|
||||||
|
_displayHeight = 200;
|
||||||
|
_displayPixels = _displayWidth * _displayHeight;
|
||||||
|
_bytesPerDisplayPixel = 1;
|
||||||
|
|
||||||
|
_visualScreen = initScreen(_pixels);
|
||||||
|
_priorityScreen = initScreen(_pixels);
|
||||||
|
_controlScreen = initScreen(_pixels);
|
||||||
|
_displayScreen = initScreen(_displayPixels);
|
||||||
|
|
||||||
|
for (i = 0; i < _height; i++) {
|
||||||
|
_baseTable[i] = base; _baseDisplayTable[i] = base;
|
||||||
|
base += _width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *SciGUIscreen::initScreen(uint16 pixelCount) {
|
||||||
|
byte *screen = (byte *)malloc(pixelCount);
|
||||||
|
memset(screen, 0, pixelCount);
|
||||||
|
return screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::UpdateWhole() {
|
||||||
|
_system->copyRectToScreen(_displayScreen, _displayWidth, 0, 0, _displayWidth, _displayHeight);
|
||||||
|
_system->updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIscreen::GetDrawingMask(byte color, byte prio, byte control) {
|
||||||
|
byte flag = 0;
|
||||||
|
if (color != 255)
|
||||||
|
flag |= SCI_SCREEN_MASK_VISUAL;
|
||||||
|
if (prio != 255)
|
||||||
|
flag |= SCI_SCREEN_MASK_PRIORITY;
|
||||||
|
if (control != 255)
|
||||||
|
flag |= SCI_SCREEN_MASK_CONTROL;
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::Put_Pixel(int x, int y, byte drawMask, byte color, byte priority, byte control) {
|
||||||
|
int offset = _baseTable[y] + x;
|
||||||
|
|
||||||
|
if (drawMask & SCI_SCREEN_MASK_VISUAL) {
|
||||||
|
if (!_s->resMan->isVGA()) {
|
||||||
|
// EGA output (16 colors, dithered)
|
||||||
|
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
|
||||||
|
}
|
||||||
|
*(_visualScreen + offset) = color;
|
||||||
|
_displayScreen[_baseDisplayTable[y] + x] = color;
|
||||||
|
}
|
||||||
|
if (drawMask & SCI_SCREEN_MASK_PRIORITY)
|
||||||
|
*(_priorityScreen + offset) = priority;
|
||||||
|
if (drawMask & SCI_SCREEN_MASK_CONTROL)
|
||||||
|
*(_controlScreen + offset) = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIscreen::Get_Visual(int x, int y) {
|
||||||
|
return _visualScreen[_baseTable[y] + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIscreen::Get_Priority(int x, int y) {
|
||||||
|
return _priorityScreen[_baseTable[y] + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIscreen::Get_Control(int x, int y) {
|
||||||
|
return _controlScreen[_baseTable[y] + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SciGUIscreen::IsFillMatch(int16 x, int16 y, byte flag, byte t_color, byte t_pri, byte t_con) {
|
||||||
|
int offset = _baseTable[y] + x;
|
||||||
|
byte match = 0;
|
||||||
|
|
||||||
|
if (flag & SCI_SCREEN_MASK_VISUAL && *(_visualScreen + offset) == t_color)
|
||||||
|
match |= SCI_SCREEN_MASK_VISUAL;
|
||||||
|
if (flag & SCI_SCREEN_MASK_PRIORITY && *(_priorityScreen + offset) == t_pri)
|
||||||
|
match |= SCI_SCREEN_MASK_PRIORITY;
|
||||||
|
if (flag & SCI_SCREEN_MASK_CONTROL && *(_controlScreen + offset) == t_con)
|
||||||
|
match |= SCI_SCREEN_MASK_CONTROL;
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SciGUIscreen::BitsGetDataSize(Common::Rect rect, byte mask) {
|
||||||
|
int byteCount = sizeof(rect) + sizeof(mask);
|
||||||
|
int pixels = rect.width() * rect.height();
|
||||||
|
if (mask & SCI_SCREEN_MASK_VISUAL) {
|
||||||
|
byteCount += pixels + (pixels * _bytesPerDisplayPixel);
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_PRIORITY) {
|
||||||
|
byteCount += pixels;
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_CONTROL) {
|
||||||
|
byteCount += pixels;
|
||||||
|
}
|
||||||
|
return byteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::BitsSave(Common::Rect rect, byte mask, byte *memoryPtr) {
|
||||||
|
memcpy(memoryPtr, (void *)&rect, sizeof(rect)); memoryPtr += sizeof(rect);
|
||||||
|
memcpy(memoryPtr, (void *)&mask, sizeof(mask)); memoryPtr += sizeof(mask);
|
||||||
|
|
||||||
|
if (mask & SCI_SCREEN_MASK_VISUAL) {
|
||||||
|
BitsSaveScreen(rect, _visualScreen, memoryPtr);
|
||||||
|
BitsSaveScreen(rect, _displayScreen, memoryPtr);
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_PRIORITY) {
|
||||||
|
BitsSaveScreen(rect, _priorityScreen, memoryPtr);
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_CONTROL) {
|
||||||
|
BitsSaveScreen(rect, _controlScreen, memoryPtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::BitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr) {
|
||||||
|
int width = rect.width();
|
||||||
|
int height = rect.height();
|
||||||
|
int y;
|
||||||
|
|
||||||
|
screen += (rect.top * _width) + rect.left;
|
||||||
|
|
||||||
|
for (y=rect.top; y<rect.bottom; y++) {
|
||||||
|
memcpy(memoryPtr, (void*)screen, width); memoryPtr += width;
|
||||||
|
screen += _width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::BitsRestore(byte *memoryPtr) {
|
||||||
|
Common::Rect rect;
|
||||||
|
byte mask;
|
||||||
|
|
||||||
|
memcpy((void *)&rect, memoryPtr, sizeof(rect)); memoryPtr += sizeof(rect);
|
||||||
|
memcpy((void *)&mask, memoryPtr, sizeof(mask)); memoryPtr += sizeof(mask);
|
||||||
|
|
||||||
|
if (mask & SCI_SCREEN_MASK_VISUAL) {
|
||||||
|
BitsRestoreScreen(rect, memoryPtr, _visualScreen);
|
||||||
|
BitsRestoreScreen(rect, memoryPtr, _displayScreen);
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_PRIORITY) {
|
||||||
|
BitsRestoreScreen(rect, memoryPtr, _priorityScreen);
|
||||||
|
}
|
||||||
|
if (mask & SCI_SCREEN_MASK_CONTROL) {
|
||||||
|
BitsRestoreScreen(rect, memoryPtr, _controlScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIscreen::BitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen) {
|
||||||
|
int width = rect.width();
|
||||||
|
int height = rect.height();
|
||||||
|
int y;
|
||||||
|
|
||||||
|
screen += (rect.top * _width) + rect.left;
|
||||||
|
|
||||||
|
for (y=rect.top; y<rect.bottom; y++) {
|
||||||
|
memcpy((void*) screen, memoryPtr, width); memoryPtr += width;
|
||||||
|
screen += _width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
88
engines/sci/gui/gui_screen.h
Normal file
88
engines/sci/gui/gui_screen.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
#define SCI_SCREEN_MAXHEIGHT 400
|
||||||
|
|
||||||
|
#define SCI_SCREEN_MASK_VISUAL 1
|
||||||
|
#define SCI_SCREEN_MASK_PRIORITY 2
|
||||||
|
#define SCI_SCREEN_MASK_CONTROL 4
|
||||||
|
#define SCI_SCREEN_MASK_ALL SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY|SCI_SCREEN_MASK_CONTROL
|
||||||
|
#define SCI_SCREEN_MASK_DITHERED 128
|
||||||
|
|
||||||
|
class SciGUIscreen {
|
||||||
|
public:
|
||||||
|
SciGUIscreen(OSystem *system, EngineState *state);
|
||||||
|
~SciGUIscreen();
|
||||||
|
|
||||||
|
void init(void);
|
||||||
|
byte *initScreen(uint16 pixelCount);
|
||||||
|
|
||||||
|
void UpdateWhole();
|
||||||
|
|
||||||
|
byte GetDrawingMask(byte color, byte prio, byte control);
|
||||||
|
void Put_Pixel(int x, int y, byte drawMask, byte color, byte prio, byte control);
|
||||||
|
byte Get_Visual(int x, int y);
|
||||||
|
byte Get_Priority(int x, int y);
|
||||||
|
byte Get_Control(int x, int y);
|
||||||
|
byte IsFillMatch(int16 x, int16 y, byte drawMask, byte t_color, byte t_pri, byte t_con);
|
||||||
|
|
||||||
|
int BitsGetDataSize(Common::Rect rect, byte mask);
|
||||||
|
void BitsSave(Common::Rect rect, byte mask, byte *memoryPtr);
|
||||||
|
void BitsRestore(byte *memoryPtr);
|
||||||
|
|
||||||
|
sciPalette _sysPalette;
|
||||||
|
|
||||||
|
uint16 _width;
|
||||||
|
uint16 _height;
|
||||||
|
uint _pixels;
|
||||||
|
uint16 _displayWidth;
|
||||||
|
uint16 _displayHeight;
|
||||||
|
uint _displayPixels;
|
||||||
|
byte _bytesPerDisplayPixel;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void BitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen);
|
||||||
|
void BitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
|
||||||
|
uint16 _baseTable[SCI_SCREEN_MAXHEIGHT];
|
||||||
|
uint16 _baseDisplayTable[SCI_SCREEN_MAXHEIGHT];
|
||||||
|
|
||||||
|
// these screens have the real resolution of the game engine (320x200 for SCI0/SCI1/SCI11 games, 640x480 for SCI2 games)
|
||||||
|
// SCI0 games will be dithered in here at any time
|
||||||
|
byte *_visualScreen;
|
||||||
|
byte *_priorityScreen;
|
||||||
|
byte *_controlScreen;
|
||||||
|
|
||||||
|
// this screen is the one that is actually displayed to the user. It may be 640x480 for japanese SCI1 games
|
||||||
|
// SCI0 games may be undithered in here. Only read from this buffer for Save/ShowBits usage.
|
||||||
|
byte *_displayScreen;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
296
engines/sci/gui/gui_view.cpp
Normal file
296
engines/sci/gui/gui_view.cpp
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_gfx.h"
|
||||||
|
#include "sci/gui/gui_screen.h"
|
||||||
|
#include "sci/gui/gui_view.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUIview::SciGUIview(OSystem *system, EngineState *state, SciGUIgfx *gfx, SciGUIscreen *screen, sciResourceId resourceId)
|
||||||
|
: _system(system), _s(state), _gfx(gfx), _screen(screen), _resourceId(resourceId) {
|
||||||
|
assert(resourceId != -1);
|
||||||
|
initData(resourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUIview::~SciGUIview() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIview::initData(sciResourceId resourceId) {
|
||||||
|
Resource *viewResource = _s->resMan->findResource(ResourceId(kResourceTypeView, resourceId), false);
|
||||||
|
if (!viewResource) {
|
||||||
|
error("view resource %d not found", resourceId);
|
||||||
|
}
|
||||||
|
_resourceData = viewResource->data;
|
||||||
|
|
||||||
|
byte *cellData, *loopData;
|
||||||
|
uint16 cellOffset;
|
||||||
|
sciViewCellInfo *cell;
|
||||||
|
uint16 cellCount = 0;
|
||||||
|
uint16 mirrorBits = 0;
|
||||||
|
uint16 palOffset = 0;
|
||||||
|
uint16 headerSize = 0;
|
||||||
|
uint16 loopSize = 0, cellSize = 0;
|
||||||
|
int loopNo, cellNo;
|
||||||
|
int16 version;
|
||||||
|
byte seekEntry;
|
||||||
|
|
||||||
|
_embeddedPal = false;
|
||||||
|
_loopCount = 0;
|
||||||
|
|
||||||
|
version = READ_LE_UINT16(_resourceData + 4);
|
||||||
|
switch (version) {
|
||||||
|
case 0: // View-format SCI1
|
||||||
|
// LoopCount:WORD MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD...
|
||||||
|
|
||||||
|
// bit 0x8000 of _resourceData[1] means palette is set
|
||||||
|
_loopCount = _resourceData[0];
|
||||||
|
mirrorBits = READ_LE_UINT16(_resourceData + 2);
|
||||||
|
palOffset = READ_LE_UINT16(_resourceData + 6);
|
||||||
|
|
||||||
|
if (palOffset && palOffset != 0x100) {
|
||||||
|
_gfx->CreatePaletteFromData(_resourceData + palOffset, &_palette);
|
||||||
|
_embeddedPal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_loop = new sciViewLoopInfo[_loopCount];
|
||||||
|
for (loopNo = 0; loopNo < _loopCount; loopNo++) {
|
||||||
|
loopData = _resourceData + READ_LE_UINT16(_resourceData + 8 + loopNo * 2);
|
||||||
|
// CellCount:WORD Unknown:WORD CellOffset0:WORD CellOffset1:WORD...
|
||||||
|
|
||||||
|
cellCount = READ_LE_UINT16(loopData);
|
||||||
|
_loop[loopNo].cellCount = cellCount;
|
||||||
|
_loop[loopNo].mirrorFlag = mirrorBits & 1 ? true : false;
|
||||||
|
mirrorBits >>= 1;
|
||||||
|
|
||||||
|
// read cel info
|
||||||
|
_loop[loopNo].cell = new sciViewCellInfo[cellCount];
|
||||||
|
for (cellNo = 0; cellNo < cellCount; cellNo++) {
|
||||||
|
cellOffset = READ_LE_UINT16(loopData + 4 + cellNo * 2);
|
||||||
|
cellData = _resourceData + cellOffset;
|
||||||
|
|
||||||
|
cell = &_loop[loopNo].cell[cellNo];
|
||||||
|
cell->width = READ_LE_UINT16(cellData);
|
||||||
|
cell->height = READ_LE_UINT16(cellData + 2);
|
||||||
|
cell->displaceX = cellData[4];
|
||||||
|
cell->displaceY = cellData[5];
|
||||||
|
cell->clearKey = cellData[6];
|
||||||
|
cell->offsetRLE = cellOffset + 8;
|
||||||
|
cell->offsetLiteral = 0;
|
||||||
|
cell->rawBitmap = 0;
|
||||||
|
if (_loop[loopNo].mirrorFlag)
|
||||||
|
cell->displaceX = -cell->displaceX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // View-format SCI1.1
|
||||||
|
// LoopCount:WORD MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD...
|
||||||
|
// HeaderSize:WORD LoopCount:WORD Version:WORD Unknown:WORD PaletteOffset:WORD
|
||||||
|
headerSize = READ_LE_UINT16(_resourceData + 0);
|
||||||
|
_loopCount = READ_LE_UINT16(_resourceData + 2);
|
||||||
|
palOffset = READ_LE_UINT16(_resourceData + 8);
|
||||||
|
|
||||||
|
loopData = _resourceData + headerSize;
|
||||||
|
loopSize = _resourceData[12];
|
||||||
|
cellSize = _resourceData[13];
|
||||||
|
|
||||||
|
if (palOffset) {
|
||||||
|
_gfx->CreatePaletteFromData(_resourceData + palOffset, &_palette);
|
||||||
|
_embeddedPal = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_loop = new sciViewLoopInfo[_loopCount];
|
||||||
|
for (loopNo = 0; loopNo < _loopCount; loopNo++) {
|
||||||
|
loopData = _resourceData + headerSize + (loopNo * loopSize);
|
||||||
|
|
||||||
|
seekEntry = loopData[2];
|
||||||
|
if (seekEntry != 255) {
|
||||||
|
loopData = _resourceData + headerSize + (seekEntry * loopNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
cellCount = loopData[4];
|
||||||
|
_loop[loopNo].cellCount = cellCount;
|
||||||
|
_loop[loopNo].mirrorFlag = false;
|
||||||
|
|
||||||
|
cellData = _resourceData + READ_LE_UINT16(loopData + 14);
|
||||||
|
|
||||||
|
// read cel info
|
||||||
|
_loop[loopNo].cell = new sciViewCellInfo[cellCount];
|
||||||
|
for (cellNo = 0; cellNo < cellCount; cellNo++) {
|
||||||
|
cell = &_loop[loopNo].cell[cellNo];
|
||||||
|
cell->width = READ_LE_UINT16(cellData);
|
||||||
|
cell->height = READ_LE_UINT16(cellData + 2);
|
||||||
|
cell->displaceX = READ_LE_UINT16(cellData + 4);
|
||||||
|
cell->displaceY = READ_LE_UINT16(cellData + 6);
|
||||||
|
cell->clearKey = cellData[8];
|
||||||
|
cell->offsetRLE = READ_LE_UINT16(cellData + 24);
|
||||||
|
cell->offsetLiteral = READ_LE_UINT16(cellData + 28);
|
||||||
|
cell->rawBitmap = 0;
|
||||||
|
if (_loop[loopNo].mirrorFlag)
|
||||||
|
cell->displaceX = -cell->displaceX;
|
||||||
|
|
||||||
|
cellData += cellSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sciResourceId SciGUIview::getResourceId() {
|
||||||
|
return _resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUIview::getWidth(uint16 loopNo, uint16 cellNo) {
|
||||||
|
loopNo = CLIP<int16>(loopNo, 0, _loopCount -1);
|
||||||
|
if (cellNo < 0 || cellNo >= _loop[loopNo].cellCount)
|
||||||
|
cellNo = 0;
|
||||||
|
return _loopCount ? _loop[loopNo].cell[cellNo].width : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUIview::getHeight(uint16 loopNo, uint16 cellNo) {
|
||||||
|
loopNo = CLIP<int16>(loopNo, 0, _loopCount -1);
|
||||||
|
if (cellNo < 0 || cellNo >= _loop[loopNo].cellCount)
|
||||||
|
cellNo = 0;
|
||||||
|
return _loopCount ? _loop[loopNo].cell[cellNo].height : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sciViewCellInfo *SciGUIview::getCellInfo(uint16 loopNo, uint16 cellNo) {
|
||||||
|
loopNo = CLIP<int16>(loopNo, 0, _loopCount -1);
|
||||||
|
if (cellNo < 0 || cellNo >= _loop[loopNo].cellCount)
|
||||||
|
cellNo = 0;
|
||||||
|
return _loopCount ? &_loop[loopNo].cell[cellNo] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIview::unpackView(uint16 loopNo, uint16 cellNo, byte *outPtr, uint16 pixelCount) {
|
||||||
|
byte *rlePtr = _resourceData + _loop[loopNo].cell[cellNo].offsetRLE;
|
||||||
|
byte *literalPtr = _resourceData + _loop[loopNo].cell[cellNo].offsetLiteral;
|
||||||
|
uint16 pixelNo = 0, brun;
|
||||||
|
byte b;
|
||||||
|
|
||||||
|
if (literalPtr == _resourceData) { // no extra literal data
|
||||||
|
while (pixelNo < pixelCount) {
|
||||||
|
b = *rlePtr++;
|
||||||
|
brun = b & 0x3F; // bytes run length on this step
|
||||||
|
switch (b & 0xC0) {
|
||||||
|
case 0: // copy bytes as-is
|
||||||
|
while (brun-- && pixelNo < pixelCount)
|
||||||
|
outPtr[pixelNo++] = *rlePtr++;
|
||||||
|
break;
|
||||||
|
case 0x80: // fill with color
|
||||||
|
memset(outPtr + pixelNo, *rlePtr++, MIN<uint16>(brun, pixelCount - pixelNo));
|
||||||
|
pixelNo += brun;
|
||||||
|
break;
|
||||||
|
case 0xC0: // fill with transparent
|
||||||
|
pixelNo += brun;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (pixelNo < pixelCount) {
|
||||||
|
b = *rlePtr++;
|
||||||
|
brun = b & 0x3F; // bytes run length on this step
|
||||||
|
switch (b & 0xC0) {
|
||||||
|
case 0: // copy bytes as-is
|
||||||
|
while (brun-- && pixelNo < pixelCount)
|
||||||
|
outPtr[pixelNo++] = *literalPtr++;
|
||||||
|
break;
|
||||||
|
case 0x80: // fill with color
|
||||||
|
memset(outPtr + pixelNo, *literalPtr++, MIN<uint16>(brun, pixelCount - pixelNo));
|
||||||
|
pixelNo += brun;
|
||||||
|
break;
|
||||||
|
case 0xC0: // fill with transparent
|
||||||
|
pixelNo += brun;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *SciGUIview::getBitmap(uint16 loopNo, uint16 cellNo) {
|
||||||
|
loopNo = CLIP<int16>(loopNo, 0, _loopCount -1);
|
||||||
|
if (cellNo < 0 || cellNo >= _loop[loopNo].cellCount)
|
||||||
|
cellNo = 0;
|
||||||
|
if (_loop[loopNo].cell[cellNo].rawBitmap)
|
||||||
|
return _loop[loopNo].cell[cellNo].rawBitmap;
|
||||||
|
|
||||||
|
uint16 width = _loop[loopNo].cell[cellNo].width;
|
||||||
|
uint16 height = _loop[loopNo].cell[cellNo].height;
|
||||||
|
// byte *ptr = _resourceData + _loop[loopNo].cell[cellNo].offset;
|
||||||
|
// allocating memory to store cel's bitmap
|
||||||
|
assert(width * height <= 64000);
|
||||||
|
uint16 pixelCount = width * height;
|
||||||
|
_loop[loopNo].cell[cellNo].rawBitmap = new byte[pixelCount];
|
||||||
|
byte *pOut = _loop[loopNo].cell[cellNo].rawBitmap;
|
||||||
|
|
||||||
|
memset(pOut, _loop[loopNo].cell[cellNo].clearKey, pixelCount);
|
||||||
|
//if (g_sci->getPlatform() == Common::kPlatformAmiga)
|
||||||
|
// unpackViewAmiga(ptr, pOut, pixelCount);
|
||||||
|
//else
|
||||||
|
unpackView(loopNo, cellNo, pOut, pixelCount);
|
||||||
|
|
||||||
|
// mirroring the view if needed
|
||||||
|
if (_loop[loopNo].mirrorFlag) {
|
||||||
|
for (int i = 0; i < height; i++, pOut += width)
|
||||||
|
for (int j = 0; j < width / 2; j++)
|
||||||
|
SWAP(pOut[j], pOut[width - j - 1]);
|
||||||
|
}
|
||||||
|
return _loop[loopNo].cell[cellNo].rawBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIview::draw(Common::Rect rect, Common::Rect clipRect, uint16 loopNo, uint16 cellNo, byte priority, uint16 paletteNo) {
|
||||||
|
sciPalette *palette = _embeddedPal ? &_palette : &_gfx->_sysPalette;
|
||||||
|
sciViewCellInfo *cellInfo = getCellInfo(loopNo, cellNo);
|
||||||
|
byte *bitmap = getBitmap(loopNo, cellNo);
|
||||||
|
int16 cellHeight = cellInfo->height, cellWidth = cellInfo->width;
|
||||||
|
int16 width, height;
|
||||||
|
byte clearKey = cellInfo->clearKey;
|
||||||
|
byte color;
|
||||||
|
byte drawMask = priority == 255 ? SCI_SCREEN_MASK_VISUAL : SCI_SCREEN_MASK_VISUAL|SCI_SCREEN_MASK_PRIORITY;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
// Merge view palette in...
|
||||||
|
if (_embeddedPal)
|
||||||
|
_gfx->SetPalette(&_palette, 1);
|
||||||
|
|
||||||
|
width = MIN(clipRect.width(), cellWidth);
|
||||||
|
height = MIN(clipRect.height(), cellHeight);
|
||||||
|
|
||||||
|
bitmap += (clipRect.top - rect.top) * cellWidth + (clipRect.left - rect.left);
|
||||||
|
_gfx->OffsetRect(clipRect);
|
||||||
|
|
||||||
|
for (y = clipRect.top; y < clipRect.top + height; y++, bitmap += cellWidth) {
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
color = bitmap[x];
|
||||||
|
if (color != clearKey && priority >= _screen->Get_Priority(clipRect.left + x, y))
|
||||||
|
_screen->Put_Pixel(clipRect.left + x, y, drawMask, palette->mapping[color], priority, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
77
engines/sci/gui/gui_view.h
Normal file
77
engines/sci/gui/gui_view.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
struct sciViewCellInfo {
|
||||||
|
int16 width, height;
|
||||||
|
char displaceX;
|
||||||
|
byte displaceY;
|
||||||
|
byte clearKey;
|
||||||
|
uint16 offsetRLE;
|
||||||
|
uint16 offsetLiteral;
|
||||||
|
byte *rawBitmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sciViewLoopInfo {
|
||||||
|
bool mirrorFlag;
|
||||||
|
int16 cellCount;
|
||||||
|
sciViewCellInfo *cell;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SciGUIview {
|
||||||
|
public:
|
||||||
|
SciGUIview(OSystem *system, EngineState *state, SciGUIgfx *gfx, SciGUIscreen *screen, sciResourceId resourceId);
|
||||||
|
~SciGUIview();
|
||||||
|
|
||||||
|
// TODO: Remove gfx reference after putting palette things into SciGUIscreen
|
||||||
|
|
||||||
|
sciResourceId getResourceId();
|
||||||
|
int16 getWidth(uint16 loopNo, uint16 cellNo);
|
||||||
|
int16 getHeight(uint16 loopNo, uint16 cellNo);
|
||||||
|
sciViewCellInfo *getCellInfo(uint16 loop, uint16 cel);
|
||||||
|
sciViewLoopInfo *getLoopInfo(uint16 loop);
|
||||||
|
byte *getBitmap(uint16 loopNo, uint16 cellNo);
|
||||||
|
void draw(Common::Rect rect, Common::Rect clipRect, uint16 loopNo, uint16 cellNo, byte priority, uint16 paletteNo);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initData(sciResourceId resourceId);
|
||||||
|
void unpackView(uint16 loopNo, uint16 cellNo, byte *outPtr, uint16 pixelCount);
|
||||||
|
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIgfx *_gfx;
|
||||||
|
SciGUIscreen *_screen;
|
||||||
|
|
||||||
|
sciResourceId _resourceId;
|
||||||
|
byte *_resourceData;
|
||||||
|
|
||||||
|
uint16 _loopCount;
|
||||||
|
sciViewLoopInfo *_loop;
|
||||||
|
bool _embeddedPal;
|
||||||
|
sciPalette _palette;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
326
engines/sci/gui/gui_windowmgr.cpp
Normal file
326
engines/sci/gui/gui_windowmgr.cpp
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/gui/gui_gfx.h"
|
||||||
|
#include "sci/gui/gui_windowmgr.h"
|
||||||
|
#include "sci/gui/gui_memmgr.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
Common::Rect _picRect(0,10,320, 200);
|
||||||
|
|
||||||
|
// window styles
|
||||||
|
enum {
|
||||||
|
TRANSPARENT = 1,
|
||||||
|
NOFRAME = 2,
|
||||||
|
TITLE = 4,
|
||||||
|
TOPMOST = 8,
|
||||||
|
USER = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
SciGUIwindowMgr::SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx)
|
||||||
|
: _s(state), _gfx(gfx) {
|
||||||
|
|
||||||
|
// FIXME: remove memmgr
|
||||||
|
InitMem(0x320);
|
||||||
|
|
||||||
|
HEAPHANDLE wmgrPortH = heapNewPtr(sizeof(sciPort), kDataPort, "wmgrPort");
|
||||||
|
heapClearPtr(wmgrPortH);
|
||||||
|
_wmgrPort = (sciPort *)heap2Ptr(wmgrPortH);
|
||||||
|
|
||||||
|
int16 offTop = 20;
|
||||||
|
|
||||||
|
_gfx->OpenPort(_wmgrPort);
|
||||||
|
_gfx->SetPort(_wmgrPort);
|
||||||
|
_gfx->SetOrigin(0, offTop);
|
||||||
|
_wmgrPort->rect.bottom = 200 - offTop;
|
||||||
|
_wmgrPort->rect.right = 320;
|
||||||
|
_wmgrPort->rect.moveTo(0, 0);
|
||||||
|
_wmgrPort->curTop = 0;
|
||||||
|
_wmgrPort->curLeft = 0;
|
||||||
|
|
||||||
|
windowList.AddToFront(wmgrPortH);
|
||||||
|
|
||||||
|
_picWind = NewWindow(&_picRect, 0, 0, TRANSPARENT | NOFRAME, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUIwindowMgr::~SciGUIwindowMgr() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUIwindowMgr::isFrontWindow(sciWnd *pWnd) {
|
||||||
|
if (heap2Ptr(windowList.getLast()) == (byte *)pWnd)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::SelectWindow(HEAPHANDLE hh) {
|
||||||
|
sciPort *port = (sciPort *)heap2Ptr(hh);
|
||||||
|
_gfx->SetPort(port);
|
||||||
|
if (hh != windowList.getLast()) { // selecting not topmost window
|
||||||
|
sciWnd *prevwnd = (sciWnd *)heap2Ptr(port->node.prev);
|
||||||
|
BeginUpdate(prevwnd);
|
||||||
|
windowList.MoveToEnd(hh);
|
||||||
|
EndUpdate(prevwnd);
|
||||||
|
}
|
||||||
|
_gfx->SetPort(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::BeginUpdate(sciWnd *wnd) {
|
||||||
|
sciPort *oldPort = _gfx->SetPort(_wmgrPort);
|
||||||
|
sciWnd *node = (sciWnd *)heap2Ptr(windowList.getLast());
|
||||||
|
while (node != wnd) {
|
||||||
|
UpdateWindow(node);
|
||||||
|
node = (sciWnd *)heap2Ptr(node->node.prev);
|
||||||
|
}
|
||||||
|
_gfx->SetPort(oldPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::EndUpdate(sciWnd *wnd) {
|
||||||
|
sciPort *oldPort = _gfx->SetPort(_wmgrPort);
|
||||||
|
sciWnd *last = (sciWnd *)heap2Ptr(windowList.getLast());
|
||||||
|
while (wnd != last) {
|
||||||
|
wnd = (sciWnd *)heap2Ptr(wnd->node.next);
|
||||||
|
UpdateWindow(wnd);
|
||||||
|
}
|
||||||
|
_gfx->SetPort(oldPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCILanguage SciGUIwindowMgr::getSCILanguage() {
|
||||||
|
return kLangEnglish;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *SciGUIwindowMgr::StrSplit(char *buff, const char *msg, const char *fmt) {
|
||||||
|
SCILanguage gameLang = getSCILanguage();
|
||||||
|
SCILanguage subtitleLang = kLangNone;
|
||||||
|
char *retval;
|
||||||
|
// if (_theGame.getHandle())
|
||||||
|
//subtitleLang = (SCILanguage)_theGame.getProperty(0x58); // subtitleLang property
|
||||||
|
|
||||||
|
if (buff == msg) {
|
||||||
|
char str[2000];
|
||||||
|
getIntlString(str, msg, fmt, gameLang, subtitleLang);
|
||||||
|
retval = strcpy(buff, str);
|
||||||
|
} else
|
||||||
|
retval = getIntlString(buff, msg, fmt, gameLang, subtitleLang);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
//--------------------------------
|
||||||
|
// In multilanguage game the msg has format ___english_text__#I___italian_text___
|
||||||
|
// The function should place in buff a translated part of msg or the 1st one if a translation
|
||||||
|
// does not exist
|
||||||
|
char *SciGUIwindowMgr::getIntlString(char *buff, const char *msg, const char *fmt,
|
||||||
|
SCILanguage gameLang, SCILanguage subtitleLang) {
|
||||||
|
|
||||||
|
// prefer subtitleLang if set
|
||||||
|
SCILanguage lang = subtitleLang != kLangNone ? subtitleLang : gameLang;
|
||||||
|
const char *ptr = msg, *szFrom;
|
||||||
|
char ch;
|
||||||
|
int nLen = 0;
|
||||||
|
// searching for language code in msg
|
||||||
|
while (*ptr) {
|
||||||
|
ch = *(ptr + 1);
|
||||||
|
if(*ptr == '#' && (ch == 'I' || ch == 'F' || ch == 'G' || ch == 'S')) {
|
||||||
|
ptr +=2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
// if a language code was found...
|
||||||
|
if (*ptr) {
|
||||||
|
if ((lang == kLangItalian && ch == 'I') || (lang == kLangFrench && ch == 'F') ||
|
||||||
|
(lang == kLangGerman && ch == 'G') || (lang == kLangSpanish && ch == 'S')) {
|
||||||
|
nLen = (int)strlen(ptr);
|
||||||
|
szFrom = ptr;
|
||||||
|
} else {
|
||||||
|
nLen = ptr - msg - 2;
|
||||||
|
szFrom = msg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nLen = ptr - msg;
|
||||||
|
szFrom = msg;
|
||||||
|
}
|
||||||
|
if (fmt && subtitleLang != kLangNone) {
|
||||||
|
strcpy(buff, fmt);
|
||||||
|
strncat(buff, szFrom, nLen);
|
||||||
|
buff[nLen + strlen(fmt)] = 0;
|
||||||
|
} else {
|
||||||
|
strncpy(buff, szFrom, nLen);
|
||||||
|
buff[nLen] = 0;
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
sciWnd *SciGUIwindowMgr::NewWindow(Common::Rect *rect, Common::Rect *rect2, const char *title, uint16 style, uint16 arg8, uint16 argA) {
|
||||||
|
HEAPHANDLE hWnd = heapNewPtr(sizeof(sciWnd), kDataWindow, title);
|
||||||
|
Common::Rect r;
|
||||||
|
|
||||||
|
if (!hWnd) {
|
||||||
|
warning("Can't open window!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
heapClearPtr(hWnd);
|
||||||
|
if (style & TOPMOST)
|
||||||
|
windowList.AddToFront(hWnd);
|
||||||
|
else
|
||||||
|
windowList.AddToEnd(hWnd);
|
||||||
|
sciWnd *pwnd = (sciWnd *)heap2Ptr(hWnd);
|
||||||
|
_gfx->OpenPort((sciPort *)pwnd);
|
||||||
|
r = *rect;
|
||||||
|
pwnd->rect = *rect;
|
||||||
|
if (rect2)
|
||||||
|
pwnd->rect1 = *rect2;
|
||||||
|
|
||||||
|
pwnd->wndStyle = style;
|
||||||
|
pwnd->hSaved1 = pwnd->hSaved2 = NULL_REG;
|
||||||
|
pwnd->bDrawed = false;
|
||||||
|
if ((style & TRANSPARENT) == 0)
|
||||||
|
pwnd->uSaveFlag = (arg8 == 0xFFFF ? 1 : 3);
|
||||||
|
|
||||||
|
if (title && (style & TITLE)) {
|
||||||
|
HEAPHANDLE hTitle = heapNewPtr((uint16)strlen(title) + 1, kDataString, title);
|
||||||
|
if (!hTitle) {
|
||||||
|
warning("Can't open window!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pwnd->hTitle = hTitle;
|
||||||
|
StrSplit((char *)heap2Ptr(hTitle), title, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = *rect;
|
||||||
|
if (style == USER || (style & NOFRAME) == 0) {
|
||||||
|
r.grow(1);
|
||||||
|
if (style & TITLE) {
|
||||||
|
r.top -= 10;
|
||||||
|
r.bottom++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pwnd->rect0 = r;
|
||||||
|
const Common::Rect *wmprect = &_wmgrPort->rect;
|
||||||
|
int16 oldtop = pwnd->rect0.top;
|
||||||
|
int16 oldleft = pwnd->rect0.left;
|
||||||
|
if (wmprect->top > pwnd->rect0.top)
|
||||||
|
pwnd->rect0.moveTo(pwnd->rect0.left, wmprect->top);
|
||||||
|
|
||||||
|
if (wmprect->bottom < pwnd->rect0.bottom)
|
||||||
|
pwnd->rect0.moveTo(pwnd->rect0.left, wmprect->bottom
|
||||||
|
- pwnd->rect0.bottom + pwnd->rect0.top);
|
||||||
|
|
||||||
|
if (wmprect->right < pwnd->rect0.right)
|
||||||
|
pwnd->rect0.moveTo(wmprect->right + pwnd->rect0.left
|
||||||
|
- pwnd->rect0.right, pwnd->rect0.top);
|
||||||
|
|
||||||
|
if (wmprect->left > pwnd->rect0.left)
|
||||||
|
pwnd->rect0.moveTo(wmprect->left, pwnd->rect0.top);
|
||||||
|
|
||||||
|
pwnd->rect.moveTo(pwnd->rect.left + pwnd->rect0.left - oldleft,
|
||||||
|
pwnd->rect.top + pwnd->rect0.top - oldtop);
|
||||||
|
if (rect2 == 0)
|
||||||
|
pwnd->rect1 = pwnd->rect0;
|
||||||
|
|
||||||
|
if (argA)
|
||||||
|
DrawWindow(pwnd);
|
||||||
|
_gfx->SetPort((sciPort *)pwnd);
|
||||||
|
_gfx->SetOrigin(pwnd->rect.left, pwnd->rect.top + _wmgrPort->top);
|
||||||
|
pwnd->rect.moveTo(0, 0);
|
||||||
|
return pwnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::DrawWindow(sciWnd *pWnd) {
|
||||||
|
if (pWnd->bDrawed)
|
||||||
|
return;
|
||||||
|
Common::Rect r;
|
||||||
|
int16 wndStyle = pWnd->wndStyle;
|
||||||
|
|
||||||
|
pWnd->bDrawed = true;
|
||||||
|
sciPort *oldport = _gfx->SetPort(_wmgrPort);
|
||||||
|
_gfx->PenColor(0);
|
||||||
|
if ((wndStyle & TRANSPARENT) == 0) {
|
||||||
|
pWnd->hSaved1 = _gfx->SaveBits(pWnd->rect1, 1);
|
||||||
|
if (pWnd->uSaveFlag & 2) {
|
||||||
|
pWnd->hSaved2 = _gfx->SaveBits(pWnd->rect1, 2);
|
||||||
|
if ((wndStyle & USER) == 0)
|
||||||
|
_gfx->FillRect(pWnd->rect1, 2, 0, 0xF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawing frame,shadow and title
|
||||||
|
if ((wndStyle & USER) == 0) {
|
||||||
|
r = pWnd->rect0;
|
||||||
|
if ((wndStyle & NOFRAME) == 0) {
|
||||||
|
r.translate(1, 1);
|
||||||
|
_gfx->FrameRect(r);// shadow
|
||||||
|
r.translate(-1, -1);
|
||||||
|
_gfx->FrameRect(r);// window frame
|
||||||
|
if (wndStyle & TITLE) {
|
||||||
|
_gfx->FrameRect(r);
|
||||||
|
r.grow(-1);
|
||||||
|
_gfx->FillRect(r, 1, 0);
|
||||||
|
if (pWnd->hTitle) {
|
||||||
|
int16 oldcolor = _gfx->GetPort()->penClr;
|
||||||
|
_gfx->PenColor(255);
|
||||||
|
_gfx->TextBox((char *)heap2Ptr(pWnd->hTitle), 1, r, 1, 0);
|
||||||
|
_gfx->PenColor(oldcolor);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = pWnd->rect0;
|
||||||
|
r.top += 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
r.grow(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wndStyle & TRANSPARENT) == 0)
|
||||||
|
_gfx->FillRect(r, 1, pWnd->backClr);
|
||||||
|
_gfx->ShowBits(pWnd->rect0, 1);
|
||||||
|
}
|
||||||
|
_gfx->SetPort(oldport);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::DisposeWindow(sciWnd *pWnd, int16 arg2) {
|
||||||
|
_gfx->SetPort(_wmgrPort);
|
||||||
|
_gfx->RestoreBits(pWnd->hSaved1);
|
||||||
|
_gfx->RestoreBits(pWnd->hSaved2);
|
||||||
|
if (arg2)
|
||||||
|
_gfx->ShowBits(pWnd->rect0, 1);
|
||||||
|
// else
|
||||||
|
// g_sci->ReAnimate(&pwnd->rect0);
|
||||||
|
HEAPHANDLE hh = ptr2heap((byte *)pWnd);
|
||||||
|
windowList.DeleteNode(hh);
|
||||||
|
SelectWindow(windowList.getLast());
|
||||||
|
if (pWnd->hTitle)
|
||||||
|
heapDisposePtr(pWnd->hTitle);
|
||||||
|
heapDisposePtr(hh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUIwindowMgr::UpdateWindow(sciWnd *wnd) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
57
engines/sci/gui/gui_windowmgr.h
Normal file
57
engines/sci/gui/gui_windowmgr.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sci/gui/gui_dbllist.h"
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
class SciGUIwindowMgr {
|
||||||
|
public:
|
||||||
|
SciGUIwindowMgr(EngineState *state, SciGUIgfx *gfx);
|
||||||
|
~SciGUIwindowMgr();
|
||||||
|
|
||||||
|
int16 isFrontWindow(sciWnd *wnd);
|
||||||
|
void SelectWindow(HEAPHANDLE hh);
|
||||||
|
void BeginUpdate(sciWnd *wnd);
|
||||||
|
void EndUpdate(sciWnd *wnd);
|
||||||
|
SCILanguage getSCILanguage();
|
||||||
|
char* StrSplit(char*buff, const char*msg, const char*fmt);
|
||||||
|
char* getIntlString(char*buff, const char*msg, const char*fmt, SCILanguage lang, SCILanguage prop);
|
||||||
|
sciWnd *NewWindow(Common::Rect *rect, Common::Rect *rect2, const char *title, uint16 style, uint16 arg8, uint16 argA);
|
||||||
|
void DrawWindow(sciWnd *wnd);
|
||||||
|
void DisposeWindow(sciWnd *pWnd, int16 arg2);
|
||||||
|
void UpdateWindow(sciWnd *wnd);
|
||||||
|
|
||||||
|
sciPort *_wmgrPort;
|
||||||
|
sciWnd *_picWind;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EngineState *_s;
|
||||||
|
SciGUIgfx *_gfx;
|
||||||
|
|
||||||
|
DblList windowList;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Sci
|
732
engines/sci/gui32/gui32.cpp
Normal file
732
engines/sci/gui32/gui32.cpp
Normal file
|
@ -0,0 +1,732 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
#include "sci/sci.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/tools.h"
|
||||||
|
#include "sci/debug.h" // for g_debug_sleeptime_factor
|
||||||
|
#include "sci/resource.h"
|
||||||
|
#include "sci/engine/state.h"
|
||||||
|
#include "sci/engine/kernel.h"
|
||||||
|
#include "sci/gfx/gfx_gui.h"
|
||||||
|
#include "sci/gfx/gfx_widgets.h"
|
||||||
|
#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual
|
||||||
|
#include "sci/gui32/gui32.h"
|
||||||
|
|
||||||
|
// This is the real width of a text with a specified width of 0
|
||||||
|
#define MAX_TEXT_WIDTH_MAGIC_VALUE 192
|
||||||
|
|
||||||
|
#define ADD_TO_CURRENT_PORT(widget) \
|
||||||
|
{if (s->port) \
|
||||||
|
s->port->add((GfxContainer *)s->port, widget); \
|
||||||
|
else \
|
||||||
|
s->picture_port->add((GfxContainer *)s->visual, widget);}
|
||||||
|
|
||||||
|
#define ADD_TO_CURRENT_PICTURE_PORT(widget) \
|
||||||
|
{if (s->port) \
|
||||||
|
s->port->add((GfxContainer *)s->port, widget); \
|
||||||
|
else \
|
||||||
|
s->picture_port->add((GfxContainer *)s->picture_port, widget);}
|
||||||
|
|
||||||
|
#define ADD_TO_WINDOW_PORT(widget) \
|
||||||
|
s->wm_port->add((GfxContainer *)s->wm_port, widget);
|
||||||
|
|
||||||
|
#define FULL_REDRAW()\
|
||||||
|
if (s->visual) \
|
||||||
|
s->visual->draw(gfxw_point_zero); \
|
||||||
|
gfxop_update(s->gfx_state);
|
||||||
|
|
||||||
|
#define K_DRAWPIC_FLAG_MIRRORED (1 << 14)
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
SciGUI32::SciGUI32(OSystem *system, EngineState *state)
|
||||||
|
: _system(system), s(state) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SciGUI32::~SciGUI32() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::init(bool oldGfxFunctions) {
|
||||||
|
_usesOldGfxFunctions = oldGfxFunctions;
|
||||||
|
activated_icon_bar = false;
|
||||||
|
port_origin_x = 0;
|
||||||
|
port_origin_y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUI32::getTimeTicks() {
|
||||||
|
uint32 start_time;
|
||||||
|
start_time = _system->getMillis() - s->game_start_time;
|
||||||
|
return start_time * 60 / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::wait(int16 ticks) {
|
||||||
|
uint32 time;
|
||||||
|
|
||||||
|
time = g_system->getMillis();
|
||||||
|
s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000);
|
||||||
|
s->last_wait_time = time;
|
||||||
|
|
||||||
|
ticks *= g_debug_sleeptime_factor;
|
||||||
|
gfxop_sleep(s->gfx_state, ticks * 1000 / 60);
|
||||||
|
|
||||||
|
|
||||||
|
// Reset speed throttler: Game is playing along nicely anyway
|
||||||
|
if (ticks > 0)
|
||||||
|
s->speedThrottler->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::setPort(uint16 portPtr) {
|
||||||
|
GfxPort *new_port;
|
||||||
|
|
||||||
|
/* We depart from official semantics here, sorry!
|
||||||
|
Reasoning: Sierra SCI does not clip ports while we do.
|
||||||
|
Therefore a draw to the titlebar port (which is the
|
||||||
|
official semantics) would cut off the lower part of the
|
||||||
|
icons in an SCI1 icon bar. Instead we have an
|
||||||
|
iconbar_port that does not exist in SSCI. */
|
||||||
|
if (portPtr == 65535) portPtr = s->iconbar_port->_ID;
|
||||||
|
|
||||||
|
new_port = s->visual->getPort(portPtr);
|
||||||
|
|
||||||
|
if (!new_port) {
|
||||||
|
warning("Invalid port %04x requested", portPtr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->port->draw(gfxw_point_zero); // Update the port we're leaving
|
||||||
|
s->port = new_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft) {
|
||||||
|
if (activated_icon_bar) {
|
||||||
|
port_origin_x = port_origin_y = 0;
|
||||||
|
activated_icon_bar = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
port_origin_y = rect.top;
|
||||||
|
port_origin_x = rect.left;
|
||||||
|
|
||||||
|
if (rect.top == -10) {
|
||||||
|
s->port->draw(gfxw_point_zero); // Update the port we're leaving
|
||||||
|
s->port = s->iconbar_port;
|
||||||
|
activated_icon_bar = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify the graphics resource manager that the pic port bounds changed
|
||||||
|
s->gfx_state->gfxResMan->changePortBounds(picLeft, picTop, rect.right + picLeft, rect.bottom + picTop);
|
||||||
|
|
||||||
|
// LSL6 calls kSetPort to extend the screen to draw the GUI. If we free all resources
|
||||||
|
// here, the background picture is freed too, and this makes everything a big mess.
|
||||||
|
// FIXME/TODO: This code really needs to be rewritten to conform to the original behavior
|
||||||
|
if (s->_gameName != "lsl6") {
|
||||||
|
s->gfx_state->pic_port_bounds = gfx_rect(picLeft, picTop, rect.right, rect.bottom);
|
||||||
|
|
||||||
|
// FIXME: Should really only invalidate all loaded pic resources here;
|
||||||
|
// this is overkill
|
||||||
|
s->gfx_state->gfxResMan->freeAllResources();
|
||||||
|
} else {
|
||||||
|
// WORKAROUND for LSL6
|
||||||
|
warning("SetPort case 6 called in LSL6.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI32::getPort() {
|
||||||
|
return make_reg(0, s->port->_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::globalToLocal(int16 *x, int16 *y) {
|
||||||
|
*x = *x - s->port->zone.x;
|
||||||
|
*y = *y - s->port->zone.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::localToGlobal(int16 *x, int16 *y) {
|
||||||
|
*x = *x + s->port->zone.x;
|
||||||
|
*y = *y + s->port->zone.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI32::newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) {
|
||||||
|
GfxPort *window;
|
||||||
|
int x, y, xl, yl;
|
||||||
|
gfx_color_t bgcolor;
|
||||||
|
gfx_color_t fgcolor;
|
||||||
|
gfx_color_t black;
|
||||||
|
gfx_color_t lWhite;
|
||||||
|
|
||||||
|
y = rect1.top;
|
||||||
|
x = rect1.left;
|
||||||
|
yl = rect1.height();
|
||||||
|
xl = rect1.width();
|
||||||
|
|
||||||
|
y += s->wm_port->_bounds.y;
|
||||||
|
|
||||||
|
if (x + xl > 319)
|
||||||
|
x -= ((x + xl) - 319);
|
||||||
|
|
||||||
|
bgcolor.mask = 0;
|
||||||
|
|
||||||
|
if (colorBack >= 0) {
|
||||||
|
if (!s->resMan->isVGA())
|
||||||
|
bgcolor.visual = get_pic_color(s, MIN<int>(colorBack, 15));
|
||||||
|
else
|
||||||
|
bgcolor.visual = get_pic_color(s, colorBack);
|
||||||
|
bgcolor.mask = GFX_MASK_VISUAL;
|
||||||
|
} else {
|
||||||
|
bgcolor.visual = PaletteEntry(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bgcolor.priority = priority;
|
||||||
|
bgcolor.mask |= priority >= 0 ? GFX_MASK_PRIORITY : 0;
|
||||||
|
bgcolor.alpha = 0;
|
||||||
|
bgcolor.control = -1;
|
||||||
|
debugC(2, kDebugLevelGraphics, "New window with params %d, %d, %d, %d\n", rect1.top, rect1.left, rect1.height(), rect1.width());
|
||||||
|
|
||||||
|
fgcolor.visual = get_pic_color(s, colorPen);
|
||||||
|
fgcolor.mask = GFX_MASK_VISUAL;
|
||||||
|
fgcolor.control = -1;
|
||||||
|
fgcolor.priority = -1;
|
||||||
|
fgcolor.alpha = 0;
|
||||||
|
black.visual = get_pic_color(s, 0);
|
||||||
|
black.mask = GFX_MASK_VISUAL;
|
||||||
|
black.alpha = 0;
|
||||||
|
black.control = -1;
|
||||||
|
black.priority = -1;
|
||||||
|
lWhite.visual = get_pic_color(s, !s->resMan->isVGA() ? 15 : 255);
|
||||||
|
lWhite.mask = GFX_MASK_VISUAL;
|
||||||
|
lWhite.alpha = 0;
|
||||||
|
lWhite.priority = -1;
|
||||||
|
lWhite.control = -1;
|
||||||
|
|
||||||
|
window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor,
|
||||||
|
s->titlebar_port->_font, lWhite, black, title ? s->strSplit(title, NULL).c_str() : NULL, style);
|
||||||
|
|
||||||
|
// PQ3 and SCI1.1 games have the interpreter store underBits implicitly
|
||||||
|
if (rect2.top != 0 && rect2.left != 0 && rect2.height() != 0 && rect2.width() != 0)
|
||||||
|
gfxw_port_auto_restore_background(s->visual, window, gfx_rect(rect2.left, rect2.top + s->wm_port->_bounds.y, rect2.width(), rect2.height()));
|
||||||
|
|
||||||
|
ADD_TO_WINDOW_PORT(window);
|
||||||
|
FULL_REDRAW();
|
||||||
|
|
||||||
|
window->draw(gfxw_point_zero);
|
||||||
|
gfxop_update(s->gfx_state);
|
||||||
|
|
||||||
|
s->port = window; // Set active port
|
||||||
|
|
||||||
|
return make_reg(0, window->_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::disposeWindow(uint16 windowPtr, int16 arg2) {
|
||||||
|
GfxPort *goner;
|
||||||
|
GfxPort *pred;
|
||||||
|
|
||||||
|
goner = s->visual->getPort(windowPtr);
|
||||||
|
if ((windowPtr < 3) || (goner == NULL)) {
|
||||||
|
error("Removal of invalid window %04x requested", windowPtr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->dyn_views && (GfxContainer *)s->dyn_views->_parent == (GfxContainer *)goner) {
|
||||||
|
reparentize_primary_widget_lists(s, (GfxPort *) goner->_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->drop_views && (GfxContainer *)s->drop_views->_parent == (GfxContainer *)goner)
|
||||||
|
s->drop_views = NULL; // Kill it
|
||||||
|
|
||||||
|
pred = gfxw_remove_port(s->visual, goner);
|
||||||
|
|
||||||
|
if (goner == s->port) // Did we kill the active port?
|
||||||
|
s->port = pred;
|
||||||
|
|
||||||
|
// Find the last port that exists and that isn't marked no-switch
|
||||||
|
int id = s->visual->_portRefs.size() - 1;
|
||||||
|
while (id > 0 && (!s->visual->_portRefs[id] || (s->visual->_portRefs[id]->_flags & GFXW_FLAG_NO_IMPLICIT_SWITCH)))
|
||||||
|
id--;
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Activating port %d after disposing window %d\n", id, windowPtr);
|
||||||
|
s->port = (id >= 0) ? s->visual->_portRefs[id] : 0;
|
||||||
|
|
||||||
|
if (!s->port)
|
||||||
|
s->port = gfxw_find_default_port(s->visual);
|
||||||
|
|
||||||
|
gfxop_update(s->gfx_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define K_DISPLAY_SET_COORDS 100
|
||||||
|
#define K_DISPLAY_SET_ALIGNMENT 101
|
||||||
|
#define K_DISPLAY_SET_COLOR 102
|
||||||
|
#define K_DISPLAY_SET_BGCOLOR 103
|
||||||
|
#define K_DISPLAY_SET_GRAYTEXT 104
|
||||||
|
#define K_DISPLAY_SET_FONT 105
|
||||||
|
#define K_DISPLAY_WIDTH 106
|
||||||
|
#define K_DISPLAY_SAVE_UNDER 107
|
||||||
|
#define K_DISPLAY_RESTORE_UNDER 108
|
||||||
|
#define K_DONT_UPDATE_IMMEDIATELY 121
|
||||||
|
|
||||||
|
void SciGUI32::display(const char *text, int argc, reg_t *argv) {
|
||||||
|
int argpt = 0;
|
||||||
|
int temp;
|
||||||
|
bool save_under = false;
|
||||||
|
gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 };
|
||||||
|
GfxPort *port = (s->port) ? s->port : s->picture_port;
|
||||||
|
bool update_immediately = true;
|
||||||
|
|
||||||
|
gfx_color_t color0, *color1, bg_color;
|
||||||
|
gfx_alignment_t halign = ALIGN_LEFT;
|
||||||
|
rect_t area = gfx_rect(port->draw_pos.x, port->draw_pos.y, 320 - port->draw_pos.x, 200 - port->draw_pos.y);
|
||||||
|
int gray = port->gray_text;
|
||||||
|
int font_nr = port->_font;
|
||||||
|
GfxText *text_handle;
|
||||||
|
|
||||||
|
color0 = port->_color;
|
||||||
|
bg_color = port->_bgcolor;
|
||||||
|
// TODO: in SCI1VGA the default colors for text and background are #0 (black)
|
||||||
|
// SCI0 case should be checked
|
||||||
|
if (s->resMan->isVGA()) {
|
||||||
|
// This priority check fixes the colors in the menus in KQ5
|
||||||
|
// TODO/FIXME: Is this correct?
|
||||||
|
if (color0.priority >= 0)
|
||||||
|
color0.visual = get_pic_color(s, 0);
|
||||||
|
if (bg_color.priority >= 0)
|
||||||
|
bg_color.visual = get_pic_color(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (argpt < argc) {
|
||||||
|
switch (argv[argpt++].toUint16()) {
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_COORDS:
|
||||||
|
|
||||||
|
area.x = argv[argpt++].toUint16();
|
||||||
|
area.y = argv[argpt++].toUint16();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_coords(%d, %d)\n", area.x, area.y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_ALIGNMENT:
|
||||||
|
|
||||||
|
halign = (gfx_alignment_t)argv[argpt++].toSint16();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_align(%d)\n", halign);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_COLOR:
|
||||||
|
|
||||||
|
temp = argv[argpt++].toSint16();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_color(%d)\n", temp);
|
||||||
|
if (!s->resMan->isVGA() && temp >= 0 && temp <= 15)
|
||||||
|
color0 = (s->ega_colors[temp]);
|
||||||
|
else
|
||||||
|
if (s->resMan->isVGA() && temp >= 0 && temp < 256) {
|
||||||
|
color0.visual = get_pic_color(s, temp);
|
||||||
|
color0.mask = GFX_MASK_VISUAL;
|
||||||
|
} else
|
||||||
|
if (temp == -1)
|
||||||
|
color0 = transparent;
|
||||||
|
else
|
||||||
|
warning("Display: Attempt to set invalid fg color %d", temp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_BGCOLOR:
|
||||||
|
|
||||||
|
temp = argv[argpt++].toSint16();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_bg_color(%d)\n", temp);
|
||||||
|
if (!s->resMan->isVGA() && temp >= 0 && temp <= 15)
|
||||||
|
bg_color = s->ega_colors[temp];
|
||||||
|
else
|
||||||
|
if (s->resMan->isVGA() && temp >= 0 && temp <= 256) {
|
||||||
|
bg_color.visual = get_pic_color(s, temp);
|
||||||
|
bg_color.mask = GFX_MASK_VISUAL;
|
||||||
|
} else
|
||||||
|
if (temp == -1)
|
||||||
|
bg_color = transparent;
|
||||||
|
else
|
||||||
|
warning("Display: Attempt to set invalid fg color %d", temp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_GRAYTEXT:
|
||||||
|
|
||||||
|
gray = argv[argpt++].toSint16();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_graytext(%d)\n", gray);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SET_FONT:
|
||||||
|
|
||||||
|
font_nr = argv[argpt++].toUint16();
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_font(\"font.%03d\")\n", font_nr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_WIDTH:
|
||||||
|
|
||||||
|
area.width = argv[argpt++].toUint16();
|
||||||
|
if (area.width == 0)
|
||||||
|
area.width = MAX_TEXT_WIDTH_MAGIC_VALUE;
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_width(%d)\n", area.width);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_SAVE_UNDER:
|
||||||
|
|
||||||
|
save_under = true;
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_save_under()\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case K_DISPLAY_RESTORE_UNDER:
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: restore_under(%04x)\n", argv[argpt].toUint16());
|
||||||
|
graph_restore_box(s, argv[argpt++]);
|
||||||
|
update_immediately = true;
|
||||||
|
argpt++;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case K_DONT_UPDATE_IMMEDIATELY:
|
||||||
|
|
||||||
|
update_immediately = false;
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: set_dont_update()\n");
|
||||||
|
argpt++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
debugC(2, kDebugLevelGraphics, "Unknown Display() command %x\n", argv[argpt - 1].toUint16());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (halign == ALIGN_LEFT) {
|
||||||
|
// If the text does not fit on the screen, move it to the left and upwards until it does
|
||||||
|
gfxop_get_text_params(s->gfx_state, font_nr, text, area.width, &area.width, &area.height, 0, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// Make the text fit on the screen
|
||||||
|
if (area.x + area.width > 320)
|
||||||
|
area.x += 320 - area.x - area.width; // Plus negative number = subtraction
|
||||||
|
|
||||||
|
if (area.y + area.height > 200)
|
||||||
|
area.y += 200 - area.y - area.height; // Plus negative number = subtraction
|
||||||
|
} else {
|
||||||
|
// If the text does not fit on the screen, clip it till it does
|
||||||
|
if (area.x + area.width > s->gfx_state->pic_port_bounds.width)
|
||||||
|
area.width = s->gfx_state->pic_port_bounds.width - area.x;
|
||||||
|
|
||||||
|
if (area.y + area.height > s->gfx_state->pic_port_bounds.height)
|
||||||
|
area.height = s->gfx_state->pic_port_bounds.height - area.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gray)
|
||||||
|
color1 = &bg_color;
|
||||||
|
else
|
||||||
|
color1 = &color0;
|
||||||
|
|
||||||
|
assert_primary_widget_lists(s);
|
||||||
|
|
||||||
|
text_handle = gfxw_new_text(s->gfx_state, area, font_nr, s->strSplit(text).c_str(), halign, ALIGN_TOP, color0, *color1, bg_color, 0);
|
||||||
|
|
||||||
|
if (!text_handle) {
|
||||||
|
error("Display: Failed to create text widget");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save_under) { // Backup
|
||||||
|
rect_t save_area = text_handle->_bounds;
|
||||||
|
save_area.x += port->_bounds.x;
|
||||||
|
save_area.y += port->_bounds.y;
|
||||||
|
|
||||||
|
s->r_acc = graph_save_box(s, save_area);
|
||||||
|
text_handle->_serial++; // This is evil!
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Saving (%d, %d) size (%d, %d) as %04x:%04x\n", save_area.x, save_area.y, save_area.width, save_area.height, PRINT_REG(s->r_acc));
|
||||||
|
}
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Display: Commiting text '%s'\n", text);
|
||||||
|
|
||||||
|
//ADD_TO_CURRENT_PICTURE_PORT(text_handle);
|
||||||
|
|
||||||
|
ADD_TO_CURRENT_PICTURE_PORT(text_handle);
|
||||||
|
if ((!s->pic_not_valid) && update_immediately) { // Refresh if drawn to valid picture
|
||||||
|
FULL_REDRAW();
|
||||||
|
debugC(2, kDebugLevelGraphics, "Refreshing display...\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::textSize(const char *text, int16 fontId, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
|
||||||
|
int width, height;
|
||||||
|
if (maxWidth < 0)
|
||||||
|
maxWidth = 0;
|
||||||
|
gfxop_get_text_params(s->gfx_state, fontId, text, maxWidth ? maxWidth : MAX_TEXT_WIDTH_MAGIC_VALUE,
|
||||||
|
&width, &height, 0, NULL, NULL, NULL);
|
||||||
|
*textWidth = width; *textHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::textFonts(int argc, reg_t *argv) {
|
||||||
|
// stub
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::textColors(int argc, reg_t *argv) {
|
||||||
|
// stub
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::drawPicture(sciResourceId pictureId, uint16 showStyle, uint16 flags, int16 EGApaletteNo) {
|
||||||
|
drawn_pic_t dp;
|
||||||
|
gfx_color_t transparent = s->wm_port->_bgcolor;
|
||||||
|
int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY;
|
||||||
|
bool add_to_pic = flags;
|
||||||
|
|
||||||
|
dp.nr = pictureId;
|
||||||
|
if (EGApaletteNo != -1) {
|
||||||
|
dp.palette = EGApaletteNo;
|
||||||
|
} else {
|
||||||
|
dp.palette = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showStyle & K_DRAWPIC_FLAG_MIRRORED)
|
||||||
|
picFlags |= DRAWPIC1_FLAG_MIRRORED;
|
||||||
|
|
||||||
|
gfxop_disable_dirty_frames(s->gfx_state);
|
||||||
|
|
||||||
|
if (NULL != s->old_screen) {
|
||||||
|
gfxop_free_pixmap(s->gfx_state, s->old_screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->old_screen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 10, 320, 190));
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "Drawing pic.%03d\n", pictureId);
|
||||||
|
if (add_to_pic) {
|
||||||
|
gfxop_add_to_pic(s->gfx_state, dp.nr, picFlags, dp.palette);
|
||||||
|
} else {
|
||||||
|
gfxop_new_pic(s->gfx_state, dp.nr, picFlags, dp.palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete s->wm_port;
|
||||||
|
delete s->picture_port;
|
||||||
|
delete s->iconbar_port;
|
||||||
|
|
||||||
|
s->wm_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent);
|
||||||
|
s->picture_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent);
|
||||||
|
|
||||||
|
s->iconbar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent);
|
||||||
|
s->iconbar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
|
||||||
|
|
||||||
|
s->visual->add((GfxContainer *)s->visual, s->picture_port);
|
||||||
|
s->visual->add((GfxContainer *)s->visual, s->wm_port);
|
||||||
|
s->visual->add((GfxContainer *)s->visual, s->iconbar_port);
|
||||||
|
|
||||||
|
s->port = s->picture_port;
|
||||||
|
|
||||||
|
s->pic_priority_table = gfxop_get_pic_metainfo(s->gfx_state);
|
||||||
|
|
||||||
|
s->pic_animate = showStyle & 0xff; // The animation used during kAnimate() later on
|
||||||
|
|
||||||
|
s->dyn_views = NULL;
|
||||||
|
s->drop_views = NULL;
|
||||||
|
|
||||||
|
s->priority_first = 42;
|
||||||
|
|
||||||
|
if (_usesOldGfxFunctions)
|
||||||
|
s->priority_last = 200;
|
||||||
|
else
|
||||||
|
s->priority_last = 190;
|
||||||
|
|
||||||
|
s->pic_not_valid = 1;
|
||||||
|
s->pic_is_new = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo) {
|
||||||
|
int loop = loopNo;
|
||||||
|
int cel = cellNo;
|
||||||
|
GfxView *new_view;
|
||||||
|
|
||||||
|
gfxop_check_cel(s->gfx_state, viewId, &loop, &cel);
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "DrawCel((%d,%d), (view.%d, %d, %d), p=%d)\n", leftPos, topPos, viewId, loop, cel, priority);
|
||||||
|
|
||||||
|
new_view = gfxw_new_view(s->gfx_state, Common::Point(leftPos, topPos), viewId, loop, cel, 0, priority, -1,
|
||||||
|
ALIGN_LEFT, ALIGN_TOP, GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET);
|
||||||
|
|
||||||
|
ADD_TO_CURRENT_PICTURE_PORT(new_view);
|
||||||
|
FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse) {
|
||||||
|
rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height());
|
||||||
|
|
||||||
|
ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, text, fontId,
|
||||||
|
(int8)(style & kControlStateFramed), (int8)inverse, (int8)(style & kControlStateDisabled)));
|
||||||
|
if (!s->pic_not_valid) FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse) {
|
||||||
|
rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height());
|
||||||
|
|
||||||
|
ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, text, fontId, (gfx_alignment_t) mode,
|
||||||
|
(int8)(!!(style & kControlStateDitherFramed)), (int8)inverse));
|
||||||
|
if (!s->pic_not_valid) FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
static gfx_color_t graph_map_color(EngineState *s, int color, int priority, int control) {
|
||||||
|
gfx_color_t retval;
|
||||||
|
|
||||||
|
if (!s->resMan->isVGA()) {
|
||||||
|
retval = s->ega_colors[(color >=0 && color < 16)? color : 0];
|
||||||
|
gfxop_set_color(s->gfx_state, &retval, (color < 0) ? -1 : retval.visual.r, retval.visual.g, retval.visual.b,
|
||||||
|
(color == -1) ? 255 : 0, priority, control);
|
||||||
|
} else {
|
||||||
|
retval.visual = get_pic_color(s, color);
|
||||||
|
retval.alpha = 0;
|
||||||
|
retval.priority = priority;
|
||||||
|
retval.control = control;
|
||||||
|
retval.mask = GFX_MASK_VISUAL | ((priority >= 0) ? GFX_MASK_PRIORITY : 0) | ((control >= 0) ? GFX_MASK_CONTROL : 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _k_graph_rebuild_port_with_color(EngineState *s, gfx_color_t newbgcolor) {
|
||||||
|
GfxPort *port = s->port;
|
||||||
|
GfxPort *newport;
|
||||||
|
|
||||||
|
newport = sciw_new_window(s, port->zone, port->_font, port->_color, newbgcolor,
|
||||||
|
s->titlebar_port->_font, s->ega_colors[15], s->ega_colors[8],
|
||||||
|
port->_title_text.c_str(), port->port_flags & ~kWindowTransparent);
|
||||||
|
|
||||||
|
if (s->dyn_views) {
|
||||||
|
int found = 0;
|
||||||
|
GfxContainer *parent = s->dyn_views->_parent;
|
||||||
|
|
||||||
|
while (parent && !(found |= (parent == port)))
|
||||||
|
parent = parent->_parent;
|
||||||
|
|
||||||
|
s->dyn_views = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
port->_parent->add((GfxContainer *)port->_parent, newport);
|
||||||
|
delete port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::graphFillBoxForeground(Common::Rect rect) {
|
||||||
|
_k_graph_rebuild_port_with_color(s, s->port->_color);
|
||||||
|
//port = _s->port;
|
||||||
|
|
||||||
|
FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::graphFillBoxBackground(Common::Rect rect) {
|
||||||
|
_k_graph_rebuild_port_with_color(s, s->port->_bgcolor);
|
||||||
|
//port = _s->port;
|
||||||
|
|
||||||
|
FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control) {
|
||||||
|
gfx_color_t fillColor = graph_map_color(s, color, priority, control);
|
||||||
|
fillColor.mask = (byte)colorMask;
|
||||||
|
rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height());
|
||||||
|
|
||||||
|
//debugC(2, kDebugLevelGraphics, "fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n",
|
||||||
|
// argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[6].toSint16(), priority, control, argv[5].toUint16());
|
||||||
|
|
||||||
|
// FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now
|
||||||
|
//ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code
|
||||||
|
|
||||||
|
// FillBox seems to be meant again s->port instead of s->picture_port, at least in QfG3
|
||||||
|
// warning("Fillbox");
|
||||||
|
// ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT));
|
||||||
|
s->picture_port->add((GfxContainer *)s->picture_port, gfxw_new_box(s->gfx_state, area, fillColor, fillColor, GFX_BOX_SHADE_FLAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control) {
|
||||||
|
gfx_color_t gfxcolor = graph_map_color(s, color, priority, control);
|
||||||
|
|
||||||
|
debugC(2, kDebugLevelGraphics, "draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n",
|
||||||
|
rect.left, rect.top, rect.right, rect.bottom, color, priority, control, gfxcolor.mask);
|
||||||
|
|
||||||
|
// Note: it's quite possible that the coordinates of the line will *not* form a valid rectangle (e.g. it might
|
||||||
|
// have negative width/height). The actual dirty rectangle is constructed in gfxdr_add_dirty().
|
||||||
|
// FIXME/TODO: We need to change the semantics of this call, so that no fake rectangles are used. As it is, it's
|
||||||
|
// not possible change rect_t to Common::Rect, as we assume that Common::Rect forms a *valid* rectangle.
|
||||||
|
ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_line(Common::Point(rect.left, rect.top), Common::Point(rect.right, rect.bottom),
|
||||||
|
gfxcolor, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL));
|
||||||
|
FULL_REDRAW();
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_t SciGUI32::graphSaveBox(Common::Rect rect, uint16 flags) {
|
||||||
|
rect_t area;
|
||||||
|
area.x = rect.left + s->port->zone.x + port_origin_x;
|
||||||
|
area.y = rect.top + s->port->zone.y + port_origin_y;
|
||||||
|
area.width = rect.width() - port_origin_x;
|
||||||
|
area.height = rect.height() - port_origin_y;
|
||||||
|
|
||||||
|
return graph_save_box(s, area);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::graphRestoreBox(reg_t handle) {
|
||||||
|
graph_restore_box(s, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::paletteSet(int resourceNo, int flags) {
|
||||||
|
//warning("STUB");
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 SciGUI32::paletteFind(int r, int g, int b) {
|
||||||
|
int i, delta, bestindex = -1, bestdelta = 200000;
|
||||||
|
|
||||||
|
for (i = 0; i < s->gfx_state->gfxResMan->getColorCount(); i++) {
|
||||||
|
int dr = abs(s->gfx_state->gfxResMan->getColor(i).r - r);
|
||||||
|
int dg = abs(s->gfx_state->gfxResMan->getColor(i).g - g);
|
||||||
|
int db = abs(s->gfx_state->gfxResMan->getColor(i).b - b);
|
||||||
|
|
||||||
|
delta = dr * dr + dg * dg + db * db;
|
||||||
|
|
||||||
|
if (delta < bestdelta) {
|
||||||
|
bestdelta = delta;
|
||||||
|
bestindex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't warn about inexact mappings -- it's actually the
|
||||||
|
// rule rather than the exception
|
||||||
|
return bestindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::paletteAnimate(int fromColor, int toColor, int speed) {
|
||||||
|
warning("STUB");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SciGUI32::moveCursor(int16 x, int16 y) {
|
||||||
|
Common::Point newPos;
|
||||||
|
|
||||||
|
// newPos = s->gfx_state->pointer_pos;
|
||||||
|
|
||||||
|
newPos.x = x + s->port->zone.x;
|
||||||
|
newPos.y = y + s->port->zone.y;
|
||||||
|
|
||||||
|
if (newPos.x > s->port->zone.x + s->port->zone.width)
|
||||||
|
newPos.x = s->port->zone.x + s->port->zone.width;
|
||||||
|
if (newPos.y > s->port->zone.y + s->port->zone.height)
|
||||||
|
newPos.y = s->port->zone.y + s->port->zone.height;
|
||||||
|
|
||||||
|
if (newPos.x < 0) newPos.x = 0;
|
||||||
|
if (newPos.y < 0) newPos.y = 0;
|
||||||
|
gfxop_set_pointer_position(s->gfx_state, newPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Sci
|
79
engines/sci/gui32/gui32.h
Normal file
79
engines/sci/gui32/gui32.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Sci {
|
||||||
|
|
||||||
|
class SciGUI32 : public SciGUI {
|
||||||
|
public:
|
||||||
|
SciGUI32(OSystem *system, EngineState *s);
|
||||||
|
~SciGUI32();
|
||||||
|
|
||||||
|
void init(bool oldGfxFunctions);
|
||||||
|
|
||||||
|
int16 getTimeTicks();
|
||||||
|
void wait(int16 ticks);
|
||||||
|
void setPort(uint16 portPtr);
|
||||||
|
void setPortPic(Common::Rect rect, int16 picTop, int16 picLeft);
|
||||||
|
reg_t getPort();
|
||||||
|
void globalToLocal(int16 *x, int16 *y);
|
||||||
|
void localToGlobal(int16 *x, int16 *y);
|
||||||
|
reg_t newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title);
|
||||||
|
void disposeWindow(uint16 windowPtr, int16 arg2);
|
||||||
|
|
||||||
|
void display(const char *text, int argc, reg_t *argv);
|
||||||
|
|
||||||
|
void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
|
||||||
|
void textFonts(int argc, reg_t *argv);
|
||||||
|
void textColors(int argc, reg_t *argv);
|
||||||
|
|
||||||
|
void drawPicture(sciResourceId pictureId, uint16 showStyle, uint16 flags, int16 EGApaletteNo);
|
||||||
|
void drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo);
|
||||||
|
void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse);
|
||||||
|
void drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse);
|
||||||
|
|
||||||
|
void graphFillBoxForeground(Common::Rect rect);
|
||||||
|
void graphFillBoxBackground(Common::Rect rect);
|
||||||
|
void graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control);
|
||||||
|
void graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control);
|
||||||
|
reg_t graphSaveBox(Common::Rect rect, uint16 flags);
|
||||||
|
void graphRestoreBox(reg_t handle);
|
||||||
|
|
||||||
|
void paletteSet(int resourceNo, int flags);
|
||||||
|
virtual int16 paletteFind(int r, int g, int b);
|
||||||
|
void paletteAnimate(int fromColor, int toColor, int speed);
|
||||||
|
|
||||||
|
void moveCursor(int16 x, int16 y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OSystem *_system;
|
||||||
|
EngineState *s;
|
||||||
|
bool _usesOldGfxFunctions;
|
||||||
|
|
||||||
|
bool activated_icon_bar; // FIXME: Avoid non-const global vars
|
||||||
|
int port_origin_x; // FIXME: Avoid non-const global vars
|
||||||
|
int port_origin_y; // FIXME: Avoid non-const global vars
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Sci
|
|
@ -55,6 +55,16 @@ MODULE_OBJS = \
|
||||||
gfx/res_pic.o \
|
gfx/res_pic.o \
|
||||||
gfx/res_view.o \
|
gfx/res_view.o \
|
||||||
gfx/seq_decoder.o \
|
gfx/seq_decoder.o \
|
||||||
|
gui/gui.o \
|
||||||
|
gui/gui_dbllist.o \
|
||||||
|
gui/gui_font.o \
|
||||||
|
gui/gui_gfx.o \
|
||||||
|
gui/gui_memmgr.o \
|
||||||
|
gui/gui_picture.o \
|
||||||
|
gui/gui_screen.o \
|
||||||
|
gui/gui_view.o \
|
||||||
|
gui/gui_windowmgr.o \
|
||||||
|
gui32/gui32.o \
|
||||||
sfx/core.o \
|
sfx/core.o \
|
||||||
sfx/iterator.o \
|
sfx/iterator.o \
|
||||||
sfx/songlib.o \
|
sfx/songlib.o \
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "sci/engine/state.h"
|
#include "sci/engine/state.h"
|
||||||
#include "sci/engine/kernel.h"
|
#include "sci/engine/kernel.h"
|
||||||
|
|
||||||
|
#include "sci/gui32/gui32.h"
|
||||||
|
|
||||||
#include "sci/gfx/gfx_resource.h"
|
#include "sci/gfx/gfx_resource.h"
|
||||||
#include "sci/gfx/gfx_tools.h"
|
#include "sci/gfx/gfx_tools.h"
|
||||||
#include "sci/gfx/operations.h"
|
#include "sci/gfx/operations.h"
|
||||||
|
@ -44,7 +46,7 @@ namespace Sci {
|
||||||
class GfxDriver;
|
class GfxDriver;
|
||||||
|
|
||||||
SciEngine::SciEngine(OSystem *syst, const SciGameDescription *desc)
|
SciEngine::SciEngine(OSystem *syst, const SciGameDescription *desc)
|
||||||
: Engine(syst), _gameDescription(desc) {
|
: Engine(syst), _gameDescription(desc), _system(syst) {
|
||||||
// Put your engine in a sane state, but do nothing big yet;
|
// Put your engine in a sane state, but do nothing big yet;
|
||||||
// in particular, do not load data from files; rather, if you
|
// in particular, do not load data from files; rather, if you
|
||||||
// need to do such things, do them from init().
|
// need to do such things, do them from init().
|
||||||
|
@ -152,6 +154,10 @@ Common::Error SciEngine::run() {
|
||||||
GfxState gfx_state;
|
GfxState gfx_state;
|
||||||
_gamestate->gfx_state = &gfx_state;
|
_gamestate->gfx_state = &gfx_state;
|
||||||
|
|
||||||
|
// GUI change
|
||||||
|
//_gamestate->gui = new SciGUI(_system, _gamestate); // new
|
||||||
|
_gamestate->gui = new SciGUI32(_system, _gamestate); // old
|
||||||
|
|
||||||
// Assign default values to the config manager, in case settings are missing
|
// Assign default values to the config manager, in case settings are missing
|
||||||
ConfMan.registerDefault("dither_mode", "0");
|
ConfMan.registerDefault("dither_mode", "0");
|
||||||
|
|
||||||
|
@ -183,6 +189,8 @@ Common::Error SciEngine::run() {
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gamestate->gui->init(_kernel->usesOldGfxFunctions());
|
||||||
|
|
||||||
printf("Emulating SCI version %s\n", getSciVersionDesc(getSciVersion()).c_str());
|
printf("Emulating SCI version %s\n", getSciVersionDesc(getSciVersion()).c_str());
|
||||||
|
|
||||||
game_run(&_gamestate); // Run the game
|
game_run(&_gamestate); // Run the game
|
||||||
|
|
|
@ -132,6 +132,7 @@ private:
|
||||||
Kernel *_kernel;
|
Kernel *_kernel;
|
||||||
Vocabulary *_vocabulary;
|
Vocabulary *_vocabulary;
|
||||||
Console *_console;
|
Console *_console;
|
||||||
|
OSystem *_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue