summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6c6b87e)
raw | patch | inline | side by side (parent: 6c6b87e)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sat, 5 Oct 2019 22:43:33 +0000 (01:43 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 13 Oct 2019 14:19:20 +0000 (17:19 +0300) |
23 files changed:
index c46e8ec4600bfd8729fc1f75e06740507aed10bb..6f1df29b44ae447aaf587fcf4bf8f4362aa86dd3 100644 (file)
uses
{$INCLUDE ../nogl/noGLuses.inc}
- SysUtils, Classes, Math, e_log, e_texture, SDL2, MAPDEF, ImagingTypes, Imaging, ImagingUtility;
+ {$IFDEF USE_SDL2}
+ SDL2,
+ {$ENDIF}
+ SysUtils, Classes, Math, e_log, e_texture,
+ MAPDEF, ImagingTypes, Imaging, ImagingUtility;
type
TMirrorType=(None, Horizontal, Vertical);
procedure e_Clear(); overload;
procedure e_EndRender();
+{$IFDEF USE_SDL2}
function e_GetGamma(win: PSDL_Window): Byte;
procedure e_SetGamma(win: PSDL_Window;Gamma: Byte);
+{$ENDIF}
procedure e_MakeScreenshot(st: TStream; Width, Height: Word);
glPopMatrix();
end;
+{$IFDEF USE_SDL2}
function e_GetGamma(win: PSDL_Window): Byte;
var
ramp: array [0..256*3-1] of Word;
SDL_SetWindowGammaRamp(win, @ramp[0], @ramp[256], @ramp[512]);
end;
+{$ENDIF}
function e_CharFont_Create(sp: ShortInt=0): DWORD;
var
diff --git a/src/engine/e_input.pas b/src/engine/e_input.pas
index 1bfd7f33407db727a8dd87c4848a392f09c64e74..e7fa6cb0df5bc9091c818170377dbd1470cb7287 100644 (file)
--- a/src/engine/e_input.pas
+++ b/src/engine/e_input.pas
{$INCLUDE ../shared/a_modes.inc}
unit e_input;
-interface
-
-uses SysUtils, SDL2;
-
-const
- e_MaxKbdKeys = SDL_NUM_SCANCODES;
- e_MaxJoys = 4;
- e_MaxJoyBtns = 32;
- e_MaxJoyAxes = 8;
- e_MaxJoyHats = 8;
- e_MaxVirtKeys = 48;
-
- e_MaxJoyKeys = e_MaxJoyBtns + e_MaxJoyAxes*2 + e_MaxJoyHats*4;
-
- e_MaxInputKeys = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
- // $$$..$$$ - 321 Keyboard buttons/keys
- // $$$..$$$ - 4*32 Joystick buttons
- // $$$..$$$ - 8*2 Joystick axes (- and +)
- // $$$..$$$ - 4*4 Joystick hats (L U R D)
- // $$$..$$$ - 48 Virtual buttons/keys
-
- KBRD_END = e_MaxKbdKeys;
- JOYK_BEG = KBRD_END;
- JOYK_END = JOYK_BEG + e_MaxJoyBtns*e_MaxJoys;
- JOYA_BEG = JOYK_END;
- JOYA_END = JOYA_BEG + e_MaxJoyAxes*2*e_MaxJoys;
- JOYH_BEG = JOYA_END;
- JOYH_END = JOYH_BEG + e_MaxJoyHats*4*e_MaxJoys;
- VIRT_BEG = JOYH_END;
- VIRT_END = VIRT_BEG + e_MaxVirtKeys;
-
- // these are apparently used in g_gui and g_game and elsewhere
- IK_INVALID = 0;
- IK_ESCAPE = SDL_SCANCODE_ESCAPE;
- IK_RETURN = SDL_SCANCODE_RETURN;
- IK_KPRETURN= SDL_SCANCODE_KP_ENTER;
- IK_ENTER = SDL_SCANCODE_RETURN;
- IK_KPINSERT = SDL_SCANCODE_KP_0;
- IK_UP = SDL_SCANCODE_UP;
- IK_KPUP = SDL_SCANCODE_KP_8;
- IK_DOWN = SDL_SCANCODE_DOWN;
- IK_KPDOWN = SDL_SCANCODE_KP_2;
- IK_LEFT = SDL_SCANCODE_LEFT;
- IK_KPLEFT = SDL_SCANCODE_KP_4;
- IK_RIGHT = SDL_SCANCODE_RIGHT;
- IK_KPRIGHT = SDL_SCANCODE_KP_6;
- IK_DELETE = SDL_SCANCODE_DELETE;
- IK_HOME = SDL_SCANCODE_HOME;
- IK_KPHOME = SDL_SCANCODE_KP_7;
- IK_INSERT = SDL_SCANCODE_INSERT;
- IK_SPACE = SDL_SCANCODE_SPACE;
- IK_CONTROL = SDL_SCANCODE_LCTRL;
- IK_SHIFT = SDL_SCANCODE_LSHIFT;
- IK_ALT = SDL_SCANCODE_LALT;
- IK_TAB = SDL_SCANCODE_TAB;
- IK_PAGEUP = SDL_SCANCODE_PAGEUP;
- IK_KPPAGEUP= SDL_SCANCODE_KP_9;
- IK_PAGEDN = SDL_SCANCODE_PAGEDOWN;
- IK_KPPAGEDN= SDL_SCANCODE_KP_3;
- IK_KP5 = SDL_SCANCODE_KP_5;
- IK_NUMLOCK = SDL_SCANCODE_NUMLOCKCLEAR;
- IK_KPDIVIDE= SDL_SCANCODE_KP_DIVIDE;
- IK_KPMULTIPLE= SDL_SCANCODE_KP_MULTIPLY;
- IK_KPMINUS = SDL_SCANCODE_KP_MINUS;
- IK_KPPLUS = SDL_SCANCODE_KP_PLUS;
- IK_KPENTER = SDL_SCANCODE_KP_ENTER;
- IK_KPDOT = SDL_SCANCODE_KP_PERIOD;
- IK_CAPSLOCK= SDL_SCANCODE_CAPSLOCK;
- IK_RSHIFT = SDL_SCANCODE_RSHIFT;
- IK_CTRL = SDL_SCANCODE_LCTRL;
- IK_RCTRL = SDL_SCANCODE_RCTRL;
- IK_RALT = SDL_SCANCODE_RALT;
- IK_WIN = SDL_SCANCODE_LGUI;
- IK_RWIN = SDL_SCANCODE_RGUI;
- IK_MENU = SDL_SCANCODE_MENU;
- IK_PRINTSCR= SDL_SCANCODE_PRINTSCREEN;
- IK_SCROLLLOCK= SDL_SCANCODE_SCROLLLOCK;
- IK_LBRACKET= SDL_SCANCODE_LEFTBRACKET;
- IK_RBRACKET= SDL_SCANCODE_RIGHTBRACKET;
- IK_SEMICOLON= SDL_SCANCODE_SEMICOLON;
- IK_QUOTE = SDL_SCANCODE_APOSTROPHE;
- IK_BACKSLASH= SDL_SCANCODE_BACKSLASH;
- IK_SLASH = SDL_SCANCODE_SLASH;
- IK_COMMA = SDL_SCANCODE_COMMA;
- IK_DOT = SDL_SCANCODE_PERIOD;
- IK_EQUALS = SDL_SCANCODE_EQUALS;
- IK_0 = SDL_SCANCODE_0;
- IK_1 = SDL_SCANCODE_1;
- IK_2 = SDL_SCANCODE_2;
- IK_3 = SDL_SCANCODE_3;
- IK_4 = SDL_SCANCODE_4;
- IK_5 = SDL_SCANCODE_5;
- IK_6 = SDL_SCANCODE_6;
- IK_7 = SDL_SCANCODE_7;
- IK_8 = SDL_SCANCODE_8;
- IK_9 = SDL_SCANCODE_9;
- IK_F1 = SDL_SCANCODE_F1;
- IK_F2 = SDL_SCANCODE_F2;
- IK_F3 = SDL_SCANCODE_F3;
- IK_F4 = SDL_SCANCODE_F4;
- IK_F5 = SDL_SCANCODE_F5;
- IK_F6 = SDL_SCANCODE_F6;
- IK_F7 = SDL_SCANCODE_F7;
- IK_F8 = SDL_SCANCODE_F8;
- IK_F9 = SDL_SCANCODE_F9;
- IK_F10 = SDL_SCANCODE_F10;
- IK_F11 = SDL_SCANCODE_F11;
- IK_F12 = SDL_SCANCODE_F12;
- IK_END = SDL_SCANCODE_END;
- IK_KPEND = SDL_SCANCODE_KP_1;
- IK_BACKSPACE = SDL_SCANCODE_BACKSPACE;
- IK_BACKQUOTE = SDL_SCANCODE_GRAVE;
- IK_GRAVE = SDL_SCANCODE_GRAVE;
- IK_PAUSE = SDL_SCANCODE_PAUSE;
- IK_Y = SDL_SCANCODE_Y;
- IK_N = SDL_SCANCODE_N;
- IK_W = SDL_SCANCODE_W;
- IK_A = SDL_SCANCODE_A;
- IK_S = SDL_SCANCODE_S;
- IK_D = SDL_SCANCODE_D;
- IK_Q = SDL_SCANCODE_Q;
- IK_E = SDL_SCANCODE_E;
- IK_H = SDL_SCANCODE_H;
- IK_J = SDL_SCANCODE_J;
- IK_T = SDL_SCANCODE_T;
- IK_Z = SDL_SCANCODE_Z;
- IK_MINUS = SDL_SCANCODE_MINUS;
- // TODO: think of something better than this shit
- IK_LASTKEY = SDL_NUM_SCANCODES-1;
-
- VK_FIRSTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys;
- VK_LEFT = VK_FIRSTKEY + 0;
- VK_RIGHT = VK_FIRSTKEY + 1;
- VK_UP = VK_FIRSTKEY + 2;
- VK_DOWN = VK_FIRSTKEY + 3;
- VK_FIRE = VK_FIRSTKEY + 4;
- VK_OPEN = VK_FIRSTKEY + 5;
- VK_JUMP = VK_FIRSTKEY + 6;
- VK_CHAT = VK_FIRSTKEY + 7;
- VK_ESCAPE = VK_FIRSTKEY + 8;
- VK_0 = VK_FIRSTKEY + 9;
- VK_1 = VK_FIRSTKEY + 10;
- VK_2 = VK_FIRSTKEY + 11;
- VK_3 = VK_FIRSTKEY + 12;
- VK_4 = VK_FIRSTKEY + 13;
- VK_5 = VK_FIRSTKEY + 14;
- VK_6 = VK_FIRSTKEY + 15;
- VK_7 = VK_FIRSTKEY + 16;
- VK_8 = VK_FIRSTKEY + 17;
- VK_9 = VK_FIRSTKEY + 18;
- VK_A = VK_FIRSTKEY + 19;
- VK_B = VK_FIRSTKEY + 20;
- VK_C = VK_FIRSTKEY + 21;
- VK_D = VK_FIRSTKEY + 22;
- VK_E = VK_FIRSTKEY + 23;
- VK_F = VK_FIRSTKEY + 24;
- VK_CONSOLE = VK_FIRSTKEY + 25;
- VK_STATUS = VK_FIRSTKEY + 26;
- VK_TEAM = VK_FIRSTKEY + 27;
- VK_PREV = VK_FIRSTKEY + 28;
- VK_NEXT = VK_FIRSTKEY + 29;
- VK_STRAFE = VK_FIRSTKEY + 30;
- VK_LSTRAFE = VK_FIRSTKEY + 31;
- VK_RSTRAFE = VK_FIRSTKEY + 32;
- VK_PRINTSCR = VK_FIRSTKEY + 33;
- VK_SHOWKBD = VK_FIRSTKEY + 34;
- VK_HIDEKBD = VK_FIRSTKEY + 35;
- VK_LASTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
-
- AX_MINUS = 0;
- AX_PLUS = 1;
- HAT_LEFT = 0;
- HAT_UP = 1;
- HAT_RIGHT = 2;
- HAT_DOWN = 3;
-
- JOY0_ATTACK = JOYK_BEG + 0*e_MaxJoyBtns + 0;
- JOY1_ATTACK = JOYK_BEG + 1*e_MaxJoyBtns + 0;
- JOY2_ATTACK = JOYK_BEG + 2*e_MaxJoyBtns + 0;
- JOY3_ATTACK = JOYK_BEG + 3*e_MaxJoyBtns + 0;
- JOY0_NEXT = JOYK_BEG + 0*e_MaxJoyBtns + 1;
- JOY1_NEXT = JOYK_BEG + 1*e_MaxJoyBtns + 1;
- JOY2_NEXT = JOYK_BEG + 2*e_MaxJoyBtns + 1;
- JOY3_NEXT = JOYK_BEG + 3*e_MaxJoyBtns + 1;
- JOY0_JUMP = JOYK_BEG + 0*e_MaxJoyBtns + 2;
- JOY1_JUMP = JOYK_BEG + 1*e_MaxJoyBtns + 2;
- JOY2_JUMP = JOYK_BEG + 2*e_MaxJoyBtns + 2;
- JOY3_JUMP = JOYK_BEG + 3*e_MaxJoyBtns + 2;
- JOY0_ACTIVATE = JOYK_BEG + 0*e_MaxJoyBtns + 3;
- JOY1_ACTIVATE = JOYK_BEG + 1*e_MaxJoyBtns + 3;
- JOY2_ACTIVATE = JOYK_BEG + 2*e_MaxJoyBtns + 3;
- JOY3_ACTIVATE = JOYK_BEG + 3*e_MaxJoyBtns + 3;
- JOY0_PREV = JOYK_BEG + 0*e_MaxJoyBtns + 4;
- JOY1_PREV = JOYK_BEG + 1*e_MaxJoyBtns + 4;
- JOY2_PREV = JOYK_BEG + 2*e_MaxJoyBtns + 4;
- JOY3_PREV = JOYK_BEG + 3*e_MaxJoyBtns + 4;
-
- JOY0_LEFT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
- JOY1_LEFT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
- JOY2_LEFT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
- JOY3_LEFT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
- JOY0_RIGHT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
- JOY1_RIGHT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
- JOY2_RIGHT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
- JOY3_RIGHT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
- JOY0_UP = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_UP;
- JOY1_UP = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_UP;
- JOY2_UP = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_UP;
- JOY3_UP = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_UP;
- JOY0_DOWN = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
- JOY1_DOWN = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
- JOY2_DOWN = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
- JOY3_DOWN = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
-
-function e_InitInput: Boolean;
-procedure e_ReleaseInput;
-procedure e_UnpressAllKeys;
-procedure e_KeyUpDown (key: Integer; down: Boolean);
-
-function e_KeyPressed (key: Integer): Boolean;
-function e_AnyKeyPressed: Boolean;
-function e_GetFirstKeyPressed: Integer;
-function e_HasJoysticks: Boolean;
-
-function e_JoyButtonToKey (id, btn: Integer): Integer;
-function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
-function e_JoyHatToKey (id, hat, dir: Integer): Integer;
-
-var
- e_JoystickAvailable: array [0..e_MaxJoys - 1] of Boolean;
- e_JoystickDeadzones: array [0..e_MaxJoys - 1] of Integer = (8192, 8192, 8192, 8192);
- e_KeyNames: array [0..e_MaxInputKeys] of String;
-
-implementation
-
-var
- InputBuffer: array [0..e_MaxInputKeys - 1] of Boolean;
-
-procedure e_UnpressAllKeys;
- var i: Integer;
-begin
- for i := 0 to High(InputBuffer) do
- InputBuffer[i] := False
-end;
-
-procedure e_KeyUpDown (key: Integer; down: Boolean);
-begin
- ASSERT(key >= 0);
- ASSERT(key < e_MaxInputKeys);
- if key > 0 then
- InputBuffer[key] := down
-end;
-
-procedure GenerateKeyNames;
- var i, j, k: Integer;
-begin
- // keyboard key names
- e_KeyNames[IK_0] := '0';
- e_KeyNames[IK_1] := '1';
- e_KeyNames[IK_2] := '2';
- e_KeyNames[IK_3] := '3';
- e_KeyNames[IK_4] := '4';
- e_KeyNames[IK_5] := '5';
- e_KeyNames[IK_6] := '6';
- e_KeyNames[IK_7] := '7';
- e_KeyNames[IK_8] := '8';
- e_KeyNames[IK_9] := '9';
-
- for i := IK_A to IK_Z do
- e_KeyNames[i] := '' + chr(ord('a') + (i - IK_a));
-
- e_KeyNames[IK_ESCAPE] := 'ESCAPE';
- e_KeyNames[IK_ENTER] := 'ENTER';
- e_KeyNames[IK_TAB] := 'TAB';
- e_KeyNames[IK_BACKSPACE] := 'BACKSPACE';
- e_KeyNames[IK_SPACE] := 'SPACE';
- e_KeyNames[IK_UP] := 'UP';
- e_KeyNames[IK_LEFT] := 'LEFT';
- e_KeyNames[IK_RIGHT] := 'RIGHT';
- e_KeyNames[IK_DOWN] := 'DOWN';
- e_KeyNames[IK_INSERT] := 'INSERT';
- e_KeyNames[IK_DELETE] := 'DELETE';
- e_KeyNames[IK_HOME] := 'HOME';
- e_KeyNames[IK_END] := 'END';
- e_KeyNames[IK_PAGEUP] := 'PGUP';
- e_KeyNames[IK_PAGEDN] := 'PGDOWN';
- e_KeyNames[IK_KPINSERT] := 'PAD0';
- e_KeyNames[IK_KPEND] := 'PAD1';
- e_KeyNames[IK_KPDOWN] := 'PAD2';
- e_KeyNames[IK_KPPAGEDN] := 'PAD3';
- e_KeyNames[IK_KPLEFT] := 'PAD4';
- e_KeyNames[IK_KP5] := 'PAD5';
- e_KeyNames[IK_KPRIGHT] := 'PAD6';
- e_KeyNames[IK_KPHOME] := 'PAD7';
- e_KeyNames[IK_KPUP] := 'PAD8';
- e_KeyNames[IK_KPPAGEUP] := 'PAD9';
- e_KeyNames[IK_NUMLOCK] := 'NUM';
- e_KeyNames[IK_KPDIVIDE] := 'PAD/';
- e_KeyNames[IK_KPMULTIPLE] := 'PAD*';
- e_KeyNames[IK_KPMINUS] := 'PAD-';
- e_KeyNames[IK_KPPLUS] := 'PAD+';
- e_KeyNames[IK_KPENTER] := 'PADENTER';
- e_KeyNames[IK_KPDOT] := 'PAD.';
- e_KeyNames[IK_CAPSLOCK] := 'CAPS';
- e_KeyNames[IK_BACKQUOTE] := 'BACKQUOTE';
- e_KeyNames[IK_F1] := 'F1';
- e_KeyNames[IK_F2] := 'F2';
- e_KeyNames[IK_F3] := 'F3';
- e_KeyNames[IK_F4] := 'F4';
- e_KeyNames[IK_F5] := 'F5';
- e_KeyNames[IK_F6] := 'F6';
- e_KeyNames[IK_F7] := 'F7';
- e_KeyNames[IK_F8] := 'F8';
- e_KeyNames[IK_F9] := 'F9';
- e_KeyNames[IK_F10] := 'F10';
- e_KeyNames[IK_F11] := 'F11';
- e_KeyNames[IK_F12] := 'F12';
- e_KeyNames[IK_SHIFT] := 'LSHIFT';
- e_KeyNames[IK_RSHIFT] := 'RSHIFT';
- e_KeyNames[IK_CTRL] := 'LCTRL';
- e_KeyNames[IK_RCTRL] := 'RCTRL';
- e_KeyNames[IK_ALT] := 'LALT';
- e_KeyNames[IK_RALT] := 'RALT';
- e_KeyNames[IK_WIN] := 'LWIN';
- e_KeyNames[IK_RWIN] := 'RWIN';
- e_KeyNames[IK_MENU] := 'MENU';
- e_KeyNames[IK_PRINTSCR] := 'PSCRN';
- e_KeyNames[IK_SCROLLLOCK] := 'SCROLL';
- e_KeyNames[IK_PAUSE] := 'PAUSE';
- e_KeyNames[IK_LBRACKET] := '[';
- e_KeyNames[IK_RBRACKET] := ']';
- e_KeyNames[IK_SEMICOLON] := ';';
- e_KeyNames[IK_QUOTE] := '''';
- e_KeyNames[IK_BACKSLASH] := '\';
- e_KeyNames[IK_SLASH] := '/';
- e_KeyNames[IK_COMMA] := ',';
- e_KeyNames[IK_DOT] := '.';
- e_KeyNames[IK_MINUS] := '-';
- e_KeyNames[IK_EQUALS] := '=';
-
- // joysticks
- for j := 0 to e_MaxJoys-1 do
- begin
- k := JOYK_BEG + j * e_MaxJoyBtns;
- // buttons
- for i := 0 to e_MaxJoyBtns-1 do
- e_KeyNames[k + i] := Format('JOY%dB%d', [j, i]);
- k := JOYA_BEG + j * e_MaxJoyAxes * 2;
- // axes
- for i := 0 to e_MaxJoyAxes-1 do
- begin
- e_KeyNames[k + i*2 ] := Format('JOY%dA%d+', [j, i]);
- e_KeyNames[k + i*2 + 1] := Format('JOY%dA%d-', [j, i]);
- end;
- k := JOYH_BEG + j * e_MaxJoyHats * 4;
- // hats
- for i := 0 to e_MaxJoyHats-1 do
- begin
- e_KeyNames[k + i*4 ] := Format('JOY%dD%dL', [j, i]);
- e_KeyNames[k + i*4 + 1] := Format('JOY%dD%dU', [j, i]);
- e_KeyNames[k + i*4 + 2] := Format('JOY%dD%dR', [j, i]);
- e_KeyNames[k + i*4 + 3] := Format('JOY%dD%dD', [j, i]);
- end;
- end;
-
- // vitrual keys
- for i := 0 to e_MaxVirtKeys-1 do
- e_KeyNames[VIRT_BEG + i] := 'VIRTUAL' + IntToStr(i);
-end;
-
-function e_HasJoysticks: Boolean;
- var i: Integer;
-begin
- i := 0;
- while (i < e_MaxJoys) and (e_JoystickAvailable[i] = False) do inc(i);
- result := i < e_MaxJoys
-end;
-
-function e_InitInput: Boolean;
- var i: Integer;
-begin
- for i := 0 to e_MaxJoys - 1 do
- e_JoystickAvailable[i] := False;
- GenerateKeyNames;
- result := True
-end;
-
-procedure e_ReleaseInput;
- var i: Integer;
-begin
- for i := 0 to e_MaxJoys - 1 do
- e_JoystickAvailable[i] := False
-end;
-
-function e_KeyPressed (key: Integer): Boolean;
-begin
- ASSERT(key >= 0);
- ASSERT(key < e_MaxInputKeys);
- result := InputBuffer[key]
-end;
-
-function e_AnyKeyPressed: Boolean;
-begin
- result := e_GetFirstKeyPressed <> IK_INVALID;
-end;
-
-function e_GetFirstKeyPressed: Integer;
- var i: Integer;
-begin
- i := 1;
- while (i < e_MaxInputKeys) and (InputBuffer[i] = False) do inc(i);
- if i < e_MaxInputKeys then
- result := i
- else
- result := IK_INVALID
-end;
-
-function e_JoyButtonToKey (id, btn: Integer): Integer;
-begin
- ASSERT(id >= 0);
- ASSERT(id < e_MaxJoys);
- ASSERT(btn >= 0);
- ASSERT(btn < e_MaxJoyBtns);
- result := JOYK_BEG + id*e_MaxJoyBtns + btn
-end;
-
-function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
-begin
- ASSERT(id >= 0);
- ASSERT(id < e_MaxJoys);
- ASSERT(ax >= 0);
- ASSERT(ax < e_MaxJoyAxes);
- ASSERT(dir in [AX_MINUS, AX_PLUS]);
- result := JOYA_BEG + id*e_MaxJoyAxes*2 + ax*2 + dir
-end;
-
-function e_JoyHatToKey (id, hat, dir: Integer): Integer;
-begin
- ASSERT(id >= 0);
- ASSERT(id < e_MaxJoys);
- ASSERT(hat >= 0);
- ASSERT(hat < e_MaxJoyHats);
- ASSERT(dir in [HAT_LEFT, HAT_UP, HAT_RIGHT, HAT_DOWN]);
- result := JOYH_BEG + id*e_MaxJoyHats*4 + hat*4 + dir
-end;
+{$IF DEFINED(USE_SYSSTUB) OR DEFINED(USE_SDL)}
+ {$I e_input_stub.inc}
+{$ELSEIF DEFINED(USE_SDL2)}
+ {$I e_input_sdl2.inc}
+{$ELSE}
+ {$ERROR e_input driver not implemented?}
+{$ENDIF}
end.
diff --git a/src/engine/e_input_sdl2.inc b/src/engine/e_input_sdl2.inc
--- /dev/null
@@ -0,0 +1,446 @@
+interface
+
+uses
+ SDL2, SysUtils;
+
+const
+ e_MaxKbdKeys = SDL_NUM_SCANCODES;
+ e_MaxJoys = 4;
+ e_MaxJoyBtns = 32;
+ e_MaxJoyAxes = 8;
+ e_MaxJoyHats = 8;
+ e_MaxVirtKeys = 48;
+
+ e_MaxJoyKeys = e_MaxJoyBtns + e_MaxJoyAxes*2 + e_MaxJoyHats*4;
+
+ e_MaxInputKeys = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
+ // $$$..$$$ - 321 Keyboard buttons/keys
+ // $$$..$$$ - 4*32 Joystick buttons
+ // $$$..$$$ - 8*2 Joystick axes (- and +)
+ // $$$..$$$ - 4*4 Joystick hats (L U R D)
+ // $$$..$$$ - 48 Virtual buttons/keys
+
+ KBRD_END = e_MaxKbdKeys;
+ JOYK_BEG = KBRD_END;
+ JOYK_END = JOYK_BEG + e_MaxJoyBtns*e_MaxJoys;
+ JOYA_BEG = JOYK_END;
+ JOYA_END = JOYA_BEG + e_MaxJoyAxes*2*e_MaxJoys;
+ JOYH_BEG = JOYA_END;
+ JOYH_END = JOYH_BEG + e_MaxJoyHats*4*e_MaxJoys;
+ VIRT_BEG = JOYH_END;
+ VIRT_END = VIRT_BEG + e_MaxVirtKeys;
+
+ // these are apparently used in g_gui and g_game and elsewhere
+ IK_INVALID = 0;
+ IK_ESCAPE = SDL_SCANCODE_ESCAPE;
+ IK_RETURN = SDL_SCANCODE_RETURN;
+ IK_KPRETURN= SDL_SCANCODE_KP_ENTER;
+ IK_ENTER = SDL_SCANCODE_RETURN;
+ IK_KPINSERT = SDL_SCANCODE_KP_0;
+ IK_UP = SDL_SCANCODE_UP;
+ IK_KPUP = SDL_SCANCODE_KP_8;
+ IK_DOWN = SDL_SCANCODE_DOWN;
+ IK_KPDOWN = SDL_SCANCODE_KP_2;
+ IK_LEFT = SDL_SCANCODE_LEFT;
+ IK_KPLEFT = SDL_SCANCODE_KP_4;
+ IK_RIGHT = SDL_SCANCODE_RIGHT;
+ IK_KPRIGHT = SDL_SCANCODE_KP_6;
+ IK_DELETE = SDL_SCANCODE_DELETE;
+ IK_HOME = SDL_SCANCODE_HOME;
+ IK_KPHOME = SDL_SCANCODE_KP_7;
+ IK_INSERT = SDL_SCANCODE_INSERT;
+ IK_SPACE = SDL_SCANCODE_SPACE;
+ IK_CONTROL = SDL_SCANCODE_LCTRL;
+ IK_SHIFT = SDL_SCANCODE_LSHIFT;
+ IK_ALT = SDL_SCANCODE_LALT;
+ IK_TAB = SDL_SCANCODE_TAB;
+ IK_PAGEUP = SDL_SCANCODE_PAGEUP;
+ IK_KPPAGEUP= SDL_SCANCODE_KP_9;
+ IK_PAGEDN = SDL_SCANCODE_PAGEDOWN;
+ IK_KPPAGEDN= SDL_SCANCODE_KP_3;
+ IK_KP5 = SDL_SCANCODE_KP_5;
+ IK_NUMLOCK = SDL_SCANCODE_NUMLOCKCLEAR;
+ IK_KPDIVIDE= SDL_SCANCODE_KP_DIVIDE;
+ IK_KPMULTIPLE= SDL_SCANCODE_KP_MULTIPLY;
+ IK_KPMINUS = SDL_SCANCODE_KP_MINUS;
+ IK_KPPLUS = SDL_SCANCODE_KP_PLUS;
+ IK_KPENTER = SDL_SCANCODE_KP_ENTER;
+ IK_KPDOT = SDL_SCANCODE_KP_PERIOD;
+ IK_CAPSLOCK= SDL_SCANCODE_CAPSLOCK;
+ IK_RSHIFT = SDL_SCANCODE_RSHIFT;
+ IK_CTRL = SDL_SCANCODE_LCTRL;
+ IK_RCTRL = SDL_SCANCODE_RCTRL;
+ IK_RALT = SDL_SCANCODE_RALT;
+ IK_WIN = SDL_SCANCODE_LGUI;
+ IK_RWIN = SDL_SCANCODE_RGUI;
+ IK_MENU = SDL_SCANCODE_MENU;
+ IK_PRINTSCR= SDL_SCANCODE_PRINTSCREEN;
+ IK_SCROLLLOCK= SDL_SCANCODE_SCROLLLOCK;
+ IK_LBRACKET= SDL_SCANCODE_LEFTBRACKET;
+ IK_RBRACKET= SDL_SCANCODE_RIGHTBRACKET;
+ IK_SEMICOLON= SDL_SCANCODE_SEMICOLON;
+ IK_QUOTE = SDL_SCANCODE_APOSTROPHE;
+ IK_BACKSLASH= SDL_SCANCODE_BACKSLASH;
+ IK_SLASH = SDL_SCANCODE_SLASH;
+ IK_COMMA = SDL_SCANCODE_COMMA;
+ IK_DOT = SDL_SCANCODE_PERIOD;
+ IK_EQUALS = SDL_SCANCODE_EQUALS;
+ IK_0 = SDL_SCANCODE_0;
+ IK_1 = SDL_SCANCODE_1;
+ IK_2 = SDL_SCANCODE_2;
+ IK_3 = SDL_SCANCODE_3;
+ IK_4 = SDL_SCANCODE_4;
+ IK_5 = SDL_SCANCODE_5;
+ IK_6 = SDL_SCANCODE_6;
+ IK_7 = SDL_SCANCODE_7;
+ IK_8 = SDL_SCANCODE_8;
+ IK_9 = SDL_SCANCODE_9;
+ IK_F1 = SDL_SCANCODE_F1;
+ IK_F2 = SDL_SCANCODE_F2;
+ IK_F3 = SDL_SCANCODE_F3;
+ IK_F4 = SDL_SCANCODE_F4;
+ IK_F5 = SDL_SCANCODE_F5;
+ IK_F6 = SDL_SCANCODE_F6;
+ IK_F7 = SDL_SCANCODE_F7;
+ IK_F8 = SDL_SCANCODE_F8;
+ IK_F9 = SDL_SCANCODE_F9;
+ IK_F10 = SDL_SCANCODE_F10;
+ IK_F11 = SDL_SCANCODE_F11;
+ IK_F12 = SDL_SCANCODE_F12;
+ IK_END = SDL_SCANCODE_END;
+ IK_KPEND = SDL_SCANCODE_KP_1;
+ IK_BACKSPACE = SDL_SCANCODE_BACKSPACE;
+ IK_BACKQUOTE = SDL_SCANCODE_GRAVE;
+ IK_GRAVE = SDL_SCANCODE_GRAVE;
+ IK_PAUSE = SDL_SCANCODE_PAUSE;
+ IK_Y = SDL_SCANCODE_Y;
+ IK_N = SDL_SCANCODE_N;
+ IK_W = SDL_SCANCODE_W;
+ IK_A = SDL_SCANCODE_A;
+ IK_S = SDL_SCANCODE_S;
+ IK_D = SDL_SCANCODE_D;
+ IK_Q = SDL_SCANCODE_Q;
+ IK_E = SDL_SCANCODE_E;
+ IK_H = SDL_SCANCODE_H;
+ IK_J = SDL_SCANCODE_J;
+ IK_T = SDL_SCANCODE_T;
+ IK_Z = SDL_SCANCODE_Z;
+ IK_MINUS = SDL_SCANCODE_MINUS;
+ // TODO: think of something better than this shit
+ IK_LASTKEY = SDL_NUM_SCANCODES-1;
+
+ VK_FIRSTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys;
+ VK_LEFT = VK_FIRSTKEY + 0;
+ VK_RIGHT = VK_FIRSTKEY + 1;
+ VK_UP = VK_FIRSTKEY + 2;
+ VK_DOWN = VK_FIRSTKEY + 3;
+ VK_FIRE = VK_FIRSTKEY + 4;
+ VK_OPEN = VK_FIRSTKEY + 5;
+ VK_JUMP = VK_FIRSTKEY + 6;
+ VK_CHAT = VK_FIRSTKEY + 7;
+ VK_ESCAPE = VK_FIRSTKEY + 8;
+ VK_0 = VK_FIRSTKEY + 9;
+ VK_1 = VK_FIRSTKEY + 10;
+ VK_2 = VK_FIRSTKEY + 11;
+ VK_3 = VK_FIRSTKEY + 12;
+ VK_4 = VK_FIRSTKEY + 13;
+ VK_5 = VK_FIRSTKEY + 14;
+ VK_6 = VK_FIRSTKEY + 15;
+ VK_7 = VK_FIRSTKEY + 16;
+ VK_8 = VK_FIRSTKEY + 17;
+ VK_9 = VK_FIRSTKEY + 18;
+ VK_A = VK_FIRSTKEY + 19;
+ VK_B = VK_FIRSTKEY + 20;
+ VK_C = VK_FIRSTKEY + 21;
+ VK_D = VK_FIRSTKEY + 22;
+ VK_E = VK_FIRSTKEY + 23;
+ VK_F = VK_FIRSTKEY + 24;
+ VK_CONSOLE = VK_FIRSTKEY + 25;
+ VK_STATUS = VK_FIRSTKEY + 26;
+ VK_TEAM = VK_FIRSTKEY + 27;
+ VK_PREV = VK_FIRSTKEY + 28;
+ VK_NEXT = VK_FIRSTKEY + 29;
+ VK_STRAFE = VK_FIRSTKEY + 30;
+ VK_LSTRAFE = VK_FIRSTKEY + 31;
+ VK_RSTRAFE = VK_FIRSTKEY + 32;
+ VK_PRINTSCR = VK_FIRSTKEY + 33;
+ VK_SHOWKBD = VK_FIRSTKEY + 34;
+ VK_HIDEKBD = VK_FIRSTKEY + 35;
+ VK_LASTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
+
+ AX_MINUS = 0;
+ AX_PLUS = 1;
+ HAT_LEFT = 0;
+ HAT_UP = 1;
+ HAT_RIGHT = 2;
+ HAT_DOWN = 3;
+
+ JOY0_ATTACK = JOYK_BEG + 0*e_MaxJoyBtns + 0;
+ JOY1_ATTACK = JOYK_BEG + 1*e_MaxJoyBtns + 0;
+ JOY2_ATTACK = JOYK_BEG + 2*e_MaxJoyBtns + 0;
+ JOY3_ATTACK = JOYK_BEG + 3*e_MaxJoyBtns + 0;
+ JOY0_NEXT = JOYK_BEG + 0*e_MaxJoyBtns + 1;
+ JOY1_NEXT = JOYK_BEG + 1*e_MaxJoyBtns + 1;
+ JOY2_NEXT = JOYK_BEG + 2*e_MaxJoyBtns + 1;
+ JOY3_NEXT = JOYK_BEG + 3*e_MaxJoyBtns + 1;
+ JOY0_JUMP = JOYK_BEG + 0*e_MaxJoyBtns + 2;
+ JOY1_JUMP = JOYK_BEG + 1*e_MaxJoyBtns + 2;
+ JOY2_JUMP = JOYK_BEG + 2*e_MaxJoyBtns + 2;
+ JOY3_JUMP = JOYK_BEG + 3*e_MaxJoyBtns + 2;
+ JOY0_ACTIVATE = JOYK_BEG + 0*e_MaxJoyBtns + 3;
+ JOY1_ACTIVATE = JOYK_BEG + 1*e_MaxJoyBtns + 3;
+ JOY2_ACTIVATE = JOYK_BEG + 2*e_MaxJoyBtns + 3;
+ JOY3_ACTIVATE = JOYK_BEG + 3*e_MaxJoyBtns + 3;
+ JOY0_PREV = JOYK_BEG + 0*e_MaxJoyBtns + 4;
+ JOY1_PREV = JOYK_BEG + 1*e_MaxJoyBtns + 4;
+ JOY2_PREV = JOYK_BEG + 2*e_MaxJoyBtns + 4;
+ JOY3_PREV = JOYK_BEG + 3*e_MaxJoyBtns + 4;
+
+ JOY0_LEFT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY1_LEFT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY2_LEFT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY3_LEFT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY0_RIGHT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY1_RIGHT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY2_RIGHT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY3_RIGHT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY0_UP = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY1_UP = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY2_UP = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY3_UP = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY0_DOWN = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY1_DOWN = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY2_DOWN = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY3_DOWN = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+
+function e_InitInput: Boolean;
+procedure e_ReleaseInput;
+procedure e_UnpressAllKeys;
+procedure e_KeyUpDown (key: Integer; down: Boolean);
+
+function e_KeyPressed (key: Integer): Boolean;
+function e_AnyKeyPressed: Boolean;
+function e_GetFirstKeyPressed: Integer;
+function e_HasJoysticks: Boolean;
+
+function e_JoyButtonToKey (id, btn: Integer): Integer;
+function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
+function e_JoyHatToKey (id, hat, dir: Integer): Integer;
+
+var
+ e_JoystickAvailable: array [0..e_MaxJoys - 1] of Boolean;
+ e_JoystickDeadzones: array [0..e_MaxJoys - 1] of Integer = (8192, 8192, 8192, 8192);
+ e_KeyNames: array [0..e_MaxInputKeys] of String;
+
+implementation
+
+var
+ InputBuffer: array [0..e_MaxInputKeys - 1] of Boolean;
+
+procedure e_UnpressAllKeys;
+ var i: Integer;
+begin
+ for i := 0 to High(InputBuffer) do
+ InputBuffer[i] := False
+end;
+
+procedure e_KeyUpDown (key: Integer; down: Boolean);
+begin
+ ASSERT(key >= 0);
+ ASSERT(key < e_MaxInputKeys);
+ if key > 0 then
+ InputBuffer[key] := down
+end;
+
+procedure GenerateKeyNames;
+ var i, j, k: Integer;
+begin
+ // keyboard key names
+ e_KeyNames[IK_0] := '0';
+ e_KeyNames[IK_1] := '1';
+ e_KeyNames[IK_2] := '2';
+ e_KeyNames[IK_3] := '3';
+ e_KeyNames[IK_4] := '4';
+ e_KeyNames[IK_5] := '5';
+ e_KeyNames[IK_6] := '6';
+ e_KeyNames[IK_7] := '7';
+ e_KeyNames[IK_8] := '8';
+ e_KeyNames[IK_9] := '9';
+
+ for i := IK_A to IK_Z do
+ e_KeyNames[i] := '' + chr(ord('a') + (i - IK_a));
+
+ e_KeyNames[IK_ESCAPE] := 'ESCAPE';
+ e_KeyNames[IK_ENTER] := 'ENTER';
+ e_KeyNames[IK_TAB] := 'TAB';
+ e_KeyNames[IK_BACKSPACE] := 'BACKSPACE';
+ e_KeyNames[IK_SPACE] := 'SPACE';
+ e_KeyNames[IK_UP] := 'UP';
+ e_KeyNames[IK_LEFT] := 'LEFT';
+ e_KeyNames[IK_RIGHT] := 'RIGHT';
+ e_KeyNames[IK_DOWN] := 'DOWN';
+ e_KeyNames[IK_INSERT] := 'INSERT';
+ e_KeyNames[IK_DELETE] := 'DELETE';
+ e_KeyNames[IK_HOME] := 'HOME';
+ e_KeyNames[IK_END] := 'END';
+ e_KeyNames[IK_PAGEUP] := 'PGUP';
+ e_KeyNames[IK_PAGEDN] := 'PGDOWN';
+ e_KeyNames[IK_KPINSERT] := 'PAD0';
+ e_KeyNames[IK_KPEND] := 'PAD1';
+ e_KeyNames[IK_KPDOWN] := 'PAD2';
+ e_KeyNames[IK_KPPAGEDN] := 'PAD3';
+ e_KeyNames[IK_KPLEFT] := 'PAD4';
+ e_KeyNames[IK_KP5] := 'PAD5';
+ e_KeyNames[IK_KPRIGHT] := 'PAD6';
+ e_KeyNames[IK_KPHOME] := 'PAD7';
+ e_KeyNames[IK_KPUP] := 'PAD8';
+ e_KeyNames[IK_KPPAGEUP] := 'PAD9';
+ e_KeyNames[IK_NUMLOCK] := 'NUM';
+ e_KeyNames[IK_KPDIVIDE] := 'PAD/';
+ e_KeyNames[IK_KPMULTIPLE] := 'PAD*';
+ e_KeyNames[IK_KPMINUS] := 'PAD-';
+ e_KeyNames[IK_KPPLUS] := 'PAD+';
+ e_KeyNames[IK_KPENTER] := 'PADENTER';
+ e_KeyNames[IK_KPDOT] := 'PAD.';
+ e_KeyNames[IK_CAPSLOCK] := 'CAPS';
+ e_KeyNames[IK_BACKQUOTE] := 'BACKQUOTE';
+ e_KeyNames[IK_F1] := 'F1';
+ e_KeyNames[IK_F2] := 'F2';
+ e_KeyNames[IK_F3] := 'F3';
+ e_KeyNames[IK_F4] := 'F4';
+ e_KeyNames[IK_F5] := 'F5';
+ e_KeyNames[IK_F6] := 'F6';
+ e_KeyNames[IK_F7] := 'F7';
+ e_KeyNames[IK_F8] := 'F8';
+ e_KeyNames[IK_F9] := 'F9';
+ e_KeyNames[IK_F10] := 'F10';
+ e_KeyNames[IK_F11] := 'F11';
+ e_KeyNames[IK_F12] := 'F12';
+ e_KeyNames[IK_SHIFT] := 'LSHIFT';
+ e_KeyNames[IK_RSHIFT] := 'RSHIFT';
+ e_KeyNames[IK_CTRL] := 'LCTRL';
+ e_KeyNames[IK_RCTRL] := 'RCTRL';
+ e_KeyNames[IK_ALT] := 'LALT';
+ e_KeyNames[IK_RALT] := 'RALT';
+ e_KeyNames[IK_WIN] := 'LWIN';
+ e_KeyNames[IK_RWIN] := 'RWIN';
+ e_KeyNames[IK_MENU] := 'MENU';
+ e_KeyNames[IK_PRINTSCR] := 'PSCRN';
+ e_KeyNames[IK_SCROLLLOCK] := 'SCROLL';
+ e_KeyNames[IK_PAUSE] := 'PAUSE';
+ e_KeyNames[IK_LBRACKET] := '[';
+ e_KeyNames[IK_RBRACKET] := ']';
+ e_KeyNames[IK_SEMICOLON] := ';';
+ e_KeyNames[IK_QUOTE] := '''';
+ e_KeyNames[IK_BACKSLASH] := '\';
+ e_KeyNames[IK_SLASH] := '/';
+ e_KeyNames[IK_COMMA] := ',';
+ e_KeyNames[IK_DOT] := '.';
+ e_KeyNames[IK_MINUS] := '-';
+ e_KeyNames[IK_EQUALS] := '=';
+
+ // joysticks
+ for j := 0 to e_MaxJoys-1 do
+ begin
+ k := JOYK_BEG + j * e_MaxJoyBtns;
+ // buttons
+ for i := 0 to e_MaxJoyBtns-1 do
+ e_KeyNames[k + i] := Format('JOY%dB%d', [j, i]);
+ k := JOYA_BEG + j * e_MaxJoyAxes * 2;
+ // axes
+ for i := 0 to e_MaxJoyAxes-1 do
+ begin
+ e_KeyNames[k + i*2 ] := Format('JOY%dA%d+', [j, i]);
+ e_KeyNames[k + i*2 + 1] := Format('JOY%dA%d-', [j, i]);
+ end;
+ k := JOYH_BEG + j * e_MaxJoyHats * 4;
+ // hats
+ for i := 0 to e_MaxJoyHats-1 do
+ begin
+ e_KeyNames[k + i*4 ] := Format('JOY%dD%dL', [j, i]);
+ e_KeyNames[k + i*4 + 1] := Format('JOY%dD%dU', [j, i]);
+ e_KeyNames[k + i*4 + 2] := Format('JOY%dD%dR', [j, i]);
+ e_KeyNames[k + i*4 + 3] := Format('JOY%dD%dD', [j, i]);
+ end;
+ end;
+
+ // vitrual keys
+ for i := 0 to e_MaxVirtKeys-1 do
+ e_KeyNames[VIRT_BEG + i] := 'VIRTUAL' + IntToStr(i);
+end;
+
+function e_HasJoysticks: Boolean;
+ var i: Integer;
+begin
+ i := 0;
+ while (i < e_MaxJoys) and (e_JoystickAvailable[i] = False) do inc(i);
+ result := i < e_MaxJoys
+end;
+
+function e_InitInput: Boolean;
+ var i: Integer;
+begin
+ for i := 0 to e_MaxJoys - 1 do
+ e_JoystickAvailable[i] := False;
+ GenerateKeyNames;
+ result := True
+end;
+
+procedure e_ReleaseInput;
+ var i: Integer;
+begin
+ for i := 0 to e_MaxJoys - 1 do
+ e_JoystickAvailable[i] := False
+end;
+
+function e_KeyPressed (key: Integer): Boolean;
+begin
+ ASSERT(key >= 0);
+ ASSERT(key < e_MaxInputKeys);
+ result := InputBuffer[key]
+end;
+
+function e_AnyKeyPressed: Boolean;
+begin
+ result := e_GetFirstKeyPressed <> IK_INVALID;
+end;
+
+function e_GetFirstKeyPressed: Integer;
+ var i: Integer;
+begin
+ i := 1;
+ while (i < e_MaxInputKeys) and (InputBuffer[i] = False) do inc(i);
+ if i < e_MaxInputKeys then
+ result := i
+ else
+ result := IK_INVALID
+end;
+
+function e_JoyButtonToKey (id, btn: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(btn >= 0);
+ ASSERT(btn < e_MaxJoyBtns);
+ result := JOYK_BEG + id*e_MaxJoyBtns + btn
+end;
+
+function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(ax >= 0);
+ ASSERT(ax < e_MaxJoyAxes);
+ ASSERT(dir in [AX_MINUS, AX_PLUS]);
+ result := JOYA_BEG + id*e_MaxJoyAxes*2 + ax*2 + dir
+end;
+
+function e_JoyHatToKey (id, hat, dir: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(hat >= 0);
+ ASSERT(hat < e_MaxJoyHats);
+ ASSERT(dir in [HAT_LEFT, HAT_UP, HAT_RIGHT, HAT_DOWN]);
+ result := JOYH_BEG + id*e_MaxJoyHats*4 + hat*4 + dir
+end;
diff --git a/src/engine/e_input_stub.inc b/src/engine/e_input_stub.inc
--- /dev/null
@@ -0,0 +1,458 @@
+interface
+
+ uses SysUtils;
+
+ const
+ e_MaxKbdKeys = 256;
+ e_MaxJoys = 4;
+ e_MaxJoyBtns = 32;
+ e_MaxJoyAxes = 8;
+ e_MaxJoyHats = 8;
+ e_MaxVirtKeys = 48;
+
+ e_MaxJoyKeys = e_MaxJoyBtns + e_MaxJoyAxes*2 + e_MaxJoyHats*4;
+
+ e_MaxInputKeys = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
+ // $$$..$$$ - 321 Keyboard buttons/keys
+ // $$$..$$$ - 4*32 Joystick buttons
+ // $$$..$$$ - 8*2 Joystick axes (- and +)
+ // $$$..$$$ - 4*4 Joystick hats (L U R D)
+ // $$$..$$$ - 48 Virtual buttons/keys
+
+ KBRD_END = e_MaxKbdKeys;
+ JOYK_BEG = KBRD_END;
+ JOYK_END = JOYK_BEG + e_MaxJoyBtns*e_MaxJoys;
+ JOYA_BEG = JOYK_END;
+ JOYA_END = JOYA_BEG + e_MaxJoyAxes*2*e_MaxJoys;
+ JOYH_BEG = JOYA_END;
+ JOYH_END = JOYH_BEG + e_MaxJoyHats*4*e_MaxJoys;
+ VIRT_BEG = JOYH_END;
+ VIRT_END = VIRT_BEG + e_MaxVirtKeys;
+
+ // these are apparently used in g_gui and g_game and elsewhere
+ IK_INVALID = 0;
+ IK_ESCAPE = 1;
+ IK_RETURN = 2;
+ IK_KPRETURN= 3;
+ IK_ENTER = IK_RETURN;
+ IK_KPINSERT = 5;
+ IK_UP = 6;
+ IK_KPUP = 7;
+ IK_DOWN = 8;
+ IK_KPDOWN = 9;
+ IK_LEFT = 10;
+ IK_KPLEFT = 11;
+ IK_RIGHT = 12;
+ IK_KPRIGHT = 13;
+ IK_DELETE = 14;
+ IK_HOME = 15;
+ IK_KPHOME = 16;
+ IK_INSERT = 17;
+ IK_SPACE = 18;
+ IK_SHIFT = 20;
+ IK_ALT = 21;
+ IK_TAB = 22;
+ IK_PAGEUP = 23;
+ IK_KPPAGEUP= 24;
+ IK_PAGEDN = 25;
+ IK_KPPAGEDN= 26;
+ IK_KP5 = 27;
+ IK_NUMLOCK = 28;
+ IK_KPDIVIDE= 29;
+ IK_KPMULTIPLE= 30;
+ IK_KPMINUS = 31;
+ IK_KPPLUS = 32;
+ IK_KPENTER = IK_KPRETURN;
+ IK_KPDOT = 34;
+ IK_CAPSLOCK= 35;
+ IK_RSHIFT = 36;
+ IK_CTRL = 37;
+ IK_RCTRL = 38;
+ IK_RALT = 39;
+ IK_WIN = 40;
+ IK_RWIN = 41;
+ IK_MENU = 42;
+ IK_PRINTSCR= 43;
+ IK_SCROLLLOCK= 44;
+ IK_LBRACKET= 45;
+ IK_RBRACKET= 46;
+ IK_SEMICOLON= 47;
+ IK_QUOTE = 48;
+ IK_BACKSLASH= 49;
+ IK_SLASH = 50;
+ IK_COMMA = 51;
+ IK_DOT = 52;
+ IK_EQUALS = 53;
+ IK_0 = 54;
+ IK_1 = 55;
+ IK_2 = 56;
+ IK_3 = 57;
+ IK_4 = 58;
+ IK_5 = 59;
+ IK_6 = 60;
+ IK_7 = 61;
+ IK_8 = 62;
+ IK_9 = 63;
+ IK_F1 = 64;
+ IK_F2 = 65;
+ IK_F3 = 66;
+ IK_F4 = 67;
+ IK_F5 = 68;
+ IK_F6 = 69;
+ IK_F7 = 70;
+ IK_F8 = 71;
+ IK_F9 = 72;
+ IK_F10 = 73;
+ IK_F11 = 74;
+ IK_F12 = 75;
+ IK_END = 76;
+ IK_KPEND = 77;
+ IK_BACKSPACE = 78;
+ IK_BACKQUOTE = 79;
+ IK_GRAVE = IK_BACKQUOTE;
+ IK_PAUSE = 81;
+ IK_A = 82;
+ IK_B = 83;
+ IK_C = 84;
+ IK_D = 85;
+ IK_E = 86;
+ IK_F = 87;
+ IK_G = 88;
+ IK_H = 89;
+ IK_I = 90;
+ IK_J = 91;
+ IK_K = 92;
+ IK_L = 93;
+ IK_M = 94;
+ IK_N = 95;
+ IK_O = 96;
+ IK_P = 97;
+ IK_Q = 98;
+ IK_R = 99;
+ IK_S = 100;
+ IK_T = 101;
+ IK_U = 102;
+ IK_V = 103;
+ IK_W = 104;
+ IK_X = 105;
+ IK_Y = 106;
+ IK_Z = 107;
+ IK_MINUS = 108;
+ // TODO: think of something better than this shit
+ IK_LASTKEY = e_MaxKbdKeys-1;
+
+ VK_FIRSTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys;
+ VK_LEFT = VK_FIRSTKEY + 0;
+ VK_RIGHT = VK_FIRSTKEY + 1;
+ VK_UP = VK_FIRSTKEY + 2;
+ VK_DOWN = VK_FIRSTKEY + 3;
+ VK_FIRE = VK_FIRSTKEY + 4;
+ VK_OPEN = VK_FIRSTKEY + 5;
+ VK_JUMP = VK_FIRSTKEY + 6;
+ VK_CHAT = VK_FIRSTKEY + 7;
+ VK_ESCAPE = VK_FIRSTKEY + 8;
+ VK_0 = VK_FIRSTKEY + 9;
+ VK_1 = VK_FIRSTKEY + 10;
+ VK_2 = VK_FIRSTKEY + 11;
+ VK_3 = VK_FIRSTKEY + 12;
+ VK_4 = VK_FIRSTKEY + 13;
+ VK_5 = VK_FIRSTKEY + 14;
+ VK_6 = VK_FIRSTKEY + 15;
+ VK_7 = VK_FIRSTKEY + 16;
+ VK_8 = VK_FIRSTKEY + 17;
+ VK_9 = VK_FIRSTKEY + 18;
+ VK_A = VK_FIRSTKEY + 19;
+ VK_B = VK_FIRSTKEY + 20;
+ VK_C = VK_FIRSTKEY + 21;
+ VK_D = VK_FIRSTKEY + 22;
+ VK_E = VK_FIRSTKEY + 23;
+ VK_F = VK_FIRSTKEY + 24;
+ VK_CONSOLE = VK_FIRSTKEY + 25;
+ VK_STATUS = VK_FIRSTKEY + 26;
+ VK_TEAM = VK_FIRSTKEY + 27;
+ VK_PREV = VK_FIRSTKEY + 28;
+ VK_NEXT = VK_FIRSTKEY + 29;
+ VK_STRAFE = VK_FIRSTKEY + 30;
+ VK_LSTRAFE = VK_FIRSTKEY + 31;
+ VK_RSTRAFE = VK_FIRSTKEY + 32;
+ VK_PRINTSCR = VK_FIRSTKEY + 33;
+ VK_SHOWKBD = VK_FIRSTKEY + 34;
+ VK_HIDEKBD = VK_FIRSTKEY + 35;
+ VK_LASTKEY = e_MaxKbdKeys + e_MaxJoys*e_MaxJoyKeys + e_MaxVirtKeys - 1;
+
+ AX_MINUS = 0;
+ AX_PLUS = 1;
+ HAT_LEFT = 0;
+ HAT_UP = 1;
+ HAT_RIGHT = 2;
+ HAT_DOWN = 3;
+
+ JOY0_ATTACK = JOYK_BEG + 0*e_MaxJoyBtns + 0;
+ JOY1_ATTACK = JOYK_BEG + 1*e_MaxJoyBtns + 0;
+ JOY2_ATTACK = JOYK_BEG + 2*e_MaxJoyBtns + 0;
+ JOY3_ATTACK = JOYK_BEG + 3*e_MaxJoyBtns + 0;
+ JOY0_NEXT = JOYK_BEG + 0*e_MaxJoyBtns + 1;
+ JOY1_NEXT = JOYK_BEG + 1*e_MaxJoyBtns + 1;
+ JOY2_NEXT = JOYK_BEG + 2*e_MaxJoyBtns + 1;
+ JOY3_NEXT = JOYK_BEG + 3*e_MaxJoyBtns + 1;
+ JOY0_JUMP = JOYK_BEG + 0*e_MaxJoyBtns + 2;
+ JOY1_JUMP = JOYK_BEG + 1*e_MaxJoyBtns + 2;
+ JOY2_JUMP = JOYK_BEG + 2*e_MaxJoyBtns + 2;
+ JOY3_JUMP = JOYK_BEG + 3*e_MaxJoyBtns + 2;
+ JOY0_ACTIVATE = JOYK_BEG + 0*e_MaxJoyBtns + 3;
+ JOY1_ACTIVATE = JOYK_BEG + 1*e_MaxJoyBtns + 3;
+ JOY2_ACTIVATE = JOYK_BEG + 2*e_MaxJoyBtns + 3;
+ JOY3_ACTIVATE = JOYK_BEG + 3*e_MaxJoyBtns + 3;
+ JOY0_PREV = JOYK_BEG + 0*e_MaxJoyBtns + 4;
+ JOY1_PREV = JOYK_BEG + 1*e_MaxJoyBtns + 4;
+ JOY2_PREV = JOYK_BEG + 2*e_MaxJoyBtns + 4;
+ JOY3_PREV = JOYK_BEG + 3*e_MaxJoyBtns + 4;
+
+ JOY0_LEFT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY1_LEFT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY2_LEFT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY3_LEFT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_LEFT;
+ JOY0_RIGHT = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY1_RIGHT = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY2_RIGHT = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY3_RIGHT = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_RIGHT;
+ JOY0_UP = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY1_UP = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY2_UP = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY3_UP = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_UP;
+ JOY0_DOWN = JOYH_BEG + 0*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY1_DOWN = JOYH_BEG + 1*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY2_DOWN = JOYH_BEG + 2*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+ JOY3_DOWN = JOYH_BEG + 3*e_MaxJoyHats*4 + 0*4 + HAT_DOWN;
+
+function e_InitInput: Boolean;
+procedure e_ReleaseInput;
+procedure e_UnpressAllKeys;
+procedure e_KeyUpDown (key: Integer; down: Boolean);
+
+function e_KeyPressed (key: Integer): Boolean;
+function e_AnyKeyPressed: Boolean;
+function e_GetFirstKeyPressed: Integer;
+function e_HasJoysticks: Boolean;
+
+function e_JoyButtonToKey (id, btn: Integer): Integer;
+function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
+function e_JoyHatToKey (id, hat, dir: Integer): Integer;
+
+var
+ e_JoystickAvailable: array [0..e_MaxJoys - 1] of Boolean;
+ e_JoystickDeadzones: array [0..e_MaxJoys - 1] of Integer = (8192, 8192, 8192, 8192);
+ e_KeyNames: array [0..e_MaxInputKeys] of String;
+
+implementation
+
+var
+ InputBuffer: array [0..e_MaxInputKeys - 1] of Boolean;
+
+procedure e_UnpressAllKeys;
+ var i: Integer;
+begin
+ for i := 0 to High(InputBuffer) do
+ InputBuffer[i] := False
+end;
+
+procedure e_KeyUpDown (key: Integer; down: Boolean);
+begin
+ ASSERT(key >= 0);
+ ASSERT(key < e_MaxInputKeys);
+ if key > 0 then
+ InputBuffer[key] := down
+end;
+
+procedure GenerateKeyNames;
+ var i, j, k: Integer;
+begin
+ // keyboard key names
+ e_KeyNames[IK_0] := '0';
+ e_KeyNames[IK_1] := '1';
+ e_KeyNames[IK_2] := '2';
+ e_KeyNames[IK_3] := '3';
+ e_KeyNames[IK_4] := '4';
+ e_KeyNames[IK_5] := '5';
+ e_KeyNames[IK_6] := '6';
+ e_KeyNames[IK_7] := '7';
+ e_KeyNames[IK_8] := '8';
+ e_KeyNames[IK_9] := '9';
+
+ for i := IK_A to IK_Z do
+ e_KeyNames[i] := '' + chr(ord('a') + (i - IK_a));
+
+ e_KeyNames[IK_ESCAPE] := 'ESCAPE';
+ e_KeyNames[IK_ENTER] := 'ENTER';
+ e_KeyNames[IK_TAB] := 'TAB';
+ e_KeyNames[IK_BACKSPACE] := 'BACKSPACE';
+ e_KeyNames[IK_SPACE] := 'SPACE';
+ e_KeyNames[IK_UP] := 'UP';
+ e_KeyNames[IK_LEFT] := 'LEFT';
+ e_KeyNames[IK_RIGHT] := 'RIGHT';
+ e_KeyNames[IK_DOWN] := 'DOWN';
+ e_KeyNames[IK_INSERT] := 'INSERT';
+ e_KeyNames[IK_DELETE] := 'DELETE';
+ e_KeyNames[IK_HOME] := 'HOME';
+ e_KeyNames[IK_END] := 'END';
+ e_KeyNames[IK_PAGEUP] := 'PGUP';
+ e_KeyNames[IK_PAGEDN] := 'PGDOWN';
+ e_KeyNames[IK_KPINSERT] := 'PAD0';
+ e_KeyNames[IK_KPEND] := 'PAD1';
+ e_KeyNames[IK_KPDOWN] := 'PAD2';
+ e_KeyNames[IK_KPPAGEDN] := 'PAD3';
+ e_KeyNames[IK_KPLEFT] := 'PAD4';
+ e_KeyNames[IK_KP5] := 'PAD5';
+ e_KeyNames[IK_KPRIGHT] := 'PAD6';
+ e_KeyNames[IK_KPHOME] := 'PAD7';
+ e_KeyNames[IK_KPUP] := 'PAD8';
+ e_KeyNames[IK_KPPAGEUP] := 'PAD9';
+ e_KeyNames[IK_NUMLOCK] := 'NUM';
+ e_KeyNames[IK_KPDIVIDE] := 'PAD/';
+ e_KeyNames[IK_KPMULTIPLE] := 'PAD*';
+ e_KeyNames[IK_KPMINUS] := 'PAD-';
+ e_KeyNames[IK_KPPLUS] := 'PAD+';
+ e_KeyNames[IK_KPENTER] := 'PADENTER';
+ e_KeyNames[IK_KPDOT] := 'PAD.';
+ e_KeyNames[IK_CAPSLOCK] := 'CAPS';
+ e_KeyNames[IK_BACKQUOTE] := 'BACKQUOTE';
+ e_KeyNames[IK_F1] := 'F1';
+ e_KeyNames[IK_F2] := 'F2';
+ e_KeyNames[IK_F3] := 'F3';
+ e_KeyNames[IK_F4] := 'F4';
+ e_KeyNames[IK_F5] := 'F5';
+ e_KeyNames[IK_F6] := 'F6';
+ e_KeyNames[IK_F7] := 'F7';
+ e_KeyNames[IK_F8] := 'F8';
+ e_KeyNames[IK_F9] := 'F9';
+ e_KeyNames[IK_F10] := 'F10';
+ e_KeyNames[IK_F11] := 'F11';
+ e_KeyNames[IK_F12] := 'F12';
+ e_KeyNames[IK_SHIFT] := 'LSHIFT';
+ e_KeyNames[IK_RSHIFT] := 'RSHIFT';
+ e_KeyNames[IK_CTRL] := 'LCTRL';
+ e_KeyNames[IK_RCTRL] := 'RCTRL';
+ e_KeyNames[IK_ALT] := 'LALT';
+ e_KeyNames[IK_RALT] := 'RALT';
+ e_KeyNames[IK_WIN] := 'LWIN';
+ e_KeyNames[IK_RWIN] := 'RWIN';
+ e_KeyNames[IK_MENU] := 'MENU';
+ e_KeyNames[IK_PRINTSCR] := 'PSCRN';
+ e_KeyNames[IK_SCROLLLOCK] := 'SCROLL';
+ e_KeyNames[IK_PAUSE] := 'PAUSE';
+ e_KeyNames[IK_LBRACKET] := '[';
+ e_KeyNames[IK_RBRACKET] := ']';
+ e_KeyNames[IK_SEMICOLON] := ';';
+ e_KeyNames[IK_QUOTE] := '''';
+ e_KeyNames[IK_BACKSLASH] := '\';
+ e_KeyNames[IK_SLASH] := '/';
+ e_KeyNames[IK_COMMA] := ',';
+ e_KeyNames[IK_DOT] := '.';
+ e_KeyNames[IK_MINUS] := '-';
+ e_KeyNames[IK_EQUALS] := '=';
+
+ // joysticks
+ for j := 0 to e_MaxJoys-1 do
+ begin
+ k := JOYK_BEG + j * e_MaxJoyBtns;
+ // buttons
+ for i := 0 to e_MaxJoyBtns-1 do
+ e_KeyNames[k + i] := Format('JOY%dB%d', [j, i]);
+ k := JOYA_BEG + j * e_MaxJoyAxes * 2;
+ // axes
+ for i := 0 to e_MaxJoyAxes-1 do
+ begin
+ e_KeyNames[k + i*2 ] := Format('JOY%dA%d+', [j, i]);
+ e_KeyNames[k + i*2 + 1] := Format('JOY%dA%d-', [j, i]);
+ end;
+ k := JOYH_BEG + j * e_MaxJoyHats * 4;
+ // hats
+ for i := 0 to e_MaxJoyHats-1 do
+ begin
+ e_KeyNames[k + i*4 ] := Format('JOY%dD%dL', [j, i]);
+ e_KeyNames[k + i*4 + 1] := Format('JOY%dD%dU', [j, i]);
+ e_KeyNames[k + i*4 + 2] := Format('JOY%dD%dR', [j, i]);
+ e_KeyNames[k + i*4 + 3] := Format('JOY%dD%dD', [j, i]);
+ end;
+ end;
+
+ // vitrual keys
+ for i := 0 to e_MaxVirtKeys-1 do
+ e_KeyNames[VIRT_BEG + i] := 'VIRTUAL' + IntToStr(i);
+end;
+
+function e_HasJoysticks: Boolean;
+ var i: Integer;
+begin
+ i := 0;
+ while (i < e_MaxJoys) and (e_JoystickAvailable[i] = False) do inc(i);
+ result := i < e_MaxJoys
+end;
+
+function e_InitInput: Boolean;
+ var i: Integer;
+begin
+ for i := 0 to e_MaxJoys - 1 do
+ e_JoystickAvailable[i] := False;
+ GenerateKeyNames;
+ result := True
+end;
+
+procedure e_ReleaseInput;
+ var i: Integer;
+begin
+ for i := 0 to e_MaxJoys - 1 do
+ e_JoystickAvailable[i] := False
+end;
+
+function e_KeyPressed (key: Integer): Boolean;
+begin
+ ASSERT(key >= 0);
+ ASSERT(key < e_MaxInputKeys);
+ result := InputBuffer[key]
+end;
+
+function e_AnyKeyPressed: Boolean;
+begin
+ result := e_GetFirstKeyPressed <> IK_INVALID;
+end;
+
+function e_GetFirstKeyPressed: Integer;
+ var i: Integer;
+begin
+ i := 1;
+ while (i < e_MaxInputKeys) and (InputBuffer[i] = False) do inc(i);
+ if i < e_MaxInputKeys then
+ result := i
+ else
+ result := IK_INVALID
+end;
+
+function e_JoyButtonToKey (id, btn: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(btn >= 0);
+ ASSERT(btn < e_MaxJoyBtns);
+ result := JOYK_BEG + id*e_MaxJoyBtns + btn
+end;
+
+function e_JoyAxisToKey (id, ax, dir: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(ax >= 0);
+ ASSERT(ax < e_MaxJoyAxes);
+ ASSERT(dir in [AX_MINUS, AX_PLUS]);
+ result := JOYA_BEG + id*e_MaxJoyAxes*2 + ax*2 + dir
+end;
+
+function e_JoyHatToKey (id, hat, dir: Integer): Integer;
+begin
+ ASSERT(id >= 0);
+ ASSERT(id < e_MaxJoys);
+ ASSERT(hat >= 0);
+ ASSERT(hat < e_MaxJoyHats);
+ ASSERT(dir in [HAT_LEFT, HAT_UP, HAT_RIGHT, HAT_DOWN]);
+ result := JOYH_BEG + id*e_MaxJoyHats*4 + hat*4 + dir
+end;
index c57e2a3c53f516deca4d04e9f58654f534a891cb..53ee47e63a9e351ffefbf73209d094305eddfdd3 100644 (file)
implementation
uses
- g_window, g_options, utils;
+ g_options, utils;
const
NUM_SOURCES = 255; // + 1 stereo
index 35cd2c34430ed5db0aa0190b2276ee605c82a4f5..4d9eaba5d983da5fc644b7255be1923dfcce928f 100644 (file)
interface
uses
- sdl2,
- SDL2_mixer,
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
- e_log,
- SysUtils;
+ SDL2, SDL2_mixer,
+ e_log, SysUtils;
type
TSoundRec = record
index 0ebe256b9d9d818245067079d9fe22c99a5e252c..ba7bcdf67057a5d65f6e057b6ab4c755838f3b01 100644 (file)
implementation
-uses sdl2, utils, e_log;
+uses
+ {$IFDEF USE_SDL}
+ SDL,
+ {$ELSE}
+ SDL2,
+ {$ENDIF}
+ utils, e_log;
(* TWAVLoaderFactory *)
end;
(* TWAVLoader *)
-
function TWAVLoader.Load(Data: Pointer; Len: LongWord; SStreaming: Boolean): Boolean;
var
Spec: TSDL_AudioSpec;
RW := SDL_RWFromConstMem(Data, Len);
+{$IFDEF USE_SDL2}
if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
+{$ELSE}
+ if SDL_LoadWAV_RW(RW, 0, @Spec, PUInt8(@TmpBuf), @TmpLen) = nil then
+{$ENDIF}
begin
e_LogWriteln('Could not load WAV: ' + SDL_GetError());
end
else
begin
FFormat.SampleRate := Spec.freq;
- FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
+ {$IFDEF USE_SDL2}
+ FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
+ {$ELSE}
+ FFormat.SampleBits := Spec.format and $FF;
+ {$ENDIF}
FFormat.Channels := Spec.channels;
FStreaming := False; // never stream wavs
FDataLen := TmpLen;
exit;
end;
+{$IFDEF USE_SDL2}
if SDL_LoadWAV_RW(RW, 0, @Spec, @TmpBuf, @TmpLen) = nil then
+{$ELSE}
+ if SDL_LoadWAV_RW(RW, 0, @Spec, PUInt8(@TmpBuf), @TmpLen) = nil then
+{$ENDIF}
begin
e_LogWritefln('Could not load WAV file `%s`: %s', [FName, SDL_GetError()]);
end
else
begin
FFormat.SampleRate := Spec.freq;
- FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
+ {$IFDEF USE_SDL2}
+ FFormat.SampleBits := SDL_AUDIO_BITSIZE(Spec.format);
+ {$ELSE}
+ FFormat.SampleBits := Spec.format and $FF;
+ {$ENDIF}
FFormat.Channels := Spec.channels;
FStreaming := False; // never stream wavs
FDataLen := TmpLen;
diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index 875879fc19d5b70d820f22182822a253ce09373e..18f1f21ac854c050c2d928da10d4ebf4e874f437 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
{$ENDIF}
{$HINTS OFF}
+{$IF DEFINED(USE_SYSSTUB)}
+ {$IF DEFINED(USE_SDL) OR DEFINED(USE_SDL2)}
+ {$ERROR Only one system driver must be selected!}
+ {$ENDIF}
+{$ELSEIF DEFINED(USE_SDL)}
+ {$IF DEFINED(USE_SYSSTUB) OR DEFINED(USE_SDL2)}
+ {$ERROR Only one system driver must be selected!}
+ {$ENDIF}
+{$ELSEIF DEFINED(USE_SDL2)}
+ {$IF DEFINED(USE_SYSSTUB) OR DEFINED(USE_SDL)}
+ {$ERROR Only one system driver must be selected!}
+ {$ENDIF}
+{$ELSE}
+ {$ERROR System driver not selected. Use -dUSE_SYSSTUB or -dUSE_SDL or -dUSE_SDL2}
+{$ENDIF}
+
{$IF DEFINED(USE_SDLMIXER)}
{$IF DEFINED(USE_FMOD) OR DEFINED(USE_OPENAL)}
{$ERROR Only one sound driver must be selected!}
{$ERROR Only one sound driver must be selected!}
{$ENDIF}
{$ELSE}
- {$ERROR Sound driver not selected. Use -DUSE_SDLMIXER or -DUSE_FMOD or -DUSE_OPENAL}
+ {$ERROR Sound driver not selected. Use -dUSE_SDLMIXER or -dUSE_FMOD or -dUSE_OPENAL}
{$ENDIF}
uses
{$IFDEF USE_MINIUPNPC}
miniupnpc in '../lib/miniupnpc/miniupnpc.pas',
{$ENDIF}
+
+{$IFDEF USE_SDL}
+ SDL,
+{$ENDIF}
+{$IFDEF USE_SDL2}
SDL2 in '../lib/sdl2/sdl2.pas',
-{$IFDEF USE_SDLMIXER}
- SDL2_mixer in '../lib/sdl2/SDL2_mixer.pas',
+ {$IFDEF USE_SDLMIXER}
+ SDL2_mixer in '../lib/sdl2/SDL2_mixer.pas',
+ {$ENDIF}
{$ENDIF}
+
{$IFDEF USE_OPENAL}
AL in '../lib/openal/al.pas',
e_soundfile in '../engine/e_soundfile.pas',
- e_soundfile_wav in '../engine/e_soundfile_wav.pas',
+ {$IF DEFINED(USE_SDL) OR DEFINED(USE_SDL2)}
+ e_soundfile_wav in '../engine/e_soundfile_wav.pas',
+ {$ENDIF}
{$IFDEF USE_VORBIS}
vorbis in '../lib/vorbis/vorbis.pas',
e_soundfile_vorbis in '../engine/e_soundfile_vorbis.pas',
ogg in '../lib/vorbis/ogg.pas', // this has to come last because link order
{$ENDIF}
{$ENDIF}
+
ENet in '../lib/enet/enet.pp',
e_graphics in '../engine/e_graphics.pas',
e_input in '../engine/e_input.pas',
g_triggers in 'g_triggers.pas',
g_weapons in 'g_weapons.pas',
g_window in 'g_window.pas',
+{$IFDEF USE_SYSSTUB}
+ g_system in 'stub/g_system.pas',
+ g_touch in 'stub/g_touch.pas',
+{$ENDIF}
+{$IFDEF USE_SDL}
+ g_system in 'sdl/g_system.pas',
+ g_touch in 'sdl/g_touch.pas',
+{$ENDIF}
+{$IFDEF USE_SDL2}
+ g_system in 'sdl2/g_system.pas',
+ g_touch in 'sdl2/g_touch.pas',
+{$ENDIF}
+
SysUtils,
{$IFDEF USE_FMOD}
fmod in '../lib/FMOD/fmod.pas',
diff --git a/src/game/g_basic.pas b/src/game/g_basic.pas
index 01a27b05ef21ccb9dcd247b8ce654884afce96c0..22e318ab4a442a24e36759d25e764053a2011e03 100644 (file)
--- a/src/game/g_basic.pas
+++ b/src/game/g_basic.pas
b: array of string;
str: string;
begin
+{
SetLength(Result, 0);
SetLength(b, 0);
if TextLen(str) > MaxWidth then
begin // Òåêóùàÿ ñòðîêà ñëèøêîì äëèííàÿ => ðàçáèâàåì
- while str <> '' do
+ while (str[0] <> #0) and (str <> '') do
begin
SetLength(Result, Length(Result)+1);
Result[High(Result)] := str;
end;
end;
+}
+ Result := nil
end;
procedure Sort(var a: SSArray);
diff --git a/src/game/g_console.pas b/src/game/g_console.pas
index b7c30dea57f6bca2b12ac4df0f3ad21e2b5e2936..7caa3ba142386b5eac3b72d0a977f6d529218cc3 100644 (file)
--- a/src/game/g_console.pas
+++ b/src/game/g_console.pas
IK_END, IK_KPEND:
CPos := Length(Line) + 1;
IK_A..IK_Z, IK_SPACE, IK_SHIFT, IK_RSHIFT, IK_CAPSLOCK, IK_LBRACKET, IK_RBRACKET,
- IK_SEMICOLON, IK_QUOTE, IK_BACKSLASH, IK_SLASH, IK_COMMA, IK_DOT, IK_EQUALS,
+ IK_SEMICOLON, IK_QUOTE, IK_BACKSLASH, IK_SLASH, IK_COMMA, IK_DOT, (*IK_EQUALS,*)
IK_0, IK_1, IK_2, IK_3, IK_4, IK_5, IK_6, IK_7, IK_8, IK_9, IK_MINUS, IK_EQUALS:
(* see TEXTINPUT event *)
end
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 963496aab5b49eddfb4779dda2ef1f7e9d14674b..aa4c189bc549556117f56d5eb802c14e04aaee8d 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
g_triggers, g_monsters, e_sound, CONFIG,
g_language, g_net,
ENet, e_msg, g_netmsg, g_netmaster,
- sfs, wadreader;
+ sfs, wadreader, g_system;
var
gDelayedEvents[n].DENum := Num;
gDelayedEvents[n].DEStr := Str;
if DEType = DE_GLOBEVENT then
- gDelayedEvents[n].Time := (GetTimer() {div 1000}) + Time
+ gDelayedEvents[n].Time := (sys_GetTicks() {div 1000}) + Time
else
gDelayedEvents[n].Time := gTime + Time;
Result := n;
KeyPress(IK_F10);
end;
- Time := GetTimer() {div 1000};
+ Time := sys_GetTicks() {div 1000};
// Îáðàáîòêà îòëîæåííûõ ñîáûòèé:
if gDelayedEvents <> nil then
begin
e_TextureFontGetSize(gStdFont, ww2, hh2);
- g_ProcessMessages();
+ sys_HandleInput;
if g_Console_Action(ACTION_SCORES) then
begin
begin
if gExit = EXIT_QUIT then Exit;
- Time := GetTimer() {div 1000};
+ Time := sys_GetTicks() {div 1000};
FPSCounter := FPSCounter+1;
if Time - FPSTime >= 1000 then
begin
g_Game_DeleteTestMap();
gExit := EXIT_QUIT;
- PushExitEvent();
+ sys_RequestQuit;
end;
procedure g_FatalError(Text: String);
procedure g_Game_ChangeResolution(newWidth, newHeight: Word; nowFull, nowMax: Boolean);
begin
- g_Window_SetSize(newWidth, newHeight, nowFull);
+ sys_SetDisplayMode(newWidth, newHeight, gBPP, nowFull);
end;
procedure g_Game_AddPlayer(Team: Byte = TEAM_NONE);
diff --git a/src/game/g_main.pas b/src/game/g_main.pas
index 3b84f30eb820982eae315c8147e4eccdfdc9458a..d60f2ddaa6de5fbf4940eff6a8d95f0e473b4299 100644 (file)
--- a/src/game/g_main.pas
+++ b/src/game/g_main.pas
{$IFDEF ENABLE_HOLMES}
g_holmes, fui_wadread, fui_style, fui_gfx_gl,
{$ENDIF}
- SDL2, wadreader, e_log, g_window,
+{$IFDEF USE_SDL2}
+ SDL2,
+{$ENDIF}
+ wadreader, e_log, g_window,
e_graphics, e_input, g_game, g_console, g_gui,
e_sound, g_options, g_sound, g_player, g_basic,
g_weapons, SysUtils, g_triggers, MAPDEF, g_map,
- g_menu, g_language, g_net, g_touch, g_res_downloader,
+ g_menu, g_language, g_net, g_touch, g_system, g_res_downloader,
utils, conbuf, envvars,
xparser;
{$ENDIF}
e_WriteToStdOut := False; //{$IFDEF HEADLESS}True;{$ELSE}False;{$ENDIF}
+{$IFDEF USE_SDL2}
{$IFDEF HEADLESS}
{$IFDEF USE_SDLMIXER}
sdlflags := SDL_INIT_TIMER or SDL_INIT_AUDIO or $00004000;
if SDL_Init(sdlflags) < 0 then
raise Exception.Create('SDL: Init failed: ' + SDL_GetError());
+{$ENDIF}
e_WriteLog('Read config file', TMsgType.Notify);
g_Options_Read(GameDir + '/' + CONFIG_FILENAME);
e_WriteLog(gLanguage, TMsgType.Notify);
g_Language_Set(gLanguage);
+{$IFNDEF USE_SDL2}
+ sys_Init;
+{$ENDIF}
+
{$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
flexloaded := true;
if not fuiAddWad('flexui.wad') then
SDLMain();
{$WARNINGS ON}
+{$IFDEF USE_SDL2}
e_WriteLog('Releasing SDL', TMsgType.Notify);
SDL_Quit();
+{$ELSE}
+ sys_Final;
+{$ENDIF}
end;
procedure Init();
diff --git a/src/game/g_menu.pas b/src/game/g_menu.pas
index 4d2da495216be1983b5f6e38ae4454fc3f7dc6a0..3ffef2697e07622dbaceb277f30d1c8036471315 100644 (file)
--- a/src/game/g_menu.pas
+++ b/src/game/g_menu.pas
{$INCLUDE ../nogl/noGLuses.inc}
g_gui, g_textures, e_graphics, g_main, g_window, g_game, g_map,
g_basic, g_console, g_sound, g_gfx, g_player, g_options, g_weapons,
- e_log, SysUtils, CONFIG, g_playermodel, DateUtils, sdl2,
+ e_log, SysUtils, CONFIG, g_playermodel, DateUtils,
MAPDEF, Math, g_saveload,
e_texture, g_language,
g_net, g_netmsg, g_netmaster, g_items, e_input, g_touch,
- utils, wadreader;
+ utils, wadreader, g_system;
type TYNCallback = procedure (yes:Boolean);
ovs := gVSync;
gVSync := TGUISwitch(menu.GetControl('swVSync')).ItemIndex = 0;
- if (ovs <> gVSync) then g_SetVSync(gVSync);
+ if (ovs <> gVSync) then
+ sys_EnableVSync(gVSync);
gTextureFilter := TGUISwitch(menu.GetControl('swTextureFilter')).ItemIndex = 0;
glLegacyNPOT := not (TGUISwitch(menu.GetControl('swLegacyNPOT')).ItemIndex = 0);
slWaitStr := _lc[I_NET_SLIST_WAIT];
g_Game_Draw;
- ReDrawWindow;
+ sys_Repaint;
slReturnPressed := True;
if g_Net_Slist_Fetch(slCurrent) then
var
menu: TGUIMenu;
list: SSArray;
- SR: DWORD;
begin
menu := TGUIMenu(g_GUI_GetWindow('OptionsVideoResMenu').GetControl('mOptionsVideoResMenu'));
with TGUIListBox(menu.GetControl('lsResolution')) do
begin
- list := GetDisplayModes(gBPP, SR);
-
+ list := sys_GetDispalyModes(gBPP);
if list <> nil then
- begin
- Items := list;
- ItemIndex := SR;
- end
+ begin
+ Items := list;
+ ItemIndex := Length(list)
+ end
else
- Clear();
+ begin
+ Clear
+ end
end;
with TGUISwitch(menu.GetControl('swFullScreen')) do
diff --git a/src/game/g_net.pas b/src/game/g_net.pas
index 63b1270d9653e1306b34b7249f38e3ee554a6f86..eaf35fad6aadc41d2be339ff12a22c1a9c06a0c1 100644 (file)
--- a/src/game/g_net.pas
+++ b/src/game/g_net.pas
uses
SysUtils,
e_input, g_nethandler, g_netmsg, g_netmaster, g_player, g_window, g_console,
- g_main, g_game, g_language, g_weapons, utils, ctypes,
+ g_main, g_game, g_language, g_weapons, utils, ctypes, g_system,
g_map;
const
end;
// предупредить что ждем слишком долго через N секунд
- TimeoutTime := GetTimer() + NET_CONNECT_TIMEOUT;
+ TimeoutTime := sys_GetTicks() + NET_CONNECT_TIMEOUT;
OuterLoop := True;
while OuterLoop do
end;
end;
- T := GetTimer();
+ T := sys_GetTicks();
if T > TimeoutTime then
begin
TimeoutTime := T + NET_CONNECT_TIMEOUT * 100; // одного предупреждения хватит
index 01d5d67ce153aec648034a1e37a373b8ad178d31..2ecad14c74378d27d7f666bf9c7dc01c39d792d8 100644 (file)
--- a/src/game/g_netmaster.pas
+++ b/src/game/g_netmaster.pas
uses
SysUtils, e_msg, e_input, e_graphics, e_log, g_window, g_net, g_console,
g_map, g_game, g_sound, g_gui, g_menu, g_options, g_language, g_basic,
- wadreader;
+ wadreader, g_system;
var
NetMHost: pENetHost = nil;
function GetTimerMS (): Int64;
begin
- Result := GetTimer() {div 1000};
+ Result := sys_GetTicks() {div 1000};
end;
if gConsoleShow or gChatShow then
Exit;
- qm := g_ProcessMessages(); // this updates kbd
+ qm := sys_HandleInput(); // this updates kbd
if qm or e_KeyPressed(IK_ESCAPE) or e_KeyPressed(VK_ESCAPE) or
e_KeyPressed(JOY0_JUMP) or e_KeyPressed(JOY1_JUMP) or
slWaitStr := _lc[I_NET_SLIST_WAIT];
g_Game_Draw;
- g_window.ReDrawWindow;
+ sys_Repaint;
if g_Net_Slist_Fetch(SL) then
begin
diff --git a/src/game/g_options.pas b/src/game/g_options.pas
index 979fe4510cd9d9144e8e3faff46a47a44cc6fe41..ac80a1b1f786cd8d11f7356510ca1c743b344b6a 100644 (file)
--- a/src/game/g_options.pas
+++ b/src/game/g_options.pas
uses
{$INCLUDE ../nogl/noGLuses.inc}
+ {$IFDEF USE_SDL2}
+ SDL2,
+ {$ENDIF}
e_log, e_input, g_console, g_window, g_sound, g_gfx, g_player, Math,
g_map, g_net, g_netmaster, SysUtils, CONFIG, g_game, g_main, e_texture,
- g_items, wadreader, e_graphics, g_touch, SDL2, envvars;
+ g_items, wadreader, e_graphics, g_touch, envvars;
var
machine: Integer;
Result := Copy(Result, 1, 10) + ' ' + IntToStr(n)
end;
+{$IFDEF USE_SDL2}
procedure g_Options_SetDefaultVideo;
var
target, closest, display: TSDL_DisplayMode;
e_LogWriteLn('g_Options_SetDefaultVideo: w = ' + IntToStr(gScreenWidth) + ' h = ' + IntToStr(gScreenHeight));
g_Console_ResetBinds;
end;
+{$ELSE}
+procedure g_Options_SetDefaultVideo;
+begin
+ {$WARNING stub}
+ gScreenWidth := 640;
+ gScreenHeight := 480;
+ gBPP := 32;
+ gFullScreen := False;
+ gWinRealPosX := 0;
+ gWinRealPosY := 0;
+ gWinMaximized := False;
+ gVSync := True;
+ gTextureFilter := True;
+ glLegacyNPOT := False;
+ e_LogWriteLn('g_Options_SetDefaultVideo: w = ' + IntToStr(gScreenWidth) + ' h = ' + IntToStr(gScreenHeight));
+ g_Console_ResetBinds;
+end;
+{$ENDIF}
procedure g_Options_SetDefault();
var
diff --git a/src/game/g_touch.pas b/src/game/g_touch.pas
--- a/src/game/g_touch.pas
+++ /dev/null
@@ -1,324 +0,0 @@
-(* Copyright (C) Doom 2D: Forever Developers
- *
- * 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, version 3 of the License ONLY.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *)
-{$INCLUDE ../shared/a_modes.inc}
-unit g_touch;
-
-interface
-
- uses
- SDL2;
-
- var
- g_touch_enabled: Boolean = False;
- g_touch_size: Single = 1.0;
- g_touch_offset: Single = 50.0;
- g_touch_fire: Boolean = True;
- g_touch_alt: Boolean = False;
-
- procedure g_Touch_Init;
- procedure g_Touch_ShowKeyboard(yes: Boolean);
- procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent);
- procedure g_Touch_Draw;
-
-implementation
-
- uses
- SysUtils,
- e_log, e_graphics, e_input, g_options, g_game, g_main, g_gui, g_weapons, g_console, g_window;
-
- var
- angleFire: Boolean;
- keyFinger: array [VK_FIRSTKEY..VK_LASTKEY] of Integer;
-
- procedure GetKeyRect(key: Integer; out x, y, w, h: Integer; out founded: Boolean);
- var
- sw, sh, sz: Integer;
- dpi: Single;
-
- procedure S (xx, yy, ww, hh: Single);
- begin
- x := Trunc(xx);
- y := Trunc(yy);
- w := Trunc(ww);
- h := Trunc(hh);
- founded := true;
- end;
-
- begin
- founded := false;
- if SDL_GetDisplayDPI(0, @dpi, nil, nil) <> 0 then
- dpi := 96;
-
- sz := Trunc(g_touch_size * dpi); sw := gScreenWidth; sh := gScreenHeight;
- x := 0; y := Round(sh * g_touch_offset / 100);
- w := sz; h := sz;
-
- if SDL_IsTextInputActive() = SDL_True then
- case key of
- VK_HIDEKBD: S(sw - (sz/2), 0, sz / 2, sz / 2);
- end
- else if g_touch_alt then
- case key of
- (* top ------- x ------------------------------- y w ----- h -- *)
- VK_CONSOLE: S(0, 0, sz / 2, sz / 2);
- VK_ESCAPE: S(sw - 1*(sz/2) - 1, 0, sz / 2, sz / 2);
- VK_SHOWKBD: S(sw - 2*(sz/2) - 1, 0, sz / 2, sz / 2);
- VK_CHAT: S(sw / 2 - (sz/2) / 2 - (sz/2) - 1, 0, sz / 2, sz / 2);
- VK_STATUS: S(sw / 2 - (sz/2) / 2 - 1, 0, sz / 2, sz / 2);
- VK_TEAM: S(sw / 2 - (sz/2) / 2 + (sz/2) - 1, 0, sz / 2, sz / 2);
- (* left --- x - y -------------- w - h --- *)
- VK_PREV: S(0, sh - 3.0*sz - 1, sz, sz / 2);
- VK_LEFT: S(0, sh - 2.0*sz - 1, sz, sz * 2);
- VK_RIGHT: S(sz, sh - 2.0*sz - 1, sz, sz * 2);
- (* right - x ------------ y -------------- w - h -- *)
- VK_NEXT: S(sw - 1*sz - 1, sh - 3.0*sz - 1, sz, sz / 2);
- VK_UP: S(sw - 2*sz - 1, sh - 2.0*sz - 1, sz, sz / 2);
- VK_FIRE: S(sw - 2*sz - 1, sh - 1.5*sz - 1, sz, sz);
- VK_DOWN: S(sw - 2*sz - 1, sh - 0.5*sz - 1, sz, sz / 2);
- VK_JUMP: S(sw - 1*sz - 1, sh - 2.0*sz - 1, sz, sz);
- VK_OPEN: S(sw - 1*sz - 1, sh - 1.0*sz - 1, sz, sz);
- end
- else
- case key of
- (* left ----- x ----- y -------------- w ----- h -- *)
- VK_ESCAPE: S(0.0*sz, y - 1*sz - sz/2, sz, sz / 2);
- VK_LSTRAFE: S(0.0*sz, y - 0*sz - sz/2, sz / 2, sz);
- VK_LEFT: S(0.5*sz, y - 0*sz - sz/2, sz, sz);
- VK_RIGHT: S(1.5*sz, y - 0*sz - sz/2, sz, sz);
- VK_RSTRAFE: S(2.5*sz, y - 0*sz - sz/2, sz / 2, sz);
- (* right - x ------------ y --------------- w - h *)
- VK_UP: S(sw - 1*sz - 1, y - 1*sz - sz/2, sz, sz);
- VK_FIRE: S(sw - 1*sz - 1, y - 0*sz - sz/2, sz, sz);
- VK_DOWN: S(sw - 1*sz - 1, y - -1*sz - sz/2, sz, sz);
- VK_NEXT: S(sw - 2*sz - 1, y - 1*sz - sz/2, sz, sz);
- VK_JUMP: S(sw - 2*sz - 1, y - 0*sz - sz/2, sz, sz);
- VK_PREV: S(sw - 3*sz - 1, y - 1*sz - sz/2, sz, sz);
- VK_OPEN: S(sw - 3*sz - 1, y - 0*sz - sz/2, sz, sz);
- (* bottom ---- x -------------------------- y ---------------- w ----- h -- *)
- VK_CHAT: S(sw/2 - sz/4 - 2*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
- VK_CONSOLE: S(sw/2 - sz/4 - 1*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
- VK_STATUS: S(sw/2 - sz/4 - 0*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
- VK_TEAM: S(sw/2 - sz/4 - -1*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
- VK_SHOWKBD: S(sw/2 - sz/4 - -2*(sz/2) - 1, sh - 2*(sz/2) - 1, sz / 2, sz / 2);
- VK_0: S(sw/2 - sz/4 - 5*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_1: S(sw/2 - sz/4 - 4*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_2: S(sw/2 - sz/4 - 3*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_3: S(sw/2 - sz/4 - 2*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_4: S(sw/2 - sz/4 - 1*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_5: S(sw/2 - sz/4 - 0*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_6: S(sw/2 - sz/4 - -1*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_7: S(sw/2 - sz/4 - -2*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_8: S(sw/2 - sz/4 - -3*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_9: S(sw/2 - sz/4 - -4*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- VK_A: S(sw/2 - sz/4 - -5*(sz/2) - 1, sh - 1*(sz/2) - 1, sz / 2, sz / 2);
- end
- end;
-
- function GetKeyName(key: Integer): String;
- begin
- case key of
- VK_SHOWKBD: result := 'KBD';
- VK_HIDEKBD: result := 'KBD';
- VK_LEFT: result := 'LEFT';
- VK_RIGHT: result := 'RIGHT';
- VK_UP: result := 'UP';
- VK_DOWN: result := 'DOWN';
- VK_FIRE: result := 'FIRE';
- VK_OPEN: result := 'OPEN';
- VK_JUMP: result := 'JUMP';
- VK_CHAT: result := 'CHAT';
- VK_ESCAPE: result := 'ESC';
- VK_0: result := '0';
- VK_1: result := '1';
- VK_2: result := '2';
- VK_3: result := '3';
- VK_4: result := '4';
- VK_5: result := '5';
- VK_6: result := '6';
- VK_7: result := '7';
- VK_8: result := '8';
- VK_9: result := '9';
- VK_A: result := '10';
- VK_B: result := '11';
- VK_C: result := '12';
- VK_D: result := '13';
- VK_E: result := '14';
- VK_F: result := '15';
- VK_CONSOLE: result := 'CON';
- VK_STATUS: result := 'STAT';
- VK_TEAM: result := 'TEAM';
- VK_PREV: result := '<PREW';
- VK_NEXT: result := 'NEXT>';
- VK_LSTRAFE: result := '<';
- VK_RSTRAFE: result := '>';
- else
- if (key > 0) and (key < e_MaxInputKeys) then
- result := e_KeyNames[key]
- else
- result := '<' + IntToStr(key) + '>'
- end
- end;
-
- function IntersectControl(ctl, xx, yy: Integer): Boolean;
- var
- x, y, w, h: Integer;
- founded: Boolean;
- begin
- GetKeyRect(ctl, x, y, w, h, founded);
- result := founded and (xx >= x) and (yy >= y) and (xx <= x + w) and (yy <= y + h);
- end;
-
- procedure g_Touch_Init;
- begin
-{$IFNDEF HEADLESS}
- g_Touch_ShowKeyboard(FALSE);
- g_touch_enabled := SDL_GetNumTouchDevices() > 0
-{$ENDIF}
- end;
-
- procedure g_Touch_ShowKeyboard(yes: Boolean);
- begin
-{$IFNDEF HEADLESS}
- if g_dbg_input then
- e_LogWritefln('g_Touch_ShowKeyboard(%s)', [yes]);
- (* on desktop we always receive text (needed for cheats) *)
- if yes or (SDL_HasScreenKeyboardSupport() = SDL_FALSE) then
- SDL_StartTextInput
- else
- SDL_StopTextInput
-{$ENDIF}
- end;
-
- procedure g_Touch_HandleEvent(const ev: TSDL_TouchFingerEvent);
- var
- x, y, i, finger: Integer;
-
- procedure KeyUp (finger, i: Integer);
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: g_touch.KeyUp, finger=%s, key=%s', [finger, i]);
-
- keyFinger[i] := 0;
- e_KeyUpDown(i, False);
- g_Console_ProcessBind(i, False);
-
- (* up/down + fire hack *)
- if g_touch_fire and (gGameSettings.GameType <> GT_NONE) and (g_ActiveWindow = nil) and angleFire then
- begin
- if (i = VK_UP) or (i = VK_DOWN) then
- begin
- angleFire := False;
- keyFinger[VK_FIRE] := 0;
- e_KeyUpDown(VK_FIRE, False);
- g_Console_ProcessBind(VK_FIRE, False)
- end
- end
- end;
-
- procedure KeyDown (finger, i: Integer);
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: g_touch.KeyDown, finger=%s, key=%s', [finger, i]);
-
- keyFinger[i] := finger;
- e_KeyUpDown(i, True);
- g_Console_ProcessBind(i, True);
-
- (* up/down + fire hack *)
- if g_touch_fire and (gGameSettings.GameType <> GT_NONE) and (g_ActiveWindow = nil) then
- begin
- if i = VK_UP then
- begin
- angleFire := True;
- keyFinger[VK_FIRE] := -1;
- e_KeyUpDown(VK_FIRE, True);
- g_Console_ProcessBind(VK_FIRE, True)
- end
- else if i = VK_DOWN then
- begin
- angleFire := True;
- keyFinger[VK_FIRE] := -1;
- e_KeyUpDown(VK_FIRE, True);
- g_Console_ProcessBind(VK_FIRE, True)
- end
- end
- end;
-
- procedure KeyMotion (finger, i: Integer);
- begin
- if keyFinger[i] <> finger then
- begin
- KeyUp(finger, i);
- KeyDown(finger, i)
- end
- end;
-
- begin
- if not g_touch_enabled then
- Exit;
-
- finger := ev.fingerId + 2;
- x := Trunc(ev.x * gScreenWidth);
- y := Trunc(ev.y * gScreenHeight);
-
- for i := VK_FIRSTKEY to VK_LASTKEY do
- begin
- if IntersectControl(i, x, y) then
- begin
- if ev.type_ = SDL_FINGERUP then
- KeyUp(finger, i)
- else if ev.type_ = SDL_FINGERMOTION then
- KeyMotion(finger, i)
- else if ev.type_ = SDL_FINGERDOWN then
- keyDown(finger, i)
- end
- else if keyFinger[i] = finger then
- begin
- if ev.type_ = SDL_FINGERUP then
- KeyUp(finger, i)
- else if ev.type_ = SDL_FINGERMOTION then
- KeyUp(finger, i)
- end
- end
- end;
-
- procedure g_Touch_Draw;
-{$IFNDEF HEADLESS}
- var i, x, y, w, h: Integer; founded: Boolean;
-{$ENDIF}
- begin
-{$IFNDEF HEADLESS}
- if not g_touch_enabled then
- Exit;
-
- for i := VK_FIRSTKEY to VK_LASTKEY do
- begin
- GetKeyRect(i, x, y, w, h, founded);
- if founded then
- begin
- e_DrawQuad(x, y, x + w, y + h, 0, 255, 0, 31);
- e_TextureFontPrintEx(x, y, GetKeyName(i), gStdFont, 255, 255, 255, 1, True)
- end
- end
-{$ENDIF}
- end;
-
-initialization
- conRegVar('touch_enable', @g_touch_enabled, 'enable/disable virtual buttons', 'draw buttons');
- conRegVar('touch_fire', @g_touch_fire, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
- conRegVar('touch_size', @g_touch_size, 0.1, 10, 'size of virtual buttons', 'button size');
- conRegVar('touch_offset', @g_touch_offset, 0, 100, '', '');
- conRegVar('touch_alt', @g_touch_alt, 'althernative virtual buttons layout', 'althernative layout');
-end.
diff --git a/src/game/g_window.pas b/src/game/g_window.pas
index 3adb2b616da1f09af1dfb5c3c7f0b0b09e1689fe..f623e8a69eca02f4924c5717b5a70a4569919679 100644 (file)
--- a/src/game/g_window.pas
+++ b/src/game/g_window.pas
utils;
function SDLMain (): Integer;
-function GetTimer (): Int64;
procedure ResetTimer ();
-procedure PushExitEvent ();
-function ProcessMessage (): Boolean;
-procedure ReDrawWindow ();
-procedure SwapBuffers ();
-procedure Sleep (ms: LongWord);
-function GetDisplayModes (dbpp: LongWord; var selres: LongWord): SSArray;
-function g_Window_SetDisplay (preserveGL: Boolean=false): Boolean;
-function g_Window_SetSize (w, h: Word; fullscreen: Boolean): Boolean;
-procedure g_SetVSync (vsync: Boolean);
-
procedure ProcessLoading (forceUpdate: Boolean=false);
-// returns `true` if quit event was received
-function g_ProcessMessages (): Boolean;
-
-
var
gwin_dump_extensions: Boolean = false;
gwin_has_stencil: Boolean = false;
g_dbg_aimline_on: Boolean = false;
g_dbg_input: Boolean = False;
-
implementation
uses
{$IFDEF WINDOWS}Windows,{$ENDIF}
-{$INCLUDE ../nogl/noGLuses.inc}
{$IFDEF ENABLE_HOLMES}
g_holmes, sdlcarcass, fui_ctls,
{$ENDIF}
SysUtils, Classes, MAPDEF, Math,
- SDL2, e_graphics, e_log, e_texture, g_main,
+ e_graphics, e_log, e_texture, g_main,
g_console, e_input, g_options, g_game,
g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net,
g_map, g_gfx, g_monsters, xprofiler,
- g_touch, g_gui;
+ g_touch, g_gui, g_system;
const
ProgressUpdateMSecs = 35; //1;//100;
var
- h_Wnd: PSDL_Window = nil;
- h_GL: TSDL_GLContext = nil;
Time, Time_Delta, Time_Old: Int64;
flag: Boolean;
-{$IF not DEFINED(HEADLESS)}
- wTitle: PChar = nil;
- wasFullscreen: Boolean = true; // so we need to recreate the window
-{$ENDIF}
wNeedTimeReset: Boolean = false;
wMinimized: Boolean = false;
wMaximized: Boolean = false;
wLoadingProgress: Boolean = false;
wLoadingQuit: Boolean = false;
-{$IFNDEF WINDOWS}
- ticksOverflow: Int64 = -1;
- lastTicks: Uint32 = 0; // to detect overflow
-{$ENDIF}
- JoystickHandle: array [0..e_MaxJoys - 1] of PSDL_Joystick;
- JoystickHatState: array [0..e_MaxJoys - 1, 0..e_MaxJoyHats - 1, HAT_LEFT..HAT_DOWN] of Boolean;
- JoystickZeroAxes: array [0..e_MaxJoys - 1, 0..e_MaxJoyAxes - 1] of Integer;
-
-procedure KillGLWindow (preserveGL: Boolean);
-begin
-{$IFDEF ENABLE_HOLMES}
- if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglDeinitCB)) then oglDeinitCB(); end;
-{$ENDIF}
- if (h_Wnd <> nil) then SDL_DestroyWindow(h_Wnd);
- if (h_GL <> nil) and (not preserveGL) then
- begin
-
-{$IFDEF USE_NANOGL}
- nanoGL_Destroy;
-{$ENDIF}
-
-{$IFDEF USE_NOGL}
- nogl_Quit;
-{$ENDIF}
-
- SDL_GL_DeleteContext(h_GL);
- end;
- h_Wnd := nil;
- if (not preserveGL) then h_GL := nil;
-end;
-
-
-function g_Window_SetDisplay (preserveGL: Boolean = false): Boolean;
-{$IF not DEFINED(HEADLESS)}
-var
- mode, cmode: TSDL_DisplayMode;
- wFlags: LongWord = 0;
- nw, nh: Integer;
-{$ENDIF}
-begin
-{$IF not DEFINED(HEADLESS)}
- result := false;
-
- e_WriteLog('Setting display mode...', TMsgType.Notify);
-
- wFlags := SDL_WINDOW_OPENGL {or SDL_WINDOW_RESIZABLE};
- if gFullscreen then wFlags := wFlags {or SDL_WINDOW_FULLSCREEN} else wFlags := wFlags or SDL_WINDOW_RESIZABLE;
- if (not gFullscreen) and (not preserveGL) and gWinMaximized then wFlags := wFlags or SDL_WINDOW_MAXIMIZED else gWinMaximized := false;
-
- if gFullscreen then
- begin
- mode.w := gScreenWidth;
- mode.h := gScreenHeight;
- mode.format := 0;
- mode.refresh_rate := 0;
- mode.driverdata := nil;
- if (SDL_GetClosestDisplayMode(0, @mode, @cmode) = nil) then
- begin
- e_WriteLog('SDL: cannot find display mode for '+IntToStr(gScreenWidth), TMsgType.Notify);
- gScreenWidth := 800;
- gScreenHeight := 600;
- end
- else
- begin
- e_WriteLog('SDL: found display mode for '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight)+': '+IntToStr(cmode.w)+'x'+IntToStr(cmode.h), TMsgType.Notify);
- gScreenWidth := cmode.w;
- gScreenHeight := cmode.h;
- end;
- end;
-
- if (preserveGL) and (h_Wnd <> nil) and (not gFullscreen) and (not wasFullscreen) then
- begin
- //SDL_SetWindowMaximumSize(h_Wnd, gScreenWidth, gScreenHeight);
- //SDL_SetWindowDisplayMode(h_Wnd, @cmode);
- if (wMaximized) then SDL_RestoreWindow(h_Wnd);
- wMaximized := false;
- gWinMaximized := false;
- SDL_SetWindowSize(h_Wnd, gScreenWidth, gScreenHeight);
- //SDL_SetWindowFullscreen(h_Wnd, SDL_WINDOW_FULLSCREEN);
- //SDL_SetWindowFullscreen(h_Wnd, 0);
- end
- else
- begin
- KillGLWindow(preserveGL);
- h_Wnd := SDL_CreateWindow(PChar(wTitle), gWinRealPosX, gWinRealPosY, gScreenWidth, gScreenHeight, wFlags);
- if gFullscreen then
- SDL_SetWindowFullscreen(h_Wnd, SDL_WINDOW_FULLSCREEN);
- if (h_Wnd = nil) then exit;
- end;
- wasFullscreen := gFullscreen;
-
- SDL_GL_MakeCurrent(h_Wnd, h_GL);
- SDL_ShowCursor(SDL_DISABLE);
- if (h_GL <> nil) then g_SetVSync(gVSync);
- if (gFullscreen) then
- begin
- nw := 0;
- nh := 0;
- SDL_GetWindowSize(h_Wnd, @nw, @nh);
- if (nw > 128) and (nh > 128) then
- begin
- e_WriteLog('SDL: fullscreen window got size '+IntToStr(nw)+'x'+IntToStr(nh)+': '+IntToStr(gScreenWidth)+'x'+IntToStr(gScreenHeight), TMsgType.Notify);
- gScreenWidth := nw;
- gScreenHeight := nh;
- end
- else
- begin
- e_WriteLog('SDL: fullscreen window got invalid size: '+IntToStr(nw)+'x'+IntToStr(nh), TMsgType.Notify);
- end;
- end;
-
- {$IFDEF ENABLE_HOLMES}
- fuiScrWdt := gScreenWidth;
- fuiScrHgt := gScreenHeight;
- if (h_GL <> nil) and (not preserveGL) then begin if (assigned(oglInitCB)) then oglInitCB(); end;
- {$ENDIF}
-{$ENDIF}
-
- result := true;
-end;
-
-
-function GetDisplayModes (dbpp: LongWord; var selres: LongWord): SSArray;
-var
- mode: TSDL_DisplayMode;
- res, i, k, n, pw, ph: Integer;
-begin
- SetLength(result, 0);
- {$IFDEF HEADLESS}exit;{$ENDIF}
- k := 0; selres := 0;
- n := SDL_GetNumDisplayModes(0);
- pw := 0; ph := 0;
- for i := 0 to n do
- begin
- res := SDL_GetDisplayMode(0, i, @mode);
- if res < 0 then continue;
- if SDL_BITSPERPIXEL(mode.format) = gBPP then continue;
- if (mode.w = pw) and (mode.h = ph) then continue;
- if (mode.w = gScreenWidth) and (mode.h = gScreenHeight) then
- selres := k;
- Inc(k);
- SetLength(result, k);
- result[k-1] := IntToStr(mode.w) + 'x' + IntToStr(mode.h);
- pw := mode.w; ph := mode.h
- end;
-
- e_WriteLog('SDL: Got ' + IntToStr(k) + ' resolutions.', TMsgType.Notify);
-end;
-
-
-procedure Sleep (ms: LongWord);
-begin
- SDL_Delay(ms);
-end;
-
-
-procedure ChangeWindowSize (requested: Boolean);
-begin
- e_LogWritefln(' ChangeWindowSize: (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]);
- gWinSizeX := gScreenWidth;
- gWinSizeY := gScreenHeight;
-{$IF not DEFINED(HEADLESS)}
- {$IFDEF ENABLE_HOLMES}
- fuiScrWdt := gScreenWidth;
- fuiScrHgt := gScreenHeight;
- {$ENDIF}
- e_ResizeWindow(gScreenWidth, gScreenHeight);
- g_Game_SetupScreenSize();
- {$IF DEFINED(ANDROID)}
- (* This will fix menu reset on keyboard showing *)
- if requested then
- g_Menu_Reset;
- {$ELSE}
- g_Menu_Reset;
- {$ENDIF}
- g_Game_ClearLoading();
-{$ENDIF}
-end;
-
-
-function g_Window_SetSize (w, h: Word; fullscreen: Boolean): Boolean;
-{$IF not DEFINED(HEADLESS)}
-var
- preserve: Boolean;
-{$ENDIF}
-begin
- result := false;
-{$IF not DEFINED(HEADLESS)}
- preserve := false;
-
- if (gScreenWidth <> w) or (gScreenHeight <> h) then
- begin
- result := true;
- preserve := true;
- gScreenWidth := w;
- gScreenHeight := h;
- end;
-
- if (gFullscreen <> fullscreen) then
- begin
- result := true;
- preserve := true;
- gFullscreen := fullscreen;
- preserve := true;
- end;
-
- if result then
- begin
- g_Window_SetDisplay(preserve);
- ChangeWindowSize(true);
- end;
-{$ENDIF}
-end;
-
-
-function WindowEventHandler (constref ev: TSDL_WindowEvent): Boolean;
-var
- wActivate, wDeactivate: Boolean;
-begin
- result := false;
- wActivate := false;
- wDeactivate := false;
-
- case ev.event of
- SDL_WINDOWEVENT_MOVED:
- begin
- if not (gFullscreen or gWinMaximized) then
- begin
- gWinRealPosX := ev.data1;
- gWinRealPosY := ev.data2;
- end;
- end;
-
- SDL_WINDOWEVENT_MINIMIZED:
- begin
- e_UnpressAllKeys();
- if not wMinimized then
- begin
- e_ResizeWindow(0, 0);
- wMinimized := true;
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Now minimized');
- e_WriteLog('[DEBUG] WinMsgs: Now minimized', TMsgType.Notify);
- end;
- wDeactivate := true;
- end;
- end;
-
- SDL_WINDOWEVENT_RESIZED:
- begin
- e_LogWritefln('Resize: (os=%dx%d) (ns=%dx%d)', [gScreenWidth, gScreenHeight, Integer(ev.data1), Integer(ev.data2)]);
- {if (gFullscreen) then
- begin
- e_LogWriteln(' fullscreen fix applied.');
- if (gScreenWidth <> ev.data1) or (gScreenHeight <> ev.data2) then
- begin
- SDL_SetWindowSize(h_Wnd, gScreenWidth, gScreenHeight);
- end;
- end
- else}
- begin
- gScreenWidth := ev.data1;
- gScreenHeight := ev.data2;
- end;
- ChangeWindowSize(false);
- SwapBuffers();
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2));
- e_WriteLog('[DEBUG] WinMsgs: Resized to ' + IntToStr(ev.data1) + 'x' + IntToStr(ev.data2), TMsgType.Notify);
- end;
- end;
-
- SDL_WINDOWEVENT_EXPOSED:
- SwapBuffers();
-
- SDL_WINDOWEVENT_MAXIMIZED:
- begin
- wMaximized := true;
- if wMinimized then
- begin
- e_ResizeWindow(gScreenWidth, gScreenHeight);
- wMinimized := false;
- wActivate := true;
- end;
- if (not gWinMaximized) and (not gFullscreen) then
- begin
- gWinMaximized := true;
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Now maximized');
- e_WriteLog('[DEBUG] WinMsgs: Now maximized', TMsgType.Notify);
- end;
- end;
- end;
-
- SDL_WINDOWEVENT_RESTORED:
- begin
- wMaximized := false;
- if wMinimized then
- begin
- e_ResizeWindow(gScreenWidth, gScreenHeight);
- wMinimized := false;
- wActivate := true;
- end;
- gWinMaximized := false;
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Now restored');
- e_WriteLog('[DEBUG] WinMsgs: Now restored', TMsgType.Notify);
- end;
- end;
-
- SDL_WINDOWEVENT_FOCUS_GAINED:
- begin
- wActivate := true;
- //e_WriteLog('window gained focus!', MSG_NOTIFY);
- end;
-
- SDL_WINDOWEVENT_FOCUS_LOST:
- begin
- wDeactivate := true;
- e_UnpressAllKeys();
- //e_WriteLog('window lost focus!', MSG_NOTIFY);
- end;
- end;
-
- if wDeactivate then
- begin
- if gWinActive then
- begin
- e_WriteLog('deactivating window', TMsgType.Notify);
- e_UnpressAllKeys;
-
- if gMuteWhenInactive then
- begin
- //e_WriteLog('deactivating sounds', MSG_NOTIFY);
- e_MuteChannels(true);
- end;
-
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Now inactive');
- e_WriteLog('[DEBUG] WinMsgs: Now inactive', TMsgType.Notify);
- end;
-
- gWinActive := false;
-
- {$IFDEF ENABLE_HOLMES}
- if assigned(winBlurCB) then winBlurCB();
- {$ENDIF}
- end;
- end
- else if wActivate then
- begin
- if not gWinActive then
- begin
- //e_WriteLog('activating window', MSG_NOTIFY);
-
- if gMuteWhenInactive then
- begin
- //e_WriteLog('activating sounds', MSG_NOTIFY);
- e_MuteChannels(false);
- end;
-
- if g_debug_WinMsgs then
- begin
- g_Console_Add('Now active');
- e_WriteLog('[DEBUG] WinMsgs: Now active', TMsgType.Notify);
- end;
-
- gWinActive := true;
-
- {$IFDEF ENABLE_HOLMES}
- if assigned(winFocusCB) then winFocusCB();
- {$ENDIF}
- end;
- end;
-end;
-
-
-function EventHandler (var ev: TSDL_Event): Boolean;
-var
- key, keychr, minuskey: Word;
- uc: UnicodeChar;
- down: Boolean;
- i: Integer;
- hat: array [HAT_LEFT..HAT_DOWN] of Boolean;
-begin
- result := false;
-
- case ev.type_ of
- SDL_WINDOWEVENT:
- result := WindowEventHandler(ev.window);
-
- SDL_QUITEV:
- begin
- if (gExit <> EXIT_QUIT) then
- begin
- if not wLoadingProgress then
- begin
- g_Game_Free();
- g_Game_Quit();
- end
- else
- begin
- wLoadingQuit := true;
- end;
- end;
- result := true;
- end;
-
- SDL_KEYDOWN, SDL_KEYUP:
- begin
- key := ev.key.keysym.scancode;
- if key = SDL_SCANCODE_AC_BACK then
- key := SDL_SCANCODE_ESCAPE;
- down := (ev.type_ = SDL_KEYDOWN);
- {$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
- if fuiOnSDLEvent(ev) then
- begin
- // event eaten, but...
- if not down then e_KeyUpDown(key, false);
- exit;
- end;
- {$ENDIF}
- if ev.key._repeat = 0 then
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: keysym, press=%s, scancode=%s', [down, key]);
- e_KeyUpDown(key, down);
- g_Console_ProcessBind(key, down);
- end
- else if gConsoleShow or gChatShow or (g_ActiveWindow <> nil) then
- begin
- // key repeat in menus and shit
- KeyPress(key);
- end;
- end;
-
- SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP:
- if (ev.jbutton.which < e_MaxJoys) and (ev.jbutton.button < e_MaxJoyBtns) then
- begin
- key := e_JoyButtonToKey(ev.jbutton.which, ev.jbutton.button);
- down := ev.type_ = SDL_JOYBUTTONDOWN;
- if g_dbg_input then
- e_LogWritefln('Input Debug: jbutton, joy=%s, button=%s, keycode=%s, press=%s', [ev.jbutton.which, ev.jbutton.button, key, down]);
- e_KeyUpDown(key, down);
- g_Console_ProcessBind(key, down);
- end
- else
- begin
- if g_dbg_input then
- begin
- down := ev.type_ = SDL_JOYBUTTONDOWN;
- e_LogWritefln('Input Debug: NOT IN RANGE! jbutton, joy=%s, button=%s, press=%s', [ev.jbutton.which, ev.jbutton.button, down])
- end
- end;
-
- SDL_JOYAXISMOTION:
- if (ev.jaxis.which < e_MaxJoys) and (ev.jaxis.axis < e_MaxJoyAxes) then
- begin
- key := e_JoyAxisToKey(ev.jaxis.which, ev.jaxis.axis, AX_PLUS);
- minuskey := e_JoyAxisToKey(ev.jaxis.which, ev.jaxis.axis, AX_MINUS);
-
- if g_dbg_input then
- e_LogWritefln('Input Debug: jaxis, joy=%s, axis=%s, value=%s, zeroaxes=%s, deadzone=%s', [ev.jaxis.which, ev.jaxis.axis, ev.jaxis.value, JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis], e_JoystickDeadzones[ev.jaxis.which]]);
-
- if ev.jaxis.value < JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] - e_JoystickDeadzones[ev.jaxis.which] then
- begin
- if (e_KeyPressed(key)) then
- begin
- e_KeyUpDown(key, False);
- g_Console_ProcessBind(key, False);
- end;
- e_KeyUpDown(minuskey, True);
- g_Console_ProcessBind(minuskey, True);
- end
- else if ev.jaxis.value > JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] + e_JoystickDeadzones[ev.jaxis.which] then
- begin
- if (e_KeyPressed(minuskey)) then
- begin
- e_KeyUpDown(minuskey, False);
- g_Console_ProcessBind(minuskey, False);
- end;
- e_KeyUpDown(key, True);
- g_Console_ProcessBind(key, True);
- end
- else
- begin
- if (e_KeyPressed(minuskey)) then
- begin
- e_KeyUpDown(minuskey, False);
- g_Console_ProcessBind(minuskey, False);
- end;
- if (e_KeyPressed(key)) then
- begin
- e_KeyUpDown(key, False);
- g_Console_ProcessBind(key, False);
- end;
- end;
- end
- else
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: NOT IN RANGE! jaxis, joy=%s, axis=%s, value=%s, zeroaxes=%s, deadzone=%s', [ev.jaxis.which, ev.jaxis.axis, ev.jaxis.value, JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis], e_JoystickDeadzones[ev.jaxis.which]])
- end;
-
- SDL_JOYHATMOTION:
- if (ev.jhat.which < e_MaxJoys) and (ev.jhat.hat < e_MaxJoyHats) then
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: jhat, joy=%s, hat=%s, value=%s', [ev.jhat.which, ev.jhat.hat, ev.jhat.value]);
- hat[HAT_UP] := LongBool(ev.jhat.value and SDL_HAT_UP);
- hat[HAT_DOWN] := LongBool(ev.jhat.value and SDL_HAT_DOWN);
- hat[HAT_LEFT] := LongBool(ev.jhat.value and SDL_HAT_LEFT);
- hat[HAT_RIGHT] := LongBool(ev.jhat.value and SDL_HAT_RIGHT);
- for i := HAT_LEFT to HAT_DOWN do
- begin
- if JoystickHatState[ev.jhat.which, ev.jhat.hat, i] <> hat[i] then
- begin
- down := hat[i];
- key := e_JoyHatToKey(ev.jhat.which, ev.jhat.hat, i);
- e_KeyUpDown(key, down);
- g_Console_ProcessBind(key, down);
- end
- end;
- JoystickHatState[ev.jhat.which, ev.jhat.hat] := hat
- end
- else
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: NOT IN RANGE! jhat, joy=%s, hat=%s, value=%s', [ev.jhat.which, ev.jhat.hat, ev.jhat.value])
- end;
-
- SDL_JOYDEVICEADDED:
- if (ev.jdevice.which < e_MaxJoys) then
- begin
- JoystickHandle[ev.jdevice.which] := SDL_JoystickOpen(ev.jdevice.which);
- if JoystickHandle[ev.jdevice.which] <> nil then
- begin
- e_LogWritefln('Added Joystick %s', [ev.jdevice.which]);
- e_JoystickAvailable[ev.jdevice.which] := True;
- for i := 0 to Min(SDL_JoystickNumAxes(JoystickHandle[ev.jdevice.which]), e_MaxJoyAxes) - 1 do
- JoystickZeroAxes[ev.jdevice.which, i] := SDL_JoystickGetAxis(JoystickHandle[ev.jdevice.which], i)
- end
- else
- e_LogWritefln('Warning! Failed to open Joystick %s', [ev.jdevice.which])
- end
- else
- begin
- e_LogWritefln('Warning! Added Joystick %s, but we support only <= %s', [ev.jdevice.which, e_MaxJoys])
- end;
-
- SDL_JOYDEVICEREMOVED:
- begin
- e_LogWritefln('Removed Joystick %s', [ev.jdevice.which]);
- if (ev.jdevice.which < e_MaxJoys) then
- begin
- e_JoystickAvailable[ev.jdevice.which] := False;
- if JoystickHandle[ev.jdevice.which] <> nil then
- SDL_JoystickClose(JoystickHandle[ev.jdevice.which]);
- JoystickHandle[ev.jdevice.which] := nil
- end
- end;
-
- {$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
- SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_MOUSEMOTION:
- fuiOnSDLEvent(ev);
- {$ENDIF}
-
- SDL_TEXTINPUT:
- begin
- if g_dbg_input then
- e_LogWritefln('Input Debug: text, text=%s', [ev.text.text]);
- Utf8ToUnicode(@uc, PChar(ev.text.text), 1);
- keychr := Word(uc);
- if (keychr > 127) then keychr := Word(wchar2win(WideChar(keychr)));
- if (keychr > 0) and (keychr <= 255) then CharPress(AnsiChar(keychr));
- end;
-
- SDL_FINGERMOTION, SDL_FINGERDOWN, SDL_FINGERUP:
- g_Touch_HandleEvent(ev.tfinger);
-
- // other key presses and joysticks are handled in e_input
- end;
-end;
-
-
-procedure SwapBuffers ();
-begin
- {$IF not DEFINED(HEADLESS)}
- SDL_GL_SwapWindow(h_Wnd);
- {$ENDIF}
-end;
-
-
-function CreateGLWindow (Title: PChar): Boolean;
-begin
- result := false;
-
- gWinSizeX := gScreenWidth;
- gWinSizeY := gScreenHeight;
-
-{$IF not DEFINED(HEADLESS)}
- wTitle := Title;
-{$ENDIF}
- e_WriteLog('Creating window', TMsgType.Notify);
-
- if not g_Window_SetDisplay() then
- begin
- KillGLWindow(false);
- e_WriteLog('Window creation error (resolution not supported?)', TMsgType.Fatal);
- exit;
- end;
-
-{$IF not DEFINED(HEADLESS)}
- h_GL := SDL_GL_CreateContext(h_Wnd);
- if (h_GL = nil) then exit;
- {$IFDEF ENABLE_HOLMES}
- fuiScrWdt := gScreenWidth;
- fuiScrHgt := gScreenHeight;
- {$ENDIF}
- SDL_GL_MakeCurrent(h_Wnd, h_GL);
-{$IFDEF USE_NANOGL}
- if nanoGL_Init() = 0 then
- begin
- KillGLWindow(false);
- e_WriteLog('nanoGL initialization error', TMsgType.Fatal);
- exit;
- end;
-{$ENDIF}
-{$IFDEF USE_NOGL}
- nogl_Init;
-{$ENDIF}
- {$IFDEF ENABLE_HOLMES}
- if (assigned(oglInitCB)) then oglInitCB();
- {$ENDIF}
- if (h_GL <> nil) then g_SetVSync(gVSync);
-{$ENDIF}
-
- e_ResizeWindow(gScreenWidth, gScreenHeight);
- e_InitGL();
-
- result := true;
-end;
-
-
-{$IFDEF WINDOWS}
-// windoze sux; in headless mode `GetTickCount()` (and SDL) returns shit
-function GetTimer (): Int64;
-var
- F, C: Int64;
-begin
- QueryPerformanceFrequency(F);
- QueryPerformanceCounter(C);
- result := Round(C/F*1000{000});
-end;
-{$ELSE}
-function GetTimer (): Int64;
-var
- t: Uint32;
- tt: Int64;
-begin
- t := SDL_GetTicks();
- if (ticksOverflow = -1) then
- begin
- ticksOverflow := 0;
- lastTicks := t;
- end
- else
- begin
- if (lastTicks > t) then
- begin
- // overflow, increment overflow ;-)
- ticksOverflow := ticksOverflow+(Int64($ffffffff)+Int64(1));
- tt := (Int64($ffffffff)+Int64(1))+Int64(t);
- t := Uint32(tt-lastTicks);
- end;
- end;
- lastTicks := t;
- result := ticksOverflow+Int64(t);
-end;
-{$ENDIF}
-
procedure ResetTimer ();
begin
wNeedTimeReset := true;
end;
-
-procedure PushExitEvent ();
-var
- ev: TSDL_Event;
-begin
- ev.type_ := SDL_QUITEV;
- SDL_PushEvent(@ev);
-end;
-
-
{$IFNDEF HEADLESS}
var
prevLoadingUpdateTime: UInt64 = 0;
procedure ProcessLoading (forceUpdate: Boolean=false);
var
- ev: TSDL_Event;
{$IFNDEF HEADLESS}
+// ev: TSDL_Event;
stt: UInt64;
{$ENDIF}
begin
- FillChar(ev, sizeof(ev), 0);
+// FillChar(ev, sizeof(ev), 0);
wLoadingProgress := true;
- while (SDL_PollEvent(@ev) > 0) do
- begin
- EventHandler(ev);
- if (ev.type_ = SDL_QUITEV) then break;
- end;
+// while (SDL_PollEvent(@ev) > 0) do
+// begin
+// EventHandler(ev);
+// if (ev.type_ = SDL_QUITEV) then break;
+// end;
//e_PollJoysticks();
- if (ev.type_ = SDL_QUITEV) or (gExit = EXIT_QUIT) then
- begin
- wLoadingProgress := false;
- exit;
- end;
+// if (ev.type_ = SDL_QUITEV) or (gExit = EXIT_QUIT) then
+// begin
+// wLoadingProgress := false;
+// exit;
+// end;
{$IFNDEF HEADLESS}
if not wMinimized then
DrawLoadingStat();
g_Console_Draw(True);
- SwapBuffers();
+ sys_Repaint;
prevLoadingUpdateTime := getTimeMilli();
end;
end;
end;
-function g_ProcessMessages (): Boolean;
-var
- ev: TSDL_Event;
-begin
- result := false;
- FillChar(ev, SizeOf(ev), 0);
- while (SDL_PollEvent(@ev) > 0) do
- begin
- result := EventHandler(ev);
- if (ev.type_ = SDL_QUITEV) then exit;
- end;
- //e_PollJoysticks();
-end;
-
-
function ProcessMessage (): Boolean;
var
i, t: Integer;
begin
- result := g_ProcessMessages();
+ result := sys_HandleInput();
- Time := GetTimer();
+ Time := sys_GetTicks();
Time_Delta := Time-Time_Old;
flag := false;
// Âðåìÿ ïðåäûäóùåãî îáíîâëåíèÿ
if flag then
begin
- Time_Old := Time-(Time_Delta mod 28);
+ Time_Old := Time - (Time_Delta mod 28);
if (not wMinimized) then
begin
- Draw();
- SwapBuffers();
- end;
+ Draw;
+ sys_Repaint
+ end
end
else
begin
- Sleep(1); // release time slice, so we won't eat 100% CPU
+ sys_Delay(1) // release time slice, so we won't eat 100% CPU
end;
e_SoundUpdate();
end;
-
-procedure ReDrawWindow ();
-begin
- SwapBuffers();
-end;
-
-
-procedure g_SetVSync (vsync: Boolean);
-{$IF not DEFINED(HEADLESS)}
-var
- v: Byte;
-{$ENDIF}
-begin
-{$IF not DEFINED(HEADLESS)}
- if vsync then v := 1 else v := 0;
- if (SDL_GL_SetSwapInterval(v) <> 0) then
- begin
- e_WriteLog('oops; can''t change vsync option, restart required', TMsgType.Warning);
- end
- else
- begin
- if vsync then e_WriteLog('VSync: ON', TMsgType.Notify) else e_WriteLog('VSync: OFF', TMsgType.Notify);
- end;
-{$ENDIF}
-end;
-
-
-procedure InitOpenGL ();
-begin
-{$IF not DEFINED(HEADLESS)}
- {$IFDEF USE_GLES1}
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
- {$ELSE}
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but...
- {$ENDIF}
-{$ENDIF}
-end;
-
-
-function glHasExtension (const name: AnsiString): Boolean;
-var
- exts: PChar;
- i: Integer;
- found: Boolean;
- extName: ShortString;
-begin
- result := false;
- if (Length(name) = 0) then exit;
- exts := glGetString(GL_EXTENSIONS);
- if (exts = nil) then exit;
- while (exts[0] <> #0) and (exts[0] = ' ') do Inc(exts);
- while (exts[0] <> #0) do
- begin
- if gwin_dump_extensions then
- begin
- i := 0;
- while (exts[i] <> #0) and (exts[i] <> ' ') do Inc(i);
- if i > 255 then
- begin
- e_WriteLog('FUUUUUUUUUUUUU', TMsgType.Warning);
- end
- else
- begin
- Move(exts^, extName[1], i);
- extName[0] := Char(i);
- e_WriteLog(Format('EXT: %s', [extName]), TMsgType.Notify);
- end;
- end;
- found := true;
- for i := 0 to length(name)-1 do
- begin
- if (exts[i] = #0) then begin found := false; break; end;
- if (exts[i] <> name[i+1]) then begin found := false; break; end;
- end;
- if found and ((exts[Length(name)] = #0) or (exts[Length(name)] = ' ')) then begin result := true; exit; end;
- while (exts[0] <> #0) and (exts[0] <> ' ') do Inc(exts);
- while (exts[0] <> #0) and (exts[0] = ' ') do Inc(exts);
- end;
-end;
-
-
function SDLMain (): Integer;
var
idx: Integer;
end;
end;
- e_WriteLog('Initializing OpenGL', TMsgType.Notify);
- InitOpenGL();
-
- e_WriteLog('Creating GL window', TMsgType.Notify);
- if not CreateGLWindow(PChar(Format('Doom 2D: Forever %s', [GAME_VERSION]))) then
- begin
- result := 0;
- e_WriteLog('Unable to create GL window: ' + SDL_GetError(), TMsgType.Fatal);
- exit;
- end;
-
- {EnumDisplayModes();}
-
-{$IFDEF HEADLESS}
- //gwin_k8_enable_light_experiments := false;
- gwin_has_stencil := false;
- glLegacyNPOT := false;
- gwin_dump_extensions := false;
-{$ELSE}
- SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, @ltmp);
- e_LogWritefln('stencil buffer size: %s', [ltmp]);
- gwin_has_stencil := (ltmp > 0);
-
- if glHasExtension('GL_ARB_texture_non_power_of_two') or
- glHasExtension('GL_OES_texture_npot') then
- begin
- e_WriteLog('NPOT textures: YES', TMsgType.Notify);
- glLegacyNPOT := false;
- end
- else
- begin
- e_WriteLog('NPOT textures: NO', TMsgType.Warning);
- glLegacyNPOT := true;
- end;
- gwin_dump_extensions := false;
-{$ENDIF}
-
- Init();
- Time_Old := GetTimer();
+ Init;
+ Time_Old := sys_GetTicks();
// Êîìàíäíàÿ ñòðîêà
if (ParamCount > 0) then g_Game_Process_Params();
while not ProcessMessage() do begin end;
Release();
- KillGLWindow(false);
-
result := 0;
end;
diff --git a/src/game/sdl/g_system.pas b/src/game/sdl/g_system.pas
--- /dev/null
@@ -0,0 +1,301 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * 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, version 3 of the License ONLY.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_system;
+
+interface
+
+ (* To fix:
+ * - Text input
+ * - Joystick support
+ * - Window resizing using SDL_VIDEORESIZE
+ *)
+
+ uses Utils;
+
+ (* --- Utils --- *)
+ function sys_GetTicks (): Int64;
+ procedure sys_Delay (ms: Integer);
+
+ (* --- Graphics --- *)
+ function sys_GetDispalyModes (bpp: Integer): SSArray;
+ function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+ procedure sys_EnableVSync (yes: Boolean);
+ procedure sys_Repaint;
+
+ (* --- Input --- *)
+ function sys_HandleInput (): Boolean;
+ procedure sys_RequestQuit;
+
+ (* --- Init --- *)
+ procedure sys_Init;
+ procedure sys_Final;
+
+implementation
+
+ uses
+ SysUtils, SDL, GL,
+ e_log, e_graphics, e_input,
+ g_options, g_window, g_console, g_game, g_menu;
+
+ var
+ screen: PSDL_Surface;
+
+ (* --------- Utils --------- *)
+
+ function sys_GetTicks (): Int64;
+ begin
+ Result := SDL_GetTicks()
+ end;
+
+ procedure sys_Delay (ms: Integer);
+ begin
+ SDL_Delay(ms)
+ end;
+
+ (* --------- Graphics --------- *)
+
+ procedure UpdateSize (w, h: Integer);
+ begin
+ gWinSizeX := w;
+ gWinSizeY := h;
+ gWinRealPosX := 0;
+ gWinRealPosY := 0;
+ gScreenWidth := w;
+ gScreenHeight := h;
+ {$IFDEF ENABLE_HOLMES}
+ fuiScrWdt := w;
+ fuiScrHgt := h;
+ {$ENDIF}
+ e_ResizeWindow(w, h);
+ e_InitGL;
+ g_Game_SetupScreenSize;
+ g_Menu_Reset;
+ g_Game_ClearLoading;
+ end;
+
+ function InitWindow (w, h, bpp: Integer; fullScreen: Boolean): Boolean;
+ var flags: Uint32;
+ begin
+ e_LogWritefln('InitWindow %s %s %s %s', [w, h, bpp, fullscreen]);
+ Result := False;
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); // lights; it is enough to have 1-bit stencil buffer for lighting, but...
+ flags := SDL_OPENGL or SDL_VIDEORESIZE;
+ if fullScreen then
+ flags := flags or SDL_FULLSCREEN;
+ if (screen = nil) or (SDL_VideoModeOk(w, h, bpp, flags) <> 0) then
+ begin
+ SDL_FreeSurface(screen);
+ screen := SDL_SetVideoMode(w, h, bpp, flags);
+ if screen <> nil then
+ begin
+ SDL_WM_SetCaption('Doom 2D: Forever (SDL 1.2)', nil);
+ UpdateSize(w, h);
+ Result := True
+ end
+ end
+ else
+ begin
+ e_LogWritefln('SDL: video mode not supported', [])
+ end
+ end;
+
+ procedure sys_Repaint;
+ begin
+ SDL_GL_SwapBuffers
+ end;
+
+ procedure sys_EnableVSync (yes: Boolean);
+ begin
+ (* ??? *)
+ end;
+
+ function sys_GetDispalyModes (bpp: Integer): SSArray;
+ var m: PPSDL_Rect; f: TSDL_PixelFormat; i, count: Integer;
+ begin
+ SetLength(result, 0);
+ FillChar(f, sizeof(f), 0);
+ f.palette := nil;
+ f.BitsPerPixel := bpp;
+ f.BytesPerPixel := (bpp + 7) div 8;
+ m := SDL_ListModes(@f, SDL_OPENGL or SDL_FULLSCREEN);
+ if (m <> NIL) and (IntPtr(m) <> -1) then
+ begin
+ count := 0;
+ while m[count] <> nil do inc(count);
+ SetLength(result, count);
+ for i := 0 to count - 1 do
+ result[i] := IntToStr(m[i].w) + 'x' + IntToStr(m[i].h);
+ end
+ end;
+
+ function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+ begin
+ result := InitWindow(w, h, bpp, fullscreen)
+ end;
+
+ (* --------- Input --------- *)
+
+ function Key2Stub (key: Integer): Integer;
+ var x: Integer;
+ begin
+ case key of
+ SDLK_ESCAPE: x := IK_ESCAPE;
+ SDLK_RETURN: x := IK_RETURN;
+ SDLK_KP_ENTER: x := IK_KPRETURN;
+ SDLK_KP0: x := IK_KPINSERT;
+ SDLK_UP: x := IK_UP;
+ SDLK_KP8: x := IK_KPUP;
+ SDLK_DOWN: x := IK_DOWN;
+ SDLK_KP2: x := IK_KPDOWN;
+ SDLK_LEFT: x := IK_LEFT;
+ SDLK_KP4: x := IK_KPLEFT;
+ SDLK_RIGHT: x := IK_RIGHT;
+ SDLK_KP6: x := IK_KPRIGHT;
+ SDLK_DELETE: x := IK_DELETE;
+ SDLK_HOME: x := IK_HOME;
+ SDLK_KP7: x := IK_KPHOME;
+ SDLK_INSERT: x := IK_INSERT;
+ SDLK_SPACE: x := IK_SPACE;
+ SDLK_LSHIFT: x := IK_SHIFT;
+ SDLK_LALT: x := IK_ALT;
+ SDLK_TAB: x := IK_TAB;
+ SDLK_PAGEUP: x := IK_PAGEUP;
+ SDLK_KP9: x := IK_KPPAGEUP;
+ SDLK_PAGEDOWN: x := IK_PAGEDN;
+ SDLK_KP3: x := IK_KPPAGEDN;
+ SDLK_KP5: x := IK_KP5;
+ SDLK_NUMLOCK: x := IK_NUMLOCK;
+ SDLK_KP_DIVIDE: x := IK_KPDIVIDE;
+ SDLK_KP_MULTIPLY: x := IK_KPMULTIPLE;
+ SDLK_KP_MINUS: x := IK_KPMINUS;
+ SDLK_KP_PLUS: x := IK_KPPLUS;
+ SDLK_KP_PERIOD: x := IK_KPDOT;
+ SDLK_CAPSLOCK: x := IK_CAPSLOCK;
+ SDLK_RSHIFT: x := IK_RSHIFT;
+ SDLK_LCTRL: x := IK_CTRL;
+ SDLK_RCTRL: x := IK_RCTRL;
+ SDLK_RALT: x := IK_RALT;
+ SDLK_LSUPER: x := IK_WIN;
+ SDLK_RSUPER: x := IK_RWIN;
+ SDLK_MENU: x := IK_MENU;
+ SDLK_PRINT: x := IK_PRINTSCR;
+ SDLK_SCROLLOCK: x := IK_SCROLLLOCK;
+ SDLK_LEFTBRACKET: x := IK_LBRACKET;
+ SDLK_RIGHTBRACKET: x := IK_RBRACKET;
+ SDLK_SEMICOLON: x := IK_SEMICOLON;
+ SDLK_QUOTE: x := IK_QUOTE;
+ SDLK_BACKSLASH: x := IK_BACKSLASH;
+ SDLK_SLASH: x := IK_SLASH;
+ SDLK_COMMA: x := IK_COMMA;
+ SDLK_PERIOD: x := IK_DOT;
+ SDLK_EQUALS: x := IK_EQUALS;
+ SDLK_0: x := IK_0;
+ SDLK_1: x := IK_1;
+ SDLK_2: x := IK_2;
+ SDLK_3: x := IK_3;
+ SDLK_4: x := IK_4;
+ SDLK_5: x := IK_5;
+ SDLK_6: x := IK_6;
+ SDLK_7: x := IK_7;
+ SDLK_8: x := IK_8;
+ SDLK_9: x := IK_9;
+ SDLK_F1: x := IK_F1;
+ SDLK_F2: x := IK_F2;
+ SDLK_F3: x := IK_F3;
+ SDLK_F4: x := IK_F4;
+ SDLK_F5: x := IK_F5;
+ SDLK_F6: x := IK_F6;
+ SDLK_F7: x := IK_F7;
+ SDLK_F8: x := IK_F8;
+ SDLK_F9: x := IK_F9;
+ SDLK_F10: x := IK_F10;
+ SDLK_F11: x := IK_F11;
+ SDLK_F12: x := IK_F12;
+ SDLK_END: x := IK_END;
+ SDLK_KP1: x := IK_KPEND;
+ SDLK_BACKSPACE: x := IK_BACKSPACE;
+ SDLK_BACKQUOTE: x := IK_BACKQUOTE;
+ SDLK_PAUSE: x := IK_PAUSE;
+ SDLK_A..SDLK_Z: x := IK_A + (key - SDLK_A);
+ SDLK_MINUS: x := IK_MINUS;
+ else
+ x := IK_INVALID
+ end;
+ result := x
+ end;
+
+ procedure HandleKeyboard (var ev: TSDL_KeyboardEvent);
+ var down: Boolean; key, stb: Integer;
+ begin
+ down := (ev.type_ = SDL_KEYDOWN);
+ key := ev.keysym.sym;
+ stb := Key2Stub(key);
+ if g_dbg_input then
+ e_LogWritefln('Input Debug: keysym, press=%s, scancode=%s SDL.ev.key.state=%s', [down, key, ev.state]);
+ e_KeyUpDown(stb, down);
+ g_Console_ProcessBind(stb, down);
+ (* !!! need text input -- console, cheaats, fields *)
+ end;
+
+ function sys_HandleInput (): Boolean;
+ var ev: TSDL_Event;
+ begin
+ result := false;
+ while SDL_PollEvent(@ev) <> 0 do
+ begin
+ case ev.type_ of
+ SDL_QUITEV: result := true;
+ SDL_VIDEORESIZE: InitWindow(ev.resize.w, ev.resize.h, gBPP, gFullscreen);
+ SDL_KEYUP, SDL_KEYDOWN: HandleKeyboard(ev.key);
+ end
+ end
+ end;
+
+ procedure sys_RequestQuit;
+ var ev: TSDL_Event;
+ begin
+ ev.quit.type_ := SDL_QUITEV;
+ SDL_PushEvent(@ev)
+ end;
+
+ (* --------- Init --------- *)
+
+ procedure sys_Init;
+ var flags: Uint32; ok: Boolean;
+ begin
+ flags := SDL_INIT_VIDEO or SDL_INIT_AUDIO or
+ SDL_INIT_TIMER or SDL_INIT_JOYSTICK
+ (*or SDL_INIT_NOPARACHUTE*);
+ if SDL_Init(flags) <> 0 then
+ raise Exception.Create('SDL: Init failed: ' + SDL_GetError());
+ ok := InitWindow(gScreenWidth, gScreenHeight, gBPP, gFullScreen);
+ if not ok then
+ raise Exception.Create('SDL: failed to set videomode: ' + SDL_GetError)
+ end;
+
+ procedure sys_Final;
+ begin
+ e_WriteLog('Releasing SDL', TMsgType.Notify);
+ SDL_FreeSurface(screen);
+ SDL_Quit
+ end;
+
+end.
diff --git a/src/game/sdl/g_touch.pas b/src/game/sdl/g_touch.pas
--- /dev/null
+++ b/src/game/sdl/g_touch.pas
@@ -0,0 +1,53 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * 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, version 3 of the License ONLY.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_touch;
+
+interface
+
+ var
+ g_touch_enabled: Boolean = False;
+ g_touch_size: Single = 1.0;
+ g_touch_offset: Single = 50.0;
+ g_touch_fire: Boolean = True;
+ g_touch_alt: Boolean = False;
+
+ procedure g_Touch_Init;
+ procedure g_Touch_ShowKeyboard(yes: Boolean);
+ procedure g_Touch_Draw;
+
+implementation
+
+ uses g_console;
+
+ procedure g_Touch_Init;
+ begin
+ end;
+
+ procedure g_Touch_ShowKeyboard(yes: Boolean);
+ begin
+ end;
+
+ procedure g_Touch_Draw;
+ begin
+ end;
+
+initialization
+ conRegVar('touch_enable', @g_touch_enabled, 'enable/disable virtual buttons', 'draw buttons');
+ conRegVar('touch_fire', @g_touch_fire, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
+ conRegVar('touch_size', @g_touch_size, 0.1, 10, 'size of virtual buttons', 'button size');
+ conRegVar('touch_offset', @g_touch_offset, 0, 100, '', '');
+ conRegVar('touch_alt', @g_touch_alt, 'althernative virtual buttons layout', 'althernative layout');
+end.
diff --git a/src/game/stub/g_system.pas b/src/game/stub/g_system.pas
--- /dev/null
@@ -0,0 +1,94 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * 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, version 3 of the License ONLY.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_system;
+
+interface
+
+ uses Utils;
+
+ (* --- Utils --- *)
+ function sys_GetTicks (): Int64;
+ procedure sys_Delay (ms: Integer);
+
+ (* --- Graphics --- *)
+ function sys_GetDispalyModes (bpp: Integer): SSArray;
+ function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+ procedure sys_EnableVSync (yes: Boolean);
+ procedure sys_Repaint;
+
+ (* --- Input --- *)
+ function sys_HandleInput (): Boolean;
+ procedure sys_RequestQuit;
+
+ (* --- Init --- *)
+ procedure sys_Init;
+ procedure sys_Final;
+
+implementation
+
+ (* --------- Utils --------- *)
+
+ function sys_GetTicks (): Int64;
+ begin
+ Result := 0
+ end;
+
+ procedure sys_Delay (ms: Integer);
+ begin
+ end;
+
+ (* --------- Graphics --------- *)
+
+ procedure sys_Repaint;
+ begin
+ end;
+
+ procedure sys_EnableVSync (yes: Boolean);
+ begin
+ end;
+
+ function sys_GetDispalyModes (bpp: Integer): SSArray;
+ begin
+ SetLength(result, 0);
+ end;
+
+ function sys_SetDisplayMode (w, h, bpp: Integer; fullscreen: Boolean): Boolean;
+ begin
+ result := True
+ end;
+
+ (* --------- Input --------- *)
+
+ function sys_HandleInput (): Boolean;
+ begin
+ result := false
+ end;
+
+ procedure sys_RequestQuit;
+ begin
+ end;
+
+ (* --------- Init --------- *)
+
+ procedure sys_Init;
+ begin
+ end;
+
+ procedure sys_Final;
+ begin
+ end;
+
+end.
diff --git a/src/game/stub/g_touch.pas b/src/game/stub/g_touch.pas
--- /dev/null
@@ -0,0 +1,53 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * 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, version 3 of the License ONLY.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../shared/a_modes.inc}
+unit g_touch;
+
+interface
+
+ var
+ g_touch_enabled: Boolean = False;
+ g_touch_size: Single = 1.0;
+ g_touch_offset: Single = 50.0;
+ g_touch_fire: Boolean = True;
+ g_touch_alt: Boolean = False;
+
+ procedure g_Touch_Init;
+ procedure g_Touch_ShowKeyboard(yes: Boolean);
+ procedure g_Touch_Draw;
+
+implementation
+
+ uses g_console;
+
+ procedure g_Touch_Init;
+ begin
+ end;
+
+ procedure g_Touch_ShowKeyboard(yes: Boolean);
+ begin
+ end;
+
+ procedure g_Touch_Draw;
+ begin
+ end;
+
+initialization
+ conRegVar('touch_enable', @g_touch_enabled, 'enable/disable virtual buttons', 'draw buttons');
+ conRegVar('touch_fire', @g_touch_fire, 'enable/disable fire when press virtual up/down', 'fire when press up/down');
+ conRegVar('touch_size', @g_touch_size, 0.1, 10, 'size of virtual buttons', 'button size');
+ conRegVar('touch_offset', @g_touch_offset, 0, 100, '', '');
+ conRegVar('touch_alt', @g_touch_alt, 'althernative virtual buttons layout', 'althernative layout');
+end.
index be2a86a28d68881d128e8ce49d47883bf04db57a..5e6212b921b5b7ddc04784ad9d601503b3d93483 100644 (file)
--- a/src/shared/xprofiler.pas
+++ b/src/shared/xprofiler.pas
{$IFNDEF IN_TOOLS}
uses
+ {$IFDEF USE_SDL}
+ SDL,
+ {$ENDIF}
+ {$IFDEF USE_SDL2}
+ SDL2,
+ {$ENDIF}
SysUtils;
{$DEFINE STOPWATCH_IS_HERE}
;
{$ENDIF} // IN_TOOLS
+{$IFDEF USE_SDL}
+ type
+ UInt64 = QWord; (* !!! *)
+{$ENDIF}
+
{$IF DEFINED(STOPWATCH_IS_HERE)}
type
TStopWatch = record
implementation
{$IFNDEF IN_TOOLS}
-uses
- SDL2;
-
type
THPTimeType = Int64;
{$ELSE}
end;
-{$IFDEF IN_TOOLS}
+{$IF DEFINED(IN_TOOLS)}
function getTimeMicro (): UInt64; inline;
var
r: THPTimeType;
result := UInt64(r)*1000000 div mFrequency;
{$ENDIF}
end;
-{$ELSE}
+(* !!!
+{$ELSEIF DEFINED(USE_SDL)}
+function getTimeMicro: UInt64; inline;
+begin
+ {$WARNING use inaccurate profiling timer}
+ result := SDL_GetTicks() * 1000
+end;
+*)
+{$ELSEIF DEFINED(USE_SDL2)}
function getTimeMicro (): UInt64; inline;
begin
Result := SDL_GetPerformanceCounter() * 1000000 div SDL_GetPerformanceFrequency()
end;
+{$ELSE}
+function getTimeMicro: UInt64; inline;
+begin
+ {$WARNING use stub profiling timer}
+end;
{$ENDIF}
function getTimeMilli (): UInt64; inline;
begin
- result := getTimeMicro div 1000;
+ result := getTimeMicro() div 1000;
end;