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.h" />
|
||||
</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">
|
||||
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
||||
<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.h" />
|
||||
</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">
|
||||
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
|
||||
<File RelativePath="..\..\engines\sci\sfx\core.h" />
|
||||
|
|
|
@ -332,18 +332,18 @@ SciKernelFunction kfunct_mappers[] = {
|
|||
DEFUN("ShowMovie", kShowMovie, "..*"),
|
||||
DEFUN("SetVideoMode", kSetVideoMode, "i"),
|
||||
DEFUN("Platform", kPlatform, "i*"),
|
||||
DEFUN("PalVary", kPalVary, "ii*"),
|
||||
DEFUN("TextColors", kTextColors, ".*"),
|
||||
DEFUN("TextFonts", kTextFonts, ".*"),
|
||||
|
||||
#if 0
|
||||
// Stub functions
|
||||
DEFUN("PalVary", kPalVary, "ii*"),
|
||||
DEFUN("ShiftScreen", kShiftScreen, ".*"),
|
||||
DEFUN("MemorySegment", kMemorySegment, ".*"),
|
||||
DEFUN("ListOps", kListOps, ".*"),
|
||||
DEFUN("ATan", kATan, ".*"),
|
||||
DEFUN("MergePoly", kMergePoly, ".*"),
|
||||
DEFUN("AssertPalette", kAssertPalette, ".*"),
|
||||
DEFUN("TextColors", kTextColors, ".*"),
|
||||
DEFUN("TextFonts", kTextFonts, ".*"),
|
||||
DEFUN("Record", kRecord, ".*"),
|
||||
DEFUN("PlayBack", kPlayBack, ".*"),
|
||||
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 kStrSplit(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
|
||||
|
||||
|
|
|
@ -206,11 +206,13 @@ reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) {
|
|||
SegManager *segMan = s->segMan;
|
||||
|
||||
if (obj.segment) {
|
||||
int x = GET_SEL32V(obj, x);
|
||||
int y = GET_SEL32V(obj, y);
|
||||
int16 x = GET_SEL32V(obj, x);
|
||||
int16 y = GET_SEL32V(obj, y);
|
||||
|
||||
PUT_SEL32V(obj, x, x - s->port->zone.x);
|
||||
PUT_SEL32V(obj, y, y - s->port->zone.y);
|
||||
s->gui->globalToLocal(&x, &y);
|
||||
|
||||
PUT_SEL32V(obj, x, x);
|
||||
PUT_SEL32V(obj, y, y);
|
||||
}
|
||||
|
||||
return s->r_acc;
|
||||
|
@ -222,11 +224,13 @@ reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv) {
|
|||
SegManager *segMan = s->segMan;
|
||||
|
||||
if (obj.segment) {
|
||||
int x = GET_SEL32V(obj, x);
|
||||
int y = GET_SEL32V(obj, y);
|
||||
int16 x = GET_SEL32V(obj, x);
|
||||
int16 y = GET_SEL32V(obj, y);
|
||||
|
||||
PUT_SEL32V(obj, x, x + s->port->zone.x);
|
||||
PUT_SEL32V(obj, y, y + s->port->zone.y);
|
||||
s->gui->localToGlobal(&x, &y);
|
||||
|
||||
PUT_SEL32V(obj, x, x);
|
||||
PUT_SEL32V(obj, y, y);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
break;
|
||||
case K_NEW_GETTIME_TIME_12HOUR :
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace Common {
|
|||
#include "sci/engine/seg_manager.h"
|
||||
#include "sci/gfx/gfx_system.h"
|
||||
#include "sci/sfx/core.h"
|
||||
#include "sci/gui/gui.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
|
@ -175,6 +176,8 @@ public:
|
|||
|
||||
/* Non-VM information */
|
||||
|
||||
SciGUI *gui; /* Currently active GUI */
|
||||
|
||||
GfxState *gfx_state; /**< Graphics state and driver */
|
||||
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);
|
||||
|
||||
/* 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
|
||||
|
||||
#endif // SCI_INCLUDE_ENGINE_H
|
||||
|
|
|
@ -248,4 +248,19 @@ void GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) {
|
|||
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
|
||||
|
|
|
@ -228,6 +228,11 @@ public:
|
|||
gfx_mode_t *getMode() { return _mode; }
|
||||
byte *getVisual0() { return _visual[0]; }
|
||||
|
||||
/**
|
||||
* Animates palette
|
||||
*/
|
||||
void animatePalette(int fromColor, int toColor, int stepCount);
|
||||
|
||||
private:
|
||||
gfx_pixmap_t *_priority[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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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;
|
||||
|
|
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_view.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/iterator.o \
|
||||
sfx/songlib.o \
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "sci/engine/state.h"
|
||||
#include "sci/engine/kernel.h"
|
||||
|
||||
#include "sci/gui32/gui32.h"
|
||||
|
||||
#include "sci/gfx/gfx_resource.h"
|
||||
#include "sci/gfx/gfx_tools.h"
|
||||
#include "sci/gfx/operations.h"
|
||||
|
@ -44,7 +46,7 @@ namespace Sci {
|
|||
class GfxDriver;
|
||||
|
||||
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;
|
||||
// in particular, do not load data from files; rather, if you
|
||||
// need to do such things, do them from init().
|
||||
|
@ -152,6 +154,10 @@ Common::Error SciEngine::run() {
|
|||
GfxState 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
|
||||
ConfMan.registerDefault("dither_mode", "0");
|
||||
|
||||
|
@ -183,6 +189,8 @@ Common::Error SciEngine::run() {
|
|||
return Common::kUnknownError;
|
||||
}
|
||||
|
||||
_gamestate->gui->init(_kernel->usesOldGfxFunctions());
|
||||
|
||||
printf("Emulating SCI version %s\n", getSciVersionDesc(getSciVersion()).c_str());
|
||||
|
||||
game_run(&_gamestate); // Run the game
|
||||
|
|
|
@ -132,6 +132,7 @@ private:
|
|||
Kernel *_kernel;
|
||||
Vocabulary *_vocabulary;
|
||||
Console *_console;
|
||||
OSystem *_system;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue