LibGame  v0.4.0
The LG Game Engine - Copyright (C) 2024-2025 ETMSoftware
lg_ui.c File Reference

Functions

const char ** lg_camcontrols_keys_str ()
 
uint32_t lg_get_user_input (LG_InputState *in, LG_TZW_Array *tzw_array)
 
LG_TouchZoneWindowlg_tzwin_new (const char *str, zboolean no_margin, LG_Color_u text_color, int x_loc, int y_loc, TTF_Font *f)
 
void lg_tzwin_show (LG_TouchZoneWindow *tzwin, lg_tzw_type type)
 
void lg_tzwin_free (LG_TouchZoneWindow *tzwin)
 
Rec2Di lg_tzwin_get_area (LG_TouchZoneWindow *tzwin)
 
void lg_draw_rect_corners (Rec2Di r, LG_Color_u c, int len)
 
void lg_draw_arrow (Rec2Di r, LG_Color_u c, lg_tzw_type type)
 
void lg_rectangle_to_arrow (Rec2Di r, lg_tzw_type arrow_type, Point2Di *p[])
 
void lg_draw_triangle (Rec2Di r, LG_Color_u c, lg_tzw_type type)
 
void lg_set_special_keys_repeat_delay (uint32_t delay)
 
LG_TZW_Arraylg_tzw_array_new ()
 
zboolean lg_tzwin_add_to_array (LG_TZW_Array *tzw_array, LG_TouchZoneWindow *tzwin)
 
LG_TZRec_Array lg_rec2di_array_from_tzw_array (LG_TZW_Array *tzw_array)
 
void lg_tzw_array_free_all_tzwin (LG_TZW_Array *tzw_array)
 
void lg_tzw_array_free_all_tzwin_after (LG_TZW_Array *tzw_array, uint32_t next_index)
 
void lg_tzw_array_free (LG_TZW_Array *tzw_array)
 
void lg_flush_in_clicks (LG_InputState *in)
 
void lg_input_state_info (LG_InputState *in)
 

Detailed Description

 === User Interface things ===

 Get all user input from keyboard, mouse, touchscreen
 Then try to make something coherent out of all that

 === Clickable/tappable areas helper macros for x and y ===
 (in lg_touchscreen.h)

 typedef enum {
    LG_FINGER_DOWN_NO_LOC = 0,
    LG_FINGER_DOWN_LEFT = 1,
    LG_FINGER_DOWN_H_CENTER = 2,
    LG_FINGER_DOWN_RIGHT = 4,
    LG_FINGER_DOWN_BOTTOM = 8,
    LG_FINGER_DOWN_V_CENTER = 16,
    LG_FINGER_DOWN_TOP = 32
 } lg_finger_down_loc;

    (below in this file)

       L     C     R
    -------------------
 T  |     |     |     |
    -------------------
 C  |     |     |     |
    -------------------
 B  |     |     |     |
    -------------------

 TZ_LEFT
 TZ_H_CENTER
 TZ_RIGHT
 TZ_BOTTOM
 TZ_V_CENTER
 TZ_TOP

 === Flight simulator/aircraft specific stuff ===

 yaw + pitch + roll = attitude (Yaw/Pitch/Roll = standard order)
 Other namings:
 yaw = heading, pan / pitch = elevation, tilt / roll = bank

 From: https://www1.grc.nasa.gov/beginners-guide-to-aeronautics/airplane-parts-function/

 Flight controls:
 =========================================================================
 yoke (left/right)       ->      ailerons                        -> roll
 yoke (forward/backward) ->      elevators (on horiz stabilizer) -> pitch
 rudder pedals           ->      rudder (on vert stabilizer)     -> yaw
 thrust lever(s)         ->      thrust
 flaps                   ->      increase lift
 air brakes
 =========================================================================

Function Documentation

◆ lg_camcontrols_keys_str()

const char** lg_camcontrols_keys_str ( )

Return an array of 9 help strings for cam controls keys

  • string[4] -> with <ctrl>
  • string[5] -> with <shift>
  • string[6] -> with <ctrl><shift>
  • string[7] -> with <alt>
Returns
The array of help strings describing what keys do

◆ lg_get_user_input()

uint32_t lg_get_user_input ( LG_InputState in,
LG_TZW_Array tzw_array 
)

Get user input (from keyboard, mouse, touchscreen) in LG_InputState and return in->last_pressed_key (SDLK_*) or LPK_MOUSE_CLICK_ACTIVITY + in->tzw_i in case of mouse left/right click

=== This is the func you should use to get user input inside the game main loop ===

Keyboard controls on Linux:

=========================================================================
| | UP | DOWN | LEFT | RIGHT |
=========================================================================
| | move_fwd++ | move_fwd-- | yaw-- | yaw++ |
=========================================================================
| <CTRL> | pitch-- | pitch++ | roll-- | roll++ |
=========================================================================
| <SHIFT> | v_orbit++ | v_orbit-- | h_orbit-- | h_orbit++ |
=========================================================================
| <CTRL><SHIFT> | move_up++ | move_up-- | cam_truck-- | cam_truck++ |
=========================================================================
| <ALT> | slow_motion |
=========================================================================

Keys which can be returned by lg_get_user_input() are so far: <enter>, <esc>, <space>, <F1> -> <F12>, <x>, <y>, <z> (see lg_get_special_keys_state())

Delay for <enter>, <esc>, plus <F1> -> <F12> is set to SPECIAL_KEYS_REPEAT_DELAY, can be overridden with lg_set_special_keys_repeat_delay()

Use lg_enable_mouse() / lg_disable_mouse() to read/ignore mouse inputs

On Android, returned value > 0 means requiring action associated with index + 1 of LG_TouchZoneWindow.area array

-> Now set in->tzw_i to index + 1 on both platforms

=== VARO: order of areas matters, ie it goes from left to right ===

Reset last_pressed_key if finger up is detected

NOTE: on Linux, if <up>/<down> with <ctrl><alt> or <ctrl><shift><alt> do nothing, they may have been hijacked by gnome keybindings - check out with dconf: /org/gnome/desktop/wm/keybindings/*

Parameters
inA pointer to a LG_InputState
tzw_arrayA pointer to a LG_TZW_Array
Returns
in->last_pressed_key

◆ lg_tzwin_new()

LG_TouchZoneWindow* lg_tzwin_new ( const char *  str,
zboolean  no_margin,
LG_Color_u  text_color,
int  x_loc,
int  y_loc,
TTF_Font *  f 
)

Create a new LG_TouchZoneWindow

A LG_TouchZoneWindow is a window that is 'clickable' (on Linux) or 'tappable' (on Android) and is rendered in immediate-mode, ie upadated and shown for every frame

=== Set touch_zone area ===

Parameters
strA string
no_margin
text_colorA LG_Color_u
xYou may also use one of TZ_LEFT, TZ_H_CENTER, TZ_RIGHT
yYou may also use one of TZ_BOTTOM, TZ_V_CENTER, TZ_TOP
fA TTF_Font
Returns
Addr of a new LG_TouchZoneWindow or NULL on error

◆ lg_tzwin_show()

void lg_tzwin_show ( LG_TouchZoneWindow tzwin,
lg_tzw_type  type 
)

Show a LG_TouchZoneWindow

Parameters
tzwinA pointer to a LG_TouchZoneWindow
typeA lg_tzw_type value

◆ lg_tzwin_free()

void lg_tzwin_free ( LG_TouchZoneWindow tzwin)

Free a LG_TouchZoneWindow

Parameters
tzwinA pointer to a LG_TouchZoneWindow

◆ lg_tzwin_get_area()

Rec2Di lg_tzwin_get_area ( LG_TouchZoneWindow tzwin)

Get area (Rec2Di) from a LG_TouchZoneWindow

Parameters
tzwinA pointer to a LG_TouchZoneWindow
Returns
tzwin->area (a Rec2Di)

◆ lg_draw_rect_corners()

void lg_draw_rect_corners ( Rec2Di  r,
LG_Color_u  c,
int  len 
)

Draw corners of a rect

Parameters
rA Rec2Di
cA LG_Color_u
lenLength of corner lines

◆ lg_draw_arrow()

void lg_draw_arrow ( Rec2Di  r,
LG_Color_u  c,
lg_tzw_type  type 
)

Draw an arrow

Parameters
rA Rec2Di, containing the arrow
cA LG_Color_u
typeOne of TZW_ARROW_UP, TZW_ARROW_DOWN, TZW_ARROW_LEFT, TZW_ARROW_RIGHT, TZW_DOUBLE_ARROW_HORIZ, TZW_DOUBLE_ARROW_VERT

◆ lg_rectangle_to_arrow()

void lg_rectangle_to_arrow ( Rec2Di  r,
lg_tzw_type  arrow_type,
Point2Di p[] 
)

Determine the points to draw a lg_tzw_type arrow (with TZW_ARROW_POINTS_NUM points) inside a rectangle

-> up/down/left/right_arrow

Parameters
rA Rec2Di
arrow_typeA lg_tzw_type value (see lg_draw_arrow() above)
pAn array of Point2Di pointers

◆ lg_draw_triangle()

void lg_draw_triangle ( Rec2Di  r,
LG_Color_u  c,
lg_tzw_type  type 
)

Draw a triangle pointing to left, right, up, down

Parameters
rA Rec2Di, containg the triangle
cA LG_Color_u
typeOne of TZW_TRIANGLE_LEFT, TZW_TRIANGLE_RIGHT, TZW_TRIANGLE_UP, TZW_TRIANGLE_DOWN

◆ lg_set_special_keys_repeat_delay()

void lg_set_special_keys_repeat_delay ( uint32_t  delay)

Set func keys repeat delay

Parameters
delayDelay in ms

◆ lg_tzw_array_new()

LG_TZW_Array* lg_tzw_array_new ( )

Create a new LG_TZW_Array and initialize it

(TZW and TZ win are shorts for LG_TouchZoneWindow)

The purpose of this struct is to keep an array of changeable TZ wins to show at each frame and to know which one was 'activated' (clicked or tapped)

#define N_TZW_MAX 256
// Array of all TZ wins for one frame
typedef struct {
LG_TouchZoneWindow *tzw[N_TZW_MAX];
typedef struct {
Rec2Di *r[N_TZW_MAX];
Rec2Di r0[N_TZW_MAX];

After that, when adding/removing TZ wins, order matters, ie it goes from left to right

When a TZ win area is clicked/tapped, LG_InputState->tzw_i is set to index + 1

// uint32_t lg_get_user_input(LG_InputState *in, Rec2Di **r) // ie Rec2Di *[]
lg_get_user_input(in, (Rec2Di **)&r_array.r);

Use in->tzw_i to decide which action to take, knowing that:

  • in->tzw_i = index + 1 of clicked/tapped TZ win in TZ win array
  • in->tzw_i = 0 means no TZ win was clicked/tapped

This API seems a bit complicated at first, but to get a better sense of how it works, make sure to check out the code in scene_editor/main_loop.c, where it is used extensively

Returns
A pointer to the new LG_TZW_Array if OK, NULL on error

◆ lg_tzwin_add_to_array()

zboolean lg_tzwin_add_to_array ( LG_TZW_Array tzw_array,
LG_TouchZoneWindow tzwin 
)

Add a TZ win at first NULL element found

Parameters
tzw_arrayPointer to a LG_TZW_Array
tzwinPointer to a LG_TouchZoneWindow
Returns
TRUE if OK, FALSE on error

◆ lg_rec2di_array_from_tzw_array()

LG_TZRec_Array lg_rec2di_array_from_tzw_array ( LG_TZW_Array tzw_array)

Create and return a LG_TZRec_Array from a LG_TZW_Array

Parameters
tzw_arrayPointer to a LG_TZW_Array
Returns
A new LG_TZRec_Array

◆ lg_tzw_array_free_all_tzwin()

void lg_tzw_array_free_all_tzwin ( LG_TZW_Array tzw_array)

Free all TZ win from a TZ win array

Parameters
tzw_arrayPointer to a LG_TZW_Array

◆ lg_tzw_array_free_all_tzwin_after()

void lg_tzw_array_free_all_tzwin_after ( LG_TZW_Array tzw_array,
uint32_t  next_index 
)

Free all TZ win after next_index from a TZ win array

Parameters
tzw_arrayPointer to a LG_TZW_Array
next_index

◆ lg_tzw_array_free()

void lg_tzw_array_free ( LG_TZW_Array tzw_array)

Free a TZ win array

Parameters
tzw_arrayPointer to a LG_TZW_Array

◆ lg_flush_in_clicks()

void lg_flush_in_clicks ( LG_InputState in)

Flush mouse clicks and reset associated states in LG_InputState

Parameters
inPointer to LG_InputState

◆ lg_input_state_info()

void lg_input_state_info ( LG_InputState in)

Take a snapshot of user input state

Parameters
inLG_InputState
LG_InputState
Definition: lg_ui.h:28
LG_TZW_Array
Definition: lg_ui.h:103
lg_tzw_array_new
LG_TZW_Array * lg_tzw_array_new()
Definition: lg_ui.c:786
lg_rec2di_array_from_tzw_array
LG_TZRec_Array lg_rec2di_array_from_tzw_array(LG_TZW_Array *tzw_array)
Definition: lg_ui.c:825
lg_get_user_input
uint32_t lg_get_user_input(LG_InputState *in, LG_TZW_Array *tzw_array)
Definition: lg_ui.c:179
LG_TZRec_Array
Definition: lg_ui.h:108
LG_TouchZoneWindow
Definition: lg_ui.h:77
Rec2Di
Definition: lg_gr_func.h:49