mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-22 20:21:06 +00:00
DS: Rewrite event handling
This commit is contained in:
parent
1f8dc4d204
commit
438c2d8714
102
backends/events/ds/ds-events.cpp
Normal file
102
backends/events/ds/ds-events.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/* 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 <nds.h>
|
||||
|
||||
#include "dsmain.h"
|
||||
#include "backends/events/ds/ds-events.h"
|
||||
|
||||
bool DSEventSource::pollEvent(Common::Event &event) {
|
||||
if (_eventQueue.empty()) {
|
||||
if (!_firstPoll) {
|
||||
_firstPoll = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
addEventsToQueue();
|
||||
if (_eventQueue.empty())
|
||||
return false;
|
||||
|
||||
_firstPoll = false;
|
||||
}
|
||||
|
||||
event = _eventQueue.pop();
|
||||
|
||||
if (Common::isMouseEvent(event)) {
|
||||
g_system->warpMouse(event.mouse.x, event.mouse.y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DSEventSource::addJoyButtonEvent(u32 keysPressed, u32 keysReleased, u32 ndsKey, uint8 svmButton) {
|
||||
if (keysPressed & ndsKey || keysReleased & ndsKey) {
|
||||
Common::Event event;
|
||||
event.type = (keysPressed & ndsKey) ? Common::EVENT_JOYBUTTON_DOWN : Common::EVENT_JOYBUTTON_UP;
|
||||
event.joystick.button = svmButton;
|
||||
|
||||
_eventQueue.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
void DSEventSource::addEventsToQueue() {
|
||||
Common::Event event;
|
||||
|
||||
scanKeys();
|
||||
uint32 held = keysHeld(), keysPressed = keysDown(), keysReleased = keysUp();
|
||||
|
||||
// Touch screen events
|
||||
if (held & KEY_TOUCH) {
|
||||
touchPosition touchPos;
|
||||
touchRead(&touchPos);
|
||||
event.mouse = DS::transformPoint(touchPos.px, touchPos.py);
|
||||
|
||||
if (keysPressed & KEY_TOUCH) {
|
||||
event.type = Common::EVENT_LBUTTONDOWN;
|
||||
_eventQueue.push(event);
|
||||
} else if (event.mouse.x != _lastTouch.x || event.mouse.y != _lastTouch.y) {
|
||||
event.type = Common::EVENT_MOUSEMOVE;
|
||||
_eventQueue.push(event);
|
||||
}
|
||||
|
||||
_lastTouch = event.mouse;
|
||||
} else if (keysReleased & KEY_TOUCH) {
|
||||
event.mouse = _lastTouch;
|
||||
event.type = Common::EVENT_LBUTTONUP;
|
||||
_eventQueue.push(event);
|
||||
}
|
||||
|
||||
// Button events
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_L, Common::JOYSTICK_BUTTON_LEFT_SHOULDER);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_R, Common::JOYSTICK_BUTTON_RIGHT_SHOULDER);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_A, Common::JOYSTICK_BUTTON_A);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_B, Common::JOYSTICK_BUTTON_B);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_X, Common::JOYSTICK_BUTTON_X);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_Y, Common::JOYSTICK_BUTTON_Y);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_UP, Common::JOYSTICK_BUTTON_DPAD_UP);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_DOWN, Common::JOYSTICK_BUTTON_DPAD_DOWN);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_LEFT, Common::JOYSTICK_BUTTON_DPAD_LEFT);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_RIGHT, Common::JOYSTICK_BUTTON_DPAD_RIGHT);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_START, Common::JOYSTICK_BUTTON_START);
|
||||
addJoyButtonEvent(keysPressed, keysReleased, KEY_SELECT, Common::JOYSTICK_BUTTON_BACK);
|
||||
}
|
@ -20,18 +20,30 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SCUMMHELP_H_
|
||||
#define _SCUMMHELP_H_
|
||||
#ifndef BACKEND_EVENTS_DS_H
|
||||
#define BACKEND_EVENTS_DS_H
|
||||
|
||||
#include "common/ustr.h"
|
||||
#include "common/platform.h"
|
||||
#include "common/events.h"
|
||||
|
||||
namespace DS {
|
||||
/**
|
||||
* The Nintendo DS event source.
|
||||
*/
|
||||
class DSEventSource : public Common::EventSource {
|
||||
public:
|
||||
DSEventSource() : _firstPoll(true) {}
|
||||
|
||||
void updateStrings(byte gameId, byte version, Common::Platform platform,
|
||||
int page, Common::U32String &title, Common::U32String *&key, Common::U32String *&dsc);
|
||||
/**
|
||||
* Gets and processes events.
|
||||
*/
|
||||
virtual bool pollEvent(Common::Event &event);
|
||||
|
||||
} // End of namespace DS
|
||||
protected:
|
||||
Common::Queue<Common::Event> _eventQueue;
|
||||
Common::Point _lastTouch;
|
||||
bool _firstPoll;
|
||||
|
||||
void addEventsToQueue();
|
||||
void addJoyButtonEvent(u32 keysPressed, u32 keysReleased, u32 ndsKey, uint8 svmButton);
|
||||
};
|
||||
|
||||
#endif
|
@ -284,6 +284,7 @@ endif
|
||||
|
||||
ifeq ($(BACKEND),ds)
|
||||
MODULE_OBJS += \
|
||||
events/ds/ds-events.o \
|
||||
fs/posix/posix-fs.o \
|
||||
fs/posix/posix-fs-factory.o \
|
||||
fs/posix/posix-iostream.o \
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -30,45 +30,6 @@
|
||||
|
||||
namespace DS {
|
||||
|
||||
|
||||
enum controlType {
|
||||
CONT_SCUMM_ORIGINAL,
|
||||
CONT_SCUMM_SAMNMAX,
|
||||
CONT_SKY,
|
||||
CONT_SIMON,
|
||||
CONT_FUTURE_WARS,
|
||||
CONT_AGI,
|
||||
CONT_GOBLINS,
|
||||
CONT_NIPPON
|
||||
};
|
||||
|
||||
struct gameListType {
|
||||
char gameId[16];
|
||||
controlType control;
|
||||
};
|
||||
|
||||
// Pen reading functions
|
||||
void penInit();
|
||||
void penUpdate();
|
||||
bool getPenDown();
|
||||
bool getPenHeld();
|
||||
bool getPenReleased();
|
||||
int getPenX();
|
||||
int getPenY();
|
||||
GLvector getPenPos();
|
||||
void consumePenEvents();
|
||||
controlType getControlType();
|
||||
|
||||
// Pad reading
|
||||
int getKeysHeld();
|
||||
void keysUpdate();
|
||||
int getKeysDown();
|
||||
int getKeysReleased();
|
||||
void consumeKeys();
|
||||
int leftHandedSwap(int keys);
|
||||
void setGameScreenSwap(bool enable);
|
||||
void setSensitivity(int sensitivity);
|
||||
|
||||
// Video
|
||||
void displayMode8Bit(); // Switch to 8-bit mode5
|
||||
void displayMode16Bit(); // Switch to 16-bit mode5
|
||||
@ -93,40 +54,25 @@ void setTimerCallback(OSystem_DS::TimerProc proc, int interval); // Setup a ca
|
||||
int getMillis(bool skipRecord = false); // Return the current runtime in milliseconds
|
||||
void doTimerCallback(); // Call callback function if required
|
||||
|
||||
// Event queue
|
||||
void addEventsToQueue();
|
||||
// Events
|
||||
void VBlankHandler();
|
||||
Common::Point transformPoint(uint16 x, uint16 y);
|
||||
|
||||
// Sam and Max Stuff
|
||||
void setGameID(int id);
|
||||
void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY);
|
||||
void setShowCursor(bool enable);
|
||||
void setMouseCursorVisible(bool visible);
|
||||
void warpMouse(int penX, int penY);
|
||||
void updateMouse();
|
||||
|
||||
// Shake
|
||||
void setShakePos(int shakeXOffset, int shakeYOffset);
|
||||
|
||||
// Reports
|
||||
void memoryReport();
|
||||
|
||||
// Virtual keyboard
|
||||
void setKeyboardIcon(bool enable);
|
||||
bool getKeyboardIcon();
|
||||
void setKeyboardEnable(bool en);
|
||||
bool getKeyboardEnable();
|
||||
|
||||
// Options
|
||||
void setLeftHanded(bool enable);
|
||||
void setTouchXOffset(int x);
|
||||
void setTouchYOffset(int y);
|
||||
void setGameScreenSwap(bool enable);
|
||||
void setUnscaledMode(bool enable);
|
||||
void setSnapToBorder(bool enable);
|
||||
void setIndyFightState(bool st);
|
||||
bool getIndyFightState();
|
||||
bool isCpuScalerEnabled();
|
||||
void setCpuScalerEnable(bool enable);
|
||||
void setTrackPadStyleEnable(bool enable);
|
||||
void setTapScreenClicksEnable(bool enable);
|
||||
|
||||
// Display
|
||||
bool getIsDisplayMode8Bit();
|
||||
@ -138,8 +84,6 @@ int getGameHeight();
|
||||
void fastRamReset();
|
||||
void* fastRamAlloc(int size);
|
||||
|
||||
void exitGame();
|
||||
|
||||
|
||||
} // End of namespace DS
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "gui/widgets/tab.h"
|
||||
#include "osystem_ds.h"
|
||||
#include "engines/scumm/scumm.h"
|
||||
#include "touchkeyboard.h"
|
||||
#include "gui/widgets/popup.h"
|
||||
|
||||
#include "common/translation.h"
|
||||
@ -58,44 +57,10 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
|
||||
|
||||
_tab = new GUI::TabWidget(this, 10, 5, 300, 230 - 20 - 40 - 20);
|
||||
|
||||
_tab->addTab(_("Controls"), "");
|
||||
|
||||
_leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, _("~L~eft handed mode"));
|
||||
_indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, _("~I~ndy fight controls"));
|
||||
_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, _("Show mouse cursor"), U32String(), 0, 'T');
|
||||
_snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, _("Snap to edges"), U32String(), 0, 'T');
|
||||
|
||||
new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, _("Touch X Offset"), Graphics::kTextAlignLeft);
|
||||
_touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, U32String("TODO: Add tooltip"), 1);
|
||||
_touchX->setMinValue(-8);
|
||||
_touchX->setMaxValue(+8);
|
||||
_touchX->setValue(0);
|
||||
_touchX->setFlags(GUI::WIDGET_CLEARBG);
|
||||
|
||||
new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, _("Touch Y Offset"), Graphics::kTextAlignLeft);
|
||||
_touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, U32String("TODO: Add tooltip"), 2);
|
||||
_touchY->setMinValue(-8);
|
||||
_touchY->setMaxValue(+8);
|
||||
_touchY->setValue(0);
|
||||
_touchY->setFlags(GUI::WIDGET_CLEARBG);
|
||||
|
||||
new GUI::StaticTextWidget(_tab, 130 + 65 - 10, 65, 20, 15, U32String("0"), Graphics::kTextAlignCenter);
|
||||
new GUI::StaticTextWidget(_tab, 130 + 130 - 10, 65, 20, 15, U32String("8"), Graphics::kTextAlignCenter);
|
||||
new GUI::StaticTextWidget(_tab, 130 - 20, 65, 20, 15, U32String("-8"), Graphics::kTextAlignCenter);
|
||||
|
||||
|
||||
_touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, _("Use laptop trackpad-style cursor control"), U32String(), 0x20000001, 'T');
|
||||
_screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, _("Tap for left click, double tap right click"), U32String(), 0x20000002, 'T');
|
||||
|
||||
_sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, _("Sensitivity"), Graphics::kTextAlignLeft);
|
||||
_sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, U32String("TODO: Add tooltip"), 1);
|
||||
_sensitivity->setMinValue(4);
|
||||
_sensitivity->setMaxValue(16);
|
||||
_sensitivity->setValue(8);
|
||||
_sensitivity->setFlags(GUI::WIDGET_CLEARBG);
|
||||
|
||||
_tab->addTab(_("Graphics"), "");
|
||||
|
||||
_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, _("Show mouse cursor"), U32String(), 0, 'T');
|
||||
|
||||
new GUI::StaticTextWidget(_tab, 5, 67, 180, 15, _("Initial top screen scale:"), Graphics::kTextAlignLeft);
|
||||
|
||||
_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 82, 80, 20, U32String("100%"), U32String("TODO: Add tooltip"), 0x30000001, 'T');
|
||||
@ -115,23 +80,11 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
|
||||
_gammaCorrection->setValue(0);
|
||||
|
||||
|
||||
|
||||
_tab->addTab(_("General"), "");
|
||||
|
||||
_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, _("Disable power off"), U32String(), 0, 'T');
|
||||
|
||||
_tab->setActiveTab(0);
|
||||
|
||||
_radioButtonMode = false;
|
||||
|
||||
#ifdef DS_BUILD_D
|
||||
_snapToBorderCheckbox->setState(confGetBool("snaptoborder", true));
|
||||
#else
|
||||
_snapToBorderCheckbox->setState(confGetBool("snaptoborder", false));
|
||||
#endif
|
||||
|
||||
_showCursorCheckbox->setState(confGetBool("showcursor", true));
|
||||
_leftHandedCheckbox->setState(confGetBool("lefthanded", false));
|
||||
_unscaledCheckbox->setState(confGetBool("unscaled", false));
|
||||
|
||||
|
||||
@ -171,26 +124,10 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
|
||||
_gammaCorrection->setValue(0);
|
||||
}
|
||||
|
||||
_disablePowerOff->setState(confGetBool("disablepoweroff", false));
|
||||
|
||||
#ifdef ALLOW_CPU_SCALER
|
||||
_cpuScaler->setState(confGetBool("cpu_scaler", false));
|
||||
#endif
|
||||
|
||||
_indyFightCheckbox->setState(DS::getIndyFightState());
|
||||
|
||||
_touchX->setValue(confGetInt("xoffset", 0));
|
||||
_touchY->setValue(confGetInt("yoffset", 0));
|
||||
_sensitivity->setValue(confGetInt("sensitivity", 8));
|
||||
|
||||
_touchPadStyle->setState(confGetBool("touchpad", false));
|
||||
_screenTaps->setState(confGetBool("screentaps", false));
|
||||
|
||||
_screenTaps->setEnabled(!_touchPadStyle->getState());
|
||||
_sensitivity->setEnabled(_touchPadStyle->getState());
|
||||
_sensitivityLabel->setEnabled(_touchPadStyle->getState());
|
||||
_sensitivityLabel->draw();
|
||||
|
||||
if (!_cpuScaler->getState() && !_unscaledCheckbox->getState()) {
|
||||
_hardScaler->setState(true);
|
||||
}
|
||||
@ -199,27 +136,18 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
|
||||
}
|
||||
|
||||
DSOptionsDialog::~DSOptionsDialog() {
|
||||
DS::setIndyFightState(_indyFightCheckbox->getState());
|
||||
ConfMan.flushToDisk();
|
||||
}
|
||||
|
||||
void DSOptionsDialog::updateConfigManager() {
|
||||
ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
|
||||
ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
|
||||
ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
|
||||
#ifdef ALLOW_CPU_SCALER
|
||||
ConfMan.setBool("cpu_scaler", _cpuScaler->getState(), "ds");
|
||||
#endif
|
||||
ConfMan.setInt("xoffset", _touchX->getValue(), "ds");
|
||||
ConfMan.setInt("yoffset", _touchY->getValue(), "ds");
|
||||
ConfMan.setBool("showcursor", _showCursorCheckbox->getState(), "ds");
|
||||
ConfMan.setBool("snaptoborder", _snapToBorderCheckbox->getState(), "ds");
|
||||
ConfMan.setBool("touchpad", _touchPadStyle->getState(), "ds");
|
||||
ConfMan.setBool("screentaps", _screenTaps->getState(), "ds");
|
||||
ConfMan.setInt("sensitivity", _sensitivity->getValue(), "ds");
|
||||
ConfMan.setInt("gamma", _gammaCorrection->getValue(), "ds");
|
||||
|
||||
u32 zoomLevel = 150;
|
||||
int zoomLevel = 150;
|
||||
|
||||
if (_100PercentCheckbox->getState()) {
|
||||
zoomLevel = 100;
|
||||
@ -266,39 +194,6 @@ void DSOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint
|
||||
}
|
||||
|
||||
|
||||
if ((!guard) && (_radioButtonMode)) {
|
||||
guard = true;
|
||||
|
||||
if ((sender == _touchPadStyle) && (cmd == 0x20000001)) {
|
||||
|
||||
if (_touchPadStyle->getState()) {
|
||||
// Swap screens when turning on trackpad style, it feels
|
||||
// much more natural!
|
||||
DS::setGameScreenSwap(true);
|
||||
|
||||
_screenTaps->setState(true);
|
||||
_screenTaps->setEnabled(false);
|
||||
_screenTaps->draw();
|
||||
_sensitivity->setEnabled(true);
|
||||
_sensitivityLabel->setEnabled(true);
|
||||
_sensitivityLabel->draw();
|
||||
_sensitivity->draw();
|
||||
} else {
|
||||
DS::setGameScreenSwap(false);
|
||||
|
||||
_screenTaps->setEnabled(true);
|
||||
_screenTaps->setState(false);
|
||||
_screenTaps->draw();
|
||||
_sensitivity->setEnabled(false);
|
||||
_sensitivityLabel->setEnabled(false);
|
||||
_sensitivityLabel->draw();
|
||||
_sensitivity->draw();
|
||||
}
|
||||
}
|
||||
|
||||
guard = false;
|
||||
}
|
||||
|
||||
if ((!guard) && (_radioButtonMode)) {
|
||||
|
||||
guard = true;
|
||||
@ -361,15 +256,8 @@ void setOptions() {
|
||||
|
||||
ConfMan.addGameDomain("ds");
|
||||
|
||||
DS::setLeftHanded(confGetBool("lefthanded", false));
|
||||
DS::setMouseCursorVisible(confGetBool("showcursor", true));
|
||||
|
||||
#ifdef DS_BUILD_D
|
||||
DS::setSnapToBorder(confGetBool("snaptoborder", true));
|
||||
#else
|
||||
DS::setSnapToBorder(confGetBool("snaptoborder", false));
|
||||
#endif
|
||||
|
||||
DS::setUnscaledMode(confGetBool("unscaled", false));
|
||||
|
||||
if (firstLoad) {
|
||||
@ -384,39 +272,12 @@ void setOptions() {
|
||||
}
|
||||
}
|
||||
|
||||
DS::setTouchXOffset(confGetInt("xoffset", 0));
|
||||
DS::setTouchYOffset(confGetInt("yoffset", 0));
|
||||
DS::setSensitivity(confGetInt("sensitivity", 8));
|
||||
|
||||
#ifdef ALLOW_CPU_SCALER
|
||||
DS::setCpuScalerEnable(confGetBool("cpu_scaler", false));
|
||||
#endif
|
||||
|
||||
DS::setTapScreenClicksEnable(confGetBool("screentaps", false));
|
||||
|
||||
DS::setGamma(confGetInt("gamma", 0));
|
||||
|
||||
|
||||
if (ConfMan.hasKey("touchpad", "ds")) {
|
||||
bool enable = ConfMan.getBool("touchpad", "ds");
|
||||
|
||||
DS::setTrackPadStyleEnable(enable);
|
||||
|
||||
if (enable && firstLoad) {
|
||||
// If we've just booted up, want to swap screens when trackpad mode is in use
|
||||
// but not every time we enter the options dialog.
|
||||
DS::setGameScreenSwap(true);
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
DS::setTapScreenClicksEnable(true);
|
||||
}
|
||||
|
||||
} else {
|
||||
DS::setTrackPadStyleEnable(false);
|
||||
}
|
||||
|
||||
|
||||
firstLoad = false;
|
||||
}
|
||||
|
||||
|
@ -51,28 +51,16 @@ protected:
|
||||
|
||||
GUI::TabWidget *_tab;
|
||||
|
||||
GUI::StaticTextWidget *_sensitivityLabel;
|
||||
|
||||
GUI::SliderWidget *_touchX;
|
||||
GUI::SliderWidget *_touchY;
|
||||
GUI::SliderWidget *_sensitivity;
|
||||
GUI::SliderWidget *_gammaCorrection;
|
||||
GUI::CheckboxWidget *_leftHandedCheckbox;
|
||||
GUI::CheckboxWidget *_unscaledCheckbox;
|
||||
GUI::CheckboxWidget *_100PercentCheckbox;
|
||||
GUI::CheckboxWidget *_150PercentCheckbox;
|
||||
GUI::CheckboxWidget *_200PercentCheckbox;
|
||||
GUI::CheckboxWidget *_indyFightCheckbox;
|
||||
GUI::CheckboxWidget *_disablePowerOff;
|
||||
GUI::CheckboxWidget *_showCursorCheckbox;
|
||||
GUI::CheckboxWidget *_snapToBorderCheckbox;
|
||||
|
||||
GUI::CheckboxWidget *_hardScaler;
|
||||
GUI::CheckboxWidget *_cpuScaler;
|
||||
|
||||
GUI::CheckboxWidget *_touchPadStyle;
|
||||
GUI::CheckboxWidget *_screenTaps;
|
||||
|
||||
bool _radioButtonMode;
|
||||
|
||||
};
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "common/util.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/translation.h"
|
||||
|
||||
#include "osystem_ds.h"
|
||||
#include "nds.h"
|
||||
@ -40,23 +41,20 @@
|
||||
#include "common/config-manager.h"
|
||||
#include "common/str.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "touchkeyboard.h"
|
||||
#include "backends/fs/devoptab/devoptab-fs-factory.h"
|
||||
#include "backends/keymapper/hardware-input.h"
|
||||
|
||||
#include "backends/audiocd/default/default-audiocd.h"
|
||||
#include "backends/events/default/default-events.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "backends/timer/default/default-timer.h"
|
||||
|
||||
#ifdef ENABLE_AGI
|
||||
#include "wordcompletion.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
OSystem_DS *OSystem_DS::_instance = NULL;
|
||||
|
||||
OSystem_DS::OSystem_DS()
|
||||
: eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _frameBufferExists(false),
|
||||
: _eventSource(NULL), _mixer(NULL), _frameBufferExists(false),
|
||||
_disableCursorPalette(true), _graphicsEnable(true), _gammaValue(0)
|
||||
{
|
||||
_instance = this;
|
||||
@ -78,6 +76,9 @@ void OSystem_DS::initBackend() {
|
||||
ConfMan.setInt("autosave_period", 0);
|
||||
ConfMan.setBool("FM_medium_quality", true);
|
||||
|
||||
_eventSource = new DSEventSource();
|
||||
_eventManager = new DefaultEventManager(_eventSource);
|
||||
|
||||
_savefileManager = new DefaultSaveFileManager();
|
||||
_timerManager = new DefaultTimerManager();
|
||||
DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
|
||||
@ -85,25 +86,21 @@ void OSystem_DS::initBackend() {
|
||||
_mixer = new Audio::MixerImpl(11025);
|
||||
_mixer->setReady(true);
|
||||
|
||||
EventsBaseBackend::initBackend();
|
||||
BaseBackend::initBackend();
|
||||
}
|
||||
|
||||
bool OSystem_DS::hasFeature(Feature f) {
|
||||
return (f == kFeatureVirtualKeyboard) || (f == kFeatureCursorPalette);
|
||||
return (f == kFeatureCursorPalette);
|
||||
}
|
||||
|
||||
void OSystem_DS::setFeatureState(Feature f, bool enable) {
|
||||
if (f == kFeatureVirtualKeyboard)
|
||||
DS::setKeyboardIcon(enable);
|
||||
else if (f == kFeatureCursorPalette) {
|
||||
if (f == kFeatureCursorPalette) {
|
||||
_disableCursorPalette = !enable;
|
||||
refreshCursor();
|
||||
}
|
||||
}
|
||||
|
||||
bool OSystem_DS::getFeatureState(Feature f) {
|
||||
if (f == kFeatureVirtualKeyboard)
|
||||
return DS::getKeyboardIcon();
|
||||
if (f == kFeatureCursorPalette)
|
||||
return !_disableCursorPalette;
|
||||
return false;
|
||||
@ -145,10 +142,7 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
|
||||
if (DS::getIsDisplayMode8Bit()) {
|
||||
int col = applyGamma(paletteValue);
|
||||
BG_PALETTE[r] = col;
|
||||
|
||||
if (!DS::getKeyboardEnable()) {
|
||||
BG_PALETTE_SUB[r] = col;
|
||||
}
|
||||
BG_PALETTE_SUB[r] = col;
|
||||
}
|
||||
|
||||
_palette[r] = paletteValue;
|
||||
@ -164,9 +158,7 @@ void OSystem_DS::restoreHardwarePalette() {
|
||||
for (int r = 0; r < 255; r++) {
|
||||
int col = applyGamma(_palette[r]);
|
||||
BG_PALETTE[r] = col;
|
||||
if (!DS::getKeyboardEnable()) {
|
||||
BG_PALETTE_SUB[r] = col;
|
||||
}
|
||||
BG_PALETTE_SUB[r] = col;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,115 +222,59 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
|
||||
|
||||
int by = 0;
|
||||
|
||||
if (DS::getKeyboardEnable()) {
|
||||
// When they keyboard is on screen, we don't update the subscreen because
|
||||
// the keyboard image uses the same VRAM addresses.
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
|
||||
u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
|
||||
const u8 *src = (const u8 *) buf + (pitch * by);
|
||||
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
|
||||
const u8 *src = (const u8 *) buf + (pitch * by);
|
||||
u32 dx;
|
||||
|
||||
u32 dx;
|
||||
u32 pixelsLeft = w;
|
||||
|
||||
u32 pixelsLeft = w;
|
||||
if (MISALIGNED16(dest)) {
|
||||
// Read modify write
|
||||
|
||||
if (MISALIGNED16(dest)) {
|
||||
// Read modify write
|
||||
dest--;
|
||||
u16 mix = *((u16 *) dest);
|
||||
|
||||
dest--;
|
||||
u16 mix = *((u16 *) dest);
|
||||
mix = (mix & 0x00FF) | (*src++ << 8);
|
||||
|
||||
mix = (mix & 0x00FF) | (*src++ << 8);
|
||||
*dest = mix;
|
||||
*destSub = mix;
|
||||
|
||||
*dest = mix;
|
||||
|
||||
dest += 2;
|
||||
pixelsLeft--;
|
||||
}
|
||||
|
||||
// We can now assume dest is aligned
|
||||
u16 *dest16 = (u16 *) dest;
|
||||
|
||||
for (dx = 0; dx < pixelsLeft; dx+=2) {
|
||||
u16 mix;
|
||||
|
||||
mix = *src + (*(src + 1) << 8);
|
||||
*dest16++ = mix;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
pixelsLeft -= dx;
|
||||
|
||||
// At the end we may have one pixel left over
|
||||
|
||||
if (pixelsLeft != 0) {
|
||||
u16 mix = *dest16;
|
||||
|
||||
mix = (mix & 0x00FF) | ((*src++) << 8);
|
||||
|
||||
*dest16 = mix;
|
||||
}
|
||||
|
||||
by++;
|
||||
dest += 2;
|
||||
destSub += 2;
|
||||
pixelsLeft--;
|
||||
}
|
||||
|
||||
} else {
|
||||
// When they keyboard is not on screen, update both vram copies
|
||||
// We can now assume dest is aligned
|
||||
u16 *dest16 = (u16 *) dest;
|
||||
u16 *destSub16 = (u16 *) destSub;
|
||||
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u8 *dest = ((u8 *) (bg)) + (dy * stride) + x;
|
||||
u8 *destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
|
||||
const u8 *src = (const u8 *) buf + (pitch * by);
|
||||
|
||||
u32 dx;
|
||||
|
||||
u32 pixelsLeft = w;
|
||||
|
||||
if (MISALIGNED16(dest)) {
|
||||
// Read modify write
|
||||
|
||||
dest--;
|
||||
u16 mix = *((u16 *) dest);
|
||||
|
||||
mix = (mix & 0x00FF) | (*src++ << 8);
|
||||
|
||||
*dest = mix;
|
||||
*destSub = mix;
|
||||
|
||||
dest += 2;
|
||||
destSub += 2;
|
||||
pixelsLeft--;
|
||||
}
|
||||
|
||||
// We can now assume dest is aligned
|
||||
u16 *dest16 = (u16 *) dest;
|
||||
u16 *destSub16 = (u16 *) destSub;
|
||||
|
||||
for (dx = 0; dx < pixelsLeft; dx+=2) {
|
||||
u16 mix;
|
||||
|
||||
mix = *src + (*(src + 1) << 8);
|
||||
*dest16++ = mix;
|
||||
*destSub16++ = mix;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
pixelsLeft -= dx;
|
||||
|
||||
// At the end we may have one pixel left over
|
||||
|
||||
if (pixelsLeft != 0) {
|
||||
u16 mix = *dest16;
|
||||
|
||||
mix = (mix & 0x00FF) | ((*src++) << 8);
|
||||
|
||||
*dest16 = mix;
|
||||
*destSub16 = mix;
|
||||
}
|
||||
|
||||
by++;
|
||||
for (dx = 0; dx < pixelsLeft; dx+=2) {
|
||||
u16 mix;
|
||||
|
||||
mix = *src + (*(src + 1) << 8);
|
||||
*dest16++ = mix;
|
||||
*destSub16++ = mix;
|
||||
src += 2;
|
||||
}
|
||||
|
||||
pixelsLeft -= dx;
|
||||
|
||||
// At the end we may have one pixel left over
|
||||
|
||||
if (pixelsLeft != 0) {
|
||||
u16 mix = *dest16;
|
||||
|
||||
mix = (mix & 0x00FF) | ((*src++) << 8);
|
||||
|
||||
*dest16 = mix;
|
||||
*destSub16 = mix;
|
||||
}
|
||||
|
||||
by++;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -347,39 +283,23 @@ void OSystem_DS::copyRectToScreen(const void *buf, int pitch, int x, int y, int
|
||||
|
||||
u16 *src = (u16 *) buf;
|
||||
|
||||
if (DS::getKeyboardEnable()) {
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
|
||||
u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
|
||||
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u16 *dest = bg + (dy * (stride >> 1)) + (x >> 1);
|
||||
DC_FlushRange(src, w << 1);
|
||||
DC_FlushRange(dest1, w << 1);
|
||||
DC_FlushRange(dest2, w << 1);
|
||||
|
||||
DC_FlushRange(src, w << 1);
|
||||
DC_FlushRange(dest, w << 1);
|
||||
dmaCopyHalfWords(3, src, dest, w);
|
||||
dmaCopyHalfWords(3, src, dest1, w);
|
||||
|
||||
while (dmaBusy(3));
|
||||
|
||||
src += pitch >> 1;
|
||||
if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
|
||||
dmaCopyHalfWords(2, src, dest2, w);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (int dy = y; dy < y + h; dy++) {
|
||||
u16 *dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
|
||||
u16 *dest2 = bgSub + (dy << 8) + (x >> 1);
|
||||
while (dmaBusy(2) || dmaBusy(3));
|
||||
|
||||
DC_FlushRange(src, w << 1);
|
||||
DC_FlushRange(dest1, w << 1);
|
||||
DC_FlushRange(dest2, w << 1);
|
||||
|
||||
dmaCopyHalfWords(3, src, dest1, w);
|
||||
|
||||
if ((!_frameBufferExists) || (buf == _framebuffer.getPixels())) {
|
||||
dmaCopyHalfWords(2, src, dest2, w);
|
||||
}
|
||||
|
||||
while (dmaBusy(2) || dmaBusy(3));
|
||||
|
||||
src += pitch >> 1;
|
||||
}
|
||||
src += pitch >> 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -393,13 +313,12 @@ void OSystem_DS::updateScreen() {
|
||||
}
|
||||
|
||||
DS::displayMode16BitFlipBuffer();
|
||||
DS::addEventsToQueue();
|
||||
|
||||
// FIXME: Evil game specific hack.
|
||||
// Force back buffer usage for Nippon Safes, as it doesn't double buffer it's output
|
||||
if (DS::getControlType() == DS::CONT_NIPPON) {
|
||||
lockScreen();
|
||||
}
|
||||
// if (DS::getControlType() == DS::CONT_NIPPON) {
|
||||
// lockScreen();
|
||||
// }
|
||||
}
|
||||
|
||||
void OSystem_DS::setShakePos(int shakeXOffset, int shakeYOffset) {
|
||||
@ -466,6 +385,7 @@ bool OSystem_DS::showMouse(bool visible) {
|
||||
}
|
||||
|
||||
void OSystem_DS::warpMouse(int x, int y) {
|
||||
DS::warpMouse(x, y);
|
||||
}
|
||||
|
||||
void OSystem_DS::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
|
||||
@ -487,45 +407,16 @@ void OSystem_DS::refreshCursor() {
|
||||
DS::setCursorIcon(_cursorImage, _cursorW, _cursorH, _cursorKey, _cursorHotX, _cursorHotY);
|
||||
}
|
||||
|
||||
void OSystem_DS::addEvent(const Common::Event& e) {
|
||||
eventQueue[queuePos++] = e;
|
||||
}
|
||||
|
||||
bool OSystem_DS::pollEvent(Common::Event &event) {
|
||||
|
||||
if (lastPenFrame != DS::getMillis()) {
|
||||
|
||||
if (eventNum == queuePos) {
|
||||
eventNum = 0;
|
||||
queuePos = 0;
|
||||
// Bodge - this last event seems to be processed sometimes and not others.
|
||||
// So we make it something harmless which won't cause any adverse effects.
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
event.kbd.ascii = 0;
|
||||
event.kbd.keycode = Common::KEYCODE_INVALID;
|
||||
event.kbd.flags = 0;
|
||||
return false;
|
||||
} else {
|
||||
event = eventQueue[eventNum++];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 OSystem_DS::getMillis(bool skipRecord) {
|
||||
return DS::getMillis();
|
||||
}
|
||||
|
||||
void OSystem_DS::delayMillis(uint msecs) {
|
||||
int st = getMillis();
|
||||
DS::addEventsToQueue();
|
||||
|
||||
while (st + msecs >= getMillis());
|
||||
|
||||
DS::doTimerCallback();
|
||||
DS::addEventsToQueue();
|
||||
}
|
||||
|
||||
|
||||
@ -627,19 +518,6 @@ void OSystem_DS::clearFocusRectangle() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void OSystem_DS::addAutoComplete(const char *word) {
|
||||
DS::addAutoComplete(word);
|
||||
}
|
||||
|
||||
void OSystem_DS::clearAutoComplete() {
|
||||
DS::clearAutoComplete();
|
||||
}
|
||||
|
||||
void OSystem_DS::setCharactersEntered(int count) {
|
||||
DS::setCharactersEntered(count);
|
||||
}
|
||||
|
||||
void OSystem_DS::logMessage(LogMessageType::Type type, const char *message) {
|
||||
#ifndef DISABLE_TEXT_CONSOLE
|
||||
nocashMessage((char *)message);
|
||||
@ -673,11 +551,38 @@ u16 OSystem_DS::applyGamma(u16 color) {
|
||||
return 0x8000 | r | (g << 5) | (b << 10);
|
||||
}
|
||||
|
||||
void OSystem_DS::engineDone() {
|
||||
DS::exitGame();
|
||||
static const Common::HardwareInputTableEntry ndsJoystickButtons[] = {
|
||||
{ "JOY_A", Common::JOYSTICK_BUTTON_A, _s("A") },
|
||||
{ "JOY_B", Common::JOYSTICK_BUTTON_B, _s("B") },
|
||||
{ "JOY_X", Common::JOYSTICK_BUTTON_X, _s("X") },
|
||||
{ "JOY_Y", Common::JOYSTICK_BUTTON_Y, _s("Y") },
|
||||
{ "JOY_BACK", Common::JOYSTICK_BUTTON_BACK, _s("Select") },
|
||||
{ "JOY_START", Common::JOYSTICK_BUTTON_START, _s("Start") },
|
||||
{ "JOY_LEFT_SHOULDER", Common::JOYSTICK_BUTTON_LEFT_SHOULDER, _s("L") },
|
||||
{ "JOY_RIGHT_SHOULDER", Common::JOYSTICK_BUTTON_RIGHT_SHOULDER, _s("R") },
|
||||
{ "JOY_UP", Common::JOYSTICK_BUTTON_DPAD_UP, _s("D-pad Up") },
|
||||
{ "JOY_DOWN", Common::JOYSTICK_BUTTON_DPAD_DOWN, _s("D-pad Down") },
|
||||
{ "JOY_LEFT", Common::JOYSTICK_BUTTON_DPAD_LEFT, _s("D-pad Left") },
|
||||
{ "JOY_RIGHT", Common::JOYSTICK_BUTTON_DPAD_RIGHT, _s("D-pad Right") },
|
||||
{ nullptr, 0, nullptr }
|
||||
};
|
||||
|
||||
#ifdef ENABLE_AGI
|
||||
DS::clearAutoCompleteWordList();
|
||||
#endif
|
||||
static const Common::AxisTableEntry ndsJoystickAxes[] = {
|
||||
{ nullptr, 0, Common::kAxisTypeFull, nullptr }
|
||||
};
|
||||
|
||||
const Common::HardwareInputTableEntry ndsMouseButtons[] = {
|
||||
{ "MOUSE_LEFT", Common::MOUSE_BUTTON_LEFT, _s("Touch") },
|
||||
{ nullptr, 0, nullptr }
|
||||
};
|
||||
|
||||
Common::HardwareInputSet *OSystem_DS::getHardwareInputSet() {
|
||||
using namespace Common;
|
||||
|
||||
CompositeHardwareInputSet *inputSet = new CompositeHardwareInputSet();
|
||||
// Touch input sends mouse events for now, so we need to declare we have a mouse...
|
||||
inputSet->addHardwareInputSet(new MouseHardwareInputSet(ndsMouseButtons));
|
||||
inputSet->addHardwareInputSet(new JoystickHardwareInputSet(ndsJoystickButtons, ndsJoystickAxes));
|
||||
|
||||
return inputSet;
|
||||
}
|
||||
|
@ -29,21 +29,14 @@
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
|
||||
|
||||
#include "backends/base-backend.h"
|
||||
#include "common/events.h"
|
||||
#include "backends/events/ds/ds-events.h"
|
||||
#include "nds.h"
|
||||
#include "audio/mixer_intern.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "graphics/palette.h"
|
||||
|
||||
class OSystem_DS : public EventsBaseBackend, public PaletteManager {
|
||||
class OSystem_DS : public BaseBackend, public PaletteManager {
|
||||
protected:
|
||||
|
||||
int eventNum;
|
||||
int lastPenFrame;
|
||||
|
||||
Common::Event eventQueue[96];
|
||||
int queuePos;
|
||||
|
||||
Audio::MixerImpl *_mixer;
|
||||
Graphics::Surface _framebuffer;
|
||||
bool _frameBufferExists;
|
||||
@ -62,6 +55,7 @@ protected:
|
||||
byte _cursorKey;
|
||||
int _cursorScale;
|
||||
|
||||
DSEventSource *_eventSource;
|
||||
|
||||
Graphics::Surface *createTempFrameBuffer();
|
||||
bool _disableCursorPalette;
|
||||
@ -111,11 +105,13 @@ public:
|
||||
virtual void warpMouse(int x, int y);
|
||||
virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, u32 keycolor, bool dontScale, const Graphics::PixelFormat *format);
|
||||
|
||||
virtual bool pollEvent(Common::Event &event);
|
||||
virtual uint32 getMillis(bool skipRecord = false);
|
||||
virtual void delayMillis(uint msecs);
|
||||
virtual void getTimeAndDate(TimeDate &t) const;
|
||||
|
||||
virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
|
||||
virtual Common::HardwareInputSet *getHardwareInputSet();
|
||||
|
||||
virtual MutexRef createMutex(void);
|
||||
virtual void lockMutex(MutexRef mutex);
|
||||
virtual void unlockMutex(MutexRef mutex);
|
||||
@ -123,9 +119,6 @@ public:
|
||||
|
||||
virtual void quit();
|
||||
|
||||
void addEvent(const Common::Event& e);
|
||||
bool isEventQueueEmpty() const { return queuePos == 0; }
|
||||
|
||||
virtual void setFocusRectangle(const Common::Rect& rect);
|
||||
|
||||
virtual void clearFocusRectangle();
|
||||
@ -139,11 +132,6 @@ public:
|
||||
|
||||
static int timerHandler(int t);
|
||||
|
||||
|
||||
virtual void addAutoComplete(const char *word);
|
||||
virtual void clearAutoComplete();
|
||||
virtual void setCharactersEntered(int count);
|
||||
|
||||
u16 getDSPaletteEntry(u32 entry) const { return _palette[entry]; }
|
||||
u16 getDSCursorPaletteEntry(u32 entry) const { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
|
||||
|
||||
@ -155,8 +143,6 @@ public:
|
||||
|
||||
u16 applyGamma(u16 color);
|
||||
void setGammaValue(int gamma) { _gammaValue = gamma; }
|
||||
|
||||
void engineDone();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,101 +0,0 @@
|
||||
/* 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 "scummhelp.h"
|
||||
#include "common/translation.h"
|
||||
|
||||
#define ADD_BIND(k,d) do { key[i] = k; dsc[i] = d; i++; } while (0)
|
||||
#define ADD_TEXT(d) ADD_BIND("",d)
|
||||
#define ADD_LINE ADD_BIND("","")
|
||||
|
||||
#define HELP_NUM_LINES 15
|
||||
|
||||
namespace DS {
|
||||
|
||||
void updateStrings(byte gameId, byte version, Common::Platform platform,
|
||||
int page, Common::U32String &title, Common::U32String *&key, Common::U32String *&dsc) {
|
||||
key = new Common::U32String[HELP_NUM_LINES];
|
||||
dsc = new Common::U32String[HELP_NUM_LINES];
|
||||
int i = 0;
|
||||
switch (page) {
|
||||
case 1: {
|
||||
title = _("DS Controls (right handed):");
|
||||
ADD_BIND(_("Pad Left"), _("Left mouse button"));
|
||||
ADD_BIND(_("Pad Right"), _("Right mouse button"));
|
||||
ADD_BIND(_("Pad Up"), _("Mouse hover mode (no click)"));
|
||||
ADD_BIND(_("Pad Down"), _("Skip dialog line (some games)"));
|
||||
ADD_BIND(_("Start"), _("Pause/Game menu"));
|
||||
ADD_BIND(_("Select"), _("DS Options menu"));
|
||||
ADD_BIND("B", _("Skip cutscenes"));
|
||||
ADD_BIND("A", _("Switch screens"));
|
||||
ADD_BIND("Y", _("Show/hide debug console"));
|
||||
ADD_BIND("X", _("Show/hide keyboard"));
|
||||
ADD_BIND("L+Pad/Pen", _("Scroll current touch screen view"));
|
||||
ADD_BIND("L+B/A", _("Zoom in/out"));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
title = _("DS Controls (left handed):");
|
||||
ADD_BIND("Y", _("Left mouse button"));
|
||||
ADD_BIND("A", _("Right mouse button"));
|
||||
ADD_BIND("X", _("Mouse hover mode (no click)"));
|
||||
ADD_BIND("B", _("Skip dialog line (some games)"));
|
||||
ADD_BIND(_("Start"), _("Pause/Game menu"));
|
||||
ADD_BIND(_("Select"), _("DS Options menu"));
|
||||
ADD_BIND(_("Pad Down"), _("Skip cutscenes"));
|
||||
ADD_BIND(_("Pad Up"), _("Show/hide keyboard"));
|
||||
ADD_BIND(_("Pad Left"), _("Show/hide debug console"));
|
||||
ADD_BIND(_("Pad Right"), _("Swap screens"));
|
||||
ADD_BIND("R+Pad/Pen", _("Scroll current touch screen view"));
|
||||
ADD_BIND("R+dwn/rgt", _("Zoom in/out"));
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
title = _("Indiana Jones Fight controls:");
|
||||
ADD_BIND(_("Pad Left"), _("Move left"));
|
||||
ADD_BIND(_("Pad Right"), _("Move right"));
|
||||
ADD_BIND(_("Pad Up"), _("High guard"));
|
||||
ADD_BIND(_("Pad Down"), _("Guard down"));
|
||||
ADD_BIND("Y", _("Guard middle"));
|
||||
ADD_BIND("X", _("Punch high"));
|
||||
ADD_BIND("A", _("Punch middle"));
|
||||
ADD_BIND("B", _("Punch low"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (i < HELP_NUM_LINES) {
|
||||
ADD_LINE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace DS
|
||||
|
||||
|
||||
|
||||
#undef ADD_BIND
|
||||
#undef ADD_TEXT
|
||||
#undef ADD_LINE
|
@ -1,538 +0,0 @@
|
||||
/* 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 <nds.h>
|
||||
#include "touchkeyboard.h"
|
||||
#include "keyboard_raw.h"
|
||||
#include "keyboard_pal_raw.h"
|
||||
#include "8x8font_tga_raw.h"
|
||||
#include "dsmain.h"
|
||||
#include "osystem_ds.h"
|
||||
|
||||
namespace DS {
|
||||
|
||||
struct key_data {
|
||||
char keyNum;
|
||||
signed char x, y;
|
||||
int character;
|
||||
bool pressed;
|
||||
};
|
||||
|
||||
#define DS_NUM_KEYS 72
|
||||
#define DS_SHIFT 2
|
||||
#define DS_BACKSPACE 8
|
||||
#define DS_RETURN 13
|
||||
#define DS_CAPSLOCK 1
|
||||
|
||||
|
||||
static key_data keys[DS_NUM_KEYS] = {
|
||||
// Key number x y character
|
||||
|
||||
// Numbers
|
||||
{28, 3, 0, '1', false},
|
||||
{29, 5, 0, '2', false},
|
||||
{30, 7, 0, '3', false},
|
||||
{31, 9, 0, '4', false},
|
||||
{32, 11, 0, '5', false},
|
||||
{33, 13, 0, '6', false},
|
||||
{34, 15, 0, '7', false},
|
||||
{35, 17, 0, '8', false},
|
||||
{36, 19, 0, '9', false},
|
||||
{27, 21, 0, '0', false},
|
||||
{45, 23, 0, Common::KEYCODE_MINUS, false},
|
||||
{50, 25, 0, Common::KEYCODE_EQUALS, false},
|
||||
{52, 27, 0, Common::KEYCODE_BACKSPACE, false},
|
||||
|
||||
// Top row
|
||||
{'Q'-'A' + 1, 4, 2, 'Q', false},
|
||||
{'W'-'A' + 1, 6, 2, 'W', false},
|
||||
{'E'-'A' + 1, 8, 2, 'E', false},
|
||||
{'R'-'A' + 1, 10, 2, 'R', false},
|
||||
{'T'-'A' + 1, 12, 2, 'T', false},
|
||||
{'Y'-'A' + 1, 14, 2, 'Y', false},
|
||||
{'U'-'A' + 1, 16, 2, 'U', false},
|
||||
{'I'-'A' + 1, 18, 2, 'I', false},
|
||||
{'O'-'A' + 1, 20, 2, 'O', false},
|
||||
{'P'-'A' + 1, 22, 2, 'P', false},
|
||||
{43, 24, 2, Common::KEYCODE_LEFTBRACKET, false},
|
||||
{44, 26, 2, Common::KEYCODE_RIGHTBRACKET, false},
|
||||
|
||||
// Middle row
|
||||
{55, 3, 4, DS_CAPSLOCK, false},
|
||||
{'A'-'A' + 1, 5, 4, 'A', false},
|
||||
{'S'-'A' + 1, 7, 4, 'S', false},
|
||||
{'D'-'A' + 1, 9, 4, 'D', false},
|
||||
{'F'-'A' + 1, 11, 4, 'F', false},
|
||||
{'G'-'A' + 1, 13, 4, 'G', false},
|
||||
{'H'-'A' + 1, 15, 4, 'H', false},
|
||||
{'J'-'A' + 1, 17, 4, 'J', false},
|
||||
{'K'-'A' + 1, 19, 4, 'K', false},
|
||||
{'L'-'A' + 1, 21, 4, 'L', false},
|
||||
{42, 23, 4, Common::KEYCODE_SEMICOLON, false},
|
||||
{41, 25, 4, Common::KEYCODE_QUOTE, false},
|
||||
{46, 27, 4, Common::KEYCODE_RETURN, false},
|
||||
|
||||
// Bottom row
|
||||
{51, 4, 6, DS_SHIFT, false},
|
||||
{'Z'-'A' + 1, 6, 6, 'Z', false},
|
||||
{'X'-'A' + 1, 8, 6, 'X', false},
|
||||
{'C'-'A' + 1, 10, 6, 'C', false},
|
||||
{'V'-'A' + 1, 12, 6, 'V', false},
|
||||
{'B'-'A' + 1, 14, 6, 'B', false},
|
||||
{'N'-'A' + 1, 16, 6, 'N', false},
|
||||
{'M'-'A' + 1, 18, 6, 'M', false},
|
||||
{38, 20, 6, Common::KEYCODE_COMMA, false},
|
||||
{39, 22, 6, Common::KEYCODE_PERIOD, false},
|
||||
{40, 24, 6, Common::KEYCODE_SLASH, false},
|
||||
|
||||
// Space bar
|
||||
{47, 9, 8, Common::KEYCODE_SPACE, false},
|
||||
{48, 11, 8, Common::KEYCODE_SPACE, false},
|
||||
{48, 13, 8, Common::KEYCODE_SPACE, false},
|
||||
{48, 15, 8, Common::KEYCODE_SPACE, false},
|
||||
{48, 17, 8, Common::KEYCODE_SPACE, false},
|
||||
{49, 19, 8, Common::KEYCODE_SPACE, false},
|
||||
|
||||
// Cursor arrows
|
||||
{52, 27, 8, Common::KEYCODE_LEFT, false},
|
||||
{54, 29, 8, Common::KEYCODE_DOWN, false},
|
||||
{53, 31, 8, Common::KEYCODE_RIGHT, false},
|
||||
{51, 29, 6, Common::KEYCODE_UP, false},
|
||||
|
||||
// Close button
|
||||
{56, 30, 0, Common::KEYCODE_INVALID, false},
|
||||
|
||||
// Function keys (needed for AGI)
|
||||
{57, 4, -2, Common::KEYCODE_F1, false},
|
||||
{58, 6, -2, Common::KEYCODE_F2, false},
|
||||
{59, 8, -2, Common::KEYCODE_F3, false},
|
||||
{60, 10, -2, Common::KEYCODE_F4, false},
|
||||
{61, 14, -2, Common::KEYCODE_F5, false},
|
||||
{62, 16, -2, Common::KEYCODE_F6, false},
|
||||
{63, 18, -2, Common::KEYCODE_F7, false},
|
||||
{64, 20, -2, Common::KEYCODE_F8, false},
|
||||
{65, 24, -2, Common::KEYCODE_F9, false},
|
||||
{66, 26, -2, Common::KEYCODE_F10, false},
|
||||
{67, 28, -2, Common::KEYCODE_F11, false},
|
||||
{68, 30, -2, Common::KEYCODE_F12, false},
|
||||
|
||||
};
|
||||
|
||||
static int keyboardX;
|
||||
static int keyboardY;
|
||||
|
||||
static int s_mapBase;
|
||||
static int s_tileBase;
|
||||
|
||||
static u16 *baseAddress;
|
||||
|
||||
static bool shiftState;
|
||||
static bool capsLockState;
|
||||
|
||||
static bool closed;
|
||||
|
||||
static char autoCompleteWord[NUM_WORDS][32];
|
||||
static int autoCompleteCount;
|
||||
|
||||
static char autoCompleteBuffer[128];
|
||||
|
||||
static int selectedCompletion = -1;
|
||||
static int charactersEntered = 0;
|
||||
static int typingTimeout = 0;
|
||||
|
||||
// Render text onto the tiled screen
|
||||
|
||||
void drawText(int tx, int ty, const char *string, bool highlight) {
|
||||
|
||||
u16 baseValue = 0;
|
||||
|
||||
if (highlight) {
|
||||
baseValue |= 0x1000;
|
||||
}
|
||||
|
||||
for (int p = 0; *string; string++, p++) {
|
||||
char c = *string;
|
||||
|
||||
if (c != ' ') {
|
||||
int tile = c - 33 + (KEYBOARD_DATA_SIZE / 32);
|
||||
baseAddress[ty * 32 + tx + p] = baseValue | tile;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace) {
|
||||
for (int r = 0; r < 32 * 32; r++) {
|
||||
((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = 0;
|
||||
}
|
||||
|
||||
for (int r = 0; r < KEYBOARD_DATA_SIZE / 2; r++) {
|
||||
((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r] = ((u16 *) (::keyboard_raw))[r];
|
||||
}
|
||||
|
||||
for (int r = 0; r < 16; r++) {
|
||||
BG_PALETTE_SUB[r] = ((u16 *) (keyboard_pal_raw))[r];
|
||||
}
|
||||
|
||||
// this is the font
|
||||
for (int tile = 0; tile < 94; tile++) {
|
||||
|
||||
u16 *tileAddr = (u16 *) (CHAR_BASE_BLOCK_SUB(tileBase) + ((KEYBOARD_DATA_SIZE) + (tile * 32)));
|
||||
const u8 *src = ((const u8 *) (::_8x8font_tga_raw)) + 18 + tile * 8;
|
||||
|
||||
for (int y = 0 ; y < 8; y++) {
|
||||
for (int x = 0; x < 2; x++) {
|
||||
*(tileAddr + (y * 2) + x) =(*(src + (y * 752) + (x * 4) + 0) & 0x0F)
|
||||
| ((*(src + (y * 752) + (x * 4) + 1) & 0x0F) << 4)
|
||||
| ((*(src + (y * 752) + (x * 4) + 2) & 0x0F) << 8)
|
||||
| ((*(src + (y * 752) + (x * 4) + 3) & 0x0F) << 12);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for (int r = 0; r < 16; r++) {
|
||||
int col = ((u16 *) (keyboard_pal_raw))[r];
|
||||
|
||||
int red = col & 0x001F;
|
||||
int green = (col & 0x03E0) >> 5;
|
||||
int blue = (col & 0x7C00) >> 10;
|
||||
|
||||
red = (red * 8) / 16;
|
||||
green = (green * 24) / 16;
|
||||
blue = (blue * 8) / 16;
|
||||
|
||||
if (green > 31) green = 31;
|
||||
|
||||
BG_PALETTE_SUB[16 + r] = red | (green << 5) | (blue << 10);
|
||||
}
|
||||
|
||||
keyboardX = -2;
|
||||
keyboardY = 2;
|
||||
|
||||
DS::s_mapBase = mapBase;
|
||||
DS::s_tileBase = tileBase;
|
||||
|
||||
shiftState = false;
|
||||
capsLockState = false;
|
||||
|
||||
int x = keyboardX;
|
||||
int y = keyboardY;
|
||||
|
||||
u16 *base = ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase));
|
||||
baseAddress = base;
|
||||
|
||||
for (int r = 0; r < DS_NUM_KEYS; r++) {
|
||||
base[(y + keys[r].y) * 32 + x + keys[r].x] = 10 + keys[r].keyNum * 2;
|
||||
base[(y + keys[r].y) * 32 + x + keys[r].x + 1] = 10 + keys[r].keyNum * 2 + 1;
|
||||
|
||||
base[(y + keys[r].y + 1) * 32 + x + keys[r].x] = 10 + 148 + keys[r].keyNum * 2;
|
||||
base[(y + keys[r].y + 1) * 32 + x + keys[r].x + 1] = 10 + 148 + keys[r].keyNum * 2 + 1;
|
||||
|
||||
keys[r].pressed = false;
|
||||
}
|
||||
|
||||
|
||||
closed = false;
|
||||
clearAutoComplete();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void drawAutoComplete() {
|
||||
|
||||
// Clear the auto complete area at the bottom of the screen.
|
||||
for (int y = 12; y < 24; y++) {
|
||||
for (int x = 0; x < 32; x++) {
|
||||
baseAddress[y * 32 + x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((autoCompleteCount == 0) || (typingTimeout > 0)) {
|
||||
|
||||
// When there's no completions on the bottom of the screen, it acts like a mouse pad
|
||||
// so this text indicates that
|
||||
drawText(11, 18, "MOUSE AREA", true);
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
printf("time: %d\n", typingTimeout);
|
||||
|
||||
// Otherwise, draw autocompletions if one isn't being entered and there are
|
||||
// some available.
|
||||
for (int r = 0; r < autoCompleteCount; r++) {
|
||||
int y = 12 + (r % 6) * 2;
|
||||
int x = 0 + ((r / 6) * 16);
|
||||
|
||||
drawText(x, y, autoCompleteWord[r], selectedCompletion == r);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool getKeyboardClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
void setKeyHighlight(int key, bool highlight) {
|
||||
u16 *base = ((u16 *) SCREEN_BASE_BLOCK_SUB(DS::s_mapBase));
|
||||
|
||||
if (highlight) {
|
||||
base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] |= 0x1000;
|
||||
base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] |= 0x1000;
|
||||
base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] |= 0x1000;
|
||||
base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] |= 0x1000;
|
||||
} else {
|
||||
base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] &= ~0x1000;
|
||||
base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000;
|
||||
base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] &= ~0x1000;
|
||||
base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000;
|
||||
}
|
||||
}
|
||||
|
||||
void addAutoComplete(const char *word) {
|
||||
if (autoCompleteCount == NUM_WORDS) return;
|
||||
strcpy(&autoCompleteWord[autoCompleteCount++][0], word);
|
||||
drawAutoComplete();
|
||||
}
|
||||
|
||||
void setCharactersEntered(int count) {
|
||||
charactersEntered = count;
|
||||
}
|
||||
|
||||
bool isInsideKeyboard(int x, int y) {
|
||||
// When completions are available, keyboard covers the whole screen.
|
||||
// otherwise, it only covers the area above KEYBOARD_BOTTOM_Y
|
||||
return (autoCompleteCount > 0) || (y < KEYBOARD_BOTTOM_Y);
|
||||
}
|
||||
|
||||
void clearAutoComplete() {
|
||||
autoCompleteCount = 0;
|
||||
selectedCompletion = -1;
|
||||
drawAutoComplete();
|
||||
}
|
||||
|
||||
void typeCompletion(int current) {
|
||||
Common::Event event;
|
||||
|
||||
strcat(autoCompleteBuffer, &autoCompleteWord[current][charactersEntered]);
|
||||
strcat(autoCompleteBuffer, " ");
|
||||
}
|
||||
|
||||
void updateTypeEvents() {
|
||||
if (autoCompleteBuffer[0] != '\0') {
|
||||
Common::Event event;
|
||||
OSystem_DS *system = OSystem_DS::instance();
|
||||
|
||||
event.kbd.keycode = (Common::KeyCode) autoCompleteBuffer[0];
|
||||
event.kbd.ascii = autoCompleteBuffer[0];
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
event.kbd.flags = 0;
|
||||
system->addEvent(event);
|
||||
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
system->addEvent(event);
|
||||
|
||||
for (int r = 0; r < (int)strlen(autoCompleteBuffer); r++) {
|
||||
autoCompleteBuffer[r] = autoCompleteBuffer[r + 1];
|
||||
}
|
||||
|
||||
typingTimeout = 100;
|
||||
}
|
||||
}
|
||||
|
||||
void createKeyEvent(int keyNum, Common::Event& event) {
|
||||
event.kbd.flags = 0;
|
||||
|
||||
if ((keys[keyNum].character >= '0') && (keys[keyNum].character <= '9')) {
|
||||
|
||||
if (!DS::shiftState) {
|
||||
event.kbd.ascii = keys[keyNum].character;
|
||||
event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
|
||||
} else {
|
||||
event.kbd.keycode = (Common::KeyCode) (Common::KEYCODE_F1 - (keys[keyNum].character - '1'));
|
||||
event.kbd.ascii = 0;
|
||||
}
|
||||
|
||||
} else if ((keys[keyNum].character >= 'A') && (keys[keyNum].character <= 'Z')) {
|
||||
|
||||
if ((!DS::shiftState) && (!DS::capsLockState)) {
|
||||
event.kbd.ascii = keys[keyNum].character + 32; // Make key lowercase.
|
||||
} else {
|
||||
event.kbd.ascii = keys[keyNum].character;
|
||||
}
|
||||
|
||||
event.kbd.keycode = (Common::KeyCode) event.kbd.ascii;
|
||||
} else {
|
||||
if ((keys[keyNum].character >= Common::KEYCODE_F1) && (keys[keyNum].character >= Common::KEYCODE_F12)) {
|
||||
event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
|
||||
event.kbd.ascii = keys[keyNum].character - Common::KEYCODE_F1 + Common::ASCII_F1;
|
||||
} else {
|
||||
event.kbd.ascii = keys[keyNum].character;
|
||||
event.kbd.keycode = (Common::KeyCode) keys[keyNum].character;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void releaseAllKeys() {
|
||||
for (int r = 0; r < DS_NUM_KEYS; r++) {
|
||||
if (keys[r].pressed) {
|
||||
DS::setKeyHighlight(r, false);
|
||||
|
||||
OSystem_DS *system = OSystem_DS::instance();
|
||||
|
||||
Common::Event event;
|
||||
createKeyEvent(r, event);
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
system->addEvent(event);
|
||||
|
||||
keys[r].pressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addKeyboardEvents() {
|
||||
bool resetShift = false;
|
||||
|
||||
updateTypeEvents();
|
||||
|
||||
if (typingTimeout > 0) {
|
||||
typingTimeout--;
|
||||
if (typingTimeout == 0) {
|
||||
drawAutoComplete();
|
||||
}
|
||||
}
|
||||
|
||||
if (DS::getPenDown()) {
|
||||
touchPosition touchPos;
|
||||
touchRead(&touchPos);
|
||||
|
||||
int tx = (touchPos.px >> 3);
|
||||
int ty = (touchPos.py >> 3);
|
||||
|
||||
if (ty >= 12) {
|
||||
int current = -1;
|
||||
|
||||
if (tx < 12) {
|
||||
current = (ty - 12) / 2;
|
||||
} else {
|
||||
current = 6 + (ty - 12) / 2;
|
||||
}
|
||||
|
||||
if (selectedCompletion == current) {
|
||||
typeCompletion(current);
|
||||
} else {
|
||||
if (current < autoCompleteCount) {
|
||||
selectedCompletion = current;
|
||||
}
|
||||
}
|
||||
|
||||
drawAutoComplete();
|
||||
}
|
||||
|
||||
tx -= keyboardX;
|
||||
ty -= keyboardY;
|
||||
|
||||
for (int r = 0; r < DS_NUM_KEYS; r++) {
|
||||
if (( (tx >= keys[r].x) && (tx <= keys[r].x + 1)) &&
|
||||
(ty >= keys[r].y) && (ty <= keys[r].y + 1)) {
|
||||
OSystem_DS *system = OSystem_DS::instance();
|
||||
Common::Event event;
|
||||
|
||||
if ((keys[r].character != Common::KEYCODE_INVALID)) {
|
||||
createKeyEvent(r, event);
|
||||
}
|
||||
|
||||
event.type = Common::EVENT_KEYDOWN;
|
||||
system->addEvent(event);
|
||||
|
||||
switch (keys[r].character) {
|
||||
case DS_SHIFT: {
|
||||
DS::shiftState = !DS::shiftState;
|
||||
DS::setKeyHighlight(r, DS::shiftState);
|
||||
break;
|
||||
}
|
||||
|
||||
case DS_CAPSLOCK: {
|
||||
DS::capsLockState = !DS::capsLockState;
|
||||
DS::setKeyHighlight(r, DS::capsLockState);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
DS::setKeyHighlight(r, true);
|
||||
keys[r].pressed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DS::getPenReleased()) {
|
||||
|
||||
for (int r = 0; r < DS_NUM_KEYS; r++) {
|
||||
if (keys[r].pressed) {
|
||||
DS::setKeyHighlight(r, false);
|
||||
|
||||
OSystem_DS *system = OSystem_DS::instance();
|
||||
|
||||
Common::Event event;
|
||||
if ((keys[r].character == Common::KEYCODE_INVALID)) {
|
||||
// Close button
|
||||
DS::closed = true;
|
||||
} else {
|
||||
createKeyEvent(r, event);
|
||||
event.type = Common::EVENT_KEYUP;
|
||||
system->addEvent(event);
|
||||
}
|
||||
|
||||
keys[r].pressed = false;
|
||||
|
||||
if (keys[r].character != DS_SHIFT) {
|
||||
resetShift = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((resetShift) && (DS::shiftState)) {
|
||||
DS::shiftState = false;
|
||||
resetShift = false;
|
||||
for (int t = 0; t < DS_NUM_KEYS; t++) {
|
||||
if (keys[t].character == DS_SHIFT) {
|
||||
DS::setKeyHighlight(t, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace DS
|
@ -1,50 +0,0 @@
|
||||
/* 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 _TOUCHKEYBOARD_H_
|
||||
#define _TOUCHKEYBOARD_H_
|
||||
|
||||
#include "osystem_ds.h"
|
||||
|
||||
namespace DS {
|
||||
|
||||
enum {
|
||||
NUM_WORDS = 12,
|
||||
KEYBOARD_DATA_SIZE = 4736 * 2,
|
||||
KEYBOARD_BOTTOM_Y = 105
|
||||
};
|
||||
|
||||
void createKeyEvent(int keyNum, Common::Event& event);
|
||||
|
||||
void drawKeyboard(int tileBase, int mapBase, u16 *saveSpace);
|
||||
void addKeyboardEvents();
|
||||
bool getKeyboardClosed();
|
||||
bool isInsideKeyboard(int x, int y);
|
||||
|
||||
void addAutoComplete(const char *word);
|
||||
void clearAutoComplete();
|
||||
void setCharactersEntered(int count);
|
||||
void releaseAllKeys();
|
||||
|
||||
} // End of namespace DS
|
||||
|
||||
#endif
|
@ -1,196 +0,0 @@
|
||||
/* 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 "osystem_ds.h"
|
||||
#include "wordcompletion.h"
|
||||
#include "engines/agi/agi.h" // Caution for #define for NUM_CHANNELS, causes problems in mixer_intern.h
|
||||
|
||||
#ifdef ENABLE_AGI
|
||||
|
||||
namespace DS {
|
||||
// Default dictionary is about 64Kb, so 96Kb should be enough for future expansion
|
||||
#define WORD_BUFFER_SIZE (96 * 1024)
|
||||
|
||||
// Default dictionary has ~8000 words
|
||||
#define MAX_WORD_COUNT 12000
|
||||
|
||||
char wordBuffer[WORD_BUFFER_SIZE];
|
||||
int wordBufferPos = 0;
|
||||
|
||||
char *wordBufferPtr[MAX_WORD_COUNT];
|
||||
int wordBufferPtrPos = 0;
|
||||
|
||||
void addAutoCompleteLine(const char *line) {
|
||||
|
||||
while (*line != 0) {
|
||||
char word[32];
|
||||
int length;
|
||||
|
||||
// Skip the T9-style numbers
|
||||
while (*line != ' ') {
|
||||
line++;
|
||||
}
|
||||
line++;
|
||||
|
||||
do {
|
||||
length = 0;
|
||||
|
||||
if (*line == ' ') line++;
|
||||
|
||||
|
||||
// Copy the new word
|
||||
do {
|
||||
word[length++] = *line++;
|
||||
} while ((*line != '\0') && (*line != ' ') && (*line != '\n'));
|
||||
|
||||
word[length] = '\0';
|
||||
|
||||
|
||||
// Store a pointer to the start of the word
|
||||
wordBufferPtr[wordBufferPtrPos++] = &wordBuffer[wordBufferPos];
|
||||
|
||||
// copy the new word into the buffer
|
||||
strcpy(&wordBuffer[wordBufferPos], word);
|
||||
wordBufferPos += strlen(word) + 1;
|
||||
} while (*line == ' ');
|
||||
}
|
||||
}
|
||||
|
||||
int stringCompare(const void *a, const void *b) {
|
||||
const char** as = (const char **) a;
|
||||
const char** bs = (const char **) b;
|
||||
|
||||
return scumm_stricmp(*as, *bs);
|
||||
}
|
||||
|
||||
void clearAutoCompleteWordList() {
|
||||
wordBufferPtrPos = 0;
|
||||
wordBufferPos = 0;
|
||||
}
|
||||
|
||||
void sortAutoCompleteWordList() {
|
||||
// Sort the whole word list into alphabetical order
|
||||
qsort((void *)wordBufferPtr, wordBufferPtrPos, 4, stringCompare);
|
||||
}
|
||||
|
||||
// Sends the current available words to the virtual keyboard code for display
|
||||
bool findWordCompletions(const char *input) {
|
||||
int min = 0;
|
||||
int max = wordBufferPtrPos - 1;
|
||||
char *word;
|
||||
int position;
|
||||
char partialWord[32];
|
||||
|
||||
// Early out if dictionary not loaded
|
||||
if (wordBufferPtrPos == 0)
|
||||
return false;
|
||||
|
||||
OSystem_DS *system = dynamic_cast<OSystem_DS *>(g_system);
|
||||
system->clearAutoComplete();
|
||||
|
||||
int start = 0;
|
||||
for (int r = strlen(input) - 1; r>0; r--) {
|
||||
if (input[r] == ' ') {
|
||||
start = r + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
strcpy(partialWord, &input[start]);
|
||||
|
||||
if (*partialWord == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
position = min + ((max - min) / 2);
|
||||
|
||||
// Get the word from the dictonary line
|
||||
word = wordBufferPtr[position];
|
||||
|
||||
// Now check to see if the word is before or after the stub we're after
|
||||
int result = scumm_stricmp(partialWord, word);
|
||||
|
||||
if (result == 0) {
|
||||
// We've found the whole word. Aren't we good.
|
||||
break;
|
||||
} else if (result > 0) {
|
||||
// We're too early, so change the minimum position
|
||||
min = position + 1;
|
||||
} else if (result < 0) {
|
||||
// We're too early, so change the maximum position
|
||||
max = position - 1;
|
||||
}
|
||||
} while (max - min > 0);
|
||||
|
||||
position = min;
|
||||
word = wordBufferPtr[position];
|
||||
|
||||
system->setCharactersEntered(strlen(partialWord));
|
||||
|
||||
|
||||
bool match = true;
|
||||
|
||||
|
||||
for (int r = 0; partialWord[r] != 0; r++) {
|
||||
if (word[r] != partialWord[r]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
position++;
|
||||
if (position == wordBufferPtrPos)
|
||||
return false;
|
||||
word = wordBufferPtr[position];
|
||||
}
|
||||
|
||||
|
||||
match = true;
|
||||
|
||||
do {
|
||||
|
||||
for (int r = 0; partialWord[r] != 0; r++) {
|
||||
if (word[r] != partialWord[r]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
system->addAutoComplete(word);
|
||||
}
|
||||
|
||||
position++;
|
||||
if (position < wordBufferPtrPos) {
|
||||
word = wordBufferPtr[position];
|
||||
}
|
||||
|
||||
} while ((match) && (position < wordBufferPtrPos));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace DS
|
||||
|
||||
#endif
|
@ -1,30 +0,0 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace DS {
|
||||
|
||||
extern void clearAutoCompleteWordList();
|
||||
extern bool findWordCompletions(const char *input);
|
||||
extern void addAutoCompleteLine(const char *line);
|
||||
extern void sortAutoCompleteWordList();
|
||||
|
||||
} // End of namespace DS
|
@ -1,74 +1,10 @@
|
||||
MODULE := backends/platform/ds
|
||||
|
||||
PORT_OBJS := \
|
||||
MODULE_OBJS := \
|
||||
arm9/source/blitters_arm.o \
|
||||
arm9/source/dsmain.o \
|
||||
arm9/source/scummhelp.o \
|
||||
arm9/source/osystem_ds.o \
|
||||
arm9/source/touchkeyboard.o \
|
||||
arm9/source/dsoptions.o \
|
||||
arm9/source/wordcompletion.o
|
||||
|
||||
DATA_OBJS := \
|
||||
arm9/data/icons.o \
|
||||
arm9/data/keyboard.o \
|
||||
arm9/data/keyboard_pal.o \
|
||||
arm9/data/default_font.o \
|
||||
arm9/data/8x8font_tga.o
|
||||
|
||||
|
||||
MODULE_OBJS := $(DATA_OBJS) $(PORT_OBJS)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# canned command sequence for binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
define bin2o
|
||||
$(MKDIR) $(*D)
|
||||
bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@)
|
||||
endef
|
||||
|
||||
define bin2h
|
||||
$(MKDIR) $(*D)
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > $@
|
||||
echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@
|
||||
echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@
|
||||
endef
|
||||
|
||||
vpath %.raw $(srcdir)
|
||||
vpath %.pal $(srcdir)
|
||||
vpath %.bin $(srcdir)
|
||||
|
||||
%.o: %.raw
|
||||
$(bin2o)
|
||||
|
||||
%_raw.h: %.raw
|
||||
$(bin2h)
|
||||
|
||||
%.o: %.pal
|
||||
$(bin2o)
|
||||
|
||||
%_raw.h: %.pal
|
||||
$(bin2h)
|
||||
|
||||
%.o: %.bin
|
||||
$(bin2o)
|
||||
|
||||
%_raw.h: %.bin
|
||||
$(bin2h)
|
||||
|
||||
|
||||
# Mark files which require the *_raw.h files manually (for now, at least)
|
||||
$(MODULE)/arm9/source/dsmain.o: \
|
||||
$(MODULE)/arm9/data/icons_raw.h \
|
||||
$(MODULE)/arm9/data/keyboard_raw.h \
|
||||
$(MODULE)/arm9/data/keyboard_pal_raw.h
|
||||
|
||||
$(MODULE)/arm9/source/touchkeyboard.o: \
|
||||
$(MODULE)/arm9/data/keyboard_raw.h \
|
||||
$(MODULE)/arm9/data/keyboard_pal_raw.h \
|
||||
$(MODULE)/arm9/data/8x8font_tga_raw.h
|
||||
|
||||
arm9/source/dsoptions.o
|
||||
|
||||
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
|
||||
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
|
||||
|
@ -167,14 +167,6 @@ int AgiEngine::agiInit() {
|
||||
if (ec == errOK)
|
||||
ec = _loader->loadResource(RESOURCETYPE_LOGIC, 0);
|
||||
|
||||
#ifdef __DS__
|
||||
// Normally, the engine loads the predictive text dictionary when the predictive dialog
|
||||
// is shown. On the DS version, the word completion feature needs the dictionary too.
|
||||
|
||||
// FIXME - loadDict() no long exists in AGI as this has been moved to within the
|
||||
// GUI Predictive Dialog, but DS Word Completion is probably broken due to this...
|
||||
#endif
|
||||
|
||||
_keyHoldMode = false;
|
||||
_keyHoldModeLastKey = Common::KEYCODE_INVALID;
|
||||
|
||||
|
@ -28,9 +28,6 @@
|
||||
#include "agi/text.h"
|
||||
#include "agi/systemui.h"
|
||||
#include "agi/words.h"
|
||||
#ifdef __DS__
|
||||
#include "wordcompletion.h"
|
||||
#endif
|
||||
|
||||
namespace Agi {
|
||||
|
||||
@ -829,9 +826,6 @@ void TextMgr::promptClear() {
|
||||
}
|
||||
|
||||
void TextMgr::promptRememberForAutoComplete(bool entered) {
|
||||
#ifdef __DS__
|
||||
DS::findWordCompletions((char *)_prompt);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TextMgr::promptCommandWindow(bool recallLastCommand, uint16 newKey) {
|
||||
@ -1000,9 +994,6 @@ void TextMgr::stringKeyPress(uint16 newKey) {
|
||||
}
|
||||
|
||||
void TextMgr::stringRememberForAutoComplete(bool entered) {
|
||||
#ifdef __DS__
|
||||
DS::findWordCompletions((char *)_inputString);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,10 +30,6 @@
|
||||
|
||||
#include "graphics/scaler.h"
|
||||
|
||||
#ifdef __DS__
|
||||
#include "scummhelp.h"
|
||||
#endif
|
||||
|
||||
#include "gui/gui-manager.h"
|
||||
#include "gui/widget.h"
|
||||
#include "gui/ThemeEval.h"
|
||||
@ -329,12 +325,7 @@ void HelpDialog::reflowLayout() {
|
||||
void HelpDialog::displayKeyBindings() {
|
||||
U32String titleStr, *keyStr, *dscStr;
|
||||
|
||||
#ifndef __DS__
|
||||
ScummHelp::updateStrings(_game.id, _game.version, _game.platform, _page, titleStr, keyStr, dscStr);
|
||||
#else
|
||||
// DS version has a different help screen
|
||||
DS::updateStrings(_game.id, _game.version, _game.platform, _page, titleStr, keyStr, dscStr);
|
||||
#endif
|
||||
|
||||
_title->setLabel(titleStr);
|
||||
for (int i = 0; i < _numLines; i++) {
|
||||
|
@ -35,10 +35,6 @@
|
||||
#include "common/file.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
#if defined(__DS__) && defined(ENABLE_AGI)
|
||||
#include "backends/platform/ds/arm9/source/wordcompletion.h"
|
||||
#endif
|
||||
|
||||
namespace GUI {
|
||||
|
||||
enum {
|
||||
@ -976,10 +972,6 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
|
||||
while ((ptr = strchr(ptr, '\n'))) {
|
||||
*ptr = 0;
|
||||
ptr++;
|
||||
#if defined(__DS__) && defined(ENABLE_AGI)
|
||||
// Pass the line on to the DS word list
|
||||
DS::addAutoCompleteLine(dict.dictLine[i - 1]);
|
||||
#endif
|
||||
dict.dictLine[i++] = ptr;
|
||||
}
|
||||
if (dict.dictLine[lines - 1][0] == 0)
|
||||
@ -989,12 +981,7 @@ void PredictiveDialog::loadDictionary(Common::SeekableReadStream *in, Dict &dict
|
||||
debug(5, "Predictive Dialog: Loaded %d lines", dict.dictLineCount);
|
||||
|
||||
// FIXME: We use binary search on _predictiveDict.dictLine, yet we make no at_tempt
|
||||
// to ever sort this array (except for the DS port). That seems risky, doesn't it?
|
||||
|
||||
#if defined(__DS__) && defined(ENABLE_AGI)
|
||||
// Sort the DS word completion list, to allow for a binary chop later (in the ds backend)
|
||||
DS::sortAutoCompleteWordList();
|
||||
#endif
|
||||
// to ever sort this array. That seems risky, doesn't it?
|
||||
|
||||
uint32 time3 = g_system->getMillis();
|
||||
debug(5, "Predictive Dialog: Time to parse %s: %d, total: %d", ConfMan.get(dict.nameDict).c_str(), time3 - time2, time3 - time1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user