Skip to content

Commit

Permalink
library: rework minimap events
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamcake committed Nov 30, 2024
1 parent 12db295 commit 12d8f0a
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 80 deletions.
93 changes: 64 additions & 29 deletions src/library/doc.texi
Original file line number Diff line number Diff line change
Expand Up @@ -593,14 +593,29 @@ end)

@eventobjectwarning{}

@node functions-onminimap
@section onminimap
@node functions-onminimapterrain
@section onminimapterrain

@eventhandler{minimap rendering events, @ref{objects-minimap}}
@eventhandler{minimap terrain events, @ref{objects-minimapterrain}}

@example lua
@verbatim
bolt.onminimap(function (event)
bolt.onminimapterrain(function (event)
-- ...
end)
@end verbatim
@end example

@eventobjectwarning{}

@node functions-onminimaprender2d
@section onminimaprender2d

@eventhandler{minimap render2d events, @ref{objects-batch2d}}

@example lua
@verbatim
bolt.onminimaprender2d(function (event)
-- ...
end)
@end verbatim
Expand Down Expand Up @@ -1811,8 +1826,9 @@ local m1, m2, m3, m4,
@node objects-batch2d
@section Batch2D Event

A Batch2D event comes from @ref{functions-onrender2d}. It occurs when
the game draws a batch of 2D icons to the screen. 2D icon renders are
A Batch2D event comes from @ref{functions-onrender2d}. or
@ref{functions-onminimaprender2d}. It occurs when the game draws a batch
of 2D icons to the screen, or to the minimap image. 2D icon renders are
uploaded to the GPU in batches rather than one-at-a-time, so to look for
an individual image, you'll need to iterate through each individual
image in the batch, by iterating through the vertices. The number of
Expand Down Expand Up @@ -1854,25 +1870,18 @@ separate triangles). To future-proof against possible engine updates,
it's recommended to use this function instead of hard-coding the number
6 into your plugin.

@node batch2d-isminimap
@subsection isminimap

Returns true if this render targets the minimap surface instead of the
user interface. There will usually be a maximum of one batch per frame
targeting the minimap surface. Renders that target the minimap will
overlay icons onto the static map image.

@node batch2d-targetsize
@subsection targetsize

Returns the width and height of the target area of this render, in
pixels.

If @ref{batch2d-isminimap} is true, this will be the size of the minimap
surface - usually 256x256. Otherwise, this will be proportional to the
size of the inner area of the game window - that is, if the user has an
interface scaling other than 100%, it will be bigger or smaller than
that area, proportionally.
For a miminap render event, this will be the size of the minimap image,
usually 256x256. For a normal render2d event, this will be proportional
to the size of the inner area of the game window, given by
@ref{functions-gamewindowsize} - that is, if the user has an interface
scaling other than 100%, it will be bigger or smaller than that area,
proportionally.

@node batch2d-vertexxy
@subsection vertexxy
Expand Down Expand Up @@ -2421,40 +2430,66 @@ local viewprojmatrix = event:modelviewprojmatrix(model)
@end verbatim
@end example

@node objects-minimap
@section Minimap Event
@node objects-minimapterrain
@section Minimap Terrain Event

A Minimap event comes from @ref{functions-onminimap}. It occurs when the
minimap gets drawn to the game view. This happens once per frame, unless
the minimap isn't visible. The event can be queried for some useful
information like the angle it's rotated to and the world position it's
centered on.
A Minimap Terrain event comes from @ref{functions-onminimapterrain}. It
occurs when the background terrain gets drawn to the minimap image,
which usually happens once per frame, unless the minimap isn't visible.
The terrain can't be inspected directly, but this event can be queried
for some useful information, like the angle the minimap is rotated to
and the world position it's centered on.

@eventobjectwarning{}

@node minimap-angle
@node minimapterrain-angle
@subsection angle

Returns the angle at which the minimap background image is being
rendered, in radians. The angle is 0 when upright (facing directly
north), and increases counter-clockwise (note that turning the camera
clockwise rotates the minimap counter-clockwise and vice versa).

@node minimap-scale
@node minimapterrain-scale
@subsection scale

Returns the scale at which the minimap background image is being
rendered. This indicates how far in or out the minimap is zoomed. It
appears to be capped between roughly 0.5 and 3.5.

@node minimap-position
@node minimapterrain-position
@subsection position

Returns an estimate of the X and Y position the minimap is centered on,
in world coordinates. This is only a rough estimate and can move around
a lot even while standing still. It usually doesn't vary by more than
half a tile.

@node objects-renderminimap
@section Render Minimap Event

A render minimap event comes from @ref{functions-onrenderminimap}. It
occurs when the minimap image gets drawn to the game window, which
usually happens once per frame, unless the minimap isn't visible. This
event can be used to find out the location of the minimap on the user's
screen. To get the minimap contents, see @ref{objects-minimapterrain}
and @ref{objects-minimaprender2d}.

@eventobjectwarning{}

@node renderminimap-xywh
@subsection xywh

Returns the x, y, width and height of where the minimap is being drawn
on the screen, in pixel coordinates. The X and Y are relative to the
top-left pixel of the inner area of the window.

@example lua
@verbatim
local x, y, width, height = event:xywh()
@end verbatim
@end example

@node objects-swapbuffers
@section SwapBuffers event

Expand Down
28 changes: 21 additions & 7 deletions src/library/gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,20 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
struct GLTexture2D* tex = c->texture_units[diffuse_map];
struct GLTexture2D* tex_target = _bolt_context_get_texture(c, draw_tex);

if (tex->is_minimap_tex_big) {
if (tex->is_minimap_tex_small && count == 6) {
const struct GLAttrBinding* binding = &attributes[c->bound_program->loc_aVertexPosition2D];
int32_t xy0[2];
int32_t xy2[2];
if (!_bolt_get_attr_binding_int(c, binding, 0, 2, xy0)) return;
if (!_bolt_get_attr_binding_int(c, binding, 2, 2, xy2)) return;
const struct RenderMinimapEvent event = {
.target_x = (int16_t)xy0[0],
.target_y = (int16_t)(roundf(2.0 / projection_matrix[5]) - xy0[1]),
.target_w = (uint16_t)(xy2[0] - xy0[0]),
.target_h = (uint16_t)(xy0[1] - xy2[1]),
};
_bolt_plugin_handle_renderminimap(&event);
} else if (tex->is_minimap_tex_big) {
tex_target->is_minimap_tex_small = 1;
if (count == 6) {
// get XY and UV of first two vertices
Expand Down Expand Up @@ -1447,12 +1460,12 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
const double cx = (scaled_xoffset + (small_tex_cx * angle_cos) - (small_tex_cy * angle_sin)) / dist_ratio;
const double cy = (scaled_yoffset + (small_tex_cx * angle_sin) + (small_tex_cy * angle_cos)) / dist_ratio;

struct RenderMinimapEvent render;
struct MinimapTerrainEvent render;
render.angle = map_angle_rads;
render.scale = dist_ratio;
render.x = tex->minimap_center_x + (64.0 * (cx - (double)(tex->width >> 1)));
render.y = tex->minimap_center_y + (64.0 * (cy - (double)(tex->height >> 1)));
_bolt_plugin_handle_minimap(&render);
_bolt_plugin_handle_minimapterrain(&render);
}
}
} else if (c->current_draw_framebuffer == 0) {
Expand All @@ -1475,7 +1488,6 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
batch.screen_height = vertex_userdata.screen_height;
batch.index_count = count;
batch.vertices_per_icon = 6;
batch.is_minimap = tex_target && tex_target->is_minimap_tex_small;
batch.vertex_functions.userdata = &vertex_userdata;
batch.vertex_functions.xy = _bolt_gl_plugin_drawelements_vertex2d_xy;
batch.vertex_functions.atlas_details = _bolt_gl_plugin_drawelements_vertex2d_atlas_details;
Expand All @@ -1487,6 +1499,8 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
batch.texture_functions.compare = _bolt_gl_plugin_texture_compare;
batch.texture_functions.data = _bolt_gl_plugin_texture_data;

void (*handler)(const struct RenderBatch2D*) = tex_target && tex_target->is_minimap_tex_small ? _bolt_plugin_handle_minimaprender2d : _bolt_plugin_handle_render2d;

if (tex->icons) {
size_t batch_start = 0;
for (size_t i = 0; i < count; i += batch.vertices_per_icon) {
Expand All @@ -1505,7 +1519,7 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
batch.index_count = i - batch_start;
if (batch.index_count) {
vertex_userdata.indices = indices + batch_start;
_bolt_plugin_handle_render2d(&batch);
handler(&batch);
}
int32_t xy0[2];
int32_t xy2[2];
Expand All @@ -1524,10 +1538,10 @@ void _bolt_gl_onDrawElements(GLenum mode, GLsizei count, GLenum type, const void
if (batch_start < count) {
batch.index_count = count - batch_start;
vertex_userdata.indices = indices + batch_start;
_bolt_plugin_handle_render2d(&batch);
handler(&batch);
}
} else {
_bolt_plugin_handle_render2d(&batch);
handler(&batch);
}
}
}
Expand Down
35 changes: 19 additions & 16 deletions src/library/plugin/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,18 @@ uint64_t _bolt_plugin_get_last_mouseevent_windowid() { return last_mouseevent_wi
static void _bolt_plugin_ipc_init(BoltSocketType*);
static void _bolt_plugin_ipc_close(BoltSocketType);

static void _bolt_plugin_window_onreposition(struct EmbeddedWindow*, struct RepositionEvent*);
static void _bolt_plugin_window_onmousemotion(struct EmbeddedWindow*, struct MouseMotionEvent*);
static void _bolt_plugin_window_onmousebutton(struct EmbeddedWindow*, struct MouseButtonEvent*);
static void _bolt_plugin_window_onmousebuttonup(struct EmbeddedWindow*, struct MouseButtonEvent*);
static void _bolt_plugin_window_onscroll(struct EmbeddedWindow*, struct MouseScrollEvent*);
static void _bolt_plugin_window_onmouseleave(struct EmbeddedWindow*, struct MouseMotionEvent*);
static void _bolt_plugin_handle_mousemotion(struct MouseMotionEvent*);
static void _bolt_plugin_handle_mousebutton(struct MouseButtonEvent*);
static void _bolt_plugin_handle_mousebuttonup(struct MouseButtonEvent*);
static void _bolt_plugin_handle_scroll(struct MouseScrollEvent*);

static void _bolt_plugin_handle_swapbuffers(struct SwapBuffersEvent*);
static void _bolt_plugin_window_onreposition(struct EmbeddedWindow*, const struct RepositionEvent*);
static void _bolt_plugin_window_onmousemotion(struct EmbeddedWindow*, const struct MouseMotionEvent*);
static void _bolt_plugin_window_onmousebutton(struct EmbeddedWindow*, const struct MouseButtonEvent*);
static void _bolt_plugin_window_onmousebuttonup(struct EmbeddedWindow*, const struct MouseButtonEvent*);
static void _bolt_plugin_window_onscroll(struct EmbeddedWindow*, const struct MouseScrollEvent*);
static void _bolt_plugin_window_onmouseleave(struct EmbeddedWindow*, const struct MouseMotionEvent*);
static void _bolt_plugin_handle_mousemotion(const struct MouseMotionEvent*);
static void _bolt_plugin_handle_mousebutton(const struct MouseButtonEvent*);
static void _bolt_plugin_handle_mousebuttonup(const struct MouseButtonEvent*);
static void _bolt_plugin_handle_scroll(const struct MouseScrollEvent*);

static void _bolt_plugin_handle_swapbuffers(const struct SwapBuffersEvent*);

const struct PluginManagedFunctions* _bolt_plugin_managed_functions() {
return &managed_functions;
Expand Down Expand Up @@ -126,7 +126,7 @@ uint64_t _bolt_plugin_itemicon_hash(const void* item, uint64_t seed0, uint64_t s
static struct hashmap* plugins;

#define DEFINE_CALLBACK(APINAME, STRUCTNAME) \
void _bolt_plugin_handle_##APINAME(struct STRUCTNAME* e) { \
void _bolt_plugin_handle_##APINAME(const struct STRUCTNAME* e) { \
if (!overlay_inited) return; \
size_t iter = 0; \
void* item; \
Expand Down Expand Up @@ -161,7 +161,7 @@ void _bolt_plugin_handle_##APINAME(struct STRUCTNAME* e) { \
#define DEFINE_CALLBACK_STATIC(APINAME, STRUCTNAME) static DEFINE_CALLBACK(APINAME, STRUCTNAME)

#define DEFINE_WINDOWEVENT(APINAME, REGNAME, EVNAME) \
void _bolt_plugin_window_on##APINAME(struct EmbeddedWindow* window, struct EVNAME* event) { \
void _bolt_plugin_window_on##APINAME(struct EmbeddedWindow* window, const struct EVNAME* event) { \
if (window->is_deleted) return; \
lua_State* state = window->plugin; \
if (window->is_browser) { \
Expand Down Expand Up @@ -1125,7 +1125,9 @@ DEFINE_CALLBACK_STATIC(swapbuffers, SwapBuffersEvent)
DEFINE_CALLBACK(render2d, RenderBatch2D)
DEFINE_CALLBACK(render3d, Render3D)
DEFINE_CALLBACK(rendericon, RenderItemIconEvent)
DEFINE_CALLBACK(minimap, RenderMinimapEvent)
DEFINE_CALLBACK(minimapterrain, MinimapTerrainEvent)
DEFINE_CALLBACK(minimaprender2d, RenderBatch2D)
DEFINE_CALLBACK(renderminimap, RenderMinimapEvent)
DEFINE_CALLBACK(mousemotion, MouseMotionEvent)
DEFINE_CALLBACK(mousebutton, MouseButtonEvent)
DEFINE_CALLBACK(mousebuttonup, MouseButtonEvent)
Expand Down Expand Up @@ -1219,7 +1221,8 @@ lua_settable(plugin->state, LUA_REGISTRYINDEX);
SETMETA(render2d)
SETMETA(render3d)
SETMETA(rendericon)
SETMETA(minimap)
SETMETA(minimapterrain)
SETMETA(renderminimap)
SETMETA(point)
SETMETA(transform)
SETMETA(buffer)
Expand Down
26 changes: 19 additions & 7 deletions src/library/plugin/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ struct RenderBatch2D {
uint32_t screen_height;
uint32_t index_count;
uint32_t vertices_per_icon;
uint8_t is_minimap;
struct Vertex2DFunctions vertex_functions;
struct TextureFunctions texture_functions;
};
Expand Down Expand Up @@ -305,13 +304,20 @@ struct RenderItemIconEvent {
uint16_t target_h;
};

struct RenderMinimapEvent {
struct MinimapTerrainEvent {
double angle;
double scale;
double x;
double y;
};

struct RenderMinimapEvent {
int16_t target_x;
int16_t target_y;
uint16_t target_w;
uint16_t target_h;
};

struct SwapBuffersEvent {
#if defined(_MSC_VER)
// MSVC doesn't allow empty structs
Expand Down Expand Up @@ -391,16 +397,22 @@ void _bolt_plugin_shm_resize(struct BoltSHM* shm, size_t length, uint64_t new_id
void _bolt_plugin_shm_remap(struct BoltSHM* shm, size_t length, void* handle);

/// Sends a RenderBatch2D to all plugins.
void _bolt_plugin_handle_render2d(struct RenderBatch2D*);
void _bolt_plugin_handle_render2d(const struct RenderBatch2D*);

/// Sends a Render3D to all plugins.
void _bolt_plugin_handle_render3d(struct Render3D*);
void _bolt_plugin_handle_render3d(const struct Render3D*);

/// Sends a RenderItemIconEvent to all plugins.
void _bolt_plugin_handle_rendericon(struct RenderItemIconEvent*);
void _bolt_plugin_handle_rendericon(const struct RenderItemIconEvent*);

/// Sends a MinimapTerrainEvent to all plugins.
void _bolt_plugin_handle_minimapterrain(const struct MinimapTerrainEvent*);

/// Sends a RenderBatch2D for the minimap image to all plugins.
void _bolt_plugin_handle_minimaprender2d(const struct RenderBatch2D*);

/// Sends a RenderMinimap to all plugins.
void _bolt_plugin_handle_minimap(struct RenderMinimapEvent*);
/// Sends a RenderMinimapEvent to all plugins.
void _bolt_plugin_handle_renderminimap(const struct RenderMinimapEvent*);

/// Gets the value from the monotonic microsecond counter, returning true on success or false on failure.
/// Can only fail on Windows, and even then there are no known cases where it would fail.
Expand Down
Loading

0 comments on commit 12d8f0a

Please sign in to comment.