Exemplo n.º 1
0
void handle_getstring (int key)
{
	static int pos = 0;		/* Cursor position */
	static char buf[40];

	if (KEY_ASCII(key) == 0)
		return;

	_D ("handling key: %02x", key);

	switch (key) {
	case KEY_ENTER:
		_D ("KEY_ENTER");
		game.has_prompt = 0;
		buf[pos] = 0;
		strcpy (game.strings[stringdata.str], buf);
		_D (_D_WARN "buffer=[%s]", buf);
		buf[pos = 0] = 0;
		new_input_mode (INPUT_NORMAL);
		print_character (stringdata.x + strlen (game.strings[stringdata.str]) + 1, stringdata.y,
			' ', game.color_fg, game.color_bg);
		return;
	case KEY_ESCAPE:
		_D ("KEY_ESCAPE");
		game.has_prompt = 0;
		buf[pos = 0] = 0;
		strcpy (game.strings[stringdata.str], buf);
		new_input_mode (INPUT_NORMAL);
		/* new_input_mode (INPUT_MENU); */
		break;
	case KEY_BACKSPACE: /*0x08:*/
		if (!pos)
			break;

		print_character (stringdata.x + (pos + 1), stringdata.y,
			' ', game.color_fg, game.color_bg);

		pos--;
		buf[pos] = 0;
		break;
	default:
		if (key < 0x20 || key > 0x7f)
			break;

		if (pos >= stringdata.len)
			break;

		buf[pos++] = key;
		buf[pos] = 0;

		/* Echo */
		print_character (stringdata.x + pos, stringdata.y,
			buf[pos - 1], game.color_fg, game.color_bg);

		break;
	}

	/* print cursor */
	print_character (stringdata.x + pos + 1, stringdata.y,
		(char)game.cursor_char, game.color_fg, game.color_bg);
}
Exemplo n.º 2
0
#define KEY_TYPE_ASCII	  1
#define KEY_TYPE_SPECIAL  2
#define KEY_TYPE_MOUSE	  3

#define KEY_ASCII(repeat,x)     ((repeat << 31) | (KEY_TYPE_ASCII   << 24) | (x))
#define KEY_SPECIAL(x)		((1 << 31) | (KEY_TYPE_SPECIAL << 24) | (x))
#define KEY_MOUSE(x)		((1 << 31) | (KEY_TYPE_MOUSE   << 24) | (x))

#define KEY_TYPE(x)		((x >> 24) & 0x7)
#define KEY_REPEAT(x)	 	(x >> 31)


/* XXX IMPROVE: might get packed tighter in 16bit words */
static const
unsigned long keycode [] = {
    KEY_ASCII(0,'s'),		/* PSP_CTRL_SELECT   = 0x000001 */
    0,				/*		       0x000002 */
    0,				/*		       0x000004 */
    KEY_ASCII(0,'a'),		/* PSP_CTRL_START    = 0x000008 */
    KEY_SPECIAL(GLUT_KEY_UP),	/* PSP_CTRL_UP	     = 0x000010 */
    KEY_SPECIAL(GLUT_KEY_RIGHT),	/* PSP_CTRL_RIGHT    = 0x000020 */
    KEY_SPECIAL(GLUT_KEY_DOWN),	/* PSP_CTRL_DOWN     = 0x000040 */
    KEY_SPECIAL(GLUT_KEY_LEFT),	/* PSP_CTRL_LEFT     = 0x000080 */
    KEY_MOUSE(GLUT_LEFT_BUTTON),	/* PSP_CTRL_LTRIGGER = 0x000100 */
    KEY_MOUSE(GLUT_RIGHT_BUTTON),	/* PSP_CTRL_RTRIGGER = 0x000200 */
    0,				/*		       0x000400 */
    0,				/*		       0x000800 */
    KEY_ASCII(1,'d'),		/* PSP_CTRL_TRIANGLE = 0x001000 */
    KEY_ASCII(1,'o'),		/* PSP_CTRL_CIRCLE   = 0x002000 */
    KEY_ASCII(1,'x'),		/* PSP_CTRL_CROSS    = 0x004000 */
    KEY_ASCII(1,'q'),		/* PSP_CTRL_SQUARE   = 0x008000 */
Exemplo n.º 3
0
int handle_controller (int key)
{
	struct vt_entry *v = &game.view_table[0];
	int i;

	/* The Black Cauldron needs KEY_ESCAPE to use menus */
	if (key == 0 /*|| key == KEY_ESCAPE*/)
		return FALSE;

	_D (_D_WARN "key = %04x", key);

	for (i = 0; i < MAX_DIRS; i++) {
		if (game.ev_keyp[i].data == key) {
			_D ("event %d: key press", i);
			game.ev_keyp[i].occured = TRUE;
			report ("event AC:%i occured\n", i);
			return TRUE;
		}
	}

#ifdef USE_MOUSE
	if (key == BUTTON_LEFT) {
		if (getflag (F_menus_work) && mouse.y <= CHAR_LINES) {
			new_input_mode (INPUT_MENU);
			return TRUE;
		}
	}
#endif

	if (game.player_control) {
		int d = 0;

		if (!KEY_ASCII (key)) {
			switch (key) {
			case KEY_UP:         d = 1; break;
			case KEY_DOWN:       d = 5; break;
			case KEY_LEFT:       d = 7; break;
			case KEY_RIGHT:      d = 3; break;
			case KEY_UP_RIGHT:   d = 2; break;
			case KEY_DOWN_RIGHT: d = 4; break;
			case KEY_UP_LEFT:    d = 8; break;
			case KEY_DOWN_LEFT:  d = 6; break;
			}
		}

#ifdef USE_MOUSE
		if (!opt.agimouse) {
			/* Handle mouse button events */
			if (key == BUTTON_LEFT) {
				v->flags |= ADJ_EGO_XY;
				v->parm1 = WIN_TO_PIC_X(mouse.x);
				v->parm2 = WIN_TO_PIC_Y(mouse.y);
				return TRUE;
			}
		}
#endif

		v->flags &= ~ADJ_EGO_XY;

		if (d || key == KEY_STATIONARY) {
			v->direction = v->direction == d ? 0 : d;
			return TRUE;
		}
	}

	return FALSE;
}
Exemplo n.º 4
0
/* If main_cycle returns false, don't process more events! */
int main_cycle() {
	unsigned int key, kascii;
	struct vt_entry *v = &game.view_table[0];

	poll_timer();		/* msdos driver -> does nothing */
	update_timer();

	if (game.ver == 0) {
		_text->message_box("Warning: game CRC not listed, assuming AGI version 2.917.");
		game.ver = -1;
	}

	key = do_poll_keyboard();

	/* In AGI Mouse emulation mode we must update the mouse-related
	 * vars in every interpreter cycle.
	 */
	if (opt.agimouse) {
		game.vars[28] = mouse.x / 2;
		game.vars[29] = mouse.y;
	}

	if (key == KEY_PRIORITY) {
		_sprites->erase_both();
		debug_.priority = !debug_.priority;
		show_pic();
		_sprites->blit_both();
		_sprites->commit_both();
		key = 0;
	}

	if (key == KEY_STATUSLN) {
		debug_.statusline = !debug_.statusline;
		_text->write_status();
		key = 0;
	}

	/* Click-to-walk mouse interface */
	if (game.player_control && v->flags & ADJ_EGO_XY) {
		v->direction = get_direction(v->x_pos, v->y_pos, v->parm1, v->parm2, v->step_size);

		if (v->direction == 0)
			in_destination(v);
	}

	kascii = KEY_ASCII(key);

	if (kascii)
		setvar(V_key, kascii);
	process_key:
	switch (game.input_mode) {
	case INPUT_NORMAL:
		if (!handle_controller(key)) {
			if (key == 0 || !game.input_enabled)
				break;
			handle_keys(key);

			/* if ESC pressed, activate menu before
			 * accept.input from the interpreter cycle
			 * sets the input mode to normal again
			 * (closes: #540856)
			 */
			if (key == KEY_ESCAPE) {
				key = 0;
				goto process_key;
			}

			/* commented out to close bug #438872
			 * if (key) game.keypress = key;
			 */
		}
		break;
	case INPUT_GETSTRING:
		handle_controller(key);
		handle_getstring(key);
		setvar(V_key, 0);	/* clear ENTER key */
		break;
	case INPUT_MENU:
		menu->keyhandler(key);
		do_update();
		return false;
	case INPUT_NONE:
		handle_controller(key);
		if (key)
			game.keypress = key;
		break;
	}

	do_update();

	if (game.msg_box_ticks > 0)
		game.msg_box_ticks--;

	return true;
}
Exemplo n.º 5
0
static void ledit_dispatch( UThread* ut, GWidget* wp, const GLViewEvent* ev )
{
    EX_PTR;

    //printf( "KR ledit %d\n", ev->type );
    switch( ev->type )
    {
        case GLV_EVENT_BUTTON_DOWN:
            if( (ev->code == GLV_BUTTON_LEFT) ||
                (ev->code == GLV_BUTTON_MIDDLE) )
            {
                ledit_setState( ut, ep, LEDIT_STATE_EDIT );
                gui_setKeyFocus( wp );

                if( ev->code == GLV_BUTTON_LEFT )
                {
                    // Don't have access to font here so just notify render.
                    ep->newCursorX = ev->x;
                    setFlag( NEW_CURSORX );
                }
                else // if( ev->code == GLV_BUTTON_MIDDLE )
                {
                    ledit_paste( ut, ep );
                    setFlag( CHANGED );
                }
            }
            break;

        case GLV_EVENT_BUTTON_UP:
        case GLV_EVENT_MOTION:
            break;

        case GLV_EVENT_KEY_DOWN:
            if( ep->strN )
            {
                UBuffer* str = ur_buffer( ep->strN );

                if( ev->state & GLV_MASK_CTRL )
                {
                    if( ev->code == KEY_k )
                    {
                        // Remove from cursor to end (from Bash).
                        int len = str->used - ep->editPos;
                        if( len > 0 )
                        {
                            ur_arrErase( str, ep->editPos, len );
                            setFlag( CHANGED );
                        }
                    }
                    else if( ev->code == KEY_v )
                    {
                        ledit_paste( ut, ep );
                        setFlag( CHANGED );
                    }
                    break;
                }

                switch( ev->code )
                {
                    case KEY_Return:
                        goto activate;

                    case KEY_Left:
                        if( ep->editPos > 0 )
                        {
                            --ep->editPos;
                            setFlag( CHANGED );
                        }
                        break;

                    case KEY_Right:
                        if( ep->editPos < str->used )
                        {
                            ++ep->editPos;
                            setFlag( CHANGED );
                        }
                        break;

                    case KEY_Home:
                        ep->editPos = 0;
                        setFlag( CHANGED );
                        break;

                    case KEY_End:
                        ep->editPos = str->used;
                        setFlag( CHANGED );
                        break;

                    case KEY_Insert:
                        break;

                    case KEY_Delete:
                        if( ep->editPos < str->used )
                        {
                            ur_arrErase( str, ep->editPos, 1 );
                            setFlag( CHANGED );
                        }
                        break;

                    case KEY_Back_Space:
                        if( ep->editPos > 0 )
                        {
                            --ep->editPos;
                            ur_arrErase( str, ep->editPos, 1 );
                            setFlag( CHANGED );
                        }
                        break;

                    default:
                        if( str->used < ep->maxChars )
                        {
                            int key = KEY_ASCII(ev);
                            if( key >= ' ' )
                            {
                                if( ep->filterN )
                                {
                                    UBuffer* bin = ur_buffer( ep->filterN );
                                    if( ! _bitIsSet( bin->ptr.b, key ) )
                                        break;
                                }

                                ur_arrExpand( str, ep->editPos, 1 );
                                if( ur_strIsUcs2(str) )
                                    str->ptr.u16[ ep->editPos ] = key;
                                else
                                    str->ptr.b[ ep->editPos ] = key;
                                ++ep->editPos;
                                setFlag( CHANGED );
                            }
                            else
                            {
                                gui_ignoreEvent( ev );
                            }
                        }
                        break;
                }
            }
            break;

        case GLV_EVENT_KEY_UP:
            gui_ignoreEvent( ev );
            break;

        case GLV_EVENT_FOCUS_IN:
            break;

        case GLV_EVENT_FOCUS_OUT:
            ledit_setState( ut, ep, LEDIT_STATE_DISPLAY );
            break;
    }
    return;

activate:

    if( ep->codeN )
        gui_doBlockN( ut, ep->codeN );
}
Exemplo n.º 6
0
// If main_cycle returns false, don't process more events!
int AgiEngine::mainCycle() {
	unsigned int key, kascii;
	VtEntry *v = &_game.viewTable[0];

	pollTimer();
	updateTimer();

	key = doPollKeyboard();

	// In AGI Mouse emulation mode we must update the mouse-related
	// vars in every interpreter cycle.
	//
	// We run AGIMOUSE always as a side effect
	if (getFeatures() & GF_AGIMOUSE || true) {
		_game.vars[28] = _mouse.x / 2;
		_game.vars[29] = _mouse.y;
	}
	if (key == KEY_PRIORITY) {
		_sprites->eraseBoth();
		_debug.priority = !_debug.priority;
		_picture->showPic();
		_sprites->blitBoth();
		_sprites->commitBoth();
		key = 0;
	}

	if (key == KEY_STATUSLN) {
		_debug.statusline = !_debug.statusline;
		writeStatus();
		key = 0;
	}

	// Click-to-walk mouse interface
	if (_game.playerControl && v->flags & ADJ_EGO_XY) {
		int toX = v->parm1;
		int toY = v->parm2;

		// AGI Mouse games use ego's sprite's bottom left corner for mouse walking target.
		// Amiga games use ego's sprite's bottom center for mouse walking target.
		// TODO: Check what Atari ST AGI and Apple IIGS AGI use for mouse walking target.
		if (getPlatform() == Common::kPlatformAmiga)
			toX -= (v->xSize / 2); // Center ego's sprite horizontally

		// Adjust ego's sprite's mouse walking target position (These parameters are
		// controlled with the adj.ego.move.to.x.y-command). Note that these values rely
		// on the horizontal centering of the ego's sprite at least on the Amiga platform.
		toX += _game.adjMouseX;
		toY += _game.adjMouseY;

		v->direction = getDirection(v->xPos, v->yPos, toX, toY, v->stepSize);

		if (v->direction == 0)
			inDestination(v);
	}

	kascii = KEY_ASCII(key);

	if (kascii)
		setvar(vKey, kascii);

process_key:

	switch (_game.inputMode) {
	case INPUT_NORMAL:
		if (!handleController(key)) {
			if (key == 0 || !_game.inputEnabled)
				break;
			handleKeys(key);

			// if ESC pressed, activate menu before
			// accept.input from the interpreter cycle
			// sets the input mode to normal again
			// (closes: #540856)
			if (key == KEY_ESCAPE) {
				key = 0;
				goto process_key;
			}

			// commented out to close Sarien bug #438872
			//if (key)
			//	_game.keypress = key;
		}
		break;
	case INPUT_GETSTRING:
		handleController(key);
		handleGetstring(key);
		setvar(vKey, 0);	// clear ENTER key
		break;
	case INPUT_MENU:
		_menu->keyhandler(key);
		_gfx->doUpdate();
		return false;
	case INPUT_NONE:
		handleController(key);
		if (key)
			_game.keypress = key;
		break;
	}
	_gfx->doUpdate();

	if (_game.msgBoxTicks > 0)
		_game.msgBoxTicks--;

	return true;
}
Exemplo n.º 7
0
int AgiEngine::handleController(int key) {
	VtEntry *v = &_game.viewTable[0];
	int i;

	// AGI 3.149 games, The Black Cauldron and King's Quest 4 need KEY_ESCAPE to use menus
	// Games with the GF_ESCPAUSE flag need KEY_ESCAPE to pause the game
	if (key == 0 ||
		(key == KEY_ESCAPE && getVersion() != 0x3149 && getGameID() != GID_BC && getGameID() != GID_KQ4 && !(getFeatures() & GF_ESCPAUSE)) )
		return false;

	if ((getGameID() == GID_MH1 || getGameID() == GID_MH2) && (key == KEY_ENTER) &&
			(_game.inputMode == INPUT_NONE)) {
		key = 0x20; // Set Enter key to Space in Manhunter when there's no text input
	}

	debugC(3, kDebugLevelInput, "key = %04x", key);

	for (i = 0; i < MAX_CONTROLLERS; i++) {
		if (_game.controllers[i].keycode == key) {
			debugC(3, kDebugLevelInput, "event %d: key press", _game.controllers[i].controller);
			_game.controllerOccured[_game.controllers[i].controller] = true;
			return true;
		}
	}

	if (key == BUTTON_LEFT) {
		if ((getflag(fMenusWork) || (getFeatures() & GF_MENUS)) && _mouse.y <= CHAR_LINES) {
			newInputMode(INPUT_MENU);
			return true;
		}
	}

	// Show predictive dialog if the user clicks on input area
	if (key == BUTTON_LEFT &&
			(int)_mouse.y >= _game.lineUserInput * CHAR_LINES &&
			(int)_mouse.y <= (_game.lineUserInput + 1) * CHAR_LINES) {
		GUI::PredictiveDialog _predictiveDialog;
		_predictiveDialog.runModal();
		strcpy(_predictiveResult, _predictiveDialog.getResult());
		if (strcmp(_predictiveResult, "")) {
			if (_game.inputMode == INPUT_NONE) {
				for (int n = 0; _predictiveResult[n]; n++)
					keyEnqueue(_predictiveResult[n]);
			} else {
				strcpy((char *)_game.inputBuffer, _predictiveResult);
				handleKeys(KEY_ENTER);
			}
		}
		/*
		if (predictiveDialog()) {
			if (_game.inputMode == INPUT_NONE) {
				for (int n = 0; _predictiveResult[n]; n++)
					keyEnqueue(_predictiveResult[n]);
			} else {
				strcpy((char *)_game.inputBuffer, _predictiveResult);
				handleKeys(KEY_ENTER);
			}
		}
		*/
		return true;
	}

	if (_game.playerControl) {
		int d = 0;

		if (!KEY_ASCII(key)) {
			switch (key) {
			case KEY_UP:
				d = 1;
				break;
			case KEY_DOWN:
				d = 5;
				break;
			case KEY_LEFT:
				d = 7;
				break;
			case KEY_RIGHT:
				d = 3;
				break;
			case KEY_UP_RIGHT:
				d = 2;
				break;
			case KEY_DOWN_RIGHT:
				d = 4;
				break;
			case KEY_UP_LEFT:
				d = 8;
				break;
			case KEY_DOWN_LEFT:
				d = 6;
				break;
			}
		}

		if (!(getFeatures() & GF_AGIMOUSE)) {
			// Handle mouse button events
			if (key == BUTTON_LEFT) {
				if (getGameID() == GID_PQ1 && _game.vars[vCurRoom] == 116) {
					// WORKAROUND: Special handling for mouse clicks in the newspaper
					// screen of PQ1. Fixes bug #3018770.
					d = 3;	// fake a right arrow key (next page)
				} else {
					// Click-to-walk mouse interface
					v->flags |= fAdjEgoXY;
					v->parm1 = WIN_TO_PIC_X(_mouse.x);
					v->parm2 = WIN_TO_PIC_Y(_mouse.y);
					return true;
				}
			}
		}

		if (d || key == KEY_STATIONARY) {
			v->flags &= ~fAdjEgoXY;
			v->direction = v->direction == d ? 0 : d;
			return true;
		}
	}

	return false;
}
Exemplo n.º 8
0
void AgiEngine::handleGetstring(int key) {
	static int pos = 0;	// Cursor position
	static char buf[40];

	if (KEY_ASCII(key) == 0)
		return;

	debugC(3, kDebugLevelInput, "handling key: %02x", key);

	switch (key) {
	case BUTTON_LEFT:
		if ((int)_mouse.y >= _stringdata.y * CHAR_LINES &&
				(int)_mouse.y <= (_stringdata.y + 1) * CHAR_LINES) {
			GUI::PredictiveDialog _predictiveDialog;
			_predictiveDialog.runModal();
			strcpy(_predictiveResult, _predictiveDialog.getResult());
			if (strcmp(_predictiveResult, "")) {
				strcpy(_game.strings[_stringdata.str], _predictiveResult);
				newInputMode(INPUT_NORMAL);
				_gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1,
								_stringdata.y, ' ', _game.colorFg, _game.colorBg);
				return;
			}
			/*
			if (predictiveDialog()) {
				strcpy(_game.strings[_stringdata.str], _predictiveResult);
				newInputMode(INPUT_NORMAL);
				_gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1,
								_stringdata.y, ' ', _game.colorFg, _game.colorBg);
				return;
			}
			*/
		}
		break;
	case KEY_ENTER:
		debugC(3, kDebugLevelInput, "KEY_ENTER");
		_game.hasPrompt = 0;
		buf[pos] = 0;

		strcpy(_game.strings[_stringdata.str], buf);
		debugC(3, kDebugLevelInput, "buffer=[%s]", buf);
		buf[pos = 0] = 0;

		newInputMode(INPUT_NORMAL);
		_gfx->printCharacter(_stringdata.x + strlen(_game.strings[_stringdata.str]) + 1,
				_stringdata.y, ' ', _game.colorFg, _game.colorBg);
		return;
	case KEY_ESCAPE:
		debugC(3, kDebugLevelInput, "KEY_ESCAPE");
		_game.hasPrompt = 0;
		buf[pos = 0] = 0;

		strcpy(_game.strings[_stringdata.str], buf);
		newInputMode(INPUT_NORMAL);

		// newInputMode(INPUT_MENU);
		break;
	case KEY_BACKSPACE:	// 0x08
		if (!pos)
			break;

		_gfx->printCharacter(_stringdata.x + (pos + 1), _stringdata.y,
				' ', _game.colorFg, _game.colorBg);
		pos--;
		buf[pos] = 0;
		break;
	default:
		if (key < 0x20 || key > 0x7f)
			break;

		if (pos >= _stringdata.len)
			break;

		buf[pos++] = key;
		buf[pos] = 0;

		// Echo
		_gfx->printCharacter(_stringdata.x + pos, _stringdata.y, buf[pos - 1],
				_game.colorFg, _game.colorBg);

		break;
	}

	// print cursor
	_gfx->printCharacter(_stringdata.x + pos + 1, _stringdata.y,
			(char)_game.cursorChar, _game.colorFg, _game.colorBg);
}