Commit a6cec353 authored by Kirinn's avatar Kirinn

sakuinput: Implement textbox scrolling with gamepad right stick

parent 99dfd944
......@@ -39,6 +39,12 @@ begin
end;
if sdl_GamepadH <> NIL then log('Opened gamepad: ' + SDL_GameControllerName(sdl_GamepadH));
with sysvar do begin
gamepadLeftStick.x := 0; // sticks should be in -32768..32767 by SDK docs, triggers in 0..32767.
gamepadLeftStick.y := 0;
gamepadRightStick.x := 0;
gamepadRightStick.y := 0;
end;
end;
procedure AutosizeGameWindow;
......@@ -355,7 +361,7 @@ begin
SDL_MOUSEWHEEL: UserInput_Wheel(evd^.wheel.y);
SDL_CONTROLLERBUTTONDOWN: UserInput_GamepadButtonDown(evd^.cbutton.button);
SDL_CONTROLLERBUTTONUP: UserInput_GamepadButtonUp(evd^.cbutton.button);
//SDL_CONTROLLERAXISMOTION: UserInput_GamepadAxis(evd^.caxis.axis, evd^.caxis.value);
SDL_CONTROLLERAXISMOTION: UserInput_GamepadAxis(evd^.caxis.axis, evd^.caxis.value);
end;
end;
......@@ -421,6 +427,10 @@ begin
event.hasTriggeredInterrupt := FALSE;
sysvar.swallowRemainingUserInput := FALSE;
while SDL_PollEvent(@evd) <> 0 do HandleSDLevent(@evd);
with sysvar do begin
if (gamepadLeftStick.x or gamepadLeftStick.y) <> 0 then UserInput_GamepadLeftStick(tickcount);
if (gamepadRightStick.x or gamepadRightStick.y) <> 0 then UserInput_GamepadRightStick(tickcount);
end;
if sakuparam.autoTest then UserInput_Auto;
// If we just entered single-stepping mode...
......
......@@ -276,7 +276,7 @@ type TTextBox = class
destructor Destroy; override;
procedure Clear;
procedure Scroll(scrollp : longint; msecs : longint = -1; movetype : EMoveType = MT_HALFCOS; owningfiber : longint = -1);
procedure ScrollTo(scrollp : longint; msecs : longint = -1; movetype : EMoveType = MT_HALFCOS; owningfiber : longint = -1);
procedure Hide(makehidden : boolean);
procedure Snap;
procedure GetNewFont(heightp : dword);
......
......@@ -318,7 +318,7 @@ begin
{$endif}
end;
procedure TTextBox.Scroll(
procedure TTextBox.ScrollTo(
scrollp : longint; msecs : longint = -1; movetype : EMoveType = MT_HALFCOS; owningfiber : longint = -1);
// Sets up an instant or gradual scroll effect for the box, from its current scroll position to the given new one. The scroll
// position is a pixel value, feeding directly into the box's contentwinscrollofsp. Any ongoing scroll effect is immediately
......
......@@ -57,7 +57,7 @@ begin
and ((Choicematic.isActive = FALSE) or (Choicematic.choiceBox <> i))
and (contentWinScrollOfsP + longint(contentWinSizeP.h) < longint(contentFullHeightP))
then begin
Scroll(contentWinScrollOfsP + longint(contentWinSizeP.h));
ScrollTo(contentWinScrollOfsP + longint(contentWinSizeP.h));
result := TRUE;
end;
end;
......
......@@ -85,7 +85,7 @@ begin
i := lightlocp.top - (lineHeightP - font.heightP + 1) shr 1;
if i < contentWinScrollOfsP then newscrollofsp := i;
if newscrollofsp <> contentWinScrollOfsP then Scroll(newscrollofsp);
if newscrollofsp <> contentWinScrollOfsP then ScrollTo(newscrollofsp);
// Deduct choicebox's final scrolling offset.
dec(lightlocp.top, newscrollofsp);
......
......@@ -244,6 +244,8 @@ var sysvar : record
windowSize : TSizeP;
{$ifdef sakucon}
caretLocP : TCoordP; // if text input is enabled, the console port places the console caret here
{$else}
gamepadLeftStick, gamepadRightStick : TCoord32k;
{$endif}
mouseLocP : TCoordP; // straight px coord within program window
......
......@@ -440,7 +440,7 @@ begin
if newpos + longint(contentWinSizeP.h) > longint(contentFullHeightP) then
newpos := contentFullHeightP - contentWinSizeP.h;
if newpos < 0 then newpos := 0;
Scroll(newpos);
ScrollTo(newpos);
end;
end;
{$endif}
......@@ -708,7 +708,7 @@ begin
// Scroll visible, freescrollable boxes.
for i := high(BoxHub.textbox) downto 1 do with BoxHub.textbox[i] do
if (boxState <> BS_NULL) and (isHidden = FALSE) and (style.freeScrollable) then begin
if contentWinScrollOfsP > 0 then Scroll(0);
if contentWinScrollOfsP > 0 then ScrollTo(0);
exit;
end;
end;
......@@ -741,7 +741,7 @@ begin
for i := high(BoxHub.textbox) downto 1 do with BoxHub.textbox[i] do
if (boxState <> BS_NULL) and (isHidden = FALSE) and (style.freeScrollable) then begin
j := contentFullHeightP - contentWinSizeP.h;
if contentWinScrollOfsP < j then Scroll(j);
if contentWinScrollOfsP < j then ScrollTo(j);
exit;
end;
end;
......@@ -761,9 +761,9 @@ begin
if (style.freeScrollable) and (contentWinScrollOfsP > 0) then begin
j := contentWinSizeP.h - lineHeightP;
if contentWinScrollOfsP > j then
Scroll(contentWinScrollOfsP - j)
ScrollTo(contentWinScrollOfsP - j)
else
Scroll(0);
ScrollTo(0);
exit;
end;
end;
......@@ -784,7 +784,7 @@ begin
j := contentWinScrollOfsP + longint(contentWinSizeP.h - lineHeightP);
if j > contentFullHeightP - contentWinSizeP.h then j := contentFullHeightP - contentWinSizeP.h;
if contentWinScrollOfsP < j then begin
Scroll(j);
ScrollTo(j);
exit;
end;
end;
......@@ -807,9 +807,9 @@ begin
for i := high(BoxHub.textbox) downto 1 do with BoxHub.textbox[i] do
if (style.freeScrollable) and (contentWinScrollOfsP > 0) then begin
if contentWinScrollOfsP > longint(lineHeightP) then
Scroll(contentWinScrollOfsP - lineHeightP)
ScrollTo(contentWinScrollOfsP - lineHeightP)
else
Scroll(0);
ScrollTo(0);
exit;
end;
// Move to closest mouseoverable.
......@@ -836,7 +836,7 @@ begin
j := contentWinScrollOfsP + longint(lineHeightP);
if j > contentFullHeightP - contentWinSizeP.h then j := contentFullHeightP - contentWinSizeP.h;
if contentWinScrollOfsP < j then begin
Scroll(j);
ScrollTo(j);
exit;
end;
end;
......@@ -1011,13 +1011,13 @@ begin
SDL_CONTROLLER_BUTTON_BACK: UserInput_CtrlB;
// button A: low position
// button A/cross: low position
SDL_CONTROLLER_BUTTON_A: UserInput_Enter;
// button B: right position
// button B/circle: right position
SDL_CONTROLLER_BUTTON_B: UserInput_GamepadCancel;
// button Y: top position
// button Y/triangle: top position
SDL_CONTROLLER_BUTTON_Y: UserInput_GamepadMenu;
// button X: left position
// button X/square: left position
SDL_CONTROLLER_BUTTON_X: UserInput_CtrlT;
end;
end;
......@@ -1032,9 +1032,53 @@ begin
end;
end;
{procedure UserInput_GamepadAxis(anum : TSDL_GameControllerAxis; value : longint);
procedure UserInput_GamepadAxis(anum : TSDL_GameControllerAxis; value : longint);
begin
end;}
if abs(value) < preference.ctrlDeadZone then value := 0;
// Stick ranges: -32768..32767, where negatives are up/left.
case anum of
SDL_CONTROLLER_AXIS_LEFTX: sysvar.gamepadLeftStick.x := value;
SDL_CONTROLLER_AXIS_LEFTY: sysvar.gamepadLeftStick.y := value;
SDL_CONTROLLER_AXIS_RIGHTX: sysvar.gamepadRightStick.x := value;
SDL_CONTROLLER_AXIS_RIGHTY: sysvar.gamepadRightStick.y := value;
end;
end;
procedure UserInput_GamepadLeftStick(tickcount : dword);
begin
end;
procedure UserInput_GamepadRightStick(tickcount : dword);
var i : dword;
j, scrollby : longint;
begin
if sysvar.gamepadRightStick.y = 0 then exit; // actions only defined for y-axis
// If textboxes are hidden, ignore.
if BoxHub.allBoxesHidden then exit;
// Scroll topmost scrollable box.
for i := high(BoxHub.textbox) downto 1 do with BoxHub.textbox[i] do
if (boxState <> BS_NULL) and (isHidden = FALSE) and (style.freeScrollable) then begin
// For best precision, standard practice is to square the stick value, but still keep the 32k range.
j := sarlongint(sysvar.gamepadRightStick.y * abs(sysvar.gamepadRightStick.y), 15);
// Scroll values are pixel-based, so needs to be multiplied by box's parent viewport pixel size to make the
// scrolling resolution-independent. Also, multiply by tickcount to be framerate-independent.
scrollby := round(single(j * viewport[boxInViewport].viewportSizeP.h) * tickcount / 16384000);
if (scrollby < 0) and (contentWinScrollOfsP > 0) then begin
if contentWinScrollOfsP > -scrollby then
ScrollTo(contentWinScrollOfsP + scrollby, tickcount)
else
ScrollTo(0, tickcount);
end;
if scrollby > 0 then begin
j := contentWinScrollOfsP + scrollby;
if j > contentFullHeightP - contentWinSizeP.h then j := contentFullHeightP - contentWinSizeP.h;
if contentWinScrollOfsP < j then ScrollTo(j, tickcount);
end;
exit;
end;
end;
{$endif !sakucon}
// ------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment