mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-05 00:36:57 +00:00
713 lines
16 KiB
C++
713 lines
16 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*
|
|
* This file is dual-licensed.
|
|
* In addition to the GPLv3 license mentioned above, this code is also
|
|
* licensed under LGPL 2.1. See LICENSES/COPYING.LGPL file for the
|
|
* full text of the license.
|
|
*
|
|
*/
|
|
|
|
#include "common/stream.h"
|
|
|
|
#include "graphics/paletteman.h"
|
|
|
|
#include "gob/gob.h"
|
|
#include "gob/util.h"
|
|
#include "gob/global.h"
|
|
#include "gob/dataio.h"
|
|
#include "gob/draw.h"
|
|
#include "gob/game.h"
|
|
#include "gob/video.h"
|
|
#include "gob/videoplayer.h"
|
|
#include "gob/sound/sound.h"
|
|
|
|
namespace Gob {
|
|
|
|
Util::Util(GobEngine *vm) : _vm(vm) {
|
|
_mouseButtons = kMouseButtonsNone;
|
|
_keyBufferHead = 0;
|
|
_keyBufferTail = 0;
|
|
_fastMode = 0;
|
|
_frameRate = 12;
|
|
_frameWaitTime = 0;
|
|
_startFrameTime = 0;
|
|
|
|
_keyState = 0;
|
|
}
|
|
|
|
uint32 Util::getTimeKey() {
|
|
return g_system->getMillis() * _vm->_global->_speedFactor;
|
|
}
|
|
|
|
int16 Util::getRandom(int16 max) {
|
|
if (max == 0)
|
|
return 0;
|
|
|
|
return _vm->_rnd.getRandomNumber(max - 1);
|
|
}
|
|
|
|
void Util::beep(int16 freq) {
|
|
if (_vm->_global->_soundFlags == 0)
|
|
return;
|
|
|
|
_vm->_sound->speakerOn(freq, 50);
|
|
}
|
|
|
|
void Util::notifyPaused(uint32 duration) {
|
|
_startFrameTime += duration;
|
|
}
|
|
|
|
void Util::delay(uint16 msecs) {
|
|
g_system->delayMillis(msecs / _vm->_global->_speedFactor);
|
|
}
|
|
|
|
void Util::longDelay(uint16 msecs) {
|
|
uint32 time = g_system->getMillis() * _vm->_global->_speedFactor + msecs;
|
|
do {
|
|
_vm->_video->waitRetrace();
|
|
processInput();
|
|
delay(15);
|
|
} while (!_vm->shouldQuit() &&
|
|
((g_system->getMillis() * _vm->_global->_speedFactor) < time));
|
|
}
|
|
|
|
void Util::initInput() {
|
|
_mouseButtons = kMouseButtonsNone;
|
|
_keyBufferHead = _keyBufferTail = 0;
|
|
}
|
|
|
|
void Util::processInput(bool scroll) {
|
|
Common::Event event;
|
|
Common::EventManager *eventMan = g_system->getEventManager();
|
|
int16 x = 0, y = 0;
|
|
bool hasMove = false;
|
|
|
|
_vm->_vidPlayer->updateLive();
|
|
|
|
while (eventMan->pollEvent(event)) {
|
|
switch (event.type) {
|
|
case Common::EVENT_MOUSEMOVE:
|
|
hasMove = true;
|
|
x = event.mouse.x;
|
|
y = event.mouse.y;
|
|
break;
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsLeft));
|
|
break;
|
|
case Common::EVENT_RBUTTONDOWN:
|
|
_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsRight));
|
|
break;
|
|
case Common::EVENT_LBUTTONUP:
|
|
_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsLeft));
|
|
break;
|
|
case Common::EVENT_RBUTTONUP:
|
|
_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight));
|
|
break;
|
|
case Common::EVENT_KEYDOWN:
|
|
keyDown(event);
|
|
|
|
if (event.kbd.hasFlags(Common::KBD_CTRL)) {
|
|
if (event.kbd.keycode == Common::KEYCODE_f)
|
|
_fastMode ^= 1;
|
|
else if (event.kbd.keycode == Common::KEYCODE_g)
|
|
_fastMode ^= 2;
|
|
else if (event.kbd.keycode == Common::KEYCODE_p)
|
|
_vm->pauseGame();
|
|
break;
|
|
}
|
|
addKeyToBuffer(event.kbd);
|
|
break;
|
|
case Common::EVENT_KEYUP:
|
|
keyUp(event);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
_vm->_global->_speedFactor = MIN(_fastMode + 1, 3);
|
|
if (hasMove && scroll) {
|
|
x = CLIP(x, _vm->_global->_mouseMinX, _vm->_global->_mouseMaxX);
|
|
y = CLIP(y, _vm->_global->_mouseMinY, _vm->_global->_mouseMaxY);
|
|
|
|
x -= _vm->_video->_screenDeltaX;
|
|
y -= _vm->_video->_screenDeltaY;
|
|
|
|
_vm->_util->setMousePos(x, y);
|
|
_vm->_game->wantScroll(x, y);
|
|
|
|
// WORKAROUND:
|
|
// Force a check of the mouse in order to fix the sofa bug. This apply only for Gob3, and only
|
|
// in the impacted TOT file so that the second screen animation is not broken.
|
|
if ((_vm->getGameType() == kGameTypeGob3) && _vm->isCurrentTot("EMAP1008.TOT"))
|
|
_vm->_game->evaluateScroll();
|
|
}
|
|
}
|
|
|
|
void Util::clearKeyBuf() {
|
|
processInput();
|
|
_keyBufferHead = _keyBufferTail = 0;
|
|
}
|
|
|
|
bool Util::keyBufferEmpty() {
|
|
return (_keyBufferHead == _keyBufferTail);
|
|
}
|
|
|
|
void Util::addKeyToBuffer(const Common::KeyState &key) {
|
|
if ((_keyBufferHead + 1) % KEYBUFSIZE == _keyBufferTail) {
|
|
warning("key buffer overflow");
|
|
return;
|
|
}
|
|
|
|
_keyBuffer[_keyBufferHead] = key;
|
|
_keyBufferHead = (_keyBufferHead + 1) % KEYBUFSIZE;
|
|
}
|
|
|
|
bool Util::getKeyFromBuffer(Common::KeyState &key) {
|
|
if (_keyBufferHead == _keyBufferTail) return false;
|
|
|
|
key = _keyBuffer[_keyBufferTail];
|
|
_keyBufferTail = (_keyBufferTail + 1) % KEYBUFSIZE;
|
|
|
|
return true;
|
|
}
|
|
|
|
static const uint16 kLatin1ToCP850[] = {
|
|
0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE,
|
|
0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8,
|
|
0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, 0xD4, 0x90, 0xD2, 0xD3, 0xDE, 0xD6, 0xD7, 0xD8,
|
|
0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, 0x9D, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE8, 0xE1,
|
|
0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B,
|
|
0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, 0x9B, 0x97, 0xA3, 0x96, 0x81, 0xEC, 0xE7, 0x98
|
|
};
|
|
|
|
int16 Util::toCP850(uint16 latin1) {
|
|
if ((latin1 < 0xA0) || ((latin1 - 0xA0) >= ARRAYSIZE(kLatin1ToCP850)))
|
|
return 0;
|
|
|
|
return kLatin1ToCP850[latin1 - 0xA0];
|
|
}
|
|
|
|
int16 Util::translateKey(const Common::KeyState &key) {
|
|
static struct keyS {
|
|
int16 from;
|
|
int16 to;
|
|
} keys[] = {
|
|
{Common::KEYCODE_BACKSPACE, kKeyBackspace},
|
|
{Common::KEYCODE_SPACE, kKeySpace },
|
|
{Common::KEYCODE_RETURN, kKeyReturn },
|
|
{Common::KEYCODE_ESCAPE, kKeyEscape },
|
|
{Common::KEYCODE_DELETE, kKeyDelete },
|
|
{Common::KEYCODE_UP, kKeyUp },
|
|
{Common::KEYCODE_DOWN, kKeyDown },
|
|
{Common::KEYCODE_RIGHT, kKeyRight },
|
|
{Common::KEYCODE_LEFT, kKeyLeft },
|
|
{Common::KEYCODE_F1, kKeyF1 },
|
|
{Common::KEYCODE_F2, kKeyF2 },
|
|
{Common::KEYCODE_F3, kKeyF3 },
|
|
{Common::KEYCODE_F4, kKeyF4 },
|
|
{Common::KEYCODE_F5, kKeyEscape },
|
|
{Common::KEYCODE_F6, kKeyF6 },
|
|
{Common::KEYCODE_F7, kKeyF7 },
|
|
{Common::KEYCODE_F8, kKeyF8 },
|
|
{Common::KEYCODE_F9, kKeyF9 },
|
|
{Common::KEYCODE_F10, kKeyF10 }
|
|
};
|
|
|
|
// Translate special keys
|
|
for (int i = 0; i < ARRAYSIZE(keys); i++)
|
|
if (key.keycode == keys[i].from)
|
|
return keys[i].to;
|
|
|
|
// Return the ascii value, for text input
|
|
if ((key.ascii >= 32) && (key.ascii <= 127))
|
|
return key.ascii;
|
|
|
|
// Translate international characters into CP850 characters
|
|
if ((key.ascii >= 160) && (key.ascii <= 255))
|
|
return toCP850(key.ascii);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const uint8 kLowerToUpper[][2] = {
|
|
{0x81, 0x9A},
|
|
{0x82, 0x90},
|
|
{0x83, 0xB6},
|
|
{0x84, 0x8E},
|
|
{0x85, 0xB7},
|
|
{0x86, 0x8F},
|
|
{0x87, 0x80},
|
|
{0x88, 0xD2},
|
|
{0x89, 0xD3},
|
|
{0x8A, 0xD4},
|
|
{0x8B, 0xD8},
|
|
{0x8C, 0xD7},
|
|
{0x8D, 0xDE},
|
|
{0x91, 0x92},
|
|
{0x93, 0xE2},
|
|
{0x94, 0x99},
|
|
{0x95, 0xE3},
|
|
{0x96, 0xEA},
|
|
{0x97, 0xEB},
|
|
{0x95, 0xE3},
|
|
{0x96, 0xEA},
|
|
{0x97, 0xEB},
|
|
{0x9B, 0x9D},
|
|
{0xA0, 0xB5},
|
|
{0xA1, 0xD6},
|
|
{0xA2, 0xE0},
|
|
{0xA3, 0xE9},
|
|
{0xA4, 0xA5},
|
|
{0xC6, 0xC7},
|
|
{0xD0, 0xD1},
|
|
{0xE4, 0xE5},
|
|
{0xE7, 0xE8},
|
|
{0xEC, 0xED}
|
|
};
|
|
|
|
char Util::toCP850Lower(char cp850) {
|
|
const uint8 cp = (unsigned char)cp850;
|
|
if (cp <= 32)
|
|
return cp850;
|
|
|
|
if (cp <= 127)
|
|
return tolower(cp850);
|
|
|
|
for (uint i = 0; i < ARRAYSIZE(kLowerToUpper); i++)
|
|
if (cp == kLowerToUpper[i][1])
|
|
return (char)kLowerToUpper[i][0];
|
|
|
|
return cp850;
|
|
}
|
|
|
|
char Util::toCP850Upper(char cp850) {
|
|
const uint8 cp = (unsigned char)cp850;
|
|
if (cp <= 32)
|
|
return cp850;
|
|
|
|
if (cp <= 127)
|
|
return toupper(cp850);
|
|
|
|
for (uint i = 0; i < ARRAYSIZE(kLowerToUpper); i++)
|
|
if (cp == kLowerToUpper[i][0])
|
|
return (char)kLowerToUpper[i][1];
|
|
|
|
return cp850;
|
|
}
|
|
|
|
int16 Util::getKey() {
|
|
Common::KeyState key;
|
|
|
|
while (!getKeyFromBuffer(key)) {
|
|
processInput();
|
|
|
|
if (keyBufferEmpty())
|
|
g_system->delayMillis(10 / _vm->_global->_speedFactor);
|
|
}
|
|
return translateKey(key);
|
|
}
|
|
|
|
int16 Util::checkKey() {
|
|
Common::KeyState key;
|
|
|
|
getKeyFromBuffer(key);
|
|
|
|
return translateKey(key);
|
|
}
|
|
|
|
bool Util::checkKey(int16 &key) {
|
|
Common::KeyState keyS;
|
|
|
|
if (!getKeyFromBuffer(keyS))
|
|
return false;
|
|
|
|
key = translateKey(keyS);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Util::keyPressed() {
|
|
int16 key = checkKey();
|
|
if (key)
|
|
return true;
|
|
|
|
int16 x, y;
|
|
MouseButtons buttons;
|
|
|
|
getMouseState(&x, &y, &buttons);
|
|
return buttons != kMouseButtonsNone;
|
|
}
|
|
|
|
void Util::getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons) {
|
|
Common::Point mouse = g_system->getEventManager()->getMousePos();
|
|
*pX = mouse.x + _vm->_video->_scrollOffsetX - _vm->_video->_screenDeltaX;
|
|
*pY = mouse.y + _vm->_video->_scrollOffsetY - _vm->_video->_screenDeltaY;
|
|
|
|
if (pButtons != nullptr)
|
|
*pButtons = _mouseButtons;
|
|
}
|
|
|
|
void Util::setMousePos(int16 x, int16 y) {
|
|
x = CLIP<int>(x + _vm->_video->_screenDeltaX, 0, _vm->_width - 1);
|
|
y = CLIP<int>(y + _vm->_video->_screenDeltaY, 0, _vm->_height - 1);
|
|
g_system->warpMouse(x, y);
|
|
}
|
|
|
|
void Util::waitMouseUp() {
|
|
do {
|
|
processInput();
|
|
if (_mouseButtons != kMouseButtonsNone)
|
|
delay(10);
|
|
} while (_mouseButtons != kMouseButtonsNone);
|
|
}
|
|
|
|
void Util::waitMouseDown() {
|
|
int16 x;
|
|
int16 y;
|
|
MouseButtons buttons;
|
|
|
|
do {
|
|
processInput();
|
|
getMouseState(&x, &y, &buttons);
|
|
if (buttons == 0)
|
|
delay(10);
|
|
} while (buttons == 0);
|
|
}
|
|
|
|
void Util::waitMouseRelease(char drawMouse) {
|
|
MouseButtons buttons;
|
|
int16 mouseX;
|
|
int16 mouseY;
|
|
|
|
_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, drawMouse);
|
|
while (buttons != 0) {
|
|
if (drawMouse != 0)
|
|
_vm->_draw->animateCursor(2);
|
|
delay(10);
|
|
_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, drawMouse);
|
|
}
|
|
}
|
|
|
|
void Util::forceMouseUp(bool onlyWhenSynced) {
|
|
if (onlyWhenSynced && (_vm->_game->_mouseButtons != _mouseButtons))
|
|
return;
|
|
|
|
_vm->_game->_mouseButtons = kMouseButtonsNone;
|
|
_mouseButtons = kMouseButtonsNone;
|
|
}
|
|
|
|
void Util::clearPalette() {
|
|
int16 i;
|
|
byte colors[768];
|
|
|
|
_vm->validateVideoMode(_vm->_global->_videoMode);
|
|
|
|
if (_vm->_global->_setAllPalette) {
|
|
if (_vm->getPixelFormat().bytesPerPixel == 1) {
|
|
memset(colors, 0, sizeof(colors));
|
|
g_system->getPaletteManager()->setPalette(colors, 0, 256);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < 16; i++)
|
|
_vm->_video->setPalElem(i, 0, 0, 0, 0, _vm->_global->_videoMode);
|
|
}
|
|
|
|
int16 Util::getFrameRate() {
|
|
return _frameRate;
|
|
}
|
|
|
|
void Util::setFrameRate(int16 rate) {
|
|
if (rate == 0)
|
|
rate = 1;
|
|
|
|
_frameRate = rate;
|
|
_frameWaitTime = 1000 / rate;
|
|
_startFrameTime = getTimeKey();
|
|
}
|
|
|
|
void Util::notifyNewAnim() {
|
|
_startFrameTime = getTimeKey();
|
|
}
|
|
|
|
void Util::waitEndFrame(bool handleInput) {
|
|
int32 time;
|
|
|
|
time = getTimeKey() - _startFrameTime;
|
|
if ((time > 1000) || (time < 0)) {
|
|
_vm->_video->retrace();
|
|
_startFrameTime = getTimeKey();
|
|
return;
|
|
}
|
|
|
|
int32 toWait = 0;
|
|
do {
|
|
if (toWait > 0)
|
|
delay(MIN<int>(toWait, 10));
|
|
|
|
if (handleInput)
|
|
processInput();
|
|
|
|
_vm->_video->retrace();
|
|
|
|
time = getTimeKey() - _startFrameTime;
|
|
toWait = _frameWaitTime - time;
|
|
} while (toWait > 0);
|
|
|
|
_startFrameTime = getTimeKey();
|
|
}
|
|
|
|
void Util::setScrollOffset(int16 x, int16 y) {
|
|
processInput();
|
|
|
|
if (x >= 0)
|
|
_vm->_video->_scrollOffsetX = x;
|
|
else
|
|
_vm->_video->_scrollOffsetX = _vm->_draw->_scrollOffsetX;
|
|
|
|
if (y >= 0)
|
|
_vm->_video->_scrollOffsetY = y;
|
|
else
|
|
_vm->_video->_scrollOffsetY = _vm->_draw->_scrollOffsetY;
|
|
|
|
_vm->_video->waitRetrace();
|
|
}
|
|
|
|
void Util::insertStr(const char *str1, char *str2, int16 pos) {
|
|
int len1 = strlen(str1);
|
|
int len2 = strlen(str2);
|
|
int from = MIN((int)pos, len2);
|
|
|
|
for (int i = len2; i >= from; i--)
|
|
str2[len1 + i] = str2[i];
|
|
for (int i = 0; i < len1; i++)
|
|
str2[i + from] = str1[i];
|
|
}
|
|
|
|
void Util::cutFromStr(char *str, int16 from, int16 cutlen) {
|
|
int len = strlen(str);
|
|
|
|
if (from >= len)
|
|
return;
|
|
if ((from + cutlen) > len) {
|
|
str[from] = 0;
|
|
return;
|
|
}
|
|
|
|
int i = from;
|
|
do {
|
|
str[i] = str[i + cutlen];
|
|
i++;
|
|
} while (str[i] != 0);
|
|
}
|
|
|
|
// A copy of this utility function is used by fileio.cpp.
|
|
void Util::replaceChar(char *str, char c1, char c2) {
|
|
while ((str = strchr(str, c1)))
|
|
*str = c2;
|
|
}
|
|
|
|
static const char trStr1[] =
|
|
" ' + - :0123456789: <=> abcdefghijklmnopqrstuvwxyz "
|
|
"abcdefghijklmnopqrstuvwxyz ";
|
|
static const char trStr2[] =
|
|
" ueaaaaceeeiii ooouu aioun"
|
|
" ";
|
|
static const char trStr3[] = " ";
|
|
|
|
void Util::cleanupStr(char *str) {
|
|
char *start, *end;
|
|
char buf[300];
|
|
|
|
Common::strcpy_s(buf, trStr1);
|
|
Common::strcat_s(buf, trStr2);
|
|
Common::strcat_s(buf, trStr3);
|
|
|
|
// Translating "wrong" characters (removing diacritics, converting to lower case)
|
|
for (size_t i = 0; i < strlen(str); i++)
|
|
str[i] = buf[MAX<int>(str[i] - 32, 32)];
|
|
|
|
// Trim spaces left
|
|
while (str[0] == ' ')
|
|
cutFromStr(str, 0, 1);
|
|
|
|
// Trim spaces right
|
|
while ((*str != '\0') && (str[strlen(str) - 1] == ' '))
|
|
cutFromStr(str, strlen(str) - 1, 1);
|
|
|
|
// Merge double spaces
|
|
start = strchr(str, ' ');
|
|
while (start) {
|
|
if (start[1] == ' ') {
|
|
cutFromStr(str, start - str, 1);
|
|
continue;
|
|
}
|
|
|
|
end = strchr(start + 1, ' ');
|
|
start = end ? end + 1 : nullptr;
|
|
}
|
|
}
|
|
|
|
void Util::listInsertFront(List *list, void *data) {
|
|
ListNode *node;
|
|
|
|
node = new ListNode;
|
|
if (list->pHead) {
|
|
node->pData = data;
|
|
node->pNext = list->pHead;
|
|
node->pPrev = nullptr;
|
|
list->pHead->pPrev = node;
|
|
list->pHead = node;
|
|
} else {
|
|
list->pHead = node;
|
|
list->pTail = node;
|
|
node->pData = data;
|
|
node->pNext = nullptr;
|
|
node->pPrev = nullptr;
|
|
}
|
|
}
|
|
|
|
void Util::listInsertBack(List *list, void *data) {
|
|
ListNode *node;
|
|
|
|
if (list->pHead != nullptr) {
|
|
if (list->pTail == nullptr) {
|
|
list->pTail = list->pHead;
|
|
warning("Util::listInsertBack(): Broken list");
|
|
}
|
|
|
|
node = new ListNode;
|
|
node->pData = data;
|
|
node->pPrev = list->pTail;
|
|
node->pNext = nullptr;
|
|
list->pTail->pNext = node;
|
|
list->pTail = node;
|
|
} else
|
|
listInsertFront(list, data);
|
|
}
|
|
|
|
void Util::listDropFront(List *list) {
|
|
if (list->pHead->pNext == nullptr) {
|
|
delete list->pHead;
|
|
list->pHead = nullptr;
|
|
list->pTail = nullptr;
|
|
} else {
|
|
list->pHead = list->pHead->pNext;
|
|
delete list->pHead->pPrev;
|
|
list->pHead->pPrev = nullptr;
|
|
}
|
|
}
|
|
|
|
void Util::deleteList(List *list) {
|
|
while (list->pHead)
|
|
listDropFront(list);
|
|
|
|
delete list;
|
|
}
|
|
|
|
#if 0
|
|
char *Util::setExtension(char *str, const char *ext) {
|
|
assert(str && ext);
|
|
|
|
if (str[0] == '\0')
|
|
return str;
|
|
|
|
char *dot = strrchr(str, '.');
|
|
if (dot)
|
|
*dot = '\0';
|
|
|
|
strcat(str, ext);
|
|
return str;
|
|
}
|
|
#endif
|
|
|
|
Common::String Util::setExtension(const Common::String &str, const Common::String &ext) {
|
|
if (str.empty())
|
|
return str;
|
|
|
|
const char *dot = strrchr(str.c_str(), '.');
|
|
if (dot)
|
|
return Common::String(str.c_str(), dot - str.c_str()) + ext;
|
|
|
|
return str + ext;
|
|
}
|
|
|
|
Common::String Util::readString(Common::SeekableReadStream &stream, int n) {
|
|
Common::String str;
|
|
|
|
char c;
|
|
while (n-- > 0) {
|
|
if ((c = stream.readByte()) == '\0')
|
|
break;
|
|
|
|
str += c;
|
|
}
|
|
|
|
if (n > 0)
|
|
stream.skip(n);
|
|
|
|
return str;
|
|
}
|
|
|
|
/* NOT IMPLEMENTED */
|
|
void Util::checkJoystick() {
|
|
_vm->_global->_useJoystick = 0;
|
|
}
|
|
|
|
uint32 Util::getKeyState() const {
|
|
return _keyState;
|
|
}
|
|
|
|
void Util::keyDown(const Common::Event &event) {
|
|
if (event.kbd.keycode == Common::KEYCODE_UP)
|
|
_keyState |= 0x0001;
|
|
else if (event.kbd.keycode == Common::KEYCODE_DOWN)
|
|
_keyState |= 0x0002;
|
|
else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
|
|
_keyState |= 0x0004;
|
|
else if (event.kbd.keycode == Common::KEYCODE_LEFT)
|
|
_keyState |= 0x0008;
|
|
else if (event.kbd.keycode == Common::KEYCODE_SPACE)
|
|
_keyState |= 0x0020;
|
|
else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
|
|
_keyState |= 0x0040;
|
|
}
|
|
|
|
void Util::keyUp(const Common::Event &event) {
|
|
if (event.kbd.keycode == Common::KEYCODE_UP)
|
|
_keyState &= ~0x0001;
|
|
else if (event.kbd.keycode == Common::KEYCODE_DOWN)
|
|
_keyState &= ~0x0002;
|
|
else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
|
|
_keyState &= ~0x0004;
|
|
else if (event.kbd.keycode == Common::KEYCODE_LEFT)
|
|
_keyState &= ~0x0008;
|
|
else if (event.kbd.keycode == Common::KEYCODE_SPACE)
|
|
_keyState &= ~0x0020;
|
|
else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
|
|
_keyState &= ~0x0040;
|
|
}
|
|
|
|
} // End of namespace Gob
|