Basic input almost done!

This commit is contained in:
mysticbbs 2012-02-22 11:02:09 -05:00
parent 9d9a736a89
commit eab6851522
2 changed files with 166 additions and 23 deletions

View File

@ -39,39 +39,79 @@ Uses
SDL; SDL;
Const Const
AppWindowX = 800; keyENTER = #13;
AppWindowY = 600; keyESCAPE = #27;
AppInputSize = 128; keyHOME = #71;
keyUP = #72;
keyPGUP = #73;
keyLEFT = #75;
keyRIGHT = #77;
keyEND = #79;
keyDOWN = #80;
keyPGDN = #81;
keyINSERT = #82;
keyDELETE = #83;
AppInputSize = 128;
SDLAppWindowX : Word = 800;
SDLAppWindowY : Word = 600;
Type Type
TSDLScreenMode = (mode_80x25, mode_80x50, mode_132x50); TSDLScreenMode = (mode_80x25, mode_80x50, mode_132x50);
TSDLKeyMap = Record
SDL : Word;
Key : String[2];
Shift : String[2];
Alt : String[2];
Ctrl : String[2];
End;
TSDLConsole = Class TSDLConsole = Class
InputBuffer : Array[1..AppInputSize] of Char; InputBuffer : Array[1..AppInputSize] of Char;
InputPos : Integer; InputPos : Integer;
InputSize : Integer; InputSize : Integer;
InputEvent : pSDL_EVENT;
Screen : pSDL_SURFACE;
InputEvent : pSDL_EVENT; Constructor Create (InitMode: TSDLScreenMode);
Screen : pSDL_SURFACE; Destructor Destroy; Override;
Constructor Create (InitMode: TSDLScreenMode); Procedure PushInput (Ch: Char);
Destructor Destroy; Procedure PushExt (Ch: Char);
Procedure PushStr (Str: String);
Procedure PushInput (Ch: Char);
Procedure ProcessEvent; Procedure ProcessEvent;
Function KeyPressed : Boolean; Function KeyPressed : Boolean;
Procedure Delay (MS: LongInt); Function ReadKey : Char;
Procedure Delay (MS: LongInt);
End; End;
Implementation Implementation
// SDL fails hard with keyboard handling. I think we need to use
// a lookup table that can be externalized into a data file so different
// countries can load their specific keyboard set.
//
// I just assumed things like this would NOT be a problem in SDL. Pretty
// disappointing actually. So below is the US mapping as I get time to
// work on it.
Const
SDLKeyMapSize = 3;
SDLKeyMapUS : Array[1..SDLKeyMapSize] of TSDLKeyMap = (
(SDL:SDLK_1; Key:'1'; Shift:'!'; Alt:'1'; CTRL:'1'),
(SDL:SDLK_2; Key:'2'; Shift:'@'; Alt:'2'; CTRL:'2'),
(SDL:SDLK_SLASH; Key:'/'; Shift:'?'; Alt:'/'; CTRL:'/')
);
Constructor TSDLConsole.Create (InitMode: TSDLScreenMode); Constructor TSDLConsole.Create (InitMode: TSDLScreenMode);
Begin Begin
Inherited Create; Inherited Create;
SDL_INIT(SDL_INIT_VIDEO OR SDL_INIT_EVENTTHREAD); SDL_INIT(SDL_INIT_VIDEO);
Screen := SDL_SetVideoMode(AppWindowX, AppWindowY, 32, SDL_SWSURFACE); Screen := SDL_SetVideoMode(SDLAppWindowX, SDLAppWindowY, 32, SDL_SWSURFACE);
If Screen = NIL Then Halt; If Screen = NIL Then Halt;
@ -96,21 +136,84 @@ Begin
If InputSize > AppInputSize Then Begin If InputSize > AppInputSize Then Begin
InputSize := 1; InputSize := 1;
InputPos := 1; InputPos := 0;
End; End;
InputBuffer[InputSize] := Ch; InputBuffer[InputSize] := Ch;
End; End;
Procedure TSDLConsole.ProcessEvent; Procedure TSDLConsole.PushExt (Ch: Char);
Begin Begin
PushInput(#0);
PushInput(Ch);
End;
Procedure TSDLConsole.PushStr (Str: String);
Begin
PushInput (Str[1]);
If Length(Str) > 1 Then PushInput (Str[2]);
End;
Procedure TSDLConsole.ProcessEvent;
Var
IsShift : Boolean = False;
IsCaps : Boolean = False;
IsAlt : Boolean = False;
IsCtrl : Boolean = False;
Found : Boolean;
Count : Integer;
Begin
IsShift := (InputEvent^.Key.KeySym.Modifier AND KMOD_SHIFT <> 0);
IsCaps := (InputEvent^.Key.KeySym.Modifier AND KMOD_CAPS <> 0);
IsAlt := (InputEvent^.Key.KeySym.Modifier AND KMOD_ALT <> 0);
IsCtrl := (InputEvent^.Key.KeySym.Modifier AND KMOD_CTRL <> 0);
Case InputEvent^.Type_ of Case InputEvent^.Type_ of
SDL_KEYDOWN : Case InputEvent^.Key.KeySym.Sym of SDL_KEYDOWN : Begin
// remap SDL keys to pascal CRT Case InputEvent^.Key.KeySym.Sym of
27 : PushInput(#27); SDLK_A..
Else SDLK_Z : Begin
PushInput(Chr(InputEvent^.Key.KeySym.Sym)); If IsShift or IsCaps Then Dec (InputEvent^.Key.KeySym.Sym, 32);
PushInput (Chr(InputEvent^.Key.KeySym.Sym));
End;
SDLK_DELETE : PushExt(keyDELETE);
SDLK_UP : PushExt(keyUP);
SDLK_DOWN : PushExt(keyDOWN);
SDLK_RIGHT : PushExt(keyRIGHT);
SDLK_LEFT : PushExt(keyLEFT);
SDLK_INSERT : PushExt(keyINSERT);
SDLK_HOME : PushExt(keyHome);
SDLK_END : PushExt(keyEnd);
SDLK_PAGEUP : PushExt(keyPGUP);
SDLK_PAGEDOWN : PushExt(keyPGDN);
SDLK_NUMLOCK..
SDLK_COMPOSE : ;
Else
Found := False;
For Count := 1 to SDLKeyMapSize Do
If InputEvent^.Key.KeySym.Sym = SDLKeyMapUS[Count].SDL Then Begin
If IsShift Then
PushStr(SDLKeyMapUS[Count].Shift)
Else
If IsAlt Then
PushStr(SDLKeyMapUS[Count].Alt)
Else
If IsCTRL Then
PushStr(SDLKeyMapUS[Count].CTRL)
Else
PushStr(SDLKeyMapUS[Count].Key);
Found := True;
Break;
End;
If Not Found Then PushInput(Chr(InputEvent^.Key.KeySym.Sym));
End;
End; End;
SDL_QUITEV : Halt;
End; End;
End; End;
@ -125,7 +228,25 @@ Begin
If Queued > 0 Then If Queued > 0 Then
ProcessEvent; ProcessEvent;
Result := InputSize > 0; Result := InputPos <> InputSize;
End;
Function TSDLConsole.ReadKey : Char;
Begin
If InputPos = InputSize Then
Repeat
SDL_WaitEvent(InputEvent);
ProcessEvent;
Until (InputSize <> InputPos);
Inc (InputPos);
Result := InputBuffer[InputPos];
If InputPos = InputSize Then Begin
InputPos := 0;
InputSize := 0;
End;
End; End;
Procedure TSDLConsole.Delay (MS: LongInt); Procedure TSDLConsole.Delay (MS: LongInt);

View File

@ -5,12 +5,34 @@ Uses
Var Var
Console : TSDLConsole; Console : TSDLConsole;
Ch : Char;
Begin Begin
Console := TSDLConsole.Create(Mode_80x25); Console := TSDLConsole.Create(Mode_80x25);
Repeat Repeat
Until Console.KeyPressed; Ch := Console.ReadKey;
Case Ch of
#00 : Case Console.ReadKey of
keyUP : WriteLn('Got Up arrow');
keyDOWN : WriteLn('Got down arrow');
keyLEFT : WriteLn('Got left arrow');
keyRIGHT : WriteLn('Got right arrow');
keyHOME : WriteLn('Got HOME');
keyEND : WriteLn('Got END');
keyPGUP : WriteLn('Got PAGE UP');
keyPGDN : WriteLn('Got PAGE Down');
keyINSERT : WriteLn('Got INSERT');
keyDELETE : WriteLn('Got DELETE');
End;
#27 : Begin
WriteLn('Got escape. Shutting down');
Break;
End;
Else
WriteLn('Got: ' + Ch);
End;
Until False;
Console.Free; Console.Free;
End. End.