OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
object.h File Reference

Game object engine with physics and collision (CONTRIB module). More...

#include <snes/types.h>

Go to the source code of this file.

Classes

struct  t_objs
 Game object data structure. More...

Macros

#define OB_MAX   80
 Maximum number of objects in the game.
#define OB_SIZE   64
 Object size in bytes.
#define OB_TYPE_MAX   64
 Maximum number of object types.

Typedefs

typedef void(* ObjInitFn) (u16 xp, u16 yp, u16 type, u16 minx, u16 maxx)
 Init callback of an object type, called by objLoadObjects() per table entry.
typedef void(* ObjUpdateFn) (u16 idx)
 Update / refresh callback of an object type; idx is the slot index.

Functions

void objCollidMap (u16 objindex)
 Check object collision with map tiles.
void objCollidMap1D (u16 objindex)
 Check object collision with map (no gravity).
void objCollidMapWithSlopes (u16 objindex)
 Check object collision with map tiles including slopes.
u16 objCollidObj (u16 idx1, u16 idx2)
 Test collision between two objects.
u16 objGetCurrentId (void)
 Handle of the last object objNew() created.
u16 objGetPointer (u16 objhandle)
 Get pointer to an object from its handle.
void objInitEngine (void)
 Initialize the object engine.
void objInitFriction1D (u16 friction)
 Opt into friction for objCollidMap1D().
void objInitFunctions (u8 objtype, ObjInitFn initfct, ObjUpdateFn updfct, ObjUpdateFn reffct)
 Register callback functions for an object type.
void objInitGravity (u16 objgravity, u16 objfriction)
 Set gravity and friction values.
void objKill (u16 objhandle)
 Kill an object.
void objKillAll (void)
 Kill all active objects.
void objKillCurrent (void)
 Kill the object being updated.
void objLoadObjects (const u8 *sourceO)
 Load objects from a data table.
u16 objNew (u8 objtype, u16 x, u16 y)
 Create a new object.
void objRefreshAll (void)
 Refresh sprites for all on-screen objects.
void objUpdateAll (void)
 Update all active objects.
void objUpdateXY (u16 objindex)
 Update object position from velocity.

Variables

FAR t_objs objWorkspace
 Object workspace.

Detailed Description

Game object engine with physics and collision (CONTRIB module).

Note
This is a contrib module, not core SDK. The implementation lives in lib/contrib/object.asm and is not transitively included by <snes.h>. Examples that use it must #include <snes/object.h> explicitly and list object in their Makefile's LIB_MODULES. See lib/contrib/README.md for the policy.

Provides managed game objects with:

  • Linked-list management (up to 80 objects, 64 types)
  • Type-based function dispatch (init, update, refresh callbacks)
  • Map collision detection (with optional slope support)
  • Fixed-point position and velocity
  • Object-to-object collision detection

Workspace Pattern

Because the object buffer resides in Bank $7E (not directly accessible from C), a workspace pattern is used. Before each C callback, the engine copies the current object's data to objWorkspace. After the callback returns, changes are copied back.

#include <snes.h>
#include <snes/object.h>
void enemy_update(u16 idx) {
// objWorkspace is pre-populated with current object data
if (objWorkspace.action == ACT_WALK) {
objWorkspace.xvel = 0x0100;
}
// Call engine functions (they sync workspace automatically)
// Read updated position from workspace
u16 screenx = objWorkspace.xpos[1] | (objWorkspace.xpos[2] << 8);
}
unsigned short u16
16-bit unsigned integer (0 to 65535)
Definition types.h:53
#define ACT_WALK
Definition map.h:94
Game object engine with physics and collision (CONTRIB module).
void objCollidMap(u16 objindex)
Check object collision with map tiles.
FAR t_objs objWorkspace
Object workspace.
void objUpdateXY(u16 objindex)
Update object position from velocity.
OpenSNES common-case master header.

Attribution

Based on: PVSnesLib object engine by Alekmaul Slope management: Nub1604 License: zlib (compatible with MIT)

Macro Definition Documentation

◆ OB_MAX

#define OB_MAX   80

Maximum number of objects in the game.

◆ OB_SIZE

#define OB_SIZE   64

Object size in bytes.

◆ OB_TYPE_MAX

#define OB_TYPE_MAX   64

Maximum number of object types.

Typedef Documentation

◆ ObjInitFn

typedef void(* ObjInitFn) (u16 xp, u16 yp, u16 type, u16 minx, u16 maxx)

Init callback of an object type, called by objLoadObjects() per table entry.

◆ ObjUpdateFn

typedef void(* ObjUpdateFn) (u16 idx)

Update / refresh callback of an object type; idx is the slot index.

Function Documentation

◆ objCollidMap()

void objCollidMap ( u16 objindex)

Check object collision with map tiles.

Tests collision in Y (gravity/jumping) then X (walls). Updates tilestand, tileabove, tilesprop, tilebprop in objWorkspace. Applies friction to X velocity. Applies gravity if airborne.

Parameters
objindexSlot index (as received in an update callback) or the handle from objNew() — see "Index or handle" below
Note
Syncs objWorkspace before and after — safe to call from C callbacks.

◆ objCollidMap1D()

void objCollidMap1D ( u16 objindex)

Check object collision with map (no gravity).

For top-down movement without gravity.

Parameters
objindexSlot index or handle

◆ objCollidMapWithSlopes()

void objCollidMapWithSlopes ( u16 objindex)

Check object collision with map tiles including slopes.

Like objCollidMap but also handles slope tiles (T_SLOPEU1..T_SLOPEUD2).

Parameters
objindexSlot index or handle

◆ objCollidObj()

u16 objCollidObj ( u16 idx1,
u16 idx2 )

Test collision between two objects.

Uses AABB (axis-aligned bounding box) collision.

Index or handle
A handle is (id << 8) | index. objKill() and objGetPointer() need the whole handle (the id byte is how a stale one is detected); this function, objCollidMap(), objCollidMapWithSlopes(), objCollidMap1D() and objUpdateXY() work on a live slot and use the index only. Since 2026-09-21 they mask the id byte themselves, so a callback's idx and a handle both work. Before that a handle's id byte was shifted into the buffer offset and the routine silently worked on memory past the pool. Since 2026-10-05 an index of 80 or more (OB_MAX slots) returns at once — 0 here, no change elsewhere; before, it addressed the engine's own state past the pool.

The id byte counts 1..255 and wraps (0 is never used): a handle kept across 255 or more objNew() calls can match a reused slot and pass as live. Re-fetch handles you keep for long, or check the object's type.

Parameters
idx1First object: slot index or handle
idx2Second object: slot index or handle
Returns
1 if collision detected, 0 otherwise

◆ objGetCurrentId()

u16 objGetCurrentId ( void )

Handle of the last object objNew() created.

Inside an init callback this is the object being created: objNew() has not returned yet, so its return value is not available there.

void marioInit(u16 xp, u16 yp, u16 type, u16 minx, u16 maxx) {
objGetPointer(objGetCurrentId()); // load the new object
mario_id = objGetCurrentId();
}
u16 objGetCurrentId(void)
Handle of the last object objNew() created.
u16 objGetPointer(u16 objhandle)
Get pointer to an object from its handle.
Returns
The handle (0 after objInitEngine(), before any objNew())

◆ objGetPointer()

u16 objGetPointer ( u16 objhandle)

Get pointer to an object from its handle.

Validates the handle and populates objWorkspace with the object's data.

Parameters
objhandleObject handle (from objNew() or objGetCurrentId())
Returns
The slot index + 1 if the handle is live, 0 if it is stale (the object was killed, or the slot reused) — in which case the workspace is left alone.

◆ objInitEngine()

void objInitEngine ( void )

Initialize the object engine.

Clears all object buffers, resets linked lists, and sets default gravity/friction values. Call once at game start.

◆ objInitFriction1D()

void objInitFriction1D ( u16 friction)

Opt into friction for objCollidMap1D().

objCollidMap1D() stops an object on a wall but never decelerates it otherwise (PVSnesLib parity; its FRICTION1D constant was defined and never used). A non-zero value here makes every objCollidMap1D() call move xvel AND yvel toward zero by that amount, clamped at zero. objInitEngine() resets it to 0 (off).

Parameters
frictionDeceleration per call, in 8.8 velocity units (0 = none; 0x0100, PVSnesLib's unused constant, is one pixel per frame)

◆ objInitFunctions()

void objInitFunctions ( u8 objtype,
ObjInitFn initfct,
ObjUpdateFn updfct,
ObjUpdateFn reffct )

Register callback functions for an object type.

Typed since 2026-09-19: pass the functions directly, no (void *) cast. A callback with the wrong signature is now a compile error instead of a corrupted stack at run time. A null callback is safe — the engine skips it.

Parameters
objtypeObject type index (0-63)
initfctInit callback (or 0)
updfctUpdate callback, called per frame (or 0)
reffctRefresh callback, called for on-screen objects (or 0)

◆ objInitGravity()

void objInitGravity ( u16 objgravity,
u16 objfriction )

Set gravity and friction values.

Parameters
objgravityGravity acceleration per frame (default: 41)
objfrictionHorizontal friction deceleration (default: 16)

◆ objKill()

void objKill ( u16 objhandle)

Kill an object.

Warning
From an update callback, kill only the current object (objKillCurrent()): objUpdateAll() has already read the next object's link, so killing THAT object from here makes the loop continue into the free list.
Parameters
objhandleObject handle

◆ objKillAll()

void objKillAll ( void )

Kill all active objects.

◆ objKillCurrent()

void objKillCurrent ( void )

Kill the object being updated.

Call it inside an update callback. objUpdateAll() removes the object once the callback returns and its workspace has been written back, the only safe moment. It does nothing in a refresh callback until the next update pass.

◆ objLoadObjects()

void objLoadObjects ( const u8 * sourceO)

Load objects from a data table.

Table format: [x:u16, y:u16, type:u16, minx:u16, maxx:u16]... terminated by 0xFFFF. Calls each type's init function for every object loaded.

Parameters
sourceOPointer to object data table

◆ objNew()

u16 objNew ( u8 objtype,
u16 x,
u16 y )

Create a new object.

Parameters
objtypeObject type (0-63)
xInitial X position in map pixels
yInitial Y position in map pixels
Returns
Object handle; 0 if no slot is free or if type is 64 or more (OB_TYPE_MAX; such a type read past the type tables until 2026-10-04). Also returned by objGetCurrentId().
Note
After objNew, the new object data is copied to objWorkspace. Set width, height, and other fields on objWorkspace before returning from the init callback.

◆ objRefreshAll()

void objRefreshAll ( void )

Refresh sprites for all on-screen objects.

Calls the refresh function for objects that are on screen (-32 to 256 X, -32 to 224 Y). Useful to avoid flickering in scrolling games.

◆ objUpdateAll()

void objUpdateAll ( void )

Update all active objects.

Iterates through all active objects. For each object within the "virtual screen" (-64 to 320 X, -64 to 288 Y), calls the type's update function with objWorkspace pre-populated.

◆ objUpdateXY()

void objUpdateXY ( u16 objindex)

Update object position from velocity.

Adds xvel/yvel to xpos/ypos (24-bit fixed point).

Parameters
objindexSlot index (the one passed to your update callback) or the handle from objNew()
Note
Syncs objWorkspace before and after.

Variable Documentation

◆ objWorkspace

FAR t_objs objWorkspace
extern

Object workspace.

Single 64-byte workspace populated before each C callback. Read/write this in init, update, and refresh callbacks. Changes are automatically copied back to the object buffer.

It is a FAR object since 2026-10-09 (it sits behind the object pool, in bank $7E, so that the collision routines work on it without copying it): objWorkspace.field reads and writes as before, at the same cost; a pointer to it or to one of its fields is a FAR pointer.