Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Engine,Editor: add Touch Script API #2440

Draft
wants to merge 1 commit into
base: ags4
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Editor/AGS.Editor/Resources/agsdefns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ managed struct Point {
};
#endif

#ifdef SCRIPT_API_v400
managed struct TouchPoint {
int ID, X, Y;
bool IsDown;
};
#endif

#define CHARID int // $AUTOCOMPLETEIGNORE$
builtin struct ColorType {
char r,g,b;
Expand Down Expand Up @@ -2752,8 +2759,12 @@ builtin managed struct VideoPlayer {
/// The volume of this video's sound, from 0 to 100.
import attribute int Volume;
};
#endif

builtin struct Touch {
/// Returns array of touch points
import static TouchPoint*[] GetTouchPoints(); // $AUTOCOMPLETESTATICONLY$
};
#endif

import ColorType palette[PALETTE_SIZE];
import Mouse mouse;
Expand Down
2 changes: 2 additions & 0 deletions Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ target_sources(engine
ac/parser.cpp
ac/parser.h
ac/path_helper.h
ac/touch.cpp
ac/touch.h
ac/properties.cpp
ac/properties.h
ac/region.cpp
Expand Down
12 changes: 12 additions & 0 deletions Engine/ac/dynobj/scriptuserobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,15 @@ ScriptUserObject *ScriptStructHelpers::CreatePoint(int x, int y)
ref.Mgr->WriteInt32(ref.Obj, sizeof(int32_t), y);
return static_cast<ScriptUserObject*>(ref.Obj);
}

// Allocates managed struct containing four ints: ID, X, Y and Up/Down state
DynObjectRef ScriptStructHelpers::CreateTouchPointRef(int id, int x, int y, int down)
{
// FIXME: type id! (is it possible to RTTI?)
DynObjectRef ref = ScriptUserObject::Create(RTTI::NoType, sizeof(int32_t) * 4);
ref.Mgr->WriteInt32(ref.Obj, 0, id);
ref.Mgr->WriteInt32(ref.Obj, sizeof(int32_t), x);
ref.Mgr->WriteInt32(ref.Obj, sizeof(int32_t)*2, y);
ref.Mgr->WriteInt32(ref.Obj, sizeof(int32_t)*3, down);
return ref;
}
1 change: 1 addition & 0 deletions Engine/ac/dynobj/scriptuserobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ namespace ScriptStructHelpers
{
// Creates a managed Point object, represented as a pair of X and Y coordinates.
ScriptUserObject *CreatePoint(int x, int y);
DynObjectRef CreateTouchPointRef(int id, int x, int y, int down);
};

#endif // __AGS_EE_DYNOBJ__SCRIPTUSERSTRUCT_H
33 changes: 32 additions & 1 deletion Engine/ac/sys_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include "core/platform.h"
#include "ac/common.h"
#include "ac/gamesetup.h"
#include "ac/gamestate.h"
#include "ac/joystick.h"
#include "ac/gamesetupstruct.h"
#include "ac/keycode.h"
#include "ac/mouse.h"
#include "ac/timer.h"
#include "ac/touch.h"
#include "device/mousew32.h"
#include "gfx/graphicsdriver.h"
#include "platform/base/agsplatformdriver.h"
Expand Down Expand Up @@ -561,7 +563,7 @@ int ags_check_mouse_wheel()
struct Fingers
{
public:
static const int MAX_FINGERS = 2;
static const int MAX_FINGERS = 10;
static const int NO_INDEX = -1;

// store fingerId, return given finger index
Expand Down Expand Up @@ -786,6 +788,29 @@ static void sync_sys_mouse_pos()
}
}

// get finger position for pointer
static Point get_touch_to_pointer_pos(float x, float y) {
const int iw = gfxDriver->GetDisplayMode().Width;
const int ih = gfxDriver->GetDisplayMode().Height;
const float w = static_cast<float>(iw);
const float h = static_cast<float>(ih);
// Save real touch pos

const int x_real = AGSMath::Clamp<int>(static_cast<int>(std::roundf(x * w)), 0, iw-1);
const int y_real = AGSMath::Clamp<int>(static_cast<int>(std::roundf(y * h)),0, ih-1);

const Rect bounds = GameScaling.ScaleRange(play.GetMainViewport());

const int x_real_bounded = Math::Clamp(x_real, bounds.Left, bounds.Right);
const int y_real_bounded = Math::Clamp(y_real, bounds.Top, bounds.Bottom);

// duplicating code from Mouse::WindowToGame
const int p_x = GameScaling.X.UnScalePt(x_real_bounded) - play.GetMainViewport().Left;
const int p_y = GameScaling.Y.UnScalePt(y_real_bounded) - play.GetMainViewport().Top;

return Point(p_x, p_y);
}

static void on_sdl_touch_down(const SDL_TouchFingerEvent &event)
{
int finger_index = touch.fingers.push(event.fingerId);
Expand All @@ -794,6 +819,8 @@ static void on_sdl_touch_down(const SDL_TouchFingerEvent &event)
touch.fingers_down |= 1 << finger_index;
detect_double_tap(event, true);

on_touch_pointer_down(finger_index, get_touch_to_pointer_pos(event.x, event.y));

switch (t2m.mode)
{
case kTouchMouse_OneFingerDrag:
Expand Down Expand Up @@ -858,6 +885,8 @@ static void on_sdl_touch_up(const SDL_TouchFingerEvent &event)
touch.fingers_down &= ~(1 << finger_index);
detect_double_tap(event, false);

on_touch_pointer_up(finger_index, get_touch_to_pointer_pos(event.x, event.y));

switch (t2m.mode)
{
case kTouchMouse_OneFingerDrag:
Expand Down Expand Up @@ -914,6 +943,8 @@ static void on_sdl_touch_motion(const SDL_TouchFingerEvent &event)
int finger_index = touch.fingers.get_index(event.fingerId);
if(finger_index == Fingers::NO_INDEX) return;

on_touch_pointer_motion(finger_index, get_touch_to_pointer_pos(event.x, event.y));

switch (t2m.mode)
{
case kTouchMouse_OneFingerDrag:
Expand Down
106 changes: 106 additions & 0 deletions Engine/ac/touch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-2024 various contributors
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================

#include <array>
#include "ac/dynobj/scriptuserobject.h"
#include "ac/dynobj/cc_dynamicarray.h"
#include "device/mousew32.h"
#include "touch.h"
#include "ac/common.h"

enum class touch_state {
up,
motion,
down
};

struct touch_point {
int x;
int y;
bool down;
};

struct tp {
static const int MAX_POINTERS = 10;
int point_count = 0;
std::array<touch_point, MAX_POINTERS> touch_points = {};
} _tp;

void on_touch_pointer(int pointer_id, Point position, touch_state state)
{
_tp.point_count = std::max(pointer_id+1, _tp.point_count);
_tp.touch_points[pointer_id].x = position.X;
_tp.touch_points[pointer_id].y = position.Y;
_tp.touch_points[pointer_id].down = state != touch_state::up;
}

void on_touch_pointer_down(int pointer_id, Point position)
{
on_touch_pointer(pointer_id, position, touch_state::down);
}

void on_touch_pointer_motion(int pointer_id, Point position)
{
on_touch_pointer(pointer_id, position, touch_state::motion);
}

void on_touch_pointer_up(int pointer_id, Point position)
{
on_touch_pointer(pointer_id, position, touch_state::up);
}

DynObjectRef create_touchpoint(int n)
{
if (n < 0 || n >= tp::MAX_POINTERS)
quit("!Touch: invalid index for touchpoint");
Copy link
Contributor

@ivan-mogilko ivan-mogilko Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good idea to use quit here, for something that is neither a fatal error nor a user's fault.
An assertion and returning null should be enough.

But seeing how this function is used, I am not sure why is it needed at all.
The loop in Touch_GetTouchPoints() below could call CreateTouchPointRef directly instead, and limit iterations to MAX_POINTERS too.


touch_point p = _tp.touch_points[n];
return ScriptStructHelpers::CreateTouchPointRef(n, p.x, p.y, p.down);
}

void* Touch_GetTouchPoints()
{
std::vector<DynObjectRef> objs{};

for(int i=0; i< _tp.point_count; i++){
objs.push_back(create_touchpoint(i));
}

DynObjectRef arr = DynamicArrayHelpers::CreateScriptArray(std::move(objs));
return arr.Obj;
}

//=============================================================================
//
// Script API Functions
//
//=============================================================================

#include "script/script_api.h"
#include "script/script_runtime.h"

// Point*[] ()
RuntimeScriptValue Sc_Touch_GetTouchPoints(const RuntimeScriptValue *params, int32_t param_count)
{
API_SCALL_OBJ(ScriptUserObject, globalDynamicArray, Touch_GetTouchPoints);
}

void RegisterTouchAPI()
{
ScFnRegister touch_api[] = {
{ "Touch::GetTouchPoints^0", API_FN_PAIR(Touch_GetTouchPoints) },
};

ccAddExternalFunctions(touch_api);
}
24 changes: 24 additions & 0 deletions Engine/ac/touch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-2024 various contributors
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================
#ifndef __AGS_EE_AC_TOUCH_H
#define __AGS_EE_AC_TOUCH_H

#include "util/geometry.h"

void on_touch_pointer_down(int pointer_id, Point position);
void on_touch_pointer_motion(int pointer_id, Point position);
void on_touch_pointer_up(int pointer_id, Point position);


#endif //__AGS_EE_AC_TOUCH_H
2 changes: 2 additions & 0 deletions Engine/script/exports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern void RegisterMouseAPI();
extern void RegisterObjectAPI();
extern void RegisterOverlayAPI();
extern void RegisterParserAPI();
extern void RegisterTouchAPI();
extern void RegisterRegionAPI();
extern void RegisterRoomAPI();
extern void RegisterScreenAPI();
Expand Down Expand Up @@ -90,6 +91,7 @@ void setup_script_exports(ScriptAPIVersion base_api, ScriptAPIVersion compat_api
RegisterObjectAPI();
RegisterOverlayAPI();
RegisterParserAPI();
RegisterTouchAPI();
RegisterRegionAPI();
RegisterRoomAPI();
RegisterScreenAPI();
Expand Down
2 changes: 2 additions & 0 deletions Solutions/Engine.App/Engine.App.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@
<ClCompile Include="..\..\Engine\ac\object.cpp" />
<ClCompile Include="..\..\Engine\ac\overlay.cpp" />
<ClCompile Include="..\..\Engine\ac\parser.cpp" />
<ClCompile Include="..\..\Engine\ac\touch.cpp" />
<ClCompile Include="..\..\Engine\ac\properties.cpp" />
<ClCompile Include="..\..\Engine\ac\route_finder_impl.cpp" />
<ClCompile Include="..\..\Engine\ac\scriptcontainers.cpp" />
Expand Down Expand Up @@ -791,6 +792,7 @@
<ClInclude Include="..\..\Engine\ac\overlay.h" />
<ClInclude Include="..\..\Engine\ac\parser.h" />
<ClInclude Include="..\..\Engine\ac\path_helper.h" />
<ClInclude Include="..\..\Engine\ac\touch.h" />
<ClInclude Include="..\..\Engine\ac\properties.h" />
<ClInclude Include="..\..\Engine\ac\route_finder_impl.h" />
<ClInclude Include="..\..\Engine\ac\sys_events.h" />
Expand Down
6 changes: 6 additions & 0 deletions Solutions/Engine.App/Engine.App.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@
<ClCompile Include="..\..\Engine\ac\parser.cpp">
<Filter>Source Files\ac</Filter>
</ClCompile>
<ClCompile Include="..\..\Engine\ac\touch.cpp">
<Filter>Source Files\ac</Filter>
</ClCompile>
<ClCompile Include="..\..\Engine\ac\properties.cpp">
<Filter>Source Files\ac</Filter>
</ClCompile>
Expand Down Expand Up @@ -947,6 +950,9 @@
<ClInclude Include="..\..\Engine\ac\path_helper.h">
<Filter>Header Files\ac</Filter>
</ClInclude>
<ClInclude Include="..\..\Engine\ac\touch.h">
<Filter>Header Files\ac</Filter>
</ClInclude>
<ClInclude Include="..\..\Engine\ac\properties.h">
<Filter>Header Files\ac</Filter>
</ClInclude>
Expand Down