ADL: Implement hires2 word wrapping

This commit is contained in:
Walter van Niftrik 2016-03-14 15:39:19 +01:00 committed by Walter van Niftrik
parent 0686ba9de8
commit b4aea80723
8 changed files with 120 additions and 24 deletions

View File

@ -161,11 +161,12 @@ Common::String AdlEngine::inputString(byte prompt) const {
}
}
byte AdlEngine::inputKey() const {
byte AdlEngine::inputKey(bool showCursor) const {
Common::EventManager *ev = g_system->getEventManager();
byte key = 0;
if (showCursor)
_display->showCursor(true);
while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {

View File

@ -149,7 +149,7 @@ protected:
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
byte inputKey() const;
byte inputKey(bool showCursor = true) const;
void loadWords(Common::ReadStream &stream, WordMap &map) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
@ -215,7 +215,7 @@ private:
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
virtual void showRoom() const = 0;
virtual void showRoom() = 0;
// Engine
Common::Error run();

View File

@ -41,8 +41,6 @@ namespace Adl {
#define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
#define DISPLAY_SIZE (DISPLAY_PITCH * DISPLAY_HEIGHT)
#define TEXT_WIDTH 40
#define TEXT_HEIGHT 24
#define TEXT_BUF_SIZE (TEXT_WIDTH * TEXT_HEIGHT)
#define COLOR_PALETTE_ENTRIES 8
@ -291,15 +289,12 @@ void Display::moveCursorTo(const Common::Point &pos) {
error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
}
void Display::printString(const Common::String &str) {
Common::String::const_iterator c;
for (c = str.begin(); c != str.end(); ++c) {
byte b = *c;
if (*c == APPLECHAR('\r'))
// FIXME: This does not currently update the surfaces
void Display::printChar(char c) {
if (c == APPLECHAR('\r'))
_cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
else if (b < 0x80 || b >= 0xa0) {
setCharAtCursor(b);
else if ((byte)c < 0x80 || (byte)c >= 0xa0) {
setCharAtCursor(c);
++_cursorPos;
}
@ -307,6 +302,11 @@ void Display::printString(const Common::String &str) {
scrollUp();
}
void Display::printString(const Common::String &str) {
Common::String::const_iterator c;
for (c = str.begin(); c != str.end(); ++c)
printChar(*c);
updateTextScreen();
}

View File

@ -40,6 +40,8 @@ namespace Adl {
#define DISPLAY_WIDTH 280
#define DISPLAY_HEIGHT 192
#define TEXT_WIDTH 40
#define TEXT_HEIGHT 24
enum DisplayMode {
DISPLAY_MODE_HIRES,
@ -71,6 +73,7 @@ public:
void moveCursorTo(const Common::Point &pos);
void moveCursorForward();
void moveCursorBackward();
void printChar(char c);
void printString(const Common::String &str);
void printAsciiString(const Common::String &str);
void setCharAtCursor(byte c);

View File

@ -303,7 +303,7 @@ void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
drawPic(item.picture, pos);
}
void HiRes1Engine::showRoom() const {
void HiRes1Engine::showRoom() {
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
drawItems();

View File

@ -101,7 +101,7 @@ private:
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printMessage(uint idx, bool wait = true) const;
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom() const;
void showRoom();
Common::File _exe;
Common::Array<uint> _corners;

View File

@ -110,6 +110,17 @@ void HiRes2Engine::initState() {
f.readByte(); // always 1, possibly disk?
_state.rooms.push_back(room);
}
loadRoom(_state.room);
}
void HiRes2Engine::loadRoom(uint i) {
Common::File f;
openFile(f, IDS_HR2_DISK_IMAGE);
Room &room = getRoom(i);
uint offset = TSO(room.track, room.sector, room.offset);
f.seek(offset);
_roomData.description = readStringAt(f, offset + f.readByte(), 0xff);
}
void HiRes2Engine::restartGame() {
@ -126,9 +137,72 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(f, pos, 0);
}
void HiRes2Engine::showRoom() const {
void HiRes2Engine::showRoom() {
_linesPrinted = 0;
drawPic(0, Common::Point());
_display->updateHiResScreen();
printString(_roomData.description);
}
void HiRes2Engine::checkTextOverflow(char c) {
if (c != APPLECHAR('\r'))
return;
++_linesPrinted;
if (_linesPrinted < 4)
return;
_linesPrinted = 0;
// Bell
while (true) {
char key = inputKey(false);
if (shouldQuit())
return;
if (key == APPLECHAR('\r'))
break;
// Bell
// Bell
// Bell
}
}
void HiRes2Engine::printString(const Common::String &str) {
Common::String s(str);
byte endPos = TEXT_WIDTH - 1;
byte pos = 0;
while (true) {
while (pos != endPos && pos != s.size()) {
s.setChar(APPLECHAR(s[pos]), pos);
++pos;
}
if (pos == s.size())
break;
while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
--pos;
s.setChar(APPLECHAR('\r'), pos);
endPos = pos + TEXT_WIDTH;
++pos;
}
pos = 0;
while (pos != s.size()) {
checkTextOverflow(s[pos]);
_display->printChar(s[pos]);
++pos;
}
checkTextOverflow(APPLECHAR('\r'));
_display->printChar(APPLECHAR('\r'));
_display->updateTextScreen();
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {

View File

@ -63,9 +63,20 @@ namespace Adl {
#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
struct Picture2 {
byte track;
byte sector;
byte offset;
};
struct RoomData {
Common::String description;
Common::Array<Picture2> pictures;
};
class HiRes2Engine : public AdlEngine {
public:
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0) { }
private:
// AdlEngine
@ -75,7 +86,14 @@ private:
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const { }
void showRoom() const;
void showRoom();
void loadRoom(uint i);
void checkTextOverflow(char c);
void printString(const Common::String &str);
RoomData _roomData;
uint _linesPrinted;
};
} // End of namespace Adl