From 79a05da7687cb1fa00c62f031639d6933a321051 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 2 Feb 2019 17:17:33 +0300 Subject: [PATCH] implemented rotation and text input --- src/lib/allegro4/allegro.pas | 23 +++--- src/nogl/noGLALSW.inc | 29 ++++++-- src/wrappers/sdl2/sdl2allegro.inc | 114 +++++++++++++++++++++--------- 3 files changed, 117 insertions(+), 49 deletions(-) diff --git a/src/lib/allegro4/allegro.pas b/src/lib/allegro4/allegro.pas index 6f4456f..388b54a 100644 --- a/src/lib/allegro4/allegro.pas +++ b/src/lib/allegro4/allegro.pas @@ -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 diff --git a/src/nogl/noGLALSW.inc b/src/nogl/noGLALSW.inc index b9f1ddd..2974fdb 100644 --- a/src/nogl/noGLALSW.inc +++ b/src/nogl/noGLALSW.inc @@ -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); diff --git a/src/wrappers/sdl2/sdl2allegro.inc b/src/wrappers/sdl2/sdl2allegro.inc index ebedf9c..3392c68 100644 --- a/src/wrappers/sdl2/sdl2allegro.inc +++ b/src/wrappers/sdl2/sdl2allegro.inc @@ -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? *) -- 2.29.2