/** * Setup a menu's contents * @remarks Originally called 'menut' */ void Menu::setText(MenuItem item, Common::String name) { Common::String s = name; switch (item._menuId) { case MENU_INVENTORY: if (item._actionId != 7) { while (s.size() < 22) s += ' '; _inventoryStringArray[item._actionId] = s; _inventoryStringArray[item._actionId].insertChar(' ', 0); } break; case MENU_MOVE: { // If the first character isn't '*' or ' ' then it's missing a heading space char c = s[0]; if (c != '*' && c != ' ') s.insertChar(' ', 0); while (s.size() < 22) s += ' '; _moveStringArray[item._actionId] = s; } break; case MENU_ACTION: { // If the first character isn't '*' or ' ' then it's missing a heading space char c = s[0]; if (c != '*' && c != ' ') s.insertChar(' ', 0); while (s.size() < 10) s += ' '; _actionStringArray[item._actionId] = s; } break; case MENU_SELF: { // If the first character isn't '*' or ' ' then it's missing a heading space char c = s[0]; if (c != '*' && c != ' ') s.insertChar(' ', 0); while (s.size() < 10) s += ' '; _selfStringArray[item._actionId] = s; } break; case MENU_DISCUSS: _discussStringArray[item._actionId] = s; break; default: break; } }
SourceListing *BasicSourceListingProvider::getListing(const Common::String &filename, ErrorCode &_err) { _err = OK; if (!_fsDirectory) { _err = SOURCE_PATH_NOT_SET; return nullptr; }; Common::String unixFilename; for (uint i = 0; i < filename.size(); i++) { if (filename[i] == '\\') { unixFilename.insertChar('/', unixFilename.size()); } else { unixFilename.insertChar(filename[i], unixFilename.size()); } } Common::SeekableReadStream *file = _fsDirectory->createReadStreamForMember(unixFilename); Common::Array<Common::String> strings; if (!file) { _err = NO_SUCH_SOURCE; } else { if (file->err()) { _err = UNKNOWN_ERROR; } while (!file->eos()) { strings.push_back(file->readLine()); if (file->err()) { _err = UNKNOWN_ERROR; } } } if (_err == OK) { return new SourceListing(strings); } else { return nullptr; } }
void ConsoleDialog::handleKeyDown(Common::KeyState state) { int i; if (_slideMode != kNoSlideMode) return; switch (state.keycode) { case Common::KEYCODE_RETURN: case Common::KEYCODE_KP_ENTER: { if (_caretVisible) drawCaret(true); nextLine(); assert(_promptEndPos >= _promptStartPos); int len = _promptEndPos - _promptStartPos; bool keepRunning = true; if (len > 0) { Common::String str; // Copy the user input to str for (i = 0; i < len; i++) str.insertChar(buffer(_promptStartPos + i), i); // Add the input to the history addToHistory(str); // Pass it to the input callback, if any if (_callbackProc) keepRunning = (*_callbackProc)(this, str.c_str(), _callbackRefCon); } print(PROMPT); _promptStartPos = _promptEndPos = _currentPos; draw(); if (!keepRunning) slideUpAndClose(); break; } case Common::KEYCODE_ESCAPE: slideUpAndClose(); break; case Common::KEYCODE_BACKSPACE: if (_caretVisible) drawCaret(true); if (_currentPos > _promptStartPos) { _currentPos--; killChar(); } scrollToCurrent(); drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_TAB: { if (_completionCallbackProc) { int len = _currentPos - _promptStartPos; assert(len >= 0); char *str = new char[len + 1]; // Copy the user input to str for (i = 0; i < len; i++) str[i] = buffer(_promptStartPos + i); str[len] = '\0'; Common::String completion; if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon)) { if (_caretVisible) drawCaret(true); insertIntoPrompt(completion.c_str()); scrollToCurrent(); drawLine(pos2line(_currentPos)); } delete[] str; } break; } // Keypad & special keys // - if num lock is set, we always go to the default case // - if num lock is not set, we either fall down to the special key case // or ignore the key press in case of 0 (INSERT) or 5 case Common::KEYCODE_KP0: case Common::KEYCODE_KP5: if (state.flags & Common::KBD_NUM) defaultKeyDownHandler(state); break; case Common::KEYCODE_KP_PERIOD: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_DELETE: if (_currentPos < _promptEndPos) { killChar(); drawLine(pos2line(_currentPos)); } break; case Common::KEYCODE_KP1: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_END: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _linesPerPage - 1) _scrollLine = _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptEndPos; } draw(); break; case Common::KEYCODE_KP2: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_DOWN: historyScroll(-1); break; case Common::KEYCODE_KP3: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_PAGEDOWN: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine += _linesPerPage - 1; if (_scrollLine > _promptEndPos / kCharsPerLine) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; } updateScrollBuffer(); draw(); } break; case Common::KEYCODE_KP4: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_LEFT: if (_currentPos > _promptStartPos) _currentPos--; drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_KP6: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_RIGHT: if (_currentPos < _promptEndPos) _currentPos++; drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_KP7: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_HOME: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptStartPos; } draw(); break; case Common::KEYCODE_KP8: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_UP: historyScroll(+1); break; case Common::KEYCODE_KP9: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_PAGEUP: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine -= _linesPerPage - 1; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); draw(); } break; default: defaultKeyDownHandler(state); } }
void GfxControls32::kernelTexteditChange(reg_t controlObject) { SciEvent curEvent; 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; uint16 textSize; bool textChanged = false; bool textAddChar = false; Common::Rect rect; if (textReference.isNull()) error("kEditControl called on object that doesn't have a text reference"); text = _segMan->getString(textReference); // TODO: Finish this warning("kEditText ('%s')", text.c_str()); return; uint16 cursorPos = 0; //uint16 oldCursorPos = cursorPos; bool captureEvents = true; EventManager* eventMan = g_sci->getEventManager(); 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) { case SCI_EVENT_MOUSE_PRESS: // TODO: Implement mouse support for cursor change break; case SCI_EVENT_KEYBOARD: switch (curEvent.character) { case SCI_KEY_BACKSPACE: if (cursorPos > 0) { 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) { // Control-C erases the whole line 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.character == 'c') { // Control-C in earlier SCI games (SCI0 - SCI1 middle) // Control-C erases the whole line cursorPos = 0; text.clear(); textChanged = true; } else if (curEvent.character > 31 && curEvent.character < 256 && textSize < maxChars) { // insert pressed character textAddChar = true; textChanged = true; } eventMan->getSciEvent(SCI_EVENT_KEYBOARD); // consume the event break; } break; } } if (textChanged) { rect = g_sci->_gfxCompare->getNSRect(controlObject); if (textAddChar) { const char *textPtr = text.c_str(); // We check if we are really able to add the new char uint16 textWidth = 0; while (*textPtr) textWidth += font->getCharWidth((byte)*textPtr++); textWidth += font->getCharWidth(curEvent.character); // Does it fit? if (textWidth >= rect.width()) { return; } text.insertChar(curEvent.character, cursorPos++); // Note: the following checkAltInput call might make the text // too wide to fit, but SSCI fails to check that too. } 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 warning("kernelTexteditChange"); #if 0 _text->createTextBitmap(controlObject, 0, 0, hunkId); _text->drawTextBitmap(0, 0, nsRect, controlObject); //texteditCursorDraw(rect, text.c_str(), cursorPos); // TODO: Cursor g_system->updateScreen(); #endif } else { // TODO: Cursor /* if (g_system->getMillis() >= _texteditBlinkTime) { _paint16->invertRect(_texteditCursorRect); _paint16->bitsShow(_texteditCursorRect); _texteditCursorVisible = !_texteditCursorVisible; texteditSetBlinkTime(); } */ } textAddChar = false; textChanged = false; g_sci->sleep(10); } // while }
void GfxControls32::kernelTexteditChange(reg_t controlObject) { SciEvent curEvent; uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max)); reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text)); GfxFont *font = _cache->getFont(readSelectorValue(_segMan, controlObject, SELECTOR(font))); Common::String text; uint16 textSize; bool textChanged = false; bool textAddChar = false; Common::Rect rect; if (textReference.isNull()) error("kEditControl called on object that doesnt have a text reference"); text = _segMan->getString(textReference); // TODO: Finish this, add a loop etc warning("kEditText ('%s')", text.c_str()); return; uint16 cursorPos = 0; //uint16 oldCursorPos = cursorPos; curEvent = g_sci->getEventManager()->getSciEvent(SCI_EVENT_KEYBOARD); if (curEvent.type != SCI_EVENT_NONE) { textSize = text.size(); switch (curEvent.type) { case SCI_EVENT_MOUSE_PRESS: // TODO: Implement mouse support for cursor change break; case SCI_EVENT_KEYBOARD: switch (curEvent.data) { case SCI_KEY_BACKSPACE: if (cursorPos > 0) { cursorPos--; text.deleteChar(cursorPos); textChanged = true; } break; case SCI_KEY_DELETE: if (cursorPos < textSize) { text.deleteChar(cursorPos); textChanged = true; } break; case SCI_KEY_HOME: // HOME cursorPos = 0; textChanged = true; break; case SCI_KEY_END: // END cursorPos = textSize; textChanged = true; break; case SCI_KEY_LEFT: // LEFT if (cursorPos > 0) { cursorPos--; textChanged = true; } break; case SCI_KEY_RIGHT: // RIGHT if (cursorPos + 1 <= textSize) { cursorPos++; textChanged = true; } break; case 3: // returned in SCI1 late and newer when Control - C is pressed if (curEvent.modifiers & SCI_KEYMOD_CTRL) { // Control-C erases the whole line cursorPos = 0; text.clear(); textChanged = true; } break; default: if ((curEvent.modifiers & SCI_KEYMOD_CTRL) && curEvent.data == 99) { // Control-C in earlier SCI games (SCI0 - SCI1 middle) // Control-C erases the whole line cursorPos = 0; text.clear(); textChanged = true; } else if (curEvent.data > 31 && curEvent.data < 256 && textSize < maxChars) { // insert pressed character textAddChar = true; textChanged = true; } break; } break; } } if (textChanged) { rect = g_sci->_gfxCompare->getNSRect(controlObject); if (textAddChar) { const char *textPtr = text.c_str(); // We check if we are really able to add the new char uint16 textWidth = 0; while (*textPtr) textWidth += font->getCharWidth((byte)*textPtr++); textWidth += font->getCharWidth(curEvent.data); // Does it fit? if (textWidth >= rect.width()) { return; } text.insertChar(curEvent.data, cursorPos++); // 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); */ // Write back string _segMan->strcpy(textReference, text.c_str()); } else { // TODO: Cursor /* if (g_system->getMillis() >= _texteditBlinkTime) { _paint16->invertRect(_texteditCursorRect); _paint16->bitsShow(_texteditCursorRect); _texteditCursorVisible = !_texteditCursorVisible; texteditSetBlinkTime(); } */ } }
void GfxControls16::kernelTexteditChange(reg_t controlObject, reg_t eventObject) { uint16 cursorPos = readSelectorValue(_segMan, controlObject, SELECTOR(cursor)); uint16 maxChars = readSelectorValue(_segMan, controlObject, SELECTOR(max)); reg_t textReference = readSelector(_segMan, controlObject, SELECTOR(text)); Common::String text; uint16 textSize, eventType, eventKey = 0, modifiers = 0; bool textChanged = false; bool textAddChar = false; Common::Rect rect; if (textReference.isNull()) error("kEditControl called on object that doesnt have a text reference"); text = _segMan->getString(textReference); uint16 oldCursorPos = cursorPos; if (!eventObject.isNull()) { textSize = text.size(); eventType = readSelectorValue(_segMan, eventObject, SELECTOR(type)); switch (eventType) { case SCI_EVENT_MOUSE_PRESS: // TODO: Implement mouse support for cursor change break; case SCI_EVENT_KEYBOARD: eventKey = readSelectorValue(_segMan, eventObject, SELECTOR(message)); modifiers = readSelectorValue(_segMan, eventObject, SELECTOR(modifiers)); switch (eventKey) { case SCI_KEY_BACKSPACE: if (cursorPos > 0) { cursorPos--; text.deleteChar(cursorPos); textChanged = true; } break; case SCI_KEY_DELETE: if (cursorPos < textSize) { text.deleteChar(cursorPos); textChanged = true; } break; case SCI_KEY_HOME: // HOME cursorPos = 0; textChanged = true; break; case SCI_KEY_END: // END cursorPos = textSize; textChanged = true; break; case SCI_KEY_LEFT: // LEFT if (cursorPos > 0) { cursorPos--; textChanged = true; } break; case SCI_KEY_RIGHT: // RIGHT if (cursorPos + 1 <= textSize) { cursorPos++; textChanged = true; } break; case 3: // returned in SCI1 late and newer when Control - C is pressed if (modifiers & SCI_KEYMOD_CTRL) { // Control-C erases the whole line cursorPos = 0; text.clear(); textChanged = true; } break; default: if ((modifiers & SCI_KEYMOD_CTRL) && eventKey == 99) { // Control-C in earlier SCI games (SCI0 - SCI1 middle) // Control-C erases the whole line cursorPos = 0; text.clear(); textChanged = true; } else if (eventKey > 31 && eventKey < 256 && textSize < maxChars) { // insert pressed character textAddChar = true; textChanged = true; } break; } break; } } if (g_sci->getVocabulary() && !textChanged && oldCursorPos != cursorPos) { assert(!textAddChar); textChanged = g_sci->getVocabulary()->checkAltInput(text, cursorPos); } if (textChanged) { GuiResourceId oldFontId = _text16->GetFontId(); GuiResourceId fontId = readSelectorValue(_segMan, controlObject, SELECTOR(font)); rect = g_sci->_gfxCompare->getNSRect(controlObject); _text16->SetFont(fontId); if (textAddChar) { const char *textPtr = text.c_str(); // We check if we are really able to add the new char uint16 textWidth = 0; while (*textPtr) textWidth += _text16->_font->getCharWidth((byte)*textPtr++); textWidth += _text16->_font->getCharWidth(eventKey); // Does it fit? if (textWidth >= rect.width()) { _text16->SetFont(oldFontId); return; } text.insertChar(eventKey, cursorPos++); // Note: the following checkAltInput call might make the text // too wide to fit, but SSCI fails to check that too. } if (g_sci->getVocabulary()) g_sci->getVocabulary()->checkAltInput(text, cursorPos); 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); _text16->SetFont(oldFontId); // Write back string _segMan->strcpy(textReference, text.c_str()); } else { if (g_system->getMillis() >= _texteditBlinkTime) { _paint16->invertRect(_texteditCursorRect); _paint16->bitsShow(_texteditCursorRect); _texteditCursorVisible = !_texteditCursorVisible; texteditSetBlinkTime(); } } writeSelectorValue(_segMan, controlObject, SELECTOR(cursor), cursorPos); }
bool WidgetFiles::getFilename() { Events &events = *_vm->_events; TattooScene &scene = *(TattooScene *)_vm->_scene; Screen &screen = *_vm->_screen; Talk &talk = *_vm->_talk; int index = 0; int done = 0; bool blinkFlag = false; int blinkCountdown = 0; int cursorColor = 192; byte color, textColor; bool insert = true; assert(_selector != -1); Common::Point pt(_surface.stringWidth("00.") + _surface.widestChar() + 5, _surface.fontHeight() + 14 + (_selector - _savegameIndex) * (_surface.fontHeight() + 1)); Common::String numStr = Common::String::format("%d.", _selector + 1); _surface.writeString(numStr, Common::Point(_surface.widestChar(), pt.y), COMMAND_HIGHLIGHTED); Common::String filename = _savegames[_selector]; if (isSlotEmpty(_selector)) { index = 0; _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.right - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); filename = ""; } else { index = filename.size(); _surface.writeString(filename, pt, COMMAND_HIGHLIGHTED); pt.x = _surface.stringWidth("00.") + _surface.stringWidth(filename) + _surface.widestChar() + 5; } do { scene.doBgAnim(); if (talk._talkToAbort) return false; char currentChar = (index == (int)filename.size()) ? ' ' : filename[index]; Common::String charString = Common::String::format("%c", currentChar); int width = screen.charWidth(currentChar); // Wait for keypress while (!events.kbHit()) { events.pollEventsAndWait(); events.setButtonState(); scene.doBgAnim(); if (talk._talkToAbort) return false; if (--blinkCountdown <= 0) { blinkCountdown = 3; blinkFlag = !blinkFlag; if (blinkFlag) { textColor = 236; color = cursorColor; } else { textColor = COMMAND_HIGHLIGHTED; color = TRANSPARENCY; } _surface.fillRect(Common::Rect(pt.x, pt.y, pt.x + width, pt.y + _surface.fontHeight()), color); if (currentChar != ' ') _surface.writeString(charString, pt, textColor); } if (_vm->shouldQuit()) return false; } Common::KeyState keyState = events.getKey(); if (keyState.keycode == Common::KEYCODE_BACKSPACE && index > 0) { pt.x -= _surface.charWidth(filename[index - 1]); --index; if (insert) { filename.deleteChar(index); } else { filename.setChar(' ', index); } _surface.fillRect(Common::Rect(pt.x, pt.y, _surface.width() - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); _surface.writeString(filename.c_str() + index, pt, COMMAND_HIGHLIGHTED); } else if ((keyState.keycode == Common::KEYCODE_LEFT && index > 0) || (keyState.keycode == Common::KEYCODE_RIGHT && index < 49 && pt.x < (_bounds.right - BUTTON_SIZE - 20)) || (keyState.keycode == Common::KEYCODE_HOME && index > 0) || (keyState.keycode == Common::KEYCODE_END)) { _surface.fillRect(Common::Rect(pt.x, pt.y, pt.x + width, pt.y + _surface.fontHeight()), TRANSPARENCY); if (currentChar) _surface.writeString(charString, pt, COMMAND_HIGHLIGHTED); switch (keyState.keycode) { case Common::KEYCODE_LEFT: pt.x -= _surface.charWidth(filename[index - 1]); --index; break; case Common::KEYCODE_RIGHT: pt.x += _surface.charWidth(filename[index]); ++index; break; case Common::KEYCODE_HOME: pt.x = _surface.stringWidth("00.") + _surface.widestChar() + 5; index = 0; break; case Common::KEYCODE_END: pt.x = _surface.stringWidth("00.") + _surface.stringWidth(filename) + _surface.widestChar() + 5; index = filename.size(); while (filename[index - 1] == ' ' && index > 0) { pt.x -= _surface.charWidth(filename[index - 1]); --index; } break; default: break; } } else if (keyState.keycode == Common::KEYCODE_INSERT) { insert = !insert; if (insert) cursorColor = 192; else cursorColor = 200; } else if (keyState.keycode == Common::KEYCODE_DELETE) { filename.deleteChar(index); _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.right - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); _surface.writeString(filename + index, pt, COMMAND_HIGHLIGHTED); } else if (keyState.keycode == Common::KEYCODE_RETURN) { done = 1; } else if (keyState.keycode == Common::KEYCODE_ESCAPE) { _selector = -1; render(RENDER_NAMES_AND_SCROLLBAR); done = -1; } if ((keyState.ascii >= ' ') && (keyState.ascii <= 'z') && (index < 50)) { if (pt.x + _surface.charWidth(keyState.ascii) < _surface.w - BUTTON_SIZE - 20) { if (insert) filename.insertChar(keyState.ascii, index); else filename.setChar(keyState.ascii, index); _surface.fillRect(Common::Rect(pt.x, pt.y, _bounds.width() - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); _surface.writeString(filename.c_str() + index, pt, COMMAND_HIGHLIGHTED); pt.x += _surface.charWidth(keyState.ascii); ++index; } } } while (!done && !_vm->shouldQuit()); scene.doBgAnim(); if (talk._talkToAbort) return false; if (done == 1) _savegames[_selector] = filename; return done == 1; }