DEADSOFTWARE

implemented rotation and text input
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Sat, 2 Feb 2019 14:17:33 +0000 (17:17 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Sun, 10 Feb 2019 10:05:11 +0000 (13:05 +0300)
src/lib/allegro4/allegro.pas
src/nogl/noGLALSW.inc
src/wrappers/sdl2/sdl2allegro.inc

index 6f4456f765baee8527637e933cbbe9eac3cd8741..388b54a1aaf0f1709d5a82d0a3803d0238a13008 100644 (file)
@@ -252,6 +252,7 @@ interface
     desktop_palette: PALETTE; LibraryLibAllegroVar;
     default_palette: PALETTE; LibraryLibAllegroVar;
     _current_palette: PALETTE; LibraryLibAllegroVar;
+    key_shifts: cint; LibraryLibAllegroVar;
 
   function get_desktop_resolution (width, height: Pcint): cint; LibraryLibAllegroImp;
   function get_gfx_mode_list (card: cint): PGFX_MODE_LIST; LibraryLibAllegroImp;
@@ -298,6 +299,17 @@ interface
 
 //  function _install_allegro (system_id: cint; errno_prt: Pcint; AtExitFunction): cint; LibraryLibAllegroImp;
 
+  procedure acquire_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
+  procedure release_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
+  procedure acquire_screen; LibraryLibAllegroImp;
+  procedure release_screen; LibraryLibAllegroImp;
+
+  procedure rotate_sprite (bmp, sprite: PBITMAP; x, y: cint; a: cint32); LibraryLibAllegroImp;
+  procedure rotate_sprite_v_flip (bmp, sprite: PBITMAP; x, y: cint; a: cint32); LibraryLibAllegroImp;
+
+  function scancode_to_ascii (scancode: cint): cint; LibraryLibAllegroImp;
+  function scancode_to_name (scancode: cint): PChar; LibraryLibAllegroImp;
+
   (* MACRO *)
   function install_allegro (system_id: cint; errno_ptr: Pcint; atexit_ptr: AtExitFunction): cint; inline;
   function allegro_init: cint; inline;
@@ -308,17 +320,6 @@ interface
   function BPS_TO_TIMER (x: clong): clong; inline;
   function BPM_TO_TIMER (x: clong): clong; inline;
 
-(*
-  function acquire_bitmap (bmp: PBITMAP); inline;
-  function release_bitmap (bmp: PBITMAP); inline;
-  function acquire_screen; inline;
-  function release_screen; inline;
-*)
-
-  procedure acquire_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
-  procedure release_bitmap (bmp: PBITMAP); LibraryLibAllegroImp;
-  procedure acquire_screen; LibraryLibAllegroImp;
-  procedure release_screen; LibraryLibAllegroImp;
 
 implementation
 
index b9f1ddd960d79fb4dfc274ec739ead974103bc94..2974fdb73063474173b1ed42272d2b8a157efee9 100644 (file)
@@ -34,7 +34,7 @@ implementation
     ccol: Integer;
     clearColor: cint;
     stack: array [0..StackSize - 1] of record
-      x, y: Integer;
+      x, y, a: Integer;
     end;
     stack_ptr: Integer;
     vpx, vpy: Integer;
@@ -165,10 +165,11 @@ implementation
 
   procedure glEnd;
     var
-      i, j, k, w, h, x0, y0, x1, y1, offx, offy, tmp, s0, t0, s1, t1: Integer;
+      i, j, k, w, h, x0, y0, x1, y1, offx, offy, tmp, s0, t0, s1, t1, angle: Integer;
       oldx0, oldy0, oldx1, oldy1: cint;
       flipv, fliph: Boolean;
       draw_sprite_proc: procedure (bmp, sprite: Allegro.PBITMAP; x, y: cint); cdecl;
+      rotate_sprite_proc: procedure (bmp, sprite: Allegro.PBITMAP; x, y: cint; a: cint32); cdecl;
   begin
     assert(cmds.mode <> GL_INVALID_ENUM);
     assert(Length(cmds.v) mod ValPerVertex = 0);
@@ -177,6 +178,7 @@ implementation
 
     offx := vpx + stack[stack_ptr].x;
     offy := vpy + stack[stack_ptr].y;
+    angle := stack[stack_ptr].a;
 
     case cmds.mode of
     GL_POINTS:
@@ -317,13 +319,27 @@ implementation
             else
               draw_sprite_proc := Allegro.draw_sprite;
 
+            if flipv and fliph then
+              rotate_sprite_proc := Allegro.rotate_sprite_v_flip (* ??? *)
+            else if flipv then
+              rotate_sprite_proc := Allegro.rotate_sprite_v_flip
+            else if fliph then
+              rotate_sprite_proc := Allegro.rotate_sprite (* ??? *)
+            else
+              rotate_sprite_proc := Allegro.rotate_sprite;
+
             oldx0 := 0; oldy0 := 0; oldx1 := 0; oldy1 := 0;
             get_clip_rect(sdl2allegro_screen, oldx0, oldy0, oldx1, oldy1);
             set_clip_rect(sdl2allegro_screen, max(oldx0, offx + x0), max(oldy0, offy + y0), min(oldx1, offx + x1), min(oldy1, offy + y1));
 
-            for j := 0 to (y1 - y0 + h - 1) div h - 1 do
-              for k := 0 to (x1 - x0 + w - 1) div w - 1 do
-                draw_sprite_proc(sdl2allegro_screen, tex[ctex].bmp, offx + x0 + k * w - s0, offy + y0 + j * h - t0);
+            if angle = 0 then
+              for j := 0 to (y1 - y0 + h - 1) div h - 1 do
+                for k := 0 to (x1 - x0 + w - 1) div w - 1 do
+                  draw_sprite_proc(sdl2allegro_screen, tex[ctex].bmp, offx + x0 + k * w - s0, offy + y0 + j * h - t0)
+            else
+              for j := 0 to (y1 - y0 + h - 1) div h - 1 do
+                for k := 0 to (x1 - x0 + w - 1) div w - 1 do
+                  rotate_sprite_proc(sdl2allegro_screen, tex[ctex].bmp, offx + x0 + k * w - s0, offy + y0 + j * h - t0, angle);
 
             set_clip_rect(sdl2allegro_screen, oldx0, oldy0, oldx1, oldy1);
 
@@ -464,7 +480,8 @@ implementation
     if matrixMode <> GL_MODELVIEW then Exit;
     ASSERT(x = 0); (* 3D not supported *)
     ASSERT(y = 0); (* 3D not supported *)
-    (* TODO a := deg(angle * z) *)
+    // angle 360deg == 256 with conversion to fixed point 16.16
+    stack[stack_ptr].a += floor(angle * z * 0.71111) * 65536
   end;
 
   procedure glScalef(x, y, z: GLfloat);
index ebedf9c02a85980f99b5b8e619959d3a6c257575..3392c68ef45f081cd50a796f15d189122fc31401 100644 (file)
@@ -205,7 +205,7 @@ interface
       type_: UInt32;                                          // SDL_TEXTINPUT
       timestamp: UInt32;
       windowID: UInt32;                                       // The window with keyboard focus, if any
-      text: array[0..SDL_TEXTINPUTEVENT_TEXT_SIZE] of Char;   // The input text
+      text: array[0..SDL_TEXTINPUTEVENT_TEXT_SIZE - 1] of Char;   // The input text
     end;
 
     TSDL_QuitEvent = record
@@ -377,9 +377,32 @@ implementation
   var
     keyring: array [0..maxKeyBuffer - 1] of Integer;
     keybeg, keyend: Integer;
+    inputChar: Char;
+    inputText: Boolean;
     ticks: UInt32;
     quit: Boolean;
 
+    s2lc: array [0..KEY_MAX] of char = (
+      #00, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+      'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
+      '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', #00,
+      #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, '`', '-', '=', #00,
+      #09, '[', ']', #10, ';', #39, '\', '\', ',', '.', '/', ' ', #00, #00, #00, #00,
+      #00, #00, #00, #00, #00, '/', '*', '-', '+', #00, #00, #00, #00, #00, #00, #00,
+      #00, #00, #00, #00, '@', #00, ':', #00, '=', #00, ';', #00, #00, #00, #00, #00,
+      #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00
+    );
+    s2uc: array [0..KEY_MAX] of char = (
+      #00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+      'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ')', '!', '@', '#', '$',
+      '%', '^', '&', '*', '(', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', #00,
+      #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, '~', '_', '+', #00,
+      #09, '{', '}', #10, ':', '"', '|', '|', '<', '>', '?', ' ', #00, #00, #00, #00,
+      #00, #00, #00, #00, #00, '/', '*', '-', '+', #00, #00, #00, #00, #00, #00, #00,
+      #00, #00, #00, #00, '@', #00, ':', #00, '=', #00, ';', #00, #00, #00, #00, #00,
+      #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00, #00
+    );
+
   function IsEmptyKeyboard: Boolean;
   begin
     result := keybeg = keyend
@@ -465,15 +488,20 @@ implementation
 
   function SDL_IsTextInputActive: TSDL_Bool;
   begin
-    result := SDL_FALSE
+    if inputText then
+      result := SDL_TRUE
+    else
+      result := SDL_FALSE
   end;
 
   procedure SDL_StartTextInput;
   begin
+    inputText := True
   end;
 
   procedure SDL_StopTextInput;
   begin
+    inputText := False
   end;
 
 (********** JOYSTICK **********)
@@ -753,27 +781,17 @@ implementation
 
 (********** OPENGL MANAGEMENT **********)
 
-  function SDL_GL_MakeCurrent(window: PSDL_Window; context: TSDL_GLContext): SInt32;
-  begin
-    e_LogWriteln('SDL_GL_MakeCurrent');
-    result := 0
-  end;
-
-  procedure SDL_GL_DeleteContext(context: TSDL_GLContext);
+  function SDL_GL_SetAttribute(attr: TSDL_GLattr; value: SInt32): SInt32;
   begin
-    e_LogWriteln('SDL_GL_DeleteContext');
+    e_LogWritefln('SDL_GL_SetAttribute %s %s', [attr, value]);
+    allegro_error := 'Attribute ' + IntToStr(attr) + ' := ' + IntToStr(value) + 'not supported';
+    result := -1
   end;
 
-  procedure SDL_GL_SwapWindow(window: PSDL_Window);
-    var res: cint;
+  function SDL_GL_GetAttribute(attr: TSDL_GLattr; value: PInt): SInt32;
   begin
-    //e_LogWriteln('SDL_GL_SwapWindow');
-    ASSERT(sdl2allegro_screen <> nil);
-    acquire_screen;
-    blit(sdl2allegro_screen, screen, 0, 0, 0, 0, sdl2allegro_screen.w, sdl2allegro_screen.h);
-    res := show_video_bitmap(screen);
-    release_screen;
-//    ASSERT(res = 0);
+    e_LogWritefln('SDL_GL_GetAttribute %s', [attr]);
+    value^ := 0; result := -1
   end;
 
   function SDL_GL_CreateContext(window: PSDL_Window): TSDL_GLContext;
@@ -782,23 +800,30 @@ implementation
     result := window
   end;
 
-  function SDL_GL_SetSwapInterval(interval: SInt32): SInt32;
+  function SDL_GL_MakeCurrent(window: PSDL_Window; context: TSDL_GLContext): SInt32;
   begin
-    e_LogWritefln('SDL_GL_SetSwapInterval %s', [interval]);
+    e_LogWriteln('SDL_GL_MakeCurrent');
     result := 0
   end;
 
-  function SDL_GL_SetAttribute(attr: TSDL_GLattr; value: SInt32): SInt32;
+  procedure SDL_GL_DeleteContext(context: TSDL_GLContext);
   begin
-    e_LogWritefln('SDL_GL_SetAttribute %s %s', [attr, value]);
-    allegro_error := 'Attribute ' + IntToStr(attr) + ' := ' + IntToStr(value) + 'not supported';
-    result := -1
+    e_LogWriteln('SDL_GL_DeleteContext');
   end;
 
-  function SDL_GL_GetAttribute(attr: TSDL_GLattr; value: PInt): SInt32;
+  function SDL_GL_SetSwapInterval(interval: SInt32): SInt32;
   begin
-    e_LogWritefln('SDL_GL_GetAttribute %s', [attr]);
-    value^ := 0; result := -1
+    e_LogWritefln('SDL_GL_SetSwapInterval %s', [interval]);
+    result := 0
+  end;
+
+  procedure SDL_GL_SwapWindow(window: PSDL_Window);
+  begin
+    ASSERT(sdl2allegro_screen <> nil);
+    acquire_screen;
+    blit(sdl2allegro_screen, screen, 0, 0, 0, 0, sdl2allegro_screen.w, sdl2allegro_screen.h);
+    show_video_bitmap(screen);
+    release_screen;
   end;
 
 (********** EVENTS **********)
@@ -894,7 +919,7 @@ implementation
   end;
 
   function SDL_PollEvent(event: PSDL_Event): SInt32;
-    var alscan: Integer;
+    var alscan: Integer; pressed, shift, caps: Boolean;
   begin
     result := 0;
 
@@ -907,22 +932,47 @@ implementation
       Exit
     end;
 
+    if inputText and (inputChar <> #0) then
+    begin
+      event.type_ := SDL_TEXTINPUT;
+      event.text.timestamp := ticks;
+      event.text.windowID := 0;
+      event.text.text[0] := inputChar;
+      event.text.text[1] := #0;
+      inputChar := #0;
+      result := 1;
+      Exit
+    end;
+
     poll_keyboard;
     if not IsEmptyKeyboard then
     begin
       alscan := NextScancode;
-      if alscan and $80 = 0 then
+      pressed := alscan and $80 = 0;
+      if pressed then
+      begin
+        shift := key_shifts and KB_SHIFT_FLAG <> 0;
+        caps := key_shifts and KB_CAPSLOCK_FLAG <> 0;
+        if shift xor caps then
+          inputChar := s2uc[alscan and $7F]
+        else
+          inputChar := s2lc[alscan and $7F];
         event.type_ := SDL_KEYDOWN
+      end
       else
-        event.type_ := SDL_KEYUP;
+      begin
+        inputChar := #0;
+        event.type_ := SDL_KEYUP
+      end;
       event.key.timestamp := ticks;
       event.key.windowID := 0;
       (**** df not use it?
-      if alscan and $80 = 0 then
+      if pressed then
         event.key.state := SDL_PRESSED
       else
         event.key.state := SDL_RELEASED;
       ****)
+      event.key._repeat := 0;
       event.key.keysym.scancode := allegro_to_sdl_scancode(alscan);
       event.key.keysym.sym := 0; (* df not use it? *)
       event.key.keysym._mod := 0; (* df not use it? *)