Basic input almost done!
This commit is contained in:
parent
9d9a736a89
commit
eab6851522
147
mdl/m_sdlcrt.pas
147
mdl/m_sdlcrt.pas
|
@ -39,39 +39,79 @@ Uses
|
||||||
SDL;
|
SDL;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
AppWindowX = 800;
|
keyENTER = #13;
|
||||||
AppWindowY = 600;
|
keyESCAPE = #27;
|
||||||
|
keyHOME = #71;
|
||||||
|
keyUP = #72;
|
||||||
|
keyPGUP = #73;
|
||||||
|
keyLEFT = #75;
|
||||||
|
keyRIGHT = #77;
|
||||||
|
keyEND = #79;
|
||||||
|
keyDOWN = #80;
|
||||||
|
keyPGDN = #81;
|
||||||
|
keyINSERT = #82;
|
||||||
|
keyDELETE = #83;
|
||||||
|
|
||||||
AppInputSize = 128;
|
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;
|
InputEvent : pSDL_EVENT;
|
||||||
Screen : pSDL_SURFACE;
|
Screen : pSDL_SURFACE;
|
||||||
|
|
||||||
Constructor Create (InitMode: TSDLScreenMode);
|
Constructor Create (InitMode: TSDLScreenMode);
|
||||||
Destructor Destroy;
|
Destructor Destroy; Override;
|
||||||
|
|
||||||
Procedure PushInput (Ch: Char);
|
Procedure PushInput (Ch: Char);
|
||||||
|
Procedure PushExt (Ch: Char);
|
||||||
|
Procedure PushStr (Str: String);
|
||||||
Procedure ProcessEvent;
|
Procedure ProcessEvent;
|
||||||
Function KeyPressed : Boolean;
|
Function KeyPressed : Boolean;
|
||||||
|
Function ReadKey : Char;
|
||||||
Procedure Delay (MS: LongInt);
|
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
|
||||||
|
If IsShift or IsCaps Then Dec (InputEvent^.Key.KeySym.Sym, 32);
|
||||||
PushInput (Chr(InputEvent^.Key.KeySym.Sym));
|
PushInput (Chr(InputEvent^.Key.KeySym.Sym));
|
||||||
End;
|
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;
|
||||||
|
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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue