SCI: More work on kEditText

This commit is contained in:
Filippos Karapetis 2011-10-30 12:12:40 +02:00
parent acebd6d0be
commit 9caacac724
5 changed files with 147 additions and 103 deletions

View file

@ -20,6 +20,8 @@
*
*/
#include "common/system.h"
#include "sci/sci.h"
#include "sci/event.h"
#include "sci/engine/kernel.h"
@ -33,8 +35,8 @@
namespace Sci {
GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen)
: _segMan(segMan), _cache(cache), _screen(screen) {
GfxControls32::GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text)
: _segMan(segMan), _cache(cache), _screen(screen), _text(text) {
}
GfxControls32::~GfxControls32() {
@ -42,7 +44,7 @@ GfxControls32::~GfxControls32() {
void GfxControls32::kernelTexteditChange(reg_t controlObject) {
SciEvent curEvent;
uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max));
uint16 maxChars = 40; //readSelectorValue(_segMan, controlObject, SELECTOR(max)); // TODO
reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text));
GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font)));
Common::String text;
@ -55,15 +57,21 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
error("kEditControl called on object that doesnt have a text reference");
text = _segMan->getString(textReference);
// TODO: Finish this, add a loop etc
// TODO: Finish this
warning("kEditText ('%s')", text.c_str());
return;
uint16 cursorPos = 0;
//uint16 oldCursorPos = cursorPos;
bool captureEvents = true;
EventManager* eventMan = g_sci->getEventManager();
curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD);
if (curEvent.type != SCI_EVENT_NONE) {
while (captureEvents) {
curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK);
if (curEvent.type == SCI_EVENT_NONE) {
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
} else {
textSize = text.size();
switch (curEvent.type) {
@ -77,28 +85,34 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
cursorPos--; text.deleteChar(cursorPos);
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_DELETE:
if (cursorPos < textSize) {
text.deleteChar(cursorPos);
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_HOME: // HOME
cursorPos = 0; textChanged = true;
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_END: // END
cursorPos = textSize; textChanged = true;
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_LEFT: // LEFT
if (cursorPos > 0) {
cursorPos--; textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_RIGHT: // RIGHT
if (cursorPos + 1 <= textSize) {
cursorPos++; textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case 3: // returned in SCI1 late and newer when Control - C is pressed
if (curEvent.modifiers & SCI_KEYMOD_CTRL) {
@ -106,6 +120,15 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
cursorPos = 0; text.clear();
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
case SCI_KEY_UP:
case SCI_KEY_DOWN:
case SCI_KEY_ENTER:
case SCI_KEY_ESC:
case SCI_KEY_TAB:
case SCI_KEY_SHIFT_TAB:
captureEvents = false;
break;
default:
if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) {
@ -118,6 +141,7 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
textAddChar = true;
textChanged = true;
}
eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event
break;
}
break;
@ -146,16 +170,19 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
// Note: the following checkAltInput call might make the text
// too wide to fit, but SSCI fails to check that too.
}
// TODO: Cursor
/*
texteditCursorErase();
_paint16->eraseRect(rect);
_text16->Box(text.c_str(), false, rect, SCI_TEXT16_ALIGNMENT_LEFT, -1);
_paint16->bitsShow(rect);
texteditCursorDraw(rect, text.c_str(), cursorPos);
*/
reg_t hunkId = readSelector(_segMan, controlObject, SELECTOR(bitmap));
Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(controlObject);
//texteditCursorErase(); // TODO: Cursor
// Write back string
_segMan->strcpy(textReference, text.c_str());
// Modify the buffer and show it
_text->createTextBitmap(controlObject, 0, 0, hunkId);
_text->drawTextBitmap(0, 0, nsRect, controlObject);
//texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor
g_system->updateScreen();
} else {
// TODO: Cursor
/*
@ -167,6 +194,11 @@ void GfxControls32::kernelTexteditChange(reg_t controlObject) {
}
*/
}
textAddChar = false;
textChanged = false;
g_sci->sleep(10);
} // while
}
} // End of namespace Sci

View file

@ -27,12 +27,14 @@ namespace Sci {
class GfxCache;
class GfxScreen;
class GfxText32;
/**
* Controls class, handles drawing of controls in SCI32 (SCI2, SCI2.1, SCI3) games
*/
class GfxControls32 {
public:
GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen);
GfxControls32(SegManager *segMan, GfxCache *cache, GfxScreen *screen, GfxText32 *text);
~GfxControls32();
void kernelTexteditChange(reg_t controlObject);
@ -41,6 +43,7 @@ private:
SegManager *_segMan;
GfxCache *_cache;
GfxScreen *_screen;
GfxText32 *_text;
};
} // End of namespace Sci

View file

@ -52,7 +52,7 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen)
GfxText32::~GfxText32() {
}
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) {
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight, reg_t prevHunk) {
reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));
// The object in the text selector of the item can be either a raw string
@ -91,11 +91,20 @@ reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxH
}
int entrySize = width * height + BITMAP_HEADER_SIZE;
reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
reg_t memoryId = NULL_REG;
if (prevHunk.isNull()) {
memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
} else {
memoryId = prevHunk;
}
byte *memoryPtr = _segMan->getHunkPointer(memoryId);
memset(memoryPtr, backColor, entrySize);
if (prevHunk.isNull())
memset(memoryPtr, 0, BITMAP_HEADER_SIZE);
byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;
memset(bitmap, backColor, width * height);
// Save totalWidth, totalHeight
WRITE_LE_UINT16(memoryPtr, width);

View file

@ -35,7 +35,7 @@ class GfxText32 {
public:
GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen);
~GfxText32();
reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0);
reg_t createTextBitmap(reg_t textObject, uint16 maxWidth = 0, uint16 maxHeight = 0, reg_t prevHunk = NULL_REG);
void disposeTextBitmap(reg_t hunkId);
void drawTextBitmap(uint16 x, uint16 y, Common::Rect planeRect, reg_t textObject);
int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font);

View file

@ -626,7 +626,7 @@ void SciEngine::initGraphics() {
_gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
_gfxPaint = _gfxPaint32;
_gfxText32 = new GfxText32(_gamestate->_segMan, _gfxCache, _gfxScreen);
_gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen);
_gfxControls32 = new GfxControls32(_gamestate->_segMan, _gfxCache, _gfxScreen, _gfxText32);
_robotDecoder = new RobotDecoder(g_system->getMixer(), getPlatform() == Common::kPlatformMacintosh);
_gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
} else {