Logo Search packages:      
Sourcecode: scummvm version File versions

touchkeyboard.cpp

/* 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 <nds.h>
#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();
                        OSystem::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 = OSystem::EVENT_KEYDOWN;
                        event.kbd.flags = 0;
                        system->addEvent(event);

                        event.type = OSystem::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;
                  }
            }     
      }
}

}


Generated by  Doxygen 1.6.0   Back to index