Exemple #1
0
void TextMgr::inputEditOff() {
	if (_inputEditEnabled) {
		_inputEditEnabled = false;
		if (_inputCursorChar) {
			displayCharacter(_inputCursorChar);
		}
	}
}
Exemple #2
0
void TextMgr::inputEditOn() {
	if (!_inputEditEnabled) {
		_inputEditEnabled = true;
		if (_inputCursorChar) {
			displayCharacter(0x08); // backspace
		}
	}
}
Exemple #3
0
void TextMgr::displayText(const char *textPtr, bool disabledLook) {
	const char *curTextPtr = textPtr;
	byte  curCharacter = 0;

	while (1) {
		curCharacter = *curTextPtr;
		if (!curCharacter)
			break;

		curTextPtr++;
		displayCharacter(curCharacter, disabledLook);
	}
}
Exemple #4
0
void TextMgr::stringEdit(int16 stringMaxLen) {
	int16 inputStringLen = strlen((const char *)_inputString);

	// Remember current position for predictive dialog
	_inputStringRow = _textPos.row;
	_inputStringColumn = _textPos.column;

	if (_inputCursorChar) {
		// Cursor character is shown, which means we are one beyond the start of the input
		// Adjust the column for predictive input dialog
		_inputStringColumn--;
	}

	// Caller can set the input string
	_inputStringCursorPos = 0;
	while (_inputStringCursorPos < inputStringLen) {
		displayCharacter(_inputString[_inputStringCursorPos]);
		_inputStringCursorPos++;
	}

	// should never happen unless there is a coding glitch
	assert(_inputStringCursorPos <= stringMaxLen);

	_inputStringMaxLen = stringMaxLen;
	_inputStringEntered = false;

	inputEditOff();

	do {
		_vm->processAGIEvents();
	} while (_vm->cycleInnerLoopIsActive() && !(_vm->shouldQuit() || _vm->_restartGame));

	inputEditOn();

	// Forget non-blocking text, user was asked to enter something
	_vm->nonBlockingText_Forget();
}
Exemple #5
0
void TextMgr::displayCharacter(byte character, bool disabledLook) {
	TextPos_Struct charCurPos;

	charPos_Get(&charCurPos);

	switch (character) {
	case 0x08: // backspace
		if (charCurPos.column) {
			charCurPos.column--;
		} else if (charCurPos.row > 21) {
			charCurPos.column = (FONT_COLUMN_CHARACTERS - 1);
			charCurPos.row--;
		}
		clearBlock(charCurPos.row, charCurPos.column, charCurPos.row, charCurPos.column, _textAttrib.background);
		charPos_Set(&charCurPos);
		break;

	case 0x0D:
	case 0x0A: // CR/LF
		if (charCurPos.row < (FONT_ROW_CHARACTERS - 1))
			charCurPos.row++;
		charCurPos.column = _reset_Column;
		charPos_Set(&charCurPos);
		break;
	default:
		// ch_attrib(state.text_comb, conversion);
		_gfx->drawCharacter(charCurPos.row, charCurPos.column, character, _textAttrib.combinedForeground, _textAttrib.combinedBackground, disabledLook);

		charCurPos.column++;
		if (charCurPos.column <= (FONT_COLUMN_CHARACTERS - 1)) {
			charPos_Set(&charCurPos);
		} else {
			displayCharacter(0x0D); // go to next line
		}
	}
}
Exemple #6
0
void TextMgr::stringKeyPress(uint16 newKey) {
	inputEditOn();

	switch (newKey) {
	case 0x3:       // ctrl-c
	case 0x18: {    // ctrl-x
		// clear string
		while (_inputStringCursorPos) {
			_inputStringCursorPos--;
			_inputString[_inputStringCursorPos] = 0;
			displayCharacter(0x08);
		}
		break;
	}

	case AGI_KEY_BACKSPACE: {
		if (_inputStringCursorPos) {
			_inputStringCursorPos--;
			_inputString[_inputStringCursorPos] = 0;
			displayCharacter(newKey);

			stringRememberForAutoComplete();
		}
		break;
	}

	case AGI_KEY_ENTER: {
		stringRememberForAutoComplete(true);

		_inputStringEntered = true;

		_vm->cycleInnerLoopInactive(); // exit GetString-loop
		break;
	}

	case AGI_KEY_ESCAPE: {
		_inputString[0] = 0;
		_inputStringCursorPos = 0;
		_inputStringEntered = false;

		_vm->cycleInnerLoopInactive(); // exit GetString-loop
		break;
	}

	default:
		if (_inputStringMaxLen > _inputStringCursorPos) {
			bool acceptableInput = false;

			// FEATURE: Sierra didn't check for valid characters (filtered out umlauts etc.)
			// In text-mode this sort of worked at least with the DOS interpreter
			// but as soon as invalid characters were used in graphics mode they weren't properly shown
			switch (_vm->getLanguage()) {
			case Common::RU_RUS:
				if (newKey >= 0x20)
					acceptableInput = true;
				break;
			default:
				if ((newKey >= 0x20) && (newKey <= 0x7f))
					acceptableInput = true;
				break;
			}

			if (acceptableInput) {
				if ((_vm->_game.cycleInnerLoopType == CYCLE_INNERLOOP_GETSTRING) || ((newKey >= '0') && (newKey <= '9'))) {
					// Additionally check for GETNUMBER-mode, if character is a number
					// Sierra also did not do this
					_inputString[_inputStringCursorPos] = newKey;
					_inputStringCursorPos++;
					_inputString[_inputStringCursorPos] = 0;
					displayCharacter(newKey);

					stringRememberForAutoComplete();
				}
			}
		}
		break;
	}

	inputEditOff();
}
Exemple #7
0
void TextMgr::promptKeyPress(uint16 newKey) {
	int16 maxChars = 0;
	int16 scriptsInputLen = _vm->getVar(VM_VAR_MAX_INPUT_CHARACTERS);

	if (_messageState.dialogue_Open) {
		maxChars = TEXT_STRING_MAX_SIZE - 4;
	} else {
		maxChars = TEXT_STRING_MAX_SIZE - strlen(_vm->_game.strings[0]); // string 0 is the prompt string prefix
	}

	if (_promptCursorPos)
		maxChars--;

	if (scriptsInputLen < maxChars)
		maxChars = scriptsInputLen;

	inputEditOn();

	switch (newKey) {
	case AGI_KEY_BACKSPACE: {
		if (_promptCursorPos) {
			_promptCursorPos--;
			_prompt[_promptCursorPos] = 0;
			displayCharacter(newKey);

			promptRememberForAutoComplete();
		}
		break;
	}
	case 0x0A: // LF
		break;
	case AGI_KEY_ENTER: {
		if (_promptCursorPos) {
			// something got entered? -> process it and pass it to the scripts
			promptRememberForAutoComplete(true);

			memcpy(&_promptPrevious, &_prompt, sizeof(_prompt));
			// parse text
			_vm->_words->parseUsingDictionary((char *)&_prompt);

			_promptCursorPos = 0;
			_prompt[0] = 0;
			promptRedraw();
		}
		break;
	}
	default:
		if (maxChars > _promptCursorPos) {
			bool acceptableInput = false;

			// FEATURE: Sierra didn't check for valid characters (filtered out umlauts etc.)
			// In text-mode this sort of worked at least with the DOS interpreter
			// but as soon as invalid characters were used in graphics mode they weren't properly shown
			switch (_vm->getLanguage()) {
			case Common::RU_RUS:
				if (newKey >= 0x20)
					acceptableInput = true;
				break;
			default:
				if ((newKey >= 0x20) && (newKey <= 0x7f))
					acceptableInput = true;
				break;
			}

			if (acceptableInput) {
				_prompt[_promptCursorPos] = newKey;
				_promptCursorPos++;
				_prompt[_promptCursorPos] = 0;
				displayCharacter(newKey);

				promptRememberForAutoComplete();
			}
		}
		break;
	}

	inputEditOff();
}
Exemple #8
0
void
H19::processCharacter(char ch)
{
    // mask off the high bit just in case, the real H19 would not have it set.
    ch &= 0x7f;

    if (mode_m == Normal)
    {
        switch (ch)
        {
            case ascii::NUL:
            case ascii::SOH:
            case ascii::STX:
            case ascii::ETX:
            case ascii::EOT:
            case ascii::ENQ:
            case ascii::ACK:
            case ascii::VT:
            case ascii::FF:
            case ascii::SO:
            case ascii::SI:
            case ascii::DLE:
            case ascii::DC1:
            case ascii::DC2:
            case ascii::DC3:
            case ascii::DC4:
            case ascii::NAK:
            case ascii::SYN:
            case ascii::ETB:
            case ascii::EM:
            case ascii::SUB:
            case ascii::FS:
            case ascii::GS:
            case ascii::RS:
            case ascii::US:
            case ascii::DEL:
                // From manual, these characters are not processed by the terminal
                break;

            case ascii::BEL: // Rings the bell.
                /// \todo - implement ringing bell.
                consoleLog("<BEL>");
                break;

            case ascii::BS: // Backspace
                consoleLog("<BS>");
                processBS();
                break;

            case ascii::HT: // Horizontal Tab
                consoleLog("<TAB>");
                processTAB();
                break;

            case ascii::LF: // Line Feed
                processLF();

                if (autoCR_m)
                {
                    processCR();
                }

                consoleLog("\n");
                break;

            case ascii::CR: // Carriage Return
                processCR();

                if (autoLF_m)
                {
                    processLF();
                }

                break;

            case ascii::CAN: // Cancel.
                break;

            case ascii::ESC: // Escape
                mode_m = Escape;
                consoleLog("<ESC>");
                break;

            default:
                // if Printable character display it.
#if CONSOLE_LOG
                fprintf(console_out, "%c", ch);
#endif
                displayCharacter(ch);
                break;
        }
    }
    else if (mode_m == Escape)
    {
        // Assume we go back to Normal, so only the few that don't need to set the mode.
        mode_m = Normal;

        switch (ch)
        {
            case ascii::CAN: // CAN - Cancel
                // return to Normal mode, already set.
                break;

            case ascii::ESC: // Escape
                // From the ROM listing, stay in this mode.
                mode_m = Escape;
                break;

            // Cursor Functions

            case 'H': // Cursor Home
                posX_m    = posY_m = 0;
                updated_m = true;
                break;

            case 'C': // Cursor Forward
                cursorForward();
                break;

            case 'D':        // Cursor Backward
                processBS(); // same processing as cursor backward
                break;

            case 'B': // Cursor Down
                cursorDown();
                break;

            case 'A': // Cursor Up
                cursorUp();
                break;

            case 'I': // Reverse Index
                reverseIndex();
                break;

            case 'n': // Cursor Position Report
                cursorPositionReport();
                break;

            case 'j': // Save cursor position
                saveCursorPosition();
                break;

            case 'k': // Restore cursor position
                restoreCursorPosition();
                break;

            case 'Y': // Direct Cursor Addressing
                mode_m = DCA_1;
                break;

            // Erase and Editing

            case 'E': // Clear Display
                clearDisplay();
                break;

            case 'b': // Erase Beginning of Display
                eraseBOD();
                break;

            case 'J': // Erase to End of Page
                eraseEOP();
                break;

            case 'l': // Erase entire Line
                eraseEL();
                break;

            case 'o': // Erase Beginning Of Line
                eraseBOL();
                break;

            case 'K': // Erase To End Of Line
                eraseEOL();
                break;

            case 'L': // Insert Line
                insertLine();
                break;

            case 'M': // Delete Line
                deleteLine();
                break;

            case 'N': // Delete Character
                deleteChar();
                break;

            case '@': // Enter Insert Character Mode
                insertMode_m = true;
                break;

            case 'O': // Exit Insert Character Mode
                insertMode_m = false;
                break;

            // Configuration

            case 'z': // Reset To Power-Up Configuration
                reset();
                break;

            case 'r': // Modify the Baud Rate
                /// \todo - determine if we should support this.
                debugss(ssH19, ERROR, "Error Unimplemented Modify Baud\n");
                break;

            case 'x': // Set Mode
                mode_m = SetMode;
                break;

            case 'y': // Reset Mode
                mode_m = ResetMode;
                break;

            case '<': // Enter ANSI Mode
                /// \todo - implement ANSI mode.
                // ROM - just sets the mode
                debugss(ssH19, ERROR, "Error Entering ANSI mode - unsupported\n");
                break;

            // Modes of operation

            case '[': // Enter Hold Screen Mode
                holdScreen_m = true;
                break;

            case '\\': // Exit Hold Screen Mode
                holdScreen_m = false;
                break;

            case 'p': // Enter Reverse Video Mode
                reverseVideo_m = true;
                break;

            case 'q': // Exit Reverse Video Mode
                reverseVideo_m = false;
                break;

            case 'F': // Enter Graphics Mode
                graphicMode_m = true;
                break;

            case 'G': // Exit Graphics Mode
                graphicMode_m = false;
                break;

            case 't': // Enter Keypad Shifted Mode
                keypadShifted_m = true;
                break;

            case 'u': // Exit Keypad Shifted Mode
                // ROM - just sets the mode
                keypadShifted_m = false;
                break;

            case '=': // Enter Alternate Keypad Mode
                // ROM - just sets the mode
                keypadShifted_m = true;
                break;

            case '>': // Exit Alternate Keypad Mode
                // ROM - just sets the mode
                keypadShifted_m = false;
                break;

            // Additional Functions

            case '}': // Keyboard Disable
                /// \todo - determine whether to do this.
                keyboardEnabled_m = false;
                break;

            case '{': // Keyboard Enable
                keyboardEnabled_m = true;
                break;

            case 'v': // Wrap Around at End Of Line
                wrapEOL_m = true;
                break;

            case 'w': // Discard At End Of Line
                wrapEOL_m = false;
                break;

            case 'Z': // Identify as VT52 (Data: ESC / K)
                debugss(ssH19, ERROR, "Identify request\n");
                sendData(ascii::ESC);
                sendData('/');
                sendData('K');
                break;

            case ']': // Transmit 25th Line
                transmitLine25();
                break;

            case '#': // Transmit Page
                transmitPage();
                break;

            default:
                debugss(ssH19, WARNING, "Unhandled ESC: %d\n", ch);
                /// \todo - verify this is how the H19 ROM does it.
                break;
        }
    }
    else if (mode_m == SetMode)
    {
        mode_m = Normal;

        switch (ch)
        {
            case '1': // Enable 25th line
                // From the ROM, it erases line 25 on the enable, but here we erase on the disable.
                line25_m = true;
                break;

            case '2': // No key click
                keyClick_m = true;
                break;

            case '3': // Hold screen mode
                holdScreen_m = true;
                break;

            case '4': // Block Cursor
                cursorBlock_m = true;
                updated_m     = true;
                break;

            case '5': // Cursor Off
                cursorOff_m = true;
                updated_m   = true;
                break;

            case '6': // Keypad Shifted
                keypadShifted_m = true;
                break;

            case '7': // Alternate Keypad mode
                altKeypadMode_m = true;
                break;

            case '8': // Auto LF
                autoLF_m = true;
                break;

            case '9': // Auto CR
                autoCR_m = true;
                break;

            default:
                /// \todo Need to process ch as if none of this happened...
                debugss(ssH19, WARNING, "Invalid set Mode: %c\n", ch);
                break;
        }
    }
    else if (mode_m == ResetMode)
    {
        mode_m = Normal;

        switch (ch)
        {
            case '1': // Disable 25th line
                eraseLine(rowsMain_c);
                line25_m  = false;
                updated_m = true;
                break;

            case '2': // key click
                keyClick_m = false;
                break;

            case '3': // Hold screen mode
                holdScreen_m = false;
                break;

            case '4': // Block Cursor
                cursorBlock_m = false;
                updated_m     = true;
                break;

            case '5': // Cursor On
                cursorOff_m = false;
                updated_m   = true;
                break;

            case '6': // Keypad Unshifted
                keypadShifted_m = false;
                break;

            case '7': // Exit Alternate Keypad mode
                altKeypadMode_m = false;
                break;

            case '8': // No Auto LF
                autoLF_m = false;
                break;

            case '9': // No Auto CR
                autoCR_m = false;
                break;

            default:
                /// \todo Need to process ch as if none of this happened...
                debugss(ssH19, WARNING, "Invalid reset Mode: %c\n", ch);
                break;
        }
    }
    else if (mode_m == DCA_1)
    {
        // From actual H19, once the line is specified, the cursor
        // immediately moves to that line, so no need to save the
        // position and wait for the entire command.
        /// \todo verify that this is the same on newer H19s.
        if (ch == ascii::CAN)
        {
            // cancel
            mode_m = Normal;
        }
        else
        {
            // \todo handle error conditions

            int pos = ch - 31;

            // verify valid Position
            if (((pos > 0) && (pos < (signed) rows_c)) || ((pos == (signed) rows_c) && (line25_m)))
            {
                posY_m = pos - 1;
            }
            else
            {
                /// \todo check to see how a real h19 handles this.
                debugss(ssH19, INFO, "DCA invalid Y: %d\n", pos);
            }

            mode_m = DCA_2;
        }
    }
    else if (mode_m == DCA_2)
    {
        if (ch == ascii::CAN)
        {
            // cancel
            mode_m = Normal;
        }
        else
        {
            int pos = ch - 31;

            if ((pos > 0) && (pos < 81))
            {
                posX_m = pos - 1;
            }
            else
            {
                posX_m = (cols_c - 1);
            }

            updated_m = true;
            mode_m    = Normal;
        }
    }
}