/* ScummVM - Scumm Interpreter * Copyright (C) 2005-2006 Neil Millstone * Copyright (C) 2006 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include "touchkeyboard.h" #include "keyboard_raw.h" #include "keyboard_pal_raw.h" #include "dsmain.h" #include "osystem_ds.h" namespace DS { struct key_data { char keyNum; char x, y; int character; bool pressed; }; #define DS_NUM_KEYS 60 #define DS_SHIFT 0 #define DS_BACKSPACE 8 #define DS_RETURN 13 #define DS_CAPSLOCK 1 key_data keys[DS_NUM_KEYS] = { // Key number x y character // Numbers {28, 3, 0, '1'}, {29, 5, 0, '2'}, {30, 7, 0, '3'}, {31, 9, 0, '4'}, {32, 11, 0, '5'}, {33, 13, 0, '6'}, {34, 15, 0, '7'}, {35, 17, 0, '8'}, {36, 19, 0, '9'}, {27, 21, 0, '0'}, {45, 23, 0, SDLK_MINUS}, {50, 25, 0, SDLK_EQUALS}, {52, 27, 0, SDLK_BACKSPACE}, // Top row {'Q'-'A' + 1, 4, 2, 'Q'}, {'W'-'A' + 1, 6, 2, 'W'}, {'E'-'A' + 1, 8, 2, 'E'}, {'R'-'A' + 1, 10, 2, 'R'}, {'T'-'A' + 1, 12, 2, 'T'}, {'Y'-'A' + 1, 14, 2, 'Y'}, {'U'-'A' + 1, 16, 2, 'U'}, {'I'-'A' + 1, 18, 2, 'I'}, {'O'-'A' + 1, 20, 2, 'O'}, {'P'-'A' + 1, 22, 2, 'P'}, {43, 24, 2, SDLK_LEFTBRACKET}, {44, 26, 2, SDLK_RIGHTBRACKET}, // Middle row {55, 3, 4, DS_CAPSLOCK}, {'A'-'A' + 1, 5, 4, 'A'}, {'S'-'A' + 1, 7, 4, 'S'}, {'D'-'A' + 1, 9, 4, 'D'}, {'F'-'A' + 1, 11, 4, 'F'}, {'G'-'A' + 1, 13, 4, 'G'}, {'H'-'A' + 1, 15, 4, 'H'}, {'J'-'A' + 1, 17, 4, 'J'}, {'K'-'A' + 1, 19, 4, 'K'}, {'L'-'A' + 1, 21, 4, 'L'}, {42, 23, 4, SDLK_SEMICOLON}, {41, 25, 4, SDLK_QUOTE}, {46, 27, 4, SDLK_RETURN}, // Bottom row {51, 4, 6, DS_SHIFT}, {'Z'-'A' + 1, 6, 6, 'Z'}, {'X'-'A' + 1, 8, 6, 'X'}, {'C'-'A' + 1, 10, 6, 'C'}, {'V'-'A' + 1, 12, 6, 'V'}, {'B'-'A' + 1, 14, 6, 'B'}, {'N'-'A' + 1, 16, 6, 'N'}, {'M'-'A' + 1, 18, 6, 'M'}, {38, 20, 6, SDLK_COMMA}, {39, 22, 6, SDLK_PERIOD}, {40, 24, 6, SDLK_SLASH}, // Space bar {47, 9, 8, SDLK_SPACE}, {48, 11, 8, SDLK_SPACE}, {48, 13, 8, SDLK_SPACE}, {48, 15, 8, SDLK_SPACE}, {48, 17, 8, SDLK_SPACE}, {49, 19, 8, SDLK_SPACE}, // Cursor arrows {52, 27, 8, SDLK_LEFT}, {54, 29, 8, SDLK_DOWN}, {53, 31, 8, SDLK_RIGHT}, {51, 29, 6, SDLK_UP}, // Close button {56, 30, 0, SDLK_UNKNOWN}, }; int keyboardX; int keyboardY; int mapBase; int tileBase; bool shiftState; bool capsLockState; bool closed; void restoreVRAM(int tileBase, int mapBase, u16* saveSpace) { /* for (int r = 0; r < 32 * 32; r++) { ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = *saveSpace++; } for (int r = 0; r < 4096; r++) { ((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r] = *saveSpace++; }*/ } void drawKeyboard(int tileBase, int mapBase, u16* saveSpace) { for (int r = 0; r < 32 * 32; r++) { // *saveSpace++ = ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r]; ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase))[r] = 127; } for (int r = 0; r < 4096; r++) { // *saveSpace++ = ((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r]; ((u16 *) CHAR_BASE_BLOCK_SUB(tileBase))[r] = ((u16 *) (keyboard_raw))[r]; } for (int r = 0; r < 16; r++) { BG_PALETTE_SUB[r] = ((u16 *) (keyboard_pal_raw))[r]; } for (int r = 0; r < 16; r++) { int col = ((u16 *) (keyboard_pal_raw))[r]; int red = col & 0x001F; int green = (col & 0x03E0) >> 5; int blue = (col & 0x7C00) >> 10; red = (red * 8) / 16; green = (green * 8) / 16; blue = (blue * 8) / 16; BG_PALETTE_SUB[16 + r] = red | (green << 5) | (blue << 10); } keyboardX = -2; keyboardY = 2; mapBase = mapBase; tileBase = tileBase; shiftState = false; capsLockState = false; int x = keyboardX; int y = keyboardY; u16* base = ((u16 *) SCREEN_BASE_BLOCK_SUB(mapBase)); for (int r = 0; r < DS_NUM_KEYS; r++) { base[(y + keys[r].y) * 32 + x + keys[r].x] = keys[r].keyNum * 2; base[(y + keys[r].y) * 32 + x + keys[r].x + 1] = keys[r].keyNum * 2 + 1; base[(y + keys[r].y + 1) * 32 + x + keys[r].x] = 128 + keys[r].keyNum * 2; base[(y + keys[r].y + 1) * 32 + x + keys[r].x + 1] = 128 + keys[r].keyNum * 2 + 1; keys[r].pressed = false; } closed = false; } bool getKeyboardClosed() { return closed; } void setKeyHighlight(int key, bool highlight) { u16* base = ((u16 *) SCREEN_BASE_BLOCK_SUB(DS::mapBase)); if (highlight) { base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] |= 0x1000; base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] |= 0x1000; base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] |= 0x1000; base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] |= 0x1000; } else { base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x] &= ~0x1000; base[(keyboardY + keys[key].y) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000; base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x] &= ~0x1000; base[(keyboardY + keys[key].y + 1) * 32 + keyboardX + keys[key].x + 1] &= ~0x1000; } } void addKeyboardEvents() { if (DS::getPenDown()) { int x = IPC->touchXpx; int y = IPC->touchYpx; int tx = (x >> 3) - keyboardX; int ty = (y >> 3) - keyboardY; // consolePrintf("x=%d y=%d\n", tx, ty); for (int r = 0; r < DS_NUM_KEYS; r++) { if (( (tx >= keys[r].x) && (tx <= keys[r].x + 1)) && (ty >= keys[r].y) && (ty <= keys[r].y + 1)) { OSystem_DS* system = OSystem_DS::instance(); Common::Event event; // consolePrintf("Key: %d\n", r); if ((keys[r].character == SDLK_UNKNOWN)) { // Close button DS::closed = true; } else if ((keys[r].character >= '0') && (keys[r].character <= '9')) { event.kbd.ascii = keys[r].character; event.kbd.keycode = 0; } else if ((keys[r].character >= 'A') && (keys[r].character <= 'Z')) { if ((!DS::shiftState) && (!DS::capsLockState)) { event.kbd.ascii = keys[r].character + 32; // Make key lowercase. } else { event.kbd.ascii = keys[r].character; } event.kbd.keycode = event.kbd.ascii; } else { event.kbd.ascii = keys[r].character; event.kbd.keycode = keys[r].character; } //event.kbd.keycode = keys[r].character; //event.kbd.ascii = keys[r].character; event.type = Common::EVENT_KEYDOWN; event.kbd.flags = 0; system->addEvent(event); event.type = Common::EVENT_KEYUP; system->addEvent(event); switch (keys[r].character) { case DS_SHIFT: { DS::shiftState = !DS::shiftState; DS::setKeyHighlight(r, DS::shiftState); break; } case DS_CAPSLOCK: { DS::capsLockState = !DS::capsLockState; DS::setKeyHighlight(r, DS::capsLockState); break; } default: { DS::setKeyHighlight(r, true); keys[r].pressed = true; if (DS::shiftState) { DS::shiftState = false; for (int t = 0; t < DS_NUM_KEYS; t++) { if (keys[t].character == DS_SHIFT) { DS::setKeyHighlight(t, false); } } } break; } } } } } if (DS::getPenReleased()) { for (int r = 0; r < DS_NUM_KEYS; r++) { if (keys[r].pressed) { DS::setKeyHighlight(r, false); keys[r].pressed = false; } } } } }