Files
scummvm-cursorfix/engines/ultima/ultima8/gumps/quit_gump.cpp
2026-02-02 04:50:13 +01:00

207 lines
5.9 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/ultima8/audio/audio_process.h"
#include "ultima/ultima8/gumps/quit_gump.h"
#include "ultima/ultima8/games/game_data.h"
#include "ultima/ultima8/gfx/gump_shape_archive.h"
#include "ultima/ultima8/gfx/shape.h"
#include "ultima/ultima8/gfx/shape_frame.h"
#include "ultima/ultima8/ultima8.h"
#include "ultima/ultima8/kernel/mouse.h"
#include "ultima/ultima8/gumps/widgets/button_widget.h"
#include "ultima/ultima8/gumps/widgets/text_widget.h"
namespace Ultima {
namespace Ultima8 {
DEFINE_RUNTIME_CLASSTYPE_CODE(QuitGump)
static const int u8GumpShape = 17;
static const int u8AskShapeId = 18;
static const int u8YesShapeId = 47;
static const int u8NoShapeId = 50;
static const int remGumpShape = 21;
static const int remAskShapeId = 0;
static const int remYesShapeId = 19;
static const int remNoShapeId = 20;
static const int remQuitSound = 0x109;
static const int regGumpShape = 21;
static const int regAskShapeId = 0;
static const int regYesShapeId = 19;
static const int regNoShapeId = 20;
static const int regQuitSound = 0; // TODO: Work out what sound id
QuitGump::QuitGump(): ModalGump(0, 0, 5, 5), _yesWidget(0), _noWidget(0) {
Mouse *mouse = Mouse::get_instance();
mouse->pushMouseCursor(Mouse::MOUSE_HAND);
if (GAME_IS_U8) {
_gumpShape = u8GumpShape;
_askShape = u8AskShapeId;
_yesShape = u8YesShapeId;
_noShape = u8NoShapeId;
_buttonXOff = 16;
_buttonYOff = 38;
_playSound = 0;
} else if (GAME_IS_REMORSE) {
_gumpShape = remGumpShape;
_askShape = remAskShapeId;
_yesShape = remYesShapeId;
_noShape = remNoShapeId;
_buttonXOff = 55;
_buttonYOff = 47;
_playSound = remQuitSound;
} else if (GAME_IS_REGRET) {
_gumpShape = regGumpShape;
_askShape = regAskShapeId;
_yesShape = regYesShapeId;
_noShape = regNoShapeId;
// TODO: These are pretty approximate, need adjusting.
_buttonXOff = 50;
_buttonYOff = 70;
_playSound = regQuitSound;
} else {
error("unsupported game type");
}
}
QuitGump::~QuitGump() {
Mouse::get_instance()->popMouseCursor();
}
void QuitGump::InitGump(Gump *newparent, bool take_focus) {
ModalGump::InitGump(newparent, take_focus);
_shape = GameData::get_instance()->getGumps()->getShape(_gumpShape);
UpdateDimsFromShape();
if (_askShape != 0) {
FrameID askshape(GameData::GUMPS, _askShape, 0);
askshape = _TL_SHP_(askshape);
if (askshape._shapeNum == 0) {
// In JP U8, the ask gump is replaced with text
// confirming quit
Std::string askstr = _TL_("Quit the game?");
Gump *widget = new TextWidget(0, 0, askstr, true, 6); // CONSTANT!
widget->InitGump(this, false);
widget->setRelativePosition(TOP_CENTER, 0, 13);
} else {
const Shape *askShape = GameData::get_instance()->getShape(askshape);
const ShapeFrame *sf = askShape->getFrame(askshape._frameNum);
assert(sf);
Gump *ask = new Gump(0, 0, sf->_width, sf->_height);
ask->SetShape(askShape, askshape._frameNum);
ask->InitGump(this);
ask->setRelativePosition(TOP_CENTER, 0, 5);
}
}
FrameID yesbutton_up(GameData::GUMPS, _yesShape, 0);
FrameID yesbutton_down(GameData::GUMPS, _yesShape, 1);
yesbutton_up = _TL_SHP_(yesbutton_up);
yesbutton_down = _TL_SHP_(yesbutton_down);
Gump *widget;
widget = new ButtonWidget(0, 0, yesbutton_up, yesbutton_down);
widget->InitGump(this);
widget->setRelativePosition(TOP_LEFT, _buttonXOff, _buttonYOff);
_yesWidget = widget->getObjId();
FrameID nobutton_up(GameData::GUMPS, _noShape, 0);
FrameID nobutton_down(GameData::GUMPS, _noShape, 1);
nobutton_up = _TL_SHP_(nobutton_up);
nobutton_down = _TL_SHP_(nobutton_down);
widget = new ButtonWidget(0, 0, nobutton_up, nobutton_down);
widget->InitGump(this);
widget->setRelativePosition(TOP_RIGHT, -(int)_buttonXOff, _buttonYOff);
_noWidget = widget->getObjId();
if (_playSound) {
AudioProcess *audioproc = AudioProcess::get_instance();
audioproc->playSFX(_playSound, 0x10, _objId, 1);
}
}
void QuitGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
Gump::PaintThis(surf, lerp_factor, scaled);
}
bool QuitGump::OnKeyDown(int key, int mod) {
switch (key) {
case Common::KEYCODE_ESCAPE: {
Close();
}
break;
default:
break;
}
return true;
}
void QuitGump::ChildNotify(Gump *child, uint32 message) {
ObjId cid = child->getObjId();
if (message == ButtonWidget::BUTTON_CLICK || message == ButtonWidget::BUTTON_DOUBLE) {
if (cid == _yesWidget) {
Ultima8Engine::get_instance()->quitGame();
} else if (cid == _noWidget) {
Close();
}
}
}
bool QuitGump::OnTextInput(int unicode) {
if (!(unicode & 0xFF80)) {
char c = unicode & 0x7F;
if (_TL_("Yy").find(c) != Std::string::npos) {
Ultima8Engine::get_instance()->quitGame();
} else if (_TL_("Nn").find(c) != Std::string::npos) {
Close();
}
}
return true;
}
//static
void QuitGump::verifyQuit() {
ModalGump *gump = new QuitGump();
gump->InitGump(0);
gump->setRelativePosition(CENTER);
}
bool QuitGump::loadData(Common::ReadStream *rs) {
warning("Trying to load ModalGump");
return true;
}
void QuitGump::saveData(Common::WriteStream *ws) {
warning("Trying to save ModalGump");
}
} // End of namespace Ultima8
} // End of namespace Ultima