[Scummvm-git-logs] scummvm master -> 35cf8527b30ecf4e8a97f5fcee5fb3d8ca323a63

mduggan mgithub at guarana.org
Mon Jun 22 07:17:34 UTC 2020


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
220f64d373 ULTIMA8: Stop object sounds when destroying it in crusader
8c7eb1959c ULTIMA8: Implement CruHealer and BatteryCharger processes
35cf8527b3 ULTIMA8: Add crusader keypad gump


Commit: 220f64d37307e2643eb7f7c6228f98e909291707
    https://github.com/scummvm/scummvm/commit/220f64d37307e2643eb7f7c6228f98e909291707
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-22T16:17:22+09:00

Commit Message:
ULTIMA8: Stop object sounds when destroying it in crusader

Changed paths:
    engines/ultima/ultima8/world/item.cpp


diff --git a/engines/ultima/ultima8/world/item.cpp b/engines/ultima/ultima8/world/item.cpp
index 87f010a3a8..b46d1a14a3 100644
--- a/engines/ultima/ultima8/world/item.cpp
+++ b/engines/ultima/ultima8/world/item.cpp
@@ -1260,6 +1260,13 @@ void Item::destroy(bool delnow) {
 		World::get_instance()->getCurrentMap()->removeItemFromList(this, _x, _y);
 	}
 
+	if (GAME_IS_CRUSADER) {
+		// Ensure sounds for this object are stopped
+		AudioProcess *audio = AudioProcess::get_instance();
+		if (audio)
+			audio->stopSFX(-1, _objId);
+	}
+
 	if (_extendedFlags & Item::EXT_CAMERA)
 		CameraProcess::SetCameraProcess(0);
 


Commit: 8c7eb1959c4bc62575c95c192ab0b169baf9d5c3
    https://github.com/scummvm/scummvm/commit/8c7eb1959c4bc62575c95c192ab0b169baf9d5c3
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-22T16:17:22+09:00

Commit Message:
ULTIMA8: Implement CruHealer and BatteryCharger processes

Changed paths:
  A engines/ultima/ultima8/world/actors/battery_charger_process.cpp
  A engines/ultima/ultima8/world/actors/battery_charger_process.h
  A engines/ultima/ultima8/world/actors/cru_healer_process.cpp
  A engines/ultima/ultima8/world/actors/cru_healer_process.h
    engines/ultima/module.mk
    engines/ultima/ultima8/ultima8.cpp
    engines/ultima/ultima8/usecode/remorse_intrinsics.h


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 3bc82d415b..47c271804b 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -549,7 +549,9 @@ MODULE_OBJS := \
 	ultima8/world/actors/avatar_death_process.o \
 	ultima8/world/actors/avatar_gravity_process.o \
 	ultima8/world/actors/avatar_mover_process.o \
+	ultima8/world/actors/battery_charger_process.o \
 	ultima8/world/actors/clear_feign_death_process.o \
+	ultima8/world/actors/cru_healer_process.o \
 	ultima8/world/actors/combat_process.o \
 	ultima8/world/actors/grant_peace_process.o \
 	ultima8/world/actors/heal_process.o \
diff --git a/engines/ultima/ultima8/ultima8.cpp b/engines/ultima/ultima8/ultima8.cpp
index f677707dc0..8df3b356c2 100644
--- a/engines/ultima/ultima8/ultima8.cpp
+++ b/engines/ultima/ultima8/ultima8.cpp
@@ -70,6 +70,8 @@
 #include "ultima/ultima8/world/actors/quick_avatar_mover_process.h"
 #include "ultima/ultima8/world/actors/actor.h"
 #include "ultima/ultima8/world/actors/actor_anim_process.h"
+#include "ultima/ultima8/world/actors/battery_charger_process.h"
+#include "ultima/ultima8/world/actors/cru_healer_process.h"
 #include "ultima/ultima8/world/actors/targeted_anim_process.h"
 #include "ultima/ultima8/usecode/u8_intrinsics.h"
 #include "ultima/ultima8/usecode/remorse_intrinsics.h"
@@ -1358,7 +1360,6 @@ bool Ultima8Engine::load(Common::ReadStream *rs, uint32 version) {
 	return true;
 }
 
-
 //
 // Intrinsics
 //
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index 6a5fb159de..3ae7f20269 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -287,7 +287,7 @@ Intrinsic RemorseIntrinsics[] = {
 	0, // void Intrinsic0EB(void)
 	Item::I_popToEnd,
 	Item::I_popToContainer,
-	0, // TODO: Implement BatteryChargerProcess::I_create
+	BatteryChargerProcess::I_create,
 	Kernel::I_getNumProcesses, // void Intrinsic0EF(4 bytes)
 	// 0x0F0
 	Item::I_getQHi,  // based on same coff set as 026
@@ -296,7 +296,7 @@ Intrinsic RemorseIntrinsics[] = {
 	Item::I_getQHi,  // based on same coff set as 026
 	Item::I_getQ, // void Intrinsic0F4(4 bytes)
 	Item::I_setQ, // void Intrinsic0F5(6 bytes)
-	0, // TODO: Implement CruHealer::I_create
+	CruHealerProcess::I_create,
 	Item::I_hurl, // void Intrinsic0F7(12 bytes)
 	Item::I_getNpcNum, // based on same coff as 102 (-> variable name in TRIGGER::ordinal21)
 	Item::I_hurl, // void Intrinsic0F9(12 bytes)
diff --git a/engines/ultima/ultima8/world/actors/battery_charger_process.cpp b/engines/ultima/ultima8/world/actors/battery_charger_process.cpp
new file mode 100644
index 0000000000..45da4260dc
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/battery_charger_process.cpp
@@ -0,0 +1,95 @@
+/* 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.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/world/actors/battery_charger_process.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/audio/audio_process.h"
+
+#include "common/util.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+// p_dynamic_cast stuff
+DEFINE_RUNTIME_CLASSTYPE_CODE(BatteryChargerProcess)
+
+BatteryChargerProcess::BatteryChargerProcess() : Process() {
+	// TODO: This should be the "current" avatar (if controlling a robot etc)
+	MainActor *avatar = getMainActor();
+	if (!avatar) {
+		_itemNum = 0;
+		_targetMaxEnergy = 0;
+	} else {
+		_itemNum = avatar->getObjId();
+		_targetMaxEnergy = avatar->getMaxEnergy();
+		AudioProcess *audio = AudioProcess::get_instance();
+		if (audio) {
+			audio->playSFX(0xa4, 0x80, _itemNum, 1, false);
+		}
+	}
+	_type = 0x254; // CONSTANT!
+}
+
+void BatteryChargerProcess::run() {
+	// TODO: This should be the "current" avatar (if controlling a robot etc)
+	MainActor *avatar = getMainActor();
+	AudioProcess *audio = AudioProcess::get_instance();
+
+	if (!avatar || avatar->isDead() || avatar->getMana() >= _targetMaxEnergy) {
+		// dead or finished healing
+		terminate();
+		if (audio)
+			audio->stopSFX(0xa4, _itemNum);
+		return;
+	}
+
+    if (!audio->isSFXPlayingForObject(0x10b, _itemNum))
+		audio->playSFX(0x10b, 0x80, _itemNum, 1);
+
+	uint16 newEnergy = avatar->getMana() + 25;
+	if (newEnergy > _targetMaxEnergy)
+		newEnergy = _targetMaxEnergy;
+
+	avatar->setMana(newEnergy);
+}
+
+uint32 BatteryChargerProcess::I_create(const uint8 *args, unsigned int /*argsize*/) {
+	return Kernel::get_instance()->addProcess(new BatteryChargerProcess());
+}
+
+void BatteryChargerProcess::saveData(Common::WriteStream *ws) {
+	Process::saveData(ws);
+	ws->writeUint16LE(_targetMaxEnergy);
+}
+
+bool BatteryChargerProcess::loadData(Common::ReadStream *rs, uint32 version) {
+	if (!Process::loadData(rs, version)) return false;
+	_targetMaxEnergy = rs->readUint16LE();
+
+	return true;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/actors/battery_charger_process.h b/engines/ultima/ultima8/world/actors/battery_charger_process.h
new file mode 100644
index 0000000000..d8f625ac48
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/battery_charger_process.h
@@ -0,0 +1,53 @@
+/* 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.
+ *
+ */
+
+#ifndef WORLD_ACTORS_BATTERY_CHARGER_PROCESS_H
+#define WORLD_ACTORS_BATTERY_CHARGER_PROCESS_H
+
+#include "ultima/ultima8/kernel/process.h"
+#include "ultima/ultima8/usecode/intrinsics.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class BatteryChargerProcess : public Process {
+public:
+	BatteryChargerProcess();
+
+	// p_dynamic_cast stuff
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	void run() override;
+
+	INTRINSIC(I_create);
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+private:
+	uint16 _targetMaxEnergy;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/world/actors/cru_healer_process.cpp b/engines/ultima/ultima8/world/actors/cru_healer_process.cpp
new file mode 100644
index 0000000000..8937b3d7cd
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/cru_healer_process.cpp
@@ -0,0 +1,94 @@
+/* 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.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/world/actors/cru_healer_process.h"
+#include "ultima/ultima8/world/actors/main_actor.h"
+#include "ultima/ultima8/kernel/kernel.h"
+#include "ultima/ultima8/world/get_object.h"
+#include "ultima/ultima8/audio/audio_process.h"
+
+#include "common/util.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+// p_dynamic_cast stuff
+DEFINE_RUNTIME_CLASSTYPE_CODE(CruHealerProcess)
+
+CruHealerProcess::CruHealerProcess() : Process() {
+	// TODO: This should be the "current" avatar (if controlling a robot etc)
+	MainActor *avatar = getMainActor();
+	if (!avatar) {
+		_itemNum = 0;
+		_targetMaxHP = 0;
+	} else {
+		_itemNum = avatar->getObjId();
+		_targetMaxHP = avatar->getMaxHP();
+		AudioProcess *audio = AudioProcess::get_instance();
+		if (audio) {
+			audio->playSFX(0xdb, 0x80, _itemNum, 1, false);
+		}
+	}
+	_type = 0x254; // CONSTANT!
+}
+
+void CruHealerProcess::run() {
+	// TODO: This should be the "current" avatar (if controlling a robot etc)
+	MainActor *avatar = getMainActor();
+	AudioProcess *audio = AudioProcess::get_instance();
+
+	if (!avatar || avatar->isDead() || avatar->getHP() >= _targetMaxHP) {
+		// dead or finished healing
+		if (audio)
+			audio->stopSFX(0xdb, _itemNum);
+		terminate();
+		return;
+	}
+
+    if (audio && !audio->isSFXPlayingForObject(0xba, _itemNum))
+		audio->playSFX(0xba, 0x80, _itemNum, 1);
+
+	uint16 newHP = avatar->getHP() + 1;
+	if (newHP > _targetMaxHP)
+		newHP = _targetMaxHP;
+
+	avatar->setHP(newHP);
+}
+
+uint32 CruHealerProcess::I_create(const uint8 *args, unsigned int /*argsize*/) {
+	return Kernel::get_instance()->addProcess(new CruHealerProcess());
+}
+
+void CruHealerProcess::saveData(Common::WriteStream *ws) {
+	Process::saveData(ws);
+	ws->writeUint16LE(_targetMaxHP);
+}
+
+bool CruHealerProcess::loadData(Common::ReadStream *rs, uint32 version) {
+	if (!Process::loadData(rs, version)) return false;
+	_targetMaxHP = rs->readUint16LE();
+	return true;
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/actors/cru_healer_process.h b/engines/ultima/ultima8/world/actors/cru_healer_process.h
new file mode 100644
index 0000000000..62ff8a22ec
--- /dev/null
+++ b/engines/ultima/ultima8/world/actors/cru_healer_process.h
@@ -0,0 +1,53 @@
+/* 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.
+ *
+ */
+
+#ifndef WORLD_ACTORS_CRU_HEALER_PROCESS_H
+#define WORLD_ACTORS_CRU_HEALER_PROCESS_H
+
+#include "ultima/ultima8/kernel/process.h"
+#include "ultima/ultima8/usecode/intrinsics.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+class CruHealerProcess : public Process {
+public:
+	CruHealerProcess();
+
+	// p_dynamic_cast stuff
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	void run() override;
+
+	INTRINSIC(I_create);
+
+	bool loadData(Common::ReadStream *rs, uint32 version);
+	void saveData(Common::WriteStream *ws) override;
+
+private:
+	uint16 _targetMaxHP;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif


Commit: 35cf8527b30ecf4e8a97f5fcee5fb3d8ca323a63
    https://github.com/scummvm/scummvm/commit/35cf8527b30ecf4e8a97f5fcee5fb3d8ca323a63
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2020-06-22T16:17:22+09:00

Commit Message:
ULTIMA8: Add crusader keypad gump

Changed paths:
  A engines/ultima/ultima8/gumps/keypad_gump.cpp
  A engines/ultima/ultima8/gumps/keypad_gump.h
    engines/ultima/module.mk
    engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
    engines/ultima/ultima8/usecode/remorse_intrinsics.h


diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk
index 47c271804b..449858a956 100644
--- a/engines/ultima/module.mk
+++ b/engines/ultima/module.mk
@@ -473,6 +473,7 @@ MODULE_OBJS := \
 	ultima8/gumps/gump_notify_process.o \
 	ultima8/gumps/inverter_gump.o \
 	ultima8/gumps/item_relative_gump.o \
+	ultima8/gumps/keypad_gump.o \
 	ultima8/gumps/main_menu_process.o \
 	ultima8/gumps/menu_gump.o \
 	ultima8/gumps/message_box_gump.o \
diff --git a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
index 88380e1863..8e4383235b 100644
--- a/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
+++ b/engines/ultima/ultima8/convert/crusader/convert_usecode_crusader.h
@@ -81,7 +81,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
 	"int16 Actor::I_GetNPCDataField0x63_00B(Actor *)", // Maybe get HP? Called from ANDROID::calledFromAnim, goes to NPCDEATH
 	"void I_NPCsetSomething_00C(int)",
 	"byte Item::I_getDirToItem(Item *, itemno)", // based on disasm
-	"int16 Actor::I_NPCSomething00E(Actor *, int, int)",
+	"int16 Actor::I_turnToward(Actor *, direction, unk)", // TODO: work out what unk is
 	"void I_playFlic(void), int16 I_playFlic(Item *, char *name, int16 sizex, int16 sizey)",
 	// 0010
 	"int16 Item::I_getQLo(Item *)", // same as 02B based on same coff as 02B, 066, 084, 0A1, 0AE, 0D9, 0EA
@@ -198,7 +198,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
 	"int16 MainActor::I_teleportToEgg(int, int, int)",
 	"int16 PaletteFaderProcess::I_fadeFromBlack(void)", // from black, no arg (40 frames)
 	"void Actor::I_clrImmortal(Actor *)", // same coff as 130
-	"int16 Actir::I_getHp(Actor *)", // TODO: double-check whether field 0 of NPC data is HP or *max* HP.
+	"int16 Actor::I_getHp(Actor *)", // TODO: double-check whether field 0 of NPC data is HP or *max* HP.
 	"void Actor::I_setActivity(Actor *, int)", // part of same coff set 055, 07D, 0CD, 0DB, 0F2, 131
 	"int16 Item::I_getQuality(Item *)", // based on disassembly
 	"void Item::I_setQuality(Item *, int)", // based on disassembly. same coff as 0BA, 125
@@ -275,7 +275,7 @@ const char* const ConvertUsecodeCrusader::_intrinsics[] = {
 	"void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
 	"int16 Item::I_hurl(Item *,8 bytes)", // part of same coff set 028, 08D, 0BD, 0C0, 0C2, 0C8, 0F7, 0F9, 118, 11D
 	"void Item::I_andStatus(Item *, uint16 status)", // part of same coff set 01A, 031, 069, 06E, 099, 0B2, 0BF, 0C1, 0C3, 0E9, 0FC, 101, 104, 106, 108, 10A, 10C, 10E, 110, 114, 117, 11A, 128, 132
-	"int16 I_showKeypadGump_0C4(int unk)", // TODO: what's the parameter?
+	"int16 KeypadGump::I_showKeypad(int targetCode)",
 	"byte Item::I_isOn(Item *, itemno)", // part of same coff set 044, 046, 048, 04A, 04C, 04E, 0A5, 0BC, 0C5, 0DC, 0F1, 0FA, 12C
 	"void SpriteProcess::I_createSprite(word, word, word, word, uword, uword, ubyte)",
 	"byte Item::I_getDirFromItem(Item *, itemno)", // same disasm as U8
diff --git a/engines/ultima/ultima8/gumps/keypad_gump.cpp b/engines/ultima/ultima8/gumps/keypad_gump.cpp
new file mode 100644
index 0000000000..2a716af8b9
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/keypad_gump.cpp
@@ -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.
+ *
+ */
+
+#include "ultima/ultima8/misc/pent_include.h"
+#include "ultima/ultima8/audio/audio_process.h"
+#include "ultima/ultima8/gumps/keypad_gump.h"
+#include "ultima/ultima8/gumps/gump_notify_process.h"
+#include "ultima/ultima8/games/game_data.h"
+#include "ultima/ultima8/graphics/gump_shape_archive.h"
+#include "ultima/ultima8/graphics/shape.h"
+#include "ultima/ultima8/graphics/shape_frame.h"
+#include "ultima/ultima8/ultima8.h"
+#include "ultima/ultima8/gumps/desktop_gump.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(KeypadGump)
+
+KeypadGump::KeypadGump(int targetValue): ModalGump(0, 0, 5, 5),
+		_value(0), _targetValue(targetValue) {
+	Mouse *mouse = Mouse::get_instance();
+	mouse->pushMouseCursor();
+	mouse->setMouseCursor(Mouse::MOUSE_HAND);
+	for (int i = 0; i < 12; i++) {
+		_buttons[i] = 0;
+	}
+}
+
+KeypadGump::~KeypadGump() {
+	Mouse::get_instance()->popMouseCursor();
+}
+
+void KeypadGump::InitGump(Gump *newparent, bool take_focus) {
+	ModalGump::InitGump(newparent, take_focus);
+
+	_shape = GameData::get_instance()->getGumps()->getShape(10);
+	UpdateDimsFromShape();
+
+	static const int buttonShapeNum = 11;
+	static const uint16 xoffs[] = {0x31, 0x49, 0x61};
+	static const uint16 yoffs[] = {0x19, 0x32, 0x4a, 0x62};
+
+	for (int y = 0; y < 4; y++) {
+		for (int x = 0; x < 3; x++) {
+			int bnum = y * 3 + x;
+			FrameID button_up(GameData::GUMPS, buttonShapeNum, bnum);
+			FrameID button_down(GameData::GUMPS, buttonShapeNum, bnum + 12);
+			Gump *widget = new ButtonWidget(xoffs[x], yoffs[y], button_up, button_down);
+			widget->InitGump(this);
+			widget->SetIndex(bnum);
+			_buttons[bnum] = widget->getObjId();
+		}
+	}
+}
+
+void KeypadGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled) {
+	Gump::PaintThis(surf, lerp_factor, scaled);
+	// TODO: paint text version of _value.
+}
+
+bool KeypadGump::OnKeyDown(int key, int mod) {
+	switch (key) {
+	case Common::KEYCODE_ESCAPE: {
+		Close();
+	}
+	break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+void KeypadGump::ChildNotify(Gump *child, uint32 message) {
+	//ObjId cid = child->getObjId();
+	if (message == ButtonWidget::BUTTON_CLICK) {
+		int buttonNo = child->GetIndex();
+		if (buttonNo < 10) {
+			_value *= 10;
+			_value += buttonNo + 1;
+		} else if (buttonNo == 10) {
+			_value *= 10;
+		} else if (buttonNo == 9) {
+			_value /= 10;
+		} else if (buttonNo == 11) {
+			AudioProcess *audio = AudioProcess::get_instance();
+			// TODO: Do something as a result of this other than just play a sound.
+			if (_value == _targetValue) {
+				if (audio)
+					audio->playSFX(0x32, 0x10, _objId, 1);
+				Close();
+			} else {
+				if (audio)
+					audio->playSFX(0x31, 0x10, _objId, 1);
+			}
+		}
+	}
+}
+
+bool KeypadGump::OnTextInput(int unicode) {
+	if (!(unicode & 0xFF80)) {
+		//char c = unicode & 0x7F;
+		// TODO: Accept numeric inputs
+	}
+	return true;
+}
+
+uint32 KeypadGump::I_showKeypad(const uint8 *args, unsigned int /*argsize*/) {
+	ARG_UINT16(target)
+	 // TODO: what's this parameter?
+	ModalGump *gump = new KeypadGump(target);
+	gump->InitGump(0);
+	gump->setRelativePosition(CENTER);
+
+	return gump->GetNotifyProcess()->getPid();
+}
+
+bool KeypadGump::loadData(Common::ReadStream *rs) {
+	CANT_HAPPEN_MSG("Trying to load ModalGump");
+	return true;
+}
+
+void KeypadGump::saveData(Common::WriteStream *ws) {
+	CANT_HAPPEN_MSG("Trying to save ModalGump");
+}
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
diff --git a/engines/ultima/ultima8/gumps/keypad_gump.h b/engines/ultima/ultima8/gumps/keypad_gump.h
new file mode 100644
index 0000000000..bb8b75e3c9
--- /dev/null
+++ b/engines/ultima/ultima8/gumps/keypad_gump.h
@@ -0,0 +1,66 @@
+/* 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.
+ *
+ */
+
+#ifndef ULTIMA8_GUMPS_KEYPADGUMP_H
+#define ULTIMA8_GUMPS_KEYPADGUMP_H
+
+#include "ultima/ultima8/gumps/modal_gump.h"
+#include "ultima/ultima8/usecode/intrinsics.h"
+#include "ultima/ultima8/misc/p_dynamic_cast.h"
+
+namespace Ultima {
+namespace Ultima8 {
+
+/**
+ * The keypad with numbers gump
+ */
+class KeypadGump : public ModalGump {
+public:
+	ENABLE_RUNTIME_CLASSTYPE()
+
+	KeypadGump(int targetValue);
+	~KeypadGump() override;
+
+	void InitGump(Gump *newparent, bool take_focus = true) override;
+
+	void PaintThis(RenderSurface *, int32 lerp_factor, bool scaled) override;
+
+	bool OnKeyDown(int key, int mod) override;
+	bool OnTextInput(int unicode) override;
+	void ChildNotify(Gump *child, uint32 message) override;
+
+	INTRINSIC(I_showKeypad);
+
+	bool loadData(Common::ReadStream *rs);
+	void saveData(Common::WriteStream *ws) override;
+
+protected:
+	ObjId _buttons[12];
+
+	int _value;
+	int _targetValue;
+};
+
+} // End of namespace Ultima8
+} // End of namespace Ultima
+
+#endif
diff --git a/engines/ultima/ultima8/usecode/remorse_intrinsics.h b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
index 3ae7f20269..9bf534c5a5 100644
--- a/engines/ultima/ultima8/usecode/remorse_intrinsics.h
+++ b/engines/ultima/ultima8/usecode/remorse_intrinsics.h
@@ -243,7 +243,7 @@ Intrinsic RemorseIntrinsics[] = {
 	Item::I_andStatus, // void Intrinsic0C1(6 bytes)
 	Item::I_hurl, // void Intrinsic0C2(12 bytes)
 	Item::I_andStatus, // void Intrinsic0C3(6 bytes)
-	0, // void Intrinsic0C4(2 bytes) // TODO: Implement keypad gump (gump shape 10 for the border, shape 11 frames for the buttons.)
+	KeypadGump::I_showKeypad, // void Intrinsic0C4(2 bytes)
 	Item::I_isOn,
 	SpriteProcess::I_createSprite, // void Intrinsic0C6(14 bytes)
 	Item::I_getDirFromItem, // int Intrinsic0C7(6 bytes)




More information about the Scummvm-git-logs mailing list