Compare commits
6 Commits
8f613397d6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
652ee4cdf3
|
|||
|
9fed59c4c8
|
|||
|
941eeb2493
|
|||
|
314ce5e10d
|
|||
|
d87c5d2c20
|
|||
|
6314ad7f26
|
@@ -69,6 +69,8 @@ add_library(akgl SHARED
|
|||||||
src/heap.c
|
src/heap.c
|
||||||
src/json_helpers.c
|
src/json_helpers.c
|
||||||
src/registry.c
|
src/registry.c
|
||||||
|
src/renderer.c
|
||||||
|
src/physics.c
|
||||||
src/sprite.c
|
src/sprite.c
|
||||||
src/staticstring.c
|
src/staticstring.c
|
||||||
src/tilemap.c
|
src/tilemap.c
|
||||||
@@ -142,6 +144,8 @@ install(FILES "include/akgl/controller.h" DESTINATION "include/akgl/")
|
|||||||
install(FILES "include/akgl/heap.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/heap.h" DESTINATION "include/akgl/")
|
||||||
install(FILES "include/akgl/iterator.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/iterator.h" DESTINATION "include/akgl/")
|
||||||
install(FILES "include/akgl/json_helpers.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/json_helpers.h" DESTINATION "include/akgl/")
|
||||||
|
install(FILES "include/akgl/renderer.h" DESTINATION "include/akgl/")
|
||||||
|
install(FILES "include/akgl/physics.h" DESTINATION "include/akgl/")
|
||||||
install(FILES "include/akgl/registry.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/registry.h" DESTINATION "include/akgl/")
|
||||||
install(FILES "include/akgl/sprite.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/sprite.h" DESTINATION "include/akgl/")
|
||||||
install(FILES "include/akgl/staticstring.h" DESTINATION "include/akgl/")
|
install(FILES "include/akgl/staticstring.h" DESTINATION "include/akgl/")
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#ifndef _SDL_GAMECONTROLLERDB_H_
|
#ifndef _SDL_GAMECONTROLLERDB_H_
|
||||||
#define _SDL_GAMECONTROLLERDB_H_
|
#define _SDL_GAMECONTROLLERDB_H_
|
||||||
|
|
||||||
// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Sun May 24 07:53:58 PM EDT 2026
|
// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Tue Jun 2 04:45:53 PM EDT 2026
|
||||||
|
|
||||||
#define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228
|
#define AKGL_SDL_GAMECONTROLLER_DB_LEN 2229
|
||||||
|
|
||||||
const char *SDL_GAMECONTROLLER_DB[] = {
|
const char *SDL_GAMECONTROLLER_DB[] = {
|
||||||
"03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows",
|
"03000000300f00000a01000000000000,3 In 1 Conversion Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b8,x:b3,y:b0,platform:Windows",
|
||||||
@@ -708,7 +708,7 @@ const char *SDL_GAMECONTROLLER_DB[] = {
|
|||||||
"03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows",
|
"03000000730700000601000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2,start:b9,x:b3,y:b4,platform:Windows",
|
||||||
"03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows",
|
"03000000b40400000a01000000000000,Sega Saturn Controller,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,start:b8,x:b3,y:b4,platform:Windows",
|
||||||
"030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows",
|
"030000003b07000004a1000000000000,SFX,a:b0,b:b2,back:b7,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:b5,start:b8,x:b1,y:b3,platform:Windows",
|
||||||
"03000000632500002705000000000000,ShanWan Q36,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,platform:Windows",
|
"03000000632500002705000000000000,ShanWan Gamepad,a:b0,b:b1,x:b3,y:b4,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,-lefty:-a1,+lefty:+a2,leftshoulder:b6,lefttrigger:b8,rightshoulder:b7,righttrigger:b9,start:b11,leftstick:b13,rightstick:b14,platform:Windows",
|
||||||
"03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows",
|
"03000000f82100001900000000000000,Shogun Bros Chameleon X1,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows",
|
||||||
"03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows",
|
"03000000120c00001c1e000000000000,SnakeByte 4S PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,platform:Windows",
|
||||||
"03000000140300000918000000000000,SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows",
|
"03000000140300000918000000000000,SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,platform:Windows",
|
||||||
@@ -780,6 +780,7 @@ const char *SDL_GAMECONTROLLER_DB[] = {
|
|||||||
"030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows",
|
"030000005f140000c501000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows",
|
||||||
"03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows",
|
"03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows",
|
||||||
"030000005f1400002a01000000000000,Trust Predator GM1200,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,x:b3,y:b4,platform:Windows",
|
"030000005f1400002a01000000000000,Trust Predator GM1200,a:b0,b:b1,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,lefttrigger:b7,rightshoulder:b5,righttrigger:b2,x:b3,y:b4,platform:Windows",
|
||||||
|
"03000000580400000a10000000000000,Trust Sight Fighter,a:b0,b:b1,x:b3,y:b4,back:b5,start:b2,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,lefttrigger:b8,righttrigger:b9,platform:Windows",
|
||||||
"030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows",
|
"030000004f04000087b6000000000000,TWCS Throttle,dpdown:b8,dpleft:b9,dpright:b7,dpup:b6,leftstick:b5,lefttrigger:-a5,leftx:a0,lefty:a1,righttrigger:+a5,platform:Windows",
|
||||||
"03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows",
|
"03000000411200000450000000000000,Twin Shock,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a4,start:b11,x:b3,y:b0,platform:Windows",
|
||||||
"03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows",
|
"03000000d90400000200000000000000,TwinShock PS2 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows",
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
#define AKGL_ACTOR_STATE_MOVING_RIGHT 1 << 8 // 256 0000 0001 0000 0000
|
#define AKGL_ACTOR_STATE_MOVING_RIGHT 1 << 8 // 256 0000 0001 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_MOVING_UP 1 << 9 // 512 0000 0010 0000 0000
|
#define AKGL_ACTOR_STATE_MOVING_UP 1 << 9 // 512 0000 0010 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_MOVING_DOWN 1 << 10 // 1024 0000 0100 0000 0000
|
#define AKGL_ACTOR_STATE_MOVING_DOWN 1 << 10 // 1024 0000 0100 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_UNDEFINED_11 1 << 11 // 2048 0000 1000 0000 0000
|
#define AKGL_ACTOR_STATE_MOVING_IN 1 << 11 // 2048 0000 1000 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_UNDEFINED_12 1 << 12 // 4096 0001 0000 0000 0000
|
#define AKGL_ACTOR_STATE_MOVING_OUT 1 << 12 // 4096 0001 0000 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_UNDEFINED_13 1 << 13 // 8192 0010 0000 0000 0000
|
#define AKGL_ACTOR_STATE_UNDEFINED_13 1 << 13 // 8192 0010 0000 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_UNDEFINED_14 1 << 14 // 16384 0100 0000 0000 0000
|
#define AKGL_ACTOR_STATE_UNDEFINED_14 1 << 14 // 16384 0100 0000 0000 0000
|
||||||
#define AKGL_ACTOR_STATE_UNDEFINED_15 1 << 15 // 32768 1000 0000 0000 0000
|
#define AKGL_ACTOR_STATE_UNDEFINED_15 1 << 15 // 32768 1000 0000 0000 0000
|
||||||
@@ -70,25 +70,51 @@ typedef struct akgl_Actor {
|
|||||||
bool movement_controls_face;
|
bool movement_controls_face;
|
||||||
void *actorData;
|
void *actorData;
|
||||||
bool visible;
|
bool visible;
|
||||||
SDL_Time logictimer;
|
SDL_Time movetimer;
|
||||||
|
// Velocity. Combined effect of all forces acting on the actor resulting
|
||||||
|
// in energy along an axis.
|
||||||
|
float32_t vx;
|
||||||
|
float32_t vy;
|
||||||
|
float32_t vz;
|
||||||
|
// Environmental velocity. These are the forces acting on the actor by the
|
||||||
|
// environment (such as gravity and atmospheric drag)
|
||||||
|
float32_t ex;
|
||||||
|
float32_t ey;
|
||||||
|
float32_t ez;
|
||||||
|
// Thrust. Energy originating only from the actor's own acceleration on a
|
||||||
|
// given axis, before the effects of gravity and drag.
|
||||||
|
float32_t tx;
|
||||||
|
float32_t ty;
|
||||||
|
float32_t tz;
|
||||||
|
// Acceleration. These are borrowed from the base character object.
|
||||||
|
// A given axis resets to 0 when the actor stops moving in a given axis.
|
||||||
|
float32_t ax;
|
||||||
|
float32_t ay;
|
||||||
|
float32_t az;
|
||||||
|
// Max speed. These are borrowed from the base character object.
|
||||||
|
float32_t sx;
|
||||||
|
float32_t sy;
|
||||||
|
float32_t sz;
|
||||||
|
// Position.
|
||||||
float32_t x;
|
float32_t x;
|
||||||
float32_t y;
|
float32_t y;
|
||||||
|
float32_t z;
|
||||||
float32_t scale;
|
float32_t scale;
|
||||||
struct akgl_Actor *children[AKGL_ACTOR_MAX_CHILDREN];
|
struct akgl_Actor *children[AKGL_ACTOR_MAX_CHILDREN];
|
||||||
struct akgl_Actor *parent;
|
struct akgl_Actor *parent;
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*updatefunc)(struct akgl_Actor *obj);
|
akerr_ErrorContext AKERR_NOIGNORE *(*updatefunc)(struct akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*renderfunc)(struct akgl_Actor *obj, SDL_Renderer *renderer);
|
akerr_ErrorContext AKERR_NOIGNORE *(*renderfunc)(struct akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*facefunc)(struct akgl_Actor *obj);
|
akerr_ErrorContext AKERR_NOIGNORE *(*facefunc)(struct akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*movementlogicfunc)(struct akgl_Actor *obj, SDL_Time curtimems);
|
akerr_ErrorContext AKERR_NOIGNORE *(*movementlogicfunc)(struct akgl_Actor *obj, float32_t dt);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*changeframefunc)(struct akgl_Actor *obj, akgl_Sprite *curSprite, SDL_Time curtimems);
|
akerr_ErrorContext AKERR_NOIGNORE *(*changeframefunc)(struct akgl_Actor *obj, akgl_Sprite *curSprite, SDL_Time curtimems);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*addchild)(struct akgl_Actor *obj, struct akgl_Actor *child);
|
akerr_ErrorContext AKERR_NOIGNORE *(*addchild)(struct akgl_Actor *obj, struct akgl_Actor *child);
|
||||||
} akgl_Actor;
|
} akgl_Actor;
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_initialize(akgl_Actor *obj, char *name);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_initialize(akgl_Actor *obj, char *name);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_set_character(akgl_Actor *obj, char *basecharname);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_set_character(akgl_Actor *obj, char *basecharname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_render(akgl_Actor *obj, SDL_Renderer *renderer);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_render(akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_update(akgl_Actor *obj);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_update(akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_logic_movement(akgl_Actor *obj, SDL_Time curtimems);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_logic_movement(akgl_Actor *obj, float32_t dt);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_logic_changeframe(akgl_Actor *obj, akgl_Sprite *curSprite, SDL_Time curtimems);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_logic_changeframe(akgl_Actor *obj, akgl_Sprite *curSprite, SDL_Time curtimems);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_automatic_face(akgl_Actor *obj);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_automatic_face(akgl_Actor *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_add_child(akgl_Actor *obj, akgl_Actor *child);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_actor_add_child(akgl_Actor *obj, akgl_Actor *child);
|
||||||
|
|||||||
@@ -9,14 +9,18 @@
|
|||||||
#define AKGL_MAX_HEAP_CHARACTER 256
|
#define AKGL_MAX_HEAP_CHARACTER 256
|
||||||
|
|
||||||
typedef struct akgl_Character {
|
typedef struct akgl_Character {
|
||||||
uint8_t refcount;
|
uint8_t refcount;
|
||||||
char name[AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH];
|
char name[AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH];
|
||||||
SDL_PropertiesID state_sprites;
|
SDL_PropertiesID state_sprites;
|
||||||
uint64_t movementspeed;
|
uint64_t speedtime;
|
||||||
float32_t vx;
|
float32_t ax;
|
||||||
float32_t vy;
|
float32_t ay;
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*sprite_add)(struct akgl_Character *, akgl_Sprite *, int);
|
float32_t az;
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *(*sprite_get)(struct akgl_Character *, int, akgl_Sprite **);
|
float32_t sx;
|
||||||
|
float32_t sy;
|
||||||
|
float32_t sz;
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*sprite_add)(struct akgl_Character *, akgl_Sprite *, int);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*sprite_get)(struct akgl_Character *, int, akgl_Sprite **);
|
||||||
} akgl_Character;
|
} akgl_Character;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,5 +13,6 @@
|
|||||||
_Pragma("GCC diagnostic pop")
|
_Pragma("GCC diagnostic pop")
|
||||||
|
|
||||||
#define AKGL_ERR_SDL AKERR_LAST_ERRNO_VALUE + 1
|
#define AKGL_ERR_SDL AKERR_LAST_ERRNO_VALUE + 1
|
||||||
|
#define AKGL_ERR_LOGICINTERRUPT AKERR_LAST_ERRNO_VALUE + 2
|
||||||
|
|
||||||
#endif // _ERROR_H_
|
#endif // _ERROR_H_
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
#define _AKGL_GAME_H_
|
#define _AKGL_GAME_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "types.h"
|
|
||||||
#include <SDL3_mixer/SDL_mixer.h>
|
#include <SDL3_mixer/SDL_mixer.h>
|
||||||
|
#include "types.h"
|
||||||
#include "tilemap.h"
|
#include "tilemap.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "physics.h"
|
||||||
|
|
||||||
#define AKGL_VERSION "0.1.0"
|
#define AKGL_VERSION "0.1.0"
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ typedef struct {
|
|||||||
char name[256];
|
char name[256];
|
||||||
char uri[256];
|
char uri[256];
|
||||||
akgl_GameState state;
|
akgl_GameState state;
|
||||||
|
SDL_Mutex *statelock;
|
||||||
int16_t fps;
|
int16_t fps;
|
||||||
SDL_Time gameStartTime;
|
SDL_Time gameStartTime;
|
||||||
SDL_Time lastIterTime;
|
SDL_Time lastIterTime;
|
||||||
@@ -41,15 +44,22 @@ typedef struct {
|
|||||||
} akgl_Game;
|
} akgl_Game;
|
||||||
|
|
||||||
extern SDL_Window *window;
|
extern SDL_Window *window;
|
||||||
extern SDL_Renderer *renderer;
|
|
||||||
extern akgl_Tilemap gamemap;
|
|
||||||
extern MIX_Audio *bgm;
|
extern MIX_Audio *bgm;
|
||||||
extern MIX_Mixer *akgl_mixer;
|
extern MIX_Mixer *akgl_mixer;
|
||||||
extern MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS];
|
extern MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS];
|
||||||
extern SDL_FRect camera;
|
extern SDL_FRect _akgl_camera;
|
||||||
extern akgl_Game game;
|
extern akgl_Game game;
|
||||||
|
extern akgl_RenderBackend _akgl_renderer;
|
||||||
|
extern akgl_PhysicsBackend _akgl_physics;
|
||||||
|
extern akgl_Tilemap _akgl_gamemap;
|
||||||
|
|
||||||
|
extern akgl_Tilemap *gamemap;
|
||||||
|
extern akgl_RenderBackend *renderer;
|
||||||
|
extern akgl_PhysicsBackend *physics;
|
||||||
|
extern SDL_FRect *camera;
|
||||||
|
|
||||||
#define AKGL_BITMASK_HAS(x, y) (x & y) == y
|
#define AKGL_BITMASK_HAS(x, y) (x & y) == y
|
||||||
|
#define AKGL_BITMASK_HASNOT(x, y) (x & y) != y
|
||||||
#define AKGL_BITMASK_ADD(x, y) x |= y
|
#define AKGL_BITMASK_ADD(x, y) x |= y
|
||||||
#define AKGL_BITMASK_DEL(x, y) x &= ~(y)
|
#define AKGL_BITMASK_DEL(x, y) x &= ~(y)
|
||||||
#define AKGL_BITMASK_CLEAR(x) x = 0;
|
#define AKGL_BITMASK_CLEAR(x) x = 0;
|
||||||
@@ -60,5 +70,8 @@ void akgl_game_updateFPS();
|
|||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath);
|
||||||
void akgl_game_lowfps(void);
|
void akgl_game_lowfps(void);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_state_lock(void);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_state_unlock(void);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_update(akgl_Iterator *opflags);
|
||||||
|
|
||||||
#endif //_AKGL_GAME_H_
|
#endif //_AKGL_GAME_H_
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ extern akgl_Character HEAP_CHARACTER[AKGL_MAX_HEAP_CHARACTER];
|
|||||||
extern akgl_String HEAP_STRING[AKGL_MAX_HEAP_STRING];
|
extern akgl_String HEAP_STRING[AKGL_MAX_HEAP_STRING];
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_init();
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_init();
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_init_actor();
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_actor(akgl_Actor **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_actor(akgl_Actor **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_sprite(akgl_Sprite **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_sprite(akgl_Sprite **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_spritesheet(akgl_SpriteSheet **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_heap_next_spritesheet(akgl_SpriteSheet **dest);
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_object_value(json_t *obj, char
|
|||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_boolean_value(json_t *obj, char *key, bool *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_boolean_value(json_t *obj, char *key, bool *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_integer_value(json_t *obj, char *key, int *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_integer_value(json_t *obj, char *key, int *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_number_value(json_t *obj, char *key, float *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_number_value(json_t *obj, char *key, float *dest);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_double_value(json_t *obj, char *key, double *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_string_value(json_t *obj, char *key, akgl_String **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_string_value(json_t *obj, char *key, akgl_String **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_value(json_t *obj, char *key, json_t **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_value(json_t *obj, char *key, json_t **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_object(json_t *array, int index, json_t **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_object(json_t *array, int index, json_t **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_integer(json_t *array, int index, int *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_integer(json_t *array, int index, int *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_string(json_t *array, int index, akgl_String **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_array_index_string(json_t *array, int index, akgl_String **dest);
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_with_default(akerr_ErrorContext *e, void *defval, void *dest, uint32_t defsize);
|
||||||
|
|
||||||
#endif // _JSON_HELPERS_H_
|
#endif // _JSON_HELPERS_H_
|
||||||
|
|||||||
41
include/akgl/physics.h
Normal file
41
include/akgl/physics.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _PHYSICS_H_
|
||||||
|
#define _PHYSICS_H_
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
#include <akerror.h>
|
||||||
|
#include <akgl/actor.h>
|
||||||
|
#include <akgl/iterator.h>
|
||||||
|
#include <akgl/staticstring.h>
|
||||||
|
|
||||||
|
typedef struct akgl_PhysicsBackend {
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*simulate)(struct akgl_PhysicsBackend *self, akgl_Iterator *opflags);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*gravity)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*collide)(struct akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*move)(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
|
||||||
|
double drag_x;
|
||||||
|
double drag_y;
|
||||||
|
double drag_z;
|
||||||
|
double gravity_x;
|
||||||
|
double gravity_y;
|
||||||
|
double gravity_z;
|
||||||
|
SDL_Time gravity_time;
|
||||||
|
SDL_Time timer_gravity;
|
||||||
|
} akgl_PhysicsBackend;
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_null(akgl_PhysicsBackend *self);
|
||||||
|
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_move(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_arcade(akgl_PhysicsBackend *self);
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_factory(akgl_PhysicsBackend *self, akgl_String *type);
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_simulate(akgl_PhysicsBackend *self, akgl_Iterator *opflags);
|
||||||
|
|
||||||
|
#endif // _PHYSICS_H_
|
||||||
29
include/akgl/renderer.h
Normal file
29
include/akgl/renderer.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _RENDERER_H_
|
||||||
|
#define _RENDERER_H_
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <akerror.h>
|
||||||
|
|
||||||
|
#include <akgl/iterator.h>
|
||||||
|
|
||||||
|
typedef struct akgl_RenderBackend {
|
||||||
|
SDL_Renderer *sdl_renderer;
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*shutdown)(struct akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*frame_start)(struct akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*frame_end)(struct akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*draw_texture)(struct akgl_RenderBackend *self, SDL_Texture *texture, SDL_FRect *src, SDL_FRect *dest, double angle, SDL_FPoint *center, SDL_FlipMode flip);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*draw_mesh)(struct akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *(*draw_world)(struct akgl_RenderBackend *self, akgl_Iterator *opflags);
|
||||||
|
} akgl_RenderBackend;
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_shutdown(akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_frame_start(akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_frame_end(akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_texture(akgl_RenderBackend *self, SDL_Texture *texture, SDL_FRect *src, SDL_FRect *dest, double angle, SDL_FPoint *center, SDL_FlipMode flip);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_mesh(akgl_RenderBackend *self);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_world(akgl_RenderBackend *self, akgl_Iterator *opflags);
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_init2d(akgl_RenderBackend *self);
|
||||||
|
|
||||||
|
#endif // _RENDERER_H_
|
||||||
@@ -2,8 +2,9 @@
|
|||||||
#define _TILEMAP_H_
|
#define _TILEMAP_H_
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "actor.h"
|
#include <akgl/actor.h>
|
||||||
#include "staticstring.h"
|
#include <akgl/staticstring.h>
|
||||||
|
#include <akgl/physics.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
#define AKGL_TILEMAP_MAX_WIDTH 512
|
#define AKGL_TILEMAP_MAX_WIDTH 512
|
||||||
@@ -98,11 +99,15 @@ typedef struct {
|
|||||||
float p_rate;
|
float p_rate;
|
||||||
akgl_Tileset tilesets[AKGL_TILEMAP_MAX_TILESETS];
|
akgl_Tileset tilesets[AKGL_TILEMAP_MAX_TILESETS];
|
||||||
akgl_TilemapLayer layers[AKGL_TILEMAP_MAX_LAYERS];
|
akgl_TilemapLayer layers[AKGL_TILEMAP_MAX_LAYERS];
|
||||||
|
|
||||||
|
// Different levels may have different physics.
|
||||||
|
bool use_own_physics;
|
||||||
|
akgl_PhysicsBackend physics;
|
||||||
} akgl_Tilemap;
|
} akgl_Tilemap;
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load(char *fname, akgl_Tilemap *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load(char *fname, akgl_Tilemap *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *dest, SDL_FRect *viewport, int layeridx);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw(akgl_Tilemap *dest, SDL_FRect *viewport, int layeridx);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw_tileset(SDL_Renderer *renderer, akgl_Tilemap *dest, int tilesetidx);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw_tileset(akgl_Tilemap *dest, int tilesetidx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions are part of the internal API and should not be called by the user.
|
* These functions are part of the internal API and should not be called by the user.
|
||||||
|
|||||||
132
src/actor.c
132
src/actor.c
@@ -3,6 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <akerror.h>
|
#include <akerror.h>
|
||||||
|
|
||||||
|
#include <akgl/physics.h>
|
||||||
#include <akgl/game.h>
|
#include <akgl/game.h>
|
||||||
#include <akgl/sprite.h>
|
#include <akgl/sprite.h>
|
||||||
#include <akgl/actor.h>
|
#include <akgl/actor.h>
|
||||||
@@ -50,6 +51,10 @@ akerr_ErrorContext *akgl_actor_set_character(akgl_Actor *obj, char *basecharname
|
|||||||
obj->basechar = SDL_GetPointerProperty(AKGL_REGISTRY_CHARACTER, basecharname, NULL);
|
obj->basechar = SDL_GetPointerProperty(AKGL_REGISTRY_CHARACTER, basecharname, NULL);
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Character not found in the registry");
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Character not found in the registry");
|
||||||
|
obj->ax = 0;
|
||||||
|
obj->ay = 0;
|
||||||
|
obj->sx = obj->basechar->sx;
|
||||||
|
obj->sy = obj->basechar->sy;
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,26 +117,24 @@ akerr_ErrorContext *akgl_actor_logic_changeframe(akgl_Actor *obj, akgl_Sprite *c
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_actor_logic_movement(akgl_Actor *obj, SDL_Time curtime)
|
// raises AKGL_ERR_LOGICINTERRUPT if we don't want the physics simulator to process us
|
||||||
|
akerr_ErrorContext *akgl_actor_logic_movement(akgl_Actor *actor, float32_t dt)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "Null actor reference");
|
FAIL_ZERO_RETURN(errctx, actor, AKERR_NULLPOINTER, "actor");
|
||||||
if ( obj->parent != NULL ) {
|
FAIL_ZERO_RETURN(errctx, actor, AKERR_NULLPOINTER, "actor->basechar");
|
||||||
// Children don't move independently of their parents, they just have an offset
|
actor->sx = actor->basechar->sx;
|
||||||
SUCCEED_RETURN(errctx);
|
actor->sy = actor->basechar->sy;
|
||||||
} else {
|
actor->sz = actor->basechar->sz;
|
||||||
if ( AKGL_BITMASK_HAS(obj->state, AKGL_ACTOR_STATE_MOVING_LEFT) ) {
|
if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_LEFT) ) {
|
||||||
obj->x -= obj->basechar->vx;
|
actor->ax = -actor->basechar->ax;
|
||||||
}
|
} else if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) {
|
||||||
if ( AKGL_BITMASK_HAS(obj->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) {
|
actor->ax = actor->basechar->ax;
|
||||||
obj->x += obj->basechar->vx;
|
}
|
||||||
}
|
if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_UP) ) {
|
||||||
if ( AKGL_BITMASK_HAS(obj->state, AKGL_ACTOR_STATE_MOVING_UP) ) {
|
actor->ay = -actor->basechar->ay;
|
||||||
obj->y -= obj->basechar->vy;
|
} else if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) {
|
||||||
}
|
actor->ay = actor->basechar->ay;
|
||||||
if ( AKGL_BITMASK_HAS(obj->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) {
|
|
||||||
obj->y += obj->basechar->vy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
@@ -145,21 +148,11 @@ akerr_ErrorContext *akgl_actor_update(akgl_Actor *obj)
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor reference");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor reference");
|
||||||
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
||||||
|
|
||||||
ATTEMPT {
|
SDL_GetCurrentTime(&curtime);
|
||||||
SDL_GetCurrentTime(&curtime);
|
PASS(errctx, obj->facefunc(obj));
|
||||||
CATCH(errctx, obj->facefunc(obj));
|
|
||||||
// is it time to apply movement logic?
|
|
||||||
if ( (curtime - obj->logictimer) >= obj->basechar->movementspeed ) {
|
|
||||||
CATCH(errctx, obj->movementlogicfunc(obj, curtime));
|
|
||||||
obj->logictimer = curtime;
|
|
||||||
}
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(errctx) {
|
|
||||||
} FINISH(errctx, false);
|
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
CATCH(errctx, akgl_character_sprite_get(obj->basechar, obj->state, &curSprite));
|
CATCH(errctx, akgl_character_sprite_get(obj->basechar, obj->state, &curSprite));
|
||||||
// is it time to change frames?
|
|
||||||
if ( ((curtime) - obj->curSpriteFrameTimer) >= curSprite->speed) {
|
if ( ((curtime) - obj->curSpriteFrameTimer) >= curSprite->speed) {
|
||||||
CATCH(errctx, obj->changeframefunc(obj, curSprite, curtime));
|
CATCH(errctx, obj->changeframefunc(obj, curSprite, curtime));
|
||||||
obj->curSpriteFrameTimer = curtime;
|
obj->curSpriteFrameTimer = curtime;
|
||||||
@@ -167,6 +160,8 @@ akerr_ErrorContext *akgl_actor_update(akgl_Actor *obj)
|
|||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(errctx) {
|
||||||
} HANDLE(errctx, AKERR_KEY) {
|
} HANDLE(errctx, AKERR_KEY) {
|
||||||
|
// TODO : Why are we passing this error? It could only come from akgl_character_sprite_get
|
||||||
|
// or changeframefunc, both of which should never return AKERR_KEY...
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
} FINISH(errctx, true);
|
} FINISH(errctx, true);
|
||||||
|
|
||||||
@@ -179,7 +174,6 @@ static akerr_ErrorContext *actor_visible(akgl_Actor *obj, SDL_FRect *camera, boo
|
|||||||
akgl_Sprite *curSprite = NULL;
|
akgl_Sprite *curSprite = NULL;
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, renderer, AKERR_NULLPOINTER, "NULL renderer");
|
|
||||||
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
@@ -203,7 +197,7 @@ static akerr_ErrorContext *actor_visible(akgl_Actor *obj, SDL_FRect *camera, boo
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_actor_render(akgl_Actor *obj, SDL_Renderer *renderer)
|
akerr_ErrorContext *akgl_actor_render(akgl_Actor *obj)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
akgl_Sprite *curSprite = NULL;
|
akgl_Sprite *curSprite = NULL;
|
||||||
@@ -212,12 +206,11 @@ akerr_ErrorContext *akgl_actor_render(akgl_Actor *obj, SDL_Renderer *renderer)
|
|||||||
SDL_FRect dest;
|
SDL_FRect dest;
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, renderer, AKERR_NULLPOINTER, "NULL renderer");
|
|
||||||
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "Actor has NULL base character reference");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
CATCH(errctx, akgl_character_sprite_get(obj->basechar, obj->state, &curSprite));
|
CATCH(errctx, akgl_character_sprite_get(obj->basechar, obj->state, &curSprite));
|
||||||
CATCH(errctx, actor_visible(obj, &camera, &visible));
|
CATCH(errctx, actor_visible(obj, camera, &visible));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(errctx) {
|
||||||
} HANDLE(errctx, AKERR_KEY) {
|
} HANDLE(errctx, AKERR_KEY) {
|
||||||
@@ -229,7 +222,7 @@ akerr_ErrorContext *akgl_actor_render(akgl_Actor *obj, SDL_Renderer *renderer)
|
|||||||
if ( ! visible ) {
|
if ( ! visible ) {
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (obj->curSpriteFrameId > curSprite->frames) ) {
|
if ( (obj->curSpriteFrameId > curSprite->frames) ) {
|
||||||
// This isn't necessarily an error - this actor's frame index is outside the range of
|
// This isn't necessarily an error - this actor's frame index is outside the range of
|
||||||
// their current sprite. There are a number of reasons this could happen, and it will
|
// their current sprite. There are a number of reasons this could happen, and it will
|
||||||
@@ -249,16 +242,16 @@ akerr_ErrorContext *akgl_actor_render(akgl_Actor *obj, SDL_Renderer *renderer)
|
|||||||
} FINISH(errctx, true);
|
} FINISH(errctx, true);
|
||||||
|
|
||||||
if ( obj->parent != NULL ) {
|
if ( obj->parent != NULL ) {
|
||||||
dest.x = (obj->parent->x + obj->x - camera.x);
|
dest.x = (obj->parent->x + obj->x - camera->x);
|
||||||
dest.y = (obj->parent->y + obj->y - camera.y);
|
dest.y = (obj->parent->y + obj->y - camera->y);
|
||||||
} else {
|
} else {
|
||||||
dest.x = (obj->x - camera.x);
|
dest.x = (obj->x - camera->x);
|
||||||
dest.y = (obj->y - camera.y);
|
dest.y = (obj->y - camera->y);
|
||||||
}
|
}
|
||||||
dest.w = curSprite->width * obj->scale;
|
dest.w = curSprite->width * obj->scale;
|
||||||
dest.h = curSprite->width * obj->scale;
|
dest.h = curSprite->width * obj->scale;
|
||||||
|
|
||||||
SDL_RenderTexture(renderer, curSprite->sheet->texture, &src, &dest);
|
PASS(errctx, renderer->draw_texture(renderer, curSprite->sheet->texture, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,46 +274,15 @@ akerr_ErrorContext *akgl_actor_add_child(akgl_Actor *obj, akgl_Actor *child)
|
|||||||
FAIL_RETURN(errctx, AKERR_OUTOFBOUNDS, "Parent object has no remaining child slots left");
|
FAIL_RETURN(errctx, AKERR_OUTOFBOUNDS, "Parent object has no remaining child slots left");
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL iterator so we can't return error information here, void only
|
|
||||||
// this means we don't have anywhere to send exceptions up to, so if we hit an error, we log and exit(1) here
|
|
||||||
void akgl_registry_iterate_actor(void *userdata, SDL_PropertiesID registry, const char *name)
|
|
||||||
{
|
|
||||||
PREPARE_ERROR(errctx);
|
|
||||||
akgl_Iterator *opflags = (akgl_Iterator *)userdata;
|
|
||||||
|
|
||||||
ATTEMPT {
|
|
||||||
FAIL_ZERO_BREAK(errctx, name, AKERR_NULLPOINTER, "registry_iterate_actor received NULL property name");
|
|
||||||
FAIL_ZERO_BREAK(errctx, opflags, AKERR_NULLPOINTER, "received NULL iterator flags");
|
|
||||||
akgl_Actor *obj = (akgl_Actor *)SDL_GetPointerProperty(registry, name, NULL);
|
|
||||||
FAIL_ZERO_BREAK(errctx, obj, AKERR_KEY, "registry_iterate_actor received property name that was not in the registry");
|
|
||||||
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_LAYERMASK) ) {
|
|
||||||
if ( obj->layer != opflags->layerid ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_UPDATE) ) {
|
|
||||||
CATCH(errctx, obj->updatefunc(obj));
|
|
||||||
}
|
|
||||||
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_TILEMAPSCALE) ) {
|
|
||||||
CATCH(errctx, akgl_tilemap_scale_actor(&gamemap, obj));
|
|
||||||
} else {
|
|
||||||
obj->scale = 1.0;
|
|
||||||
}
|
|
||||||
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_RENDER) ) {
|
|
||||||
CATCH(errctx, obj->renderfunc(obj, renderer));
|
|
||||||
}
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(errctx) {
|
|
||||||
} FINISH_NORETURN(errctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_left_on(akgl_Actor *obj, SDL_Event *event)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_left_on(akgl_Actor *obj, SDL_Event *event)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "event");
|
||||||
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "actor->basechar");
|
||||||
//SDL_Log("event %d (button %d / key %d) moves actor left", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) moves actor left", event->type, event->gbutton.which, event->key.key);
|
||||||
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
||||||
|
obj->ax = -(obj->basechar->ax);
|
||||||
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_LEFT | AKGL_ACTOR_STATE_FACE_LEFT));
|
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_LEFT | AKGL_ACTOR_STATE_FACE_LEFT));
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
@@ -332,6 +294,10 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_left_off(akgl_Actor *obj, SDL
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) stops moving actor left", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) stops moving actor left", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ax = 0;
|
||||||
|
obj->ex = 0;
|
||||||
|
obj->tx = 0;
|
||||||
|
obj->vx = 0;
|
||||||
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_LEFT);
|
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_LEFT);
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
@@ -342,7 +308,9 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_right_on(akgl_Actor *obj, SDL
|
|||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
|
FAIL_ZERO_RETURN(errctx, obj->basechar, AKERR_NULLPOINTER, "actor->basechar");
|
||||||
//SDL_Log("event %d (button %d / key %d) moves actor right", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) moves actor right", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ax = obj->basechar->ax;
|
||||||
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
||||||
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_RIGHT | AKGL_ACTOR_STATE_FACE_RIGHT));
|
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_RIGHT | AKGL_ACTOR_STATE_FACE_RIGHT));
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
@@ -355,6 +323,10 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_right_off(akgl_Actor *obj, SD
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) stops moving actor right", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) stops moving actor right", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ax = 0;
|
||||||
|
obj->ex = 0;
|
||||||
|
obj->tx = 0;
|
||||||
|
obj->vx = 0;
|
||||||
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_RIGHT);
|
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_RIGHT);
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
@@ -366,6 +338,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_up_on(akgl_Actor *obj, SDL_Ev
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) moves actor up", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) moves actor up", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ay = -(obj->basechar->ay);
|
||||||
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
||||||
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_FACE_UP | AKGL_ACTOR_STATE_MOVING_UP));
|
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_FACE_UP | AKGL_ACTOR_STATE_MOVING_UP));
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
@@ -378,6 +351,10 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_up_off(akgl_Actor *obj, SDL_E
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) stops moving actor up", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) stops moving actor up", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ay = 0;
|
||||||
|
obj->ey = 0;
|
||||||
|
obj->ty = 0;
|
||||||
|
obj->vy = 0;
|
||||||
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_UP);
|
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_UP);
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
@@ -389,6 +366,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_down_on(akgl_Actor *obj, SDL_
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) moves actor down", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) moves actor down", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ay = obj->basechar->ay;
|
||||||
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
AKGL_BITMASK_DEL(obj->state, (AKGL_ACTOR_STATE_FACE_ALL | AKGL_ACTOR_STATE_MOVING_ALL));
|
||||||
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_DOWN | AKGL_ACTOR_STATE_FACE_DOWN));
|
AKGL_BITMASK_ADD(obj->state, (AKGL_ACTOR_STATE_MOVING_DOWN | AKGL_ACTOR_STATE_FACE_DOWN));
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
@@ -401,6 +379,10 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_Actor_cmhf_down_off(akgl_Actor *obj, SDL
|
|||||||
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL actor");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
//SDL_Log("event %d (button %d / key %d) stops moving actor down", event->type, event->gbutton.which, event->key.key);
|
//SDL_Log("event %d (button %d / key %d) stops moving actor down", event->type, event->gbutton.which, event->key.key);
|
||||||
|
obj->ty = 0;
|
||||||
|
obj->ey = 0;
|
||||||
|
obj->ay = 0;
|
||||||
|
obj->vy = 0;
|
||||||
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_DOWN);
|
AKGL_BITMASK_DEL(obj->state, AKGL_ACTOR_STATE_MOVING_DOWN);
|
||||||
//SDL_Log("new target actor state: %b", obj->state);
|
//SDL_Log("new target actor state: %b", obj->state);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
|
|||||||
@@ -185,10 +185,12 @@ akerr_ErrorContext *akgl_character_load_json(char *filename)
|
|||||||
"Error while loading character from %s on line %d: %s", filename, error.line, error.text
|
"Error while loading character from %s on line %d: %s", filename, error.line, error.text
|
||||||
);
|
);
|
||||||
CATCH(errctx, akgl_character_load_json_inner(json, obj));
|
CATCH(errctx, akgl_character_load_json_inner(json, obj));
|
||||||
CATCH(errctx, akgl_get_json_integer_value(json, "movementspeed", (int *)&obj->movementspeed));
|
CATCH(errctx, akgl_get_json_integer_value(json, "speedtime", (int *)&obj->speedtime));
|
||||||
obj->movementspeed = obj->movementspeed * AKGL_TIME_ONESEC_MS;
|
obj->speedtime = obj->speedtime * AKGL_TIME_ONESEC_MS;
|
||||||
CATCH(errctx, akgl_get_json_number_value(json, "velocity_x", &obj->vx));
|
CATCH(errctx, akgl_get_json_number_value(json, "speed_x", &obj->sx));
|
||||||
CATCH(errctx, akgl_get_json_number_value(json, "velocity_y", &obj->vy));
|
CATCH(errctx, akgl_get_json_number_value(json, "speed_y", &obj->sy));
|
||||||
|
CATCH(errctx, akgl_get_json_number_value(json, "acceleration_x", &obj->ax));
|
||||||
|
CATCH(errctx, akgl_get_json_number_value(json, "acceleration_y", &obj->ay));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
//IGNORE(akgl_heap_release_string(tmpstr));
|
//IGNORE(akgl_heap_release_string(tmpstr));
|
||||||
if ( errctx != NULL ) {
|
if ( errctx != NULL ) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *even
|
|||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, appstate, AKERR_NULLPOINTER, "NULL appstate");
|
FAIL_ZERO_RETURN(errctx, appstate, AKERR_NULLPOINTER, "NULL appstate");
|
||||||
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
FAIL_ZERO_RETURN(errctx, event, AKERR_NULLPOINTER, "NULL event");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
for ( i = 0 ; i < AKGL_MAX_CONTROL_MAPS; i++ ) {
|
for ( i = 0 ; i < AKGL_MAX_CONTROL_MAPS; i++ ) {
|
||||||
curmap = &GAME_ControlMaps[i];
|
curmap = &GAME_ControlMaps[i];
|
||||||
@@ -83,6 +83,13 @@ akerr_ErrorContext *akgl_controller_handle_event(void *appstate, SDL_Event *even
|
|||||||
event->key.which == curmap->kbid &&
|
event->key.which == curmap->kbid &&
|
||||||
event->key.key == curcontrol->key)
|
event->key.key == curcontrol->key)
|
||||||
);
|
);
|
||||||
|
if ( event->type == 768 && event->key.which == 11 && event->key.key == 13 ) {
|
||||||
|
SDL_Log("Event type=%d, keyboard=%d, key=%d", event->type, event->key.which, event->key.key);
|
||||||
|
SDL_Log("ControlMap[%d].Controls[%d] keyboard=%d, key=%d", i, j, curmap->kbid, curcontrol->key);
|
||||||
|
SDL_Log("event %d -> control on %d off %d", event->type, curcontrol->event_on, curcontrol->event_off);
|
||||||
|
SDL_Log("eventButtonComboMatch for controlmap %d id %d = %d",
|
||||||
|
i, j, eventButtonComboMatch);
|
||||||
|
}
|
||||||
if ( event->type == curcontrol->event_on && eventButtonComboMatch) {
|
if ( event->type == curcontrol->event_on && eventButtonComboMatch) {
|
||||||
CATCH(errctx, curcontrol->handler_on(curmap->target, event));
|
CATCH(errctx, curcontrol->handler_on(curmap->target, event));
|
||||||
goto _akgl_controller_handle_event_success;
|
goto _akgl_controller_handle_event_success;
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ void akgl_draw_background(int w, int h)
|
|||||||
for (x = 0; x < w; x += dx) {
|
for (x = 0; x < w; x += dx) {
|
||||||
/* use an 8x8 checkerboard pattern */
|
/* use an 8x8 checkerboard pattern */
|
||||||
i = (((x ^ y) >> 3) & 1);
|
i = (((x ^ y) >> 3) & 1);
|
||||||
SDL_SetRenderDrawColor(renderer, col[i].r, col[i].g, col[i].b, col[i].a);
|
SDL_SetRenderDrawColor(renderer->sdl_renderer, col[i].r, col[i].g, col[i].b, col[i].a);
|
||||||
|
|
||||||
rect.x = (float)x;
|
rect.x = (float)x;
|
||||||
rect.y = (float)y;
|
rect.y = (float)y;
|
||||||
SDL_RenderFillRect(renderer, &rect);
|
SDL_RenderFillRect(renderer->sdl_renderer, &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
320
src/game.c
320
src/game.c
@@ -15,19 +15,26 @@
|
|||||||
#include <akgl/registry.h>
|
#include <akgl/registry.h>
|
||||||
#include <akgl/staticstring.h>
|
#include <akgl/staticstring.h>
|
||||||
#include <akgl/iterator.h>
|
#include <akgl/iterator.h>
|
||||||
|
#include <akgl/physics.h>
|
||||||
#include <akgl/SDL_GameControllerDB.h>
|
#include <akgl/SDL_GameControllerDB.h>
|
||||||
|
|
||||||
SDL_Window *window = NULL;
|
SDL_Window *window = NULL;
|
||||||
SDL_Renderer *renderer = NULL;
|
|
||||||
akgl_Frame ball;
|
// Currently active objects
|
||||||
akgl_Frame paddle1;
|
akgl_RenderBackend *renderer;
|
||||||
akgl_Frame paddle2;
|
akgl_PhysicsBackend *physics;
|
||||||
akgl_Frame table;
|
SDL_FRect *camera;
|
||||||
akgl_Tilemap gamemap;
|
akgl_Tilemap *gamemap;
|
||||||
|
|
||||||
|
// Default objects
|
||||||
|
akgl_RenderBackend _akgl_renderer;
|
||||||
|
akgl_PhysicsBackend _akgl_physics;
|
||||||
|
SDL_FRect _akgl_camera;
|
||||||
|
akgl_Tilemap _akgl_gamemap;
|
||||||
|
|
||||||
MIX_Audio *bgm = NULL;
|
MIX_Audio *bgm = NULL;
|
||||||
MIX_Mixer *akgl_mixer = NULL;
|
MIX_Mixer *akgl_mixer = NULL;
|
||||||
MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS];
|
MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS];
|
||||||
SDL_FRect camera;
|
|
||||||
akgl_Game game;
|
akgl_Game game;
|
||||||
|
|
||||||
void akgl_game_lowfps(void)
|
void akgl_game_lowfps(void)
|
||||||
@@ -42,28 +49,27 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_init()
|
|||||||
int screenheight = 0;
|
int screenheight = 0;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
ATTEMPT {
|
strncpy((char *)&game.libversion, AKGL_VERSION, 32);
|
||||||
strncpy((char *)&game.libversion, AKGL_VERSION, 32);
|
game.gameStartTime = SDL_GetTicksNS();
|
||||||
game.gameStartTime = SDL_GetTicksNS();
|
game.lastIterTime = game.gameStartTime;
|
||||||
game.lastIterTime = game.gameStartTime;
|
game.lastFPSTime = game.gameStartTime;
|
||||||
game.lastFPSTime = game.gameStartTime;
|
game.lowfpsfunc = &akgl_game_lowfps;
|
||||||
game.lowfpsfunc = &akgl_game_lowfps;
|
game.statelock = SDL_CreateMutex();
|
||||||
FAIL_ZERO_BREAK(errctx, strlen((char *)&game.name), AKERR_NULLPOINTER, "Must provide game name");
|
FAIL_ZERO_RETURN(e, game.statelock, AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||||
FAIL_ZERO_BREAK(errctx, strlen((char *)&game.version), AKERR_NULLPOINTER, "Must provide game version");
|
PASS(e, akgl_game_state_lock());
|
||||||
FAIL_ZERO_BREAK(errctx, strlen((char *)&game.uri), AKERR_NULLPOINTER, "Must provide game uri");
|
FAIL_ZERO_RETURN(e, strlen((char *)&game.name), AKERR_NULLPOINTER, "Must provide game name");
|
||||||
CATCH(errctx, akgl_heap_init());
|
FAIL_ZERO_RETURN(e, strlen((char *)&game.version), AKERR_NULLPOINTER, "Must provide game version");
|
||||||
CATCH(errctx, akgl_registry_init_actor());
|
FAIL_ZERO_RETURN(e, strlen((char *)&game.uri), AKERR_NULLPOINTER, "Must provide game uri");
|
||||||
CATCH(errctx, akgl_registry_init_sprite());
|
PASS(e, akgl_heap_init());
|
||||||
CATCH(errctx, akgl_registry_init_spritesheet());
|
PASS(e, akgl_registry_init_actor());
|
||||||
CATCH(errctx, akgl_registry_init_character());
|
PASS(e, akgl_registry_init_sprite());
|
||||||
CATCH(errctx, akgl_registry_init_font());
|
PASS(e, akgl_registry_init_spritesheet());
|
||||||
CATCH(errctx, akgl_registry_init_music());
|
PASS(e, akgl_registry_init_character());
|
||||||
CATCH(errctx, akgl_registry_init_properties());
|
PASS(e, akgl_registry_init_font());
|
||||||
CATCH(errctx, akgl_registry_init_actor_state_strings());
|
PASS(e, akgl_registry_init_music());
|
||||||
} CLEANUP {
|
PASS(e, akgl_registry_init_properties());
|
||||||
} PROCESS(errctx) {
|
PASS(e, akgl_registry_init_actor_state_strings());
|
||||||
} FINISH(errctx, true)
|
|
||||||
|
|
||||||
SDL_SetAppMetadata(game.name, game.version, game.uri);
|
SDL_SetAppMetadata(game.name, game.version, game.uri);
|
||||||
|
|
||||||
@@ -72,7 +78,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(
|
FAIL_ZERO_RETURN(
|
||||||
errctx,
|
e,
|
||||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD | SDL_INIT_AUDIO),
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD | SDL_INIT_AUDIO),
|
||||||
AKGL_ERR_SDL,
|
AKGL_ERR_SDL,
|
||||||
"Couldn't initialize SDL: %s",
|
"Couldn't initialize SDL: %s",
|
||||||
@@ -82,38 +88,11 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_init()
|
|||||||
|
|
||||||
for ( i = 0; i < AKGL_SDL_GAMECONTROLLER_DB_LEN ; i++ ) {
|
for ( i = 0; i < AKGL_SDL_GAMECONTROLLER_DB_LEN ; i++ ) {
|
||||||
if ( SDL_AddGamepadMapping(SDL_GAMECONTROLLER_DB[i]) == -1 ) {
|
if ( SDL_AddGamepadMapping(SDL_GAMECONTROLLER_DB[i]) == -1 ) {
|
||||||
FAIL_ZERO_RETURN(errctx, 0, AKGL_ERR_SDL, "%s", SDL_GetError());
|
FAIL_ZERO_RETURN(e, 0, AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PASS(errctx, akgl_controller_open_gamepads());
|
PASS(e, akgl_controller_open_gamepads());
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_init_screen()
|
|
||||||
{
|
|
||||||
akgl_String *width = NULL;
|
|
||||||
akgl_String *height = NULL;
|
|
||||||
int screenwidth;
|
|
||||||
int screenheight;
|
|
||||||
|
|
||||||
PREPARE_ERROR(e);
|
|
||||||
|
|
||||||
PASS(e, akgl_get_property("game.screenwidth", &width, "0"));
|
|
||||||
PASS(e, akgl_get_property("game.screenheight", &height, "0"));
|
|
||||||
PASS(e, aksl_atoi(width->data, &screenwidth));
|
|
||||||
PASS(e, aksl_atoi(height->data, &screenheight));
|
|
||||||
SDL_Log("Initializing screen (%sx%s = %dx%d)", width->data, height->data, screenwidth, screenheight);
|
|
||||||
PASS(e, akgl_heap_release_string(width));
|
|
||||||
PASS(e, akgl_heap_release_string(height));
|
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(
|
|
||||||
e,
|
|
||||||
SDL_CreateWindowAndRenderer(game.uri, screenwidth, screenheight, 0, &window, &renderer),
|
|
||||||
AKGL_ERR_SDL,
|
|
||||||
"Couldn't create window/renderer: %s",
|
|
||||||
SDL_GetError());
|
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(
|
FAIL_ZERO_RETURN(
|
||||||
e,
|
e,
|
||||||
MIX_Init(),
|
MIX_Init(),
|
||||||
@@ -135,10 +114,34 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_init_screen()
|
|||||||
"Couldn't initialize front engine: %s",
|
"Couldn't initialize front engine: %s",
|
||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
|
|
||||||
camera.x = 0;
|
camera = &_akgl_camera;
|
||||||
camera.y = 0;
|
renderer = &_akgl_renderer;
|
||||||
camera.w = screenwidth;
|
physics = &_akgl_physics;
|
||||||
camera.h = screenheight;
|
gamemap = &_akgl_gamemap;
|
||||||
|
|
||||||
|
PASS(e, akgl_game_state_unlock());
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_state_lock(void)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
SDL_Time totaltime = 0;
|
||||||
|
|
||||||
|
while ( totaltime < AKGL_TIME_ONESEC_MS ) {
|
||||||
|
if ( SDL_TryLockMutex(game.statelock) == true ) {
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
totaltime += 100;
|
||||||
|
SDL_Delay(100);
|
||||||
|
}
|
||||||
|
FAIL_RETURN(e, AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_state_unlock(void)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
SDL_UnlockMutex(game.statelock);
|
||||||
SUCCEED_RETURN(e);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,119 +169,119 @@ void akgl_game_save_actorname_iterator(void *userdata, SDL_PropertiesID props, c
|
|||||||
{
|
{
|
||||||
FILE *fp = (FILE *)userdata;
|
FILE *fp = (FILE *)userdata;
|
||||||
akgl_Actor *actor = NULL;
|
akgl_Actor *actor = NULL;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||||
CATCH(errctx, aksl_fwrite((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||||
actor = SDL_GetPointerProperty(props, name, NULL);
|
actor = SDL_GetPointerProperty(props, name, NULL);
|
||||||
CATCH(errctx, aksl_fwrite(&actor, 1, sizeof(akgl_Actor *), fp));
|
CATCH(e, aksl_fwrite(&actor, 1, sizeof(akgl_Actor *), fp));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH_NORETURN(errctx);
|
} FINISH_NORETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void akgl_game_save_spritename_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
void akgl_game_save_spritename_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
||||||
{
|
{
|
||||||
FILE *fp = (FILE *)userdata;
|
FILE *fp = (FILE *)userdata;
|
||||||
akgl_Sprite *sprite = NULL;
|
akgl_Sprite *sprite = NULL;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||||
sprite = SDL_GetPointerProperty(props, name, NULL);
|
sprite = SDL_GetPointerProperty(props, name, NULL);
|
||||||
CATCH(errctx, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite(&sprite, 1, sizeof(akgl_Sprite *), fp));
|
CATCH(e, aksl_fwrite(&sprite, 1, sizeof(akgl_Sprite *), fp));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH_NORETURN(errctx);
|
} FINISH_NORETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void akgl_game_save_spritesheetname_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
void akgl_game_save_spritesheetname_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
||||||
{
|
{
|
||||||
FILE *fp = (FILE *)userdata;
|
FILE *fp = (FILE *)userdata;
|
||||||
akgl_SpriteSheet *spritesheet = NULL;
|
akgl_SpriteSheet *spritesheet = NULL;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||||
spritesheet = SDL_GetPointerProperty(props, name, NULL);
|
spritesheet = SDL_GetPointerProperty(props, name, NULL);
|
||||||
CATCH(errctx, aksl_fwrite((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp));
|
CATCH(e, aksl_fwrite(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH_NORETURN(errctx);
|
} FINISH_NORETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void akgl_game_save_charactername_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
void akgl_game_save_charactername_iterator(void *userdata, SDL_PropertiesID props, const char *name)
|
||||||
{
|
{
|
||||||
FILE *fp = (FILE *)userdata;
|
FILE *fp = (FILE *)userdata;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
akgl_Character *character = NULL;
|
akgl_Character *character = NULL;
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||||
character = SDL_GetPointerProperty(props, name, NULL);
|
character = SDL_GetPointerProperty(props, name, NULL);
|
||||||
CATCH(errctx, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite(&character, 1, sizeof(akgl_Character *), fp));
|
CATCH(e, aksl_fwrite(&character, 1, sizeof(akgl_Character *), fp));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH_NORETURN(errctx);
|
} FINISH_NORETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save_actors(FILE *fp)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save_actors(FILE *fp)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
char nullval = 0x00;
|
char nullval = 0x00;
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||||
// write the actor name pointer table
|
// write the actor name pointer table
|
||||||
SDL_EnumerateProperties(
|
SDL_EnumerateProperties(
|
||||||
AKGL_REGISTRY_ACTOR,
|
AKGL_REGISTRY_ACTOR,
|
||||||
&akgl_game_save_actorname_iterator,
|
&akgl_game_save_actorname_iterator,
|
||||||
(void *)fp);
|
(void *)fp);
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Actor *), fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Actor *), fp));
|
||||||
// write the sprite name pointer table
|
// write the sprite name pointer table
|
||||||
SDL_EnumerateProperties(
|
SDL_EnumerateProperties(
|
||||||
AKGL_REGISTRY_SPRITE,
|
AKGL_REGISTRY_SPRITE,
|
||||||
&akgl_game_save_spritename_iterator,
|
&akgl_game_save_spritename_iterator,
|
||||||
(void *)fp);
|
(void *)fp);
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Sprite *), fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Sprite *), fp));
|
||||||
// write the spritesheet name pointer table
|
// write the spritesheet name pointer table
|
||||||
SDL_EnumerateProperties(
|
SDL_EnumerateProperties(
|
||||||
AKGL_REGISTRY_SPRITESHEET,
|
AKGL_REGISTRY_SPRITESHEET,
|
||||||
&akgl_game_save_spritesheetname_iterator,
|
&akgl_game_save_spritesheetname_iterator,
|
||||||
(void *)fp);
|
(void *)fp);
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_SpriteSheet *), fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||||
// write the character name pointer table
|
// write the character name pointer table
|
||||||
SDL_EnumerateProperties(
|
SDL_EnumerateProperties(
|
||||||
AKGL_REGISTRY_CHARACTER,
|
AKGL_REGISTRY_CHARACTER,
|
||||||
&akgl_game_save_charactername_iterator,
|
&akgl_game_save_charactername_iterator,
|
||||||
(void *)fp);
|
(void *)fp);
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||||
CATCH(errctx, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Character *), fp));
|
CATCH(e, aksl_fwrite((void *)&nullval, 1, sizeof(akgl_Character *), fp));
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH(errctx, true);
|
} FINISH(e, true);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
FAIL_ZERO_BREAK(errctx, fpath, AKERR_NULLPOINTER, "NULL file path");
|
FAIL_ZERO_BREAK(e, fpath, AKERR_NULLPOINTER, "NULL file path");
|
||||||
CATCH(errctx, aksl_fopen(fpath, "wb", &fp));
|
CATCH(e, aksl_fopen(fpath, "wb", &fp));
|
||||||
CATCH(errctx, aksl_fwrite(&game, 1, sizeof(akgl_Game), fp));
|
CATCH(e, aksl_fwrite(&game, 1, sizeof(akgl_Game), fp));
|
||||||
CATCH(errctx, akgl_game_save_actors(fp));
|
CATCH(e, akgl_game_save_actors(fp));
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
if ( fp != NULL )
|
if ( fp != NULL )
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} FINISH(errctx, true);
|
} FINISH(e, true);
|
||||||
SUCCEED_RETURN(errctx); // SUCCEED_NORETURN if in main().
|
SUCCEED_RETURN(e); // SUCCEED_NORETURN if in main().
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_PropertiesID map, int namelength, int ptrlength, SDL_PropertiesID registry)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_PropertiesID map, int namelength, int ptrlength, SDL_PropertiesID registry)
|
||||||
@@ -288,10 +291,10 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_Pr
|
|||||||
char objname[namelength];
|
char objname[namelength];
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
CATCH(errctx, aksl_fread((void *)&objname, 1, namelength, fp));
|
CATCH(e, aksl_fread((void *)&objname, 1, namelength, fp));
|
||||||
CATCH(errctx, aksl_fread((void *)&ptr, 1, ptrlength, fp));
|
CATCH(e, aksl_fread((void *)&ptr, 1, ptrlength, fp));
|
||||||
// End of the map
|
// End of the map
|
||||||
if ( ptr == 0x00 && objname[0] == 0x00 ) {
|
if ( ptr == 0x00 && objname[0] == 0x00 ) {
|
||||||
break;
|
break;
|
||||||
@@ -304,43 +307,43 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_Pr
|
|||||||
|
|
||||||
// SDL_Properties objects can only use string keys, so we can't use the
|
// SDL_Properties objects can only use string keys, so we can't use the
|
||||||
// old pointer as a key without first converting it to a string.
|
// old pointer as a key without first converting it to a string.
|
||||||
CATCH(errctx, aksl_memset((void *)&ptrstring, 0x00, 32));
|
CATCH(e, aksl_memset((void *)&ptrstring, 0x00, 32));
|
||||||
snprintf((char *)&ptrstring, 32, "%p", ptr);
|
snprintf((char *)&ptrstring, 32, "%p", ptr);
|
||||||
SDL_SetPointerProperty(
|
SDL_SetPointerProperty(
|
||||||
map,
|
map,
|
||||||
ptrstring,
|
ptrstring,
|
||||||
SDL_GetPointerProperty(registry, objname, NULL));
|
SDL_GetPointerProperty(registry, objname, NULL));
|
||||||
};
|
};
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_versioncmp(char *versiontype, char *newversion, char *curversion)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_versioncmp(char *versiontype, char *newversion, char *curversion)
|
||||||
{
|
{
|
||||||
semver_t current_version = {};
|
semver_t current_version = {};
|
||||||
semver_t compare_version = {};
|
semver_t compare_version = {};
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
FAIL_ZERO_RETURN(errctx, versiontype, AKERR_NULLPOINTER, "NULL argument");
|
FAIL_ZERO_RETURN(e, versiontype, AKERR_NULLPOINTER, "NULL argument");
|
||||||
FAIL_ZERO_RETURN(errctx, curversion, AKERR_NULLPOINTER, "NULL argument");
|
FAIL_ZERO_RETURN(e, curversion, AKERR_NULLPOINTER, "NULL argument");
|
||||||
FAIL_ZERO_RETURN(errctx, newversion, AKERR_NULLPOINTER, "NULL argument");
|
FAIL_ZERO_RETURN(e, newversion, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
// Check save game library version
|
// Check save game library version
|
||||||
FAIL_NONZERO_BREAK(
|
FAIL_NONZERO_BREAK(
|
||||||
errctx,
|
e,
|
||||||
semver_parse((const char *)curversion, ¤t_version),
|
semver_parse((const char *)curversion, ¤t_version),
|
||||||
AKERR_VALUE,
|
AKERR_VALUE,
|
||||||
"Invalid semantic %s version in current game: %s",
|
"Invalid semantic %s version in current game: %s",
|
||||||
versiontype,
|
versiontype,
|
||||||
(char *)curversion);
|
(char *)curversion);
|
||||||
FAIL_NONZERO_BREAK(
|
FAIL_NONZERO_BREAK(
|
||||||
errctx,
|
e,
|
||||||
semver_parse((const char *)newversion, &compare_version),
|
semver_parse((const char *)newversion, &compare_version),
|
||||||
AKERR_VALUE,
|
AKERR_VALUE,
|
||||||
"Invalid semantic %s version in save game: %s",
|
"Invalid semantic %s version in save game: %s",
|
||||||
versiontype,
|
versiontype,
|
||||||
(char *)&newversion);
|
(char *)&newversion);
|
||||||
FAIL_ZERO_BREAK(
|
FAIL_ZERO_BREAK(
|
||||||
errctx,
|
e,
|
||||||
semver_satisfies(compare_version, current_version, "="),
|
semver_satisfies(compare_version, current_version, "="),
|
||||||
AKERR_API,
|
AKERR_API,
|
||||||
"Incompatible save game %s version (%s != %s)",
|
"Incompatible save game %s version (%s != %s)",
|
||||||
@@ -350,9 +353,9 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_versioncmp(char *versiontype,
|
|||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
semver_free(¤t_version);
|
semver_free(¤t_version);
|
||||||
semver_free(&compare_version);
|
semver_free(&compare_version);
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH(errctx, true);
|
} FINISH(e, true);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath)
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath)
|
||||||
@@ -364,21 +367,21 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath)
|
|||||||
SDL_PropertiesID charactermap;
|
SDL_PropertiesID charactermap;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(e);
|
||||||
FAIL_ZERO_RETURN(errctx, fpath, AKERR_NULLPOINTER, "NULL file path");
|
FAIL_ZERO_RETURN(e, fpath, AKERR_NULLPOINTER, "NULL file path");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
CATCH(errctx, aksl_fopen(fpath, "rb", &fp));
|
CATCH(e, aksl_fopen(fpath, "rb", &fp));
|
||||||
CATCH(errctx, aksl_fread((void *)&savegame, 1, sizeof(akgl_Game), fp));
|
CATCH(e, aksl_fread((void *)&savegame, 1, sizeof(akgl_Game), fp));
|
||||||
CATCH(errctx, akgl_game_load_versioncmp("library", (char *)&savegame.libversion, (char *)AKGL_VERSION));
|
CATCH(e, akgl_game_load_versioncmp("library", (char *)&savegame.libversion, (char *)AKGL_VERSION));
|
||||||
CATCH(errctx, akgl_game_load_versioncmp("game", (char *)&savegame.version, (char *)&game.version));
|
CATCH(e, akgl_game_load_versioncmp("game", (char *)&savegame.version, (char *)&game.version));
|
||||||
FAIL_NONZERO_RETURN(
|
FAIL_NONZERO_RETURN(
|
||||||
errctx,
|
e,
|
||||||
strncmp((char *)&savegame.name, (char *)&game.name, 256),
|
strncmp((char *)&savegame.name, (char *)&game.name, 256),
|
||||||
AKERR_API,
|
AKERR_API,
|
||||||
"Savegame is not compatible with this game");
|
"Savegame is not compatible with this game");
|
||||||
FAIL_NONZERO_RETURN(
|
FAIL_NONZERO_RETURN(
|
||||||
errctx,
|
e,
|
||||||
strncmp((char *)&savegame.uri, (char *)&game.uri, 256),
|
strncmp((char *)&savegame.uri, (char *)&game.uri, 256),
|
||||||
AKERR_API,
|
AKERR_API,
|
||||||
"Savegame is not compatible with this game");
|
"Savegame is not compatible with this game");
|
||||||
@@ -386,23 +389,64 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath)
|
|||||||
memcpy((void *)&game, (void *)&savegame, sizeof(akgl_Game));
|
memcpy((void *)&game, (void *)&savegame, sizeof(akgl_Game));
|
||||||
// Load actor name map
|
// Load actor name map
|
||||||
actormap = SDL_CreateProperties();
|
actormap = SDL_CreateProperties();
|
||||||
CATCH(errctx, akgl_game_load_objectnamemap(fp, actormap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Actor *), AKGL_REGISTRY_ACTOR));
|
CATCH(e, akgl_game_load_objectnamemap(fp, actormap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Actor *), AKGL_REGISTRY_ACTOR));
|
||||||
// Load sprite name map
|
// Load sprite name map
|
||||||
spritemap = SDL_CreateProperties();
|
spritemap = SDL_CreateProperties();
|
||||||
CATCH(errctx, akgl_game_load_objectnamemap(fp, spritemap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Sprite *), AKGL_REGISTRY_SPRITE));
|
CATCH(e, akgl_game_load_objectnamemap(fp, spritemap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Sprite *), AKGL_REGISTRY_SPRITE));
|
||||||
// Load spritesheet name map
|
// Load spritesheet name map
|
||||||
spritesheetmap = SDL_CreateProperties();
|
spritesheetmap = SDL_CreateProperties();
|
||||||
CATCH(errctx, akgl_game_load_objectnamemap(fp, spritesheetmap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_SpriteSheet *), AKGL_REGISTRY_SPRITESHEET));
|
CATCH(e, akgl_game_load_objectnamemap(fp, spritesheetmap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_SpriteSheet *), AKGL_REGISTRY_SPRITESHEET));
|
||||||
// Load character name map
|
// Load character name map
|
||||||
charactermap = SDL_CreateProperties();
|
charactermap = SDL_CreateProperties();
|
||||||
CATCH(errctx, akgl_game_load_objectnamemap(fp, charactermap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Character *), AKGL_REGISTRY_CHARACTER));
|
CATCH(e, akgl_game_load_objectnamemap(fp, charactermap, AKGL_ACTOR_MAX_NAME_LENGTH, sizeof(akgl_Character *), AKGL_REGISTRY_CHARACTER));
|
||||||
// Now that we have all of our pointer maps built, we can load the actual binary objects and reset their pointers
|
// Now that we have all of our pointer maps built, we can load the actual binary objects and reset their pointers
|
||||||
} CLEANUP {
|
} CLEANUP {
|
||||||
if ( fp != NULL ) {
|
if ( fp != NULL ) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
} PROCESS(errctx) {
|
} PROCESS(e) {
|
||||||
} FINISH(errctx, true);
|
} FINISH(e, true);
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_game_update(akgl_Iterator *opflags)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
akgl_Iterator defflags = {
|
||||||
|
.flags = (AKGL_ITERATOR_OP_LAYERMASK | AKGL_ITERATOR_OP_LAYERMASK),
|
||||||
|
.layerid = 0
|
||||||
|
};
|
||||||
|
SDL_Time curTime = SDL_GetTicksNS();
|
||||||
|
akgl_Actor *actor = NULL;
|
||||||
|
|
||||||
|
if ( opflags == NULL ) {
|
||||||
|
opflags = &defflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
PASS(e, akgl_game_state_lock());
|
||||||
|
|
||||||
|
akgl_game_updateFPS();
|
||||||
|
|
||||||
|
for ( int i = 0; i < AKGL_TILEMAP_MAX_LAYERS; i++ ) {
|
||||||
|
if ( opflags == &defflags ) {
|
||||||
|
opflags->layerid = i;
|
||||||
|
}
|
||||||
|
for ( int j = 0; j < AKGL_MAX_HEAP_ACTOR; j++ ) {
|
||||||
|
actor = &HEAP_ACTOR[j];
|
||||||
|
if ( actor->refcount == 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_TILEMAPSCALE) ) {
|
||||||
|
PASS(e, akgl_tilemap_scale_actor(gamemap, actor));
|
||||||
|
} else {
|
||||||
|
actor->scale = 1.0;
|
||||||
|
}
|
||||||
|
PASS(e, actor->updatefunc(actor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PASS(e, physics->simulate(physics, NULL));
|
||||||
|
PASS(e, renderer->draw_world(renderer, NULL));
|
||||||
|
PASS(e, akgl_game_state_unlock());
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/heap.c
13
src/heap.c
@@ -20,9 +20,7 @@ akerr_ErrorContext *akgl_heap_init()
|
|||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
akerr_name_for_status(AKGL_ERR_SDL, "SDL Error");
|
akerr_name_for_status(AKGL_ERR_SDL, "SDL Error");
|
||||||
for ( i = 0; i < AKGL_MAX_HEAP_ACTOR; i++) {
|
PASS(errctx, akgl_heap_init_actor());
|
||||||
memset(&HEAP_ACTOR[i], 0x00, sizeof(akgl_Actor));
|
|
||||||
}
|
|
||||||
for ( i = 0; i < AKGL_MAX_HEAP_SPRITE; i++) {
|
for ( i = 0; i < AKGL_MAX_HEAP_SPRITE; i++) {
|
||||||
memset(&HEAP_SPRITE[i], 0x00, sizeof(akgl_Sprite));
|
memset(&HEAP_SPRITE[i], 0x00, sizeof(akgl_Sprite));
|
||||||
}
|
}
|
||||||
@@ -38,6 +36,15 @@ akerr_ErrorContext *akgl_heap_init()
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_heap_init_actor(void)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
for ( int i = 0; i < AKGL_MAX_HEAP_ACTOR; i++) {
|
||||||
|
memset(&HEAP_ACTOR[i], 0x00, sizeof(akgl_Actor));
|
||||||
|
}
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_heap_next_actor(akgl_Actor **dest)
|
akerr_ErrorContext *akgl_heap_next_actor(akgl_Actor **dest)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
|
|||||||
@@ -52,6 +52,17 @@ akerr_ErrorContext *akgl_get_json_number_value(json_t *obj, char *key, float *de
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_double_value(json_t *obj, char *key, double *dest)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(errctx);
|
||||||
|
FAIL_ZERO_RETURN(errctx, obj, AKERR_NULLPOINTER, "NULL pointer reference");
|
||||||
|
json_t *value = json_object_get(obj, key);
|
||||||
|
FAIL_ZERO_RETURN(errctx, value, AKERR_KEY, "Key %s not found in object", key);
|
||||||
|
FAIL_ZERO_RETURN(errctx, (json_is_number(value)), AKERR_TYPE, "Key %s in object has incorrect type", key);
|
||||||
|
*dest = json_number_value(value);
|
||||||
|
SUCCEED_RETURN(errctx);
|
||||||
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_get_json_string_value(json_t *obj, char *key, akgl_String **dest)
|
akerr_ErrorContext *akgl_get_json_string_value(json_t *obj, char *key, akgl_String **dest)
|
||||||
{
|
{
|
||||||
json_t *value = NULL;
|
json_t *value = NULL;
|
||||||
@@ -129,3 +140,26 @@ akerr_ErrorContext *akgl_get_json_array_index_string(json_t *array, int index, a
|
|||||||
strncpy((char *)&(*dest)->data, json_string_value(value), AKGL_MAX_STRING_LENGTH);
|
strncpy((char *)&(*dest)->data, json_string_value(value), AKGL_MAX_STRING_LENGTH);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_with_default(akerr_ErrorContext *err, void *defval, void *dest, uint32_t defsize)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
if ( err == NULL ) {
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
int docopy = 0;
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(e, err, AKERR_NULLPOINTER, "err");
|
||||||
|
FAIL_ZERO_RETURN(e, defval, AKERR_NULLPOINTER, "defval");
|
||||||
|
FAIL_ZERO_RETURN(e, dest, AKERR_NULLPOINTER, "dest");
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
} CLEANUP {
|
||||||
|
} PROCESS(err) {
|
||||||
|
} HANDLE_GROUP(err, AKERR_KEY) {
|
||||||
|
} HANDLE_GROUP(err, AKERR_INDEX) {
|
||||||
|
memcpy(dest, defval, defsize);
|
||||||
|
} FINISH(err, true);
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|||||||
236
src/physics.c
Normal file
236
src/physics.c
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include <akstdlib.h>
|
||||||
|
#include <akgl/physics.h>
|
||||||
|
#include <akgl/actor.h>
|
||||||
|
#include <akgl/game.h>
|
||||||
|
#include <akgl/error.h>
|
||||||
|
#include <akgl/heap.h>
|
||||||
|
#include <akgl/registry.h>
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_null_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_null(akgl_PhysicsBackend *self)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
|
||||||
|
self->gravity = akgl_physics_null_gravity;
|
||||||
|
self->collide = akgl_physics_null_collide;
|
||||||
|
self->move = akgl_physics_null_move;
|
||||||
|
self->simulate = akgl_physics_simulate;
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_gravity(akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_ZERO_RETURN(e, actor, AKERR_NULLPOINTER, "actor");
|
||||||
|
|
||||||
|
if ( self->gravity_x != 0 ) {
|
||||||
|
// Assume the X origin is - (screen left)
|
||||||
|
actor->ex -= (self->gravity_x * dt);
|
||||||
|
}
|
||||||
|
if ( self->gravity_y != 0 ) {
|
||||||
|
// Assume Y origin is + (down screen)
|
||||||
|
actor->ey += (self->gravity_y * dt);
|
||||||
|
}
|
||||||
|
if ( self->gravity_z != 0 ) {
|
||||||
|
// Assume Z origin is - (behind the camera)
|
||||||
|
actor->ez -= (self->gravity_z * dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_collide(akgl_PhysicsBackend *self, akgl_Actor *a1, akgl_Actor *a2)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_RETURN(e, AKERR_API, "Not implemented");
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_arcade_move(struct akgl_PhysicsBackend *self, akgl_Actor *actor, float32_t dt)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_ZERO_RETURN(e, actor, AKERR_NULLPOINTER, "actor");
|
||||||
|
actor->x += actor->vx * dt;
|
||||||
|
actor->y += actor->vy * dt;
|
||||||
|
actor->z += actor->vz * dt;
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_init_arcade(akgl_PhysicsBackend *self)
|
||||||
|
{
|
||||||
|
akgl_String *tmp;
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
PASS(e, akgl_heap_next_string(&tmp));
|
||||||
|
|
||||||
|
self->gravity = akgl_physics_arcade_gravity;
|
||||||
|
self->collide = akgl_physics_arcade_collide;
|
||||||
|
self->move = akgl_physics_arcade_move;
|
||||||
|
self->simulate = akgl_physics_simulate;
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
CATCH(e, akgl_get_property("physics.gravity.x", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->gravity_x));
|
||||||
|
CATCH(e, akgl_get_property("physics.gravity.y", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->gravity_y));
|
||||||
|
CATCH(e, akgl_get_property("physics.gravity.z", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->gravity_z));
|
||||||
|
CATCH(e, akgl_get_property("physics.drag.x", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->drag_x));
|
||||||
|
CATCH(e, akgl_get_property("physics.drag.y", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->drag_y));
|
||||||
|
CATCH(e, akgl_get_property("physics.drag.z", &tmp, "0.0"));
|
||||||
|
CATCH(e, aksl_atof(tmp->data, &self->drag_z));
|
||||||
|
} CLEANUP {
|
||||||
|
IGNORE(akgl_heap_release_string(tmp));
|
||||||
|
} PROCESS(e) {
|
||||||
|
} FINISH(e, true);
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_simulate(akgl_PhysicsBackend *self, akgl_Iterator *opflags)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
akgl_Iterator defflags = {
|
||||||
|
.flags = 0,
|
||||||
|
.layerid = 0
|
||||||
|
};
|
||||||
|
SDL_Time curtime = SDL_GetTicksNS();
|
||||||
|
float32_t dt = (float32_t)(curtime - self->gravity_time) / (float32_t)AKGL_TIME_ONESEC_NS;
|
||||||
|
akgl_Actor *actor = NULL;
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_ZERO_RETURN(e, self->move, AKERR_NULLPOINTER, "self->move");
|
||||||
|
|
||||||
|
if ( opflags == NULL ) {
|
||||||
|
opflags = &defflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for ( int i = 0; i < AKGL_MAX_HEAP_ACTOR; i++ ) {
|
||||||
|
actor = &HEAP_ACTOR[i];
|
||||||
|
if ( actor->refcount == 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( actor->parent != NULL ) {
|
||||||
|
// Children don't move independently of their parents, they just have an offset
|
||||||
|
actor->x = actor->parent->x + actor->vx;
|
||||||
|
actor->y = actor->parent->y + actor->vy;
|
||||||
|
actor->z = actor->parent->z + actor->vz;
|
||||||
|
continue;
|
||||||
|
} else if ( actor->basechar == NULL ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( AKGL_BITMASK_HAS(opflags->flags, AKGL_ITERATOR_OP_LAYERMASK) ) {
|
||||||
|
if ( actor->layer != opflags->layerid ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// thrust is a function of acceleration on a given axis
|
||||||
|
if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_LEFT) ||
|
||||||
|
AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_RIGHT) ) {
|
||||||
|
actor->tx += actor->ax * dt;
|
||||||
|
}
|
||||||
|
if ( AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_UP) ||
|
||||||
|
AKGL_BITMASK_HAS(actor->state, AKGL_ACTOR_STATE_MOVING_DOWN) ) {
|
||||||
|
actor->ty += actor->ay * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// velocity equals thrust unless thrust exceeds max speed
|
||||||
|
if ( fabsf(actor->tx) > fabsf(actor->sx) ) {
|
||||||
|
if ( actor->tx < 0 ) {
|
||||||
|
actor->tx = -actor->sx;
|
||||||
|
} else {
|
||||||
|
actor->tx = actor->sx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( fabsf(actor->ty) > fabsf(actor->sy) ) {
|
||||||
|
if ( actor->ty < 0 ) {
|
||||||
|
actor->ty = -actor->sy;
|
||||||
|
} else {
|
||||||
|
actor->ty = actor->sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( fabsf(actor->tz) > fabsf(actor->sz) ) {
|
||||||
|
if ( actor->tz < 0 ) {
|
||||||
|
actor->tz = -actor->sz;
|
||||||
|
} else {
|
||||||
|
actor->tz = actor->sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ATTEMPT {
|
||||||
|
CATCH(e, actor->movementlogicfunc(actor, dt));
|
||||||
|
PASS(e, self->gravity(self, actor, dt));
|
||||||
|
|
||||||
|
// Counteract velocity with atmospheric drag
|
||||||
|
if ( self->drag_x != 0 ) {
|
||||||
|
actor->ex -= actor->ex * self->drag_x * dt;
|
||||||
|
}
|
||||||
|
if ( self->drag_y != 0 ) {
|
||||||
|
actor->ey -= actor->ey * self->drag_y * dt;
|
||||||
|
}
|
||||||
|
if ( self->drag_z != 0 ) {
|
||||||
|
actor->ez -= actor->ez * self->drag_z * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
actor->vx = actor->ex + actor->tx;
|
||||||
|
actor->vy = actor->ey + actor->ty;
|
||||||
|
actor->vz = actor->ez + actor->tz;
|
||||||
|
|
||||||
|
PASS(e, self->move(self, actor, dt));
|
||||||
|
} CLEANUP {
|
||||||
|
} PROCESS(e) {
|
||||||
|
} HANDLE(e, AKGL_ERR_LOGICINTERRUPT) {
|
||||||
|
// noop
|
||||||
|
} FINISH(e, true);
|
||||||
|
}
|
||||||
|
self->gravity_time = curtime;
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_physics_factory(akgl_PhysicsBackend *self, akgl_String *type)
|
||||||
|
{
|
||||||
|
uint32_t hashval;
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_ZERO_RETURN(e, type, AKERR_NULLPOINTER, "type");
|
||||||
|
|
||||||
|
if ( strncmp(type->data, "null", 4) == 0) {
|
||||||
|
PASS(e, akgl_physics_init_null(self));
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
if ( strncmp(type->data, "arcade", 6) == 0) {
|
||||||
|
PASS(e, akgl_physics_init_arcade(self));
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
FAIL_RETURN(e, AKERR_KEY, "Invalid physics engine %s", type->data);
|
||||||
|
}
|
||||||
@@ -10,14 +10,14 @@
|
|||||||
#include <akgl/actor.h>
|
#include <akgl/actor.h>
|
||||||
#include <akgl/json_helpers.h>
|
#include <akgl/json_helpers.h>
|
||||||
|
|
||||||
SDL_PropertiesID AKGL_REGISTRY_ACTOR;
|
SDL_PropertiesID AKGL_REGISTRY_ACTOR = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_ACTOR_STATE_STRINGS;
|
SDL_PropertiesID AKGL_REGISTRY_ACTOR_STATE_STRINGS = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_SPRITE;
|
SDL_PropertiesID AKGL_REGISTRY_SPRITE = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_SPRITESHEET;
|
SDL_PropertiesID AKGL_REGISTRY_SPRITESHEET = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_CHARACTER;
|
SDL_PropertiesID AKGL_REGISTRY_CHARACTER = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_MUSIC;
|
SDL_PropertiesID AKGL_REGISTRY_MUSIC = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_FONT;
|
SDL_PropertiesID AKGL_REGISTRY_FONT = 0;
|
||||||
SDL_PropertiesID AKGL_REGISTRY_PROPERTIES;
|
SDL_PropertiesID AKGL_REGISTRY_PROPERTIES = 0;
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_registry_init()
|
akerr_ErrorContext *akgl_registry_init()
|
||||||
{
|
{
|
||||||
@@ -39,6 +39,9 @@ akerr_ErrorContext *akgl_registry_init()
|
|||||||
akerr_ErrorContext *akgl_registry_init_actor()
|
akerr_ErrorContext *akgl_registry_init_actor()
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
|
if ( AKGL_REGISTRY_ACTOR != 0 ) {
|
||||||
|
SDL_DestroyProperties(AKGL_REGISTRY_ACTOR);
|
||||||
|
}
|
||||||
AKGL_REGISTRY_ACTOR = SDL_CreateProperties();
|
AKGL_REGISTRY_ACTOR = SDL_CreateProperties();
|
||||||
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_ACTOR, AKERR_NULLPOINTER, "Error initializing actor registry");
|
FAIL_ZERO_RETURN(errctx, AKGL_REGISTRY_ACTOR, AKERR_NULLPOINTER, "Error initializing actor registry");
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
|
|||||||
136
src/renderer.c
Normal file
136
src/renderer.c
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include <akgl/renderer.h>
|
||||||
|
#include <akgl/staticstring.h>
|
||||||
|
#include <akgl/registry.h>
|
||||||
|
#include <akgl/heap.h>
|
||||||
|
#include <akgl/game.h>
|
||||||
|
|
||||||
|
#include <akerror.h>
|
||||||
|
#include <akstdlib.h>
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_init2d(akgl_RenderBackend *self)
|
||||||
|
{
|
||||||
|
akgl_String *width = NULL;
|
||||||
|
akgl_String *height = NULL;
|
||||||
|
int screenwidth;
|
||||||
|
int screenheight;
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
|
||||||
|
PASS(e, akgl_get_property("game.screenwidth", &width, "0"));
|
||||||
|
PASS(e, akgl_get_property("game.screenheight", &height, "0"));
|
||||||
|
PASS(e, aksl_atoi(width->data, &screenwidth));
|
||||||
|
PASS(e, aksl_atoi(height->data, &screenheight));
|
||||||
|
SDL_Log("Initializing screen (%sx%s = %dx%d)", width->data, height->data, screenwidth, screenheight);
|
||||||
|
PASS(e, akgl_heap_release_string(width));
|
||||||
|
PASS(e, akgl_heap_release_string(height));
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(
|
||||||
|
e,
|
||||||
|
SDL_CreateWindowAndRenderer(game.uri, screenwidth, screenheight, 0, &window, &self->sdl_renderer),
|
||||||
|
AKGL_ERR_SDL,
|
||||||
|
"Couldn't create window/renderer: %s",
|
||||||
|
SDL_GetError());
|
||||||
|
|
||||||
|
camera->x = 0;
|
||||||
|
camera->y = 0;
|
||||||
|
camera->w = screenwidth;
|
||||||
|
camera->h = screenheight;
|
||||||
|
|
||||||
|
self->shutdown = &akgl_render_2d_shutdown;
|
||||||
|
self->frame_start = &akgl_render_2d_frame_start;
|
||||||
|
self->frame_end = &akgl_render_2d_frame_end;
|
||||||
|
self->draw_texture = &akgl_render_2d_draw_texture;
|
||||||
|
self->draw_mesh = &akgl_render_2d_draw_mesh;
|
||||||
|
self->draw_world = &akgl_render_2d_draw_world;
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_shutdown(akgl_RenderBackend *self)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_frame_start(akgl_RenderBackend *self)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self->sdl_renderer, AKERR_NULLPOINTER, "No valid SDL rendering backend");
|
||||||
|
SDL_SetRenderDrawColor(self->sdl_renderer, 0, 0, 0, 255);
|
||||||
|
SDL_RenderClear(self->sdl_renderer);
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_frame_end(akgl_RenderBackend *self)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self->sdl_renderer, AKERR_NULLPOINTER, "No valid SDL rendering backend");
|
||||||
|
SDL_RenderPresent(self->sdl_renderer);
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_texture(akgl_RenderBackend *self, SDL_Texture *texture, SDL_FRect *src, SDL_FRect *dest, double angle, SDL_FPoint *center, SDL_FlipMode flip)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
FAIL_ZERO_RETURN(e, texture, AKERR_NULLPOINTER, "texture");
|
||||||
|
//FAIL_ZERO_RETURN(e, src, AKERR_NULLPOINTER, "src");
|
||||||
|
//FAIL_ZERO_RETURN(e, dest, AKERR_NULLPOINTER, "dest");
|
||||||
|
|
||||||
|
if ( angle != 0 ) {
|
||||||
|
FAIL_ZERO_RETURN(e, center, AKERR_NULLPOINTER, "center");
|
||||||
|
FAIL_ZERO_RETURN(
|
||||||
|
e,
|
||||||
|
SDL_RenderTextureRotated(self->sdl_renderer, texture, src, dest, angle, center, flip),
|
||||||
|
AKERR_NULLPOINTER, "%s", SDL_GetError()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
FAIL_ZERO_RETURN(
|
||||||
|
e,
|
||||||
|
SDL_RenderTexture(self->sdl_renderer, texture, src, dest),
|
||||||
|
AKERR_NULLPOINTER, "%s", SDL_GetError()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_mesh(akgl_RenderBackend *self)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_RETURN(e, AKERR_API, "Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_2d_draw_world(akgl_RenderBackend *self, akgl_Iterator *opflags)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
akgl_Iterator defflags;
|
||||||
|
SDL_Time curTime = SDL_GetTicksNS();
|
||||||
|
akgl_Actor *actor = NULL;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(e, self, AKERR_NULLPOINTER, "self");
|
||||||
|
|
||||||
|
if ( opflags == NULL ) {
|
||||||
|
opflags = &defflags;
|
||||||
|
PASS(e, aksl_memset((void *)opflags, 0x00, sizeof(akgl_Iterator)));
|
||||||
|
}
|
||||||
|
for ( int i = 0; i < AKGL_TILEMAP_MAX_LAYERS ; i++ ) {
|
||||||
|
if ( i < gamemap->numlayers ) {
|
||||||
|
PASS(e, akgl_tilemap_draw(gamemap, camera, i));
|
||||||
|
}
|
||||||
|
for ( int j = 0; j < AKGL_MAX_HEAP_ACTOR ; j++ ) {
|
||||||
|
actor = &HEAP_ACTOR[j];
|
||||||
|
if ( actor->refcount == 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( actor->layer != i ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PASS(e, actor->renderfunc(actor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
@@ -174,7 +174,7 @@ akerr_ErrorContext *akgl_spritesheet_initialize(akgl_SpriteSheet *sheet, int spr
|
|||||||
strncpy((char *)&sheet->name, filename, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH);
|
strncpy((char *)&sheet->name, filename, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH);
|
||||||
|
|
||||||
//snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename);
|
//snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), filename);
|
||||||
sheet->texture = IMG_LoadTexture(renderer, filename);
|
sheet->texture = IMG_LoadTexture(renderer->sdl_renderer, filename);
|
||||||
FAIL_ZERO_BREAK(errctx, sheet->texture, AKGL_ERR_SDL, "Failed loading asset %s : %s", filename, SDL_GetError());
|
FAIL_ZERO_BREAK(errctx, sheet->texture, AKGL_ERR_SDL, "Failed loading asset %s : %s", filename, SDL_GetError());
|
||||||
|
|
||||||
FAIL_ZERO_BREAK(
|
FAIL_ZERO_BREAK(
|
||||||
|
|||||||
@@ -49,12 +49,12 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_text_rendertextat(TTF_Font *font, char *
|
|||||||
color);
|
color);
|
||||||
}
|
}
|
||||||
FAIL_ZERO_RETURN(errctx, textsurf, AKERR_NULLPOINTER, "%s", SDL_GetError());
|
FAIL_ZERO_RETURN(errctx, textsurf, AKERR_NULLPOINTER, "%s", SDL_GetError());
|
||||||
texture = SDL_CreateTextureFromSurface(renderer, textsurf);
|
texture = SDL_CreateTextureFromSurface(renderer->sdl_renderer, textsurf);
|
||||||
FAIL_ZERO_RETURN(errctx, texture, AKERR_NULLPOINTER, "%s", SDL_GetError());
|
FAIL_ZERO_RETURN(errctx, texture, AKERR_NULLPOINTER, "%s", SDL_GetError());
|
||||||
dest.x = x;
|
dest.x = x;
|
||||||
dest.y = y;
|
dest.y = y;
|
||||||
SDL_GetTextureSize(texture, &dest.w, &dest.h);
|
SDL_GetTextureSize(texture, &dest.w, &dest.h);
|
||||||
FAIL_ZERO_RETURN(errctx, SDL_RenderTexture(renderer, texture, NULL, &dest), AKERR_NULLPOINTER, "%s", SDL_GetError());
|
PASS(errctx, renderer->draw_texture(renderer, texture, NULL, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
SDL_DestroySurface(textsurf);
|
SDL_DestroySurface(textsurf);
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
|
|||||||
225
src/tilemap.c
225
src/tilemap.c
@@ -24,6 +24,7 @@ akerr_ErrorContext *akgl_get_json_tilemap_property(json_t *obj, char *key, char
|
|||||||
json_t *properties = NULL;
|
json_t *properties = NULL;
|
||||||
json_t *property = NULL;
|
json_t *property = NULL;
|
||||||
akgl_String *tmpstr = NULL;
|
akgl_String *tmpstr = NULL;
|
||||||
|
akgl_String *typestr = NULL;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// This is not a generic JSON helper. It assumes we are receiving an object with a 'properties' key
|
// This is not a generic JSON helper. It assumes we are receiving an object with a 'properties' key
|
||||||
// inside of it. That key is an array of objects, and each object has a name, type, and value.
|
// inside of it. That key is an array of objects, and each object has a name, type, and value.
|
||||||
@@ -38,9 +39,9 @@ akerr_ErrorContext *akgl_get_json_tilemap_property(json_t *obj, char *key, char
|
|||||||
CATCH(errctx, akgl_heap_release_string(tmpstr));
|
CATCH(errctx, akgl_heap_release_string(tmpstr));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CATCH(errctx, akgl_get_json_string_value(property, "type", &tmpstr));
|
CATCH(errctx, akgl_get_json_string_value(property, "type", &typestr));
|
||||||
if ( strcmp(tmpstr->data, type) != 0 ) {
|
if ( strcmp(typestr->data, type) != 0 ) {
|
||||||
FAIL_BREAK(errctx, AKERR_TYPE, "Object property is present but is incorrect type");
|
FAIL_BREAK(errctx, AKERR_TYPE, "Property %s is present but is incorrect type(expected %s got %s)", key, type, (char *)typestr->data);
|
||||||
}
|
}
|
||||||
*dest = property;
|
*dest = property;
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
@@ -49,27 +50,25 @@ akerr_ErrorContext *akgl_get_json_tilemap_property(json_t *obj, char *key, char
|
|||||||
if ( tmpstr != NULL ) {
|
if ( tmpstr != NULL ) {
|
||||||
IGNORE(akgl_heap_release_string(tmpstr));
|
IGNORE(akgl_heap_release_string(tmpstr));
|
||||||
}
|
}
|
||||||
|
if ( typestr != NULL ) {
|
||||||
|
IGNORE(akgl_heap_release_string(typestr));
|
||||||
|
}
|
||||||
} PROCESS(errctx) {
|
} PROCESS(errctx) {
|
||||||
} FINISH(errctx, true);
|
} FINISH(errctx, true);
|
||||||
|
|
||||||
FAIL_RETURN(errctx, AKERR_KEY, "Property not found in properties map");
|
FAIL_RETURN(errctx, AKERR_KEY, "Property not found in properties map");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_get_json_properties_string(json_t *obj, char *key, akgl_String **dest)
|
akerr_ErrorContext *akgl_get_json_properties_string(json_t *obj, char *key, akgl_String **dest)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
json_t *property;
|
json_t *property;
|
||||||
|
|
||||||
ATTEMPT {
|
PASS(errctx, akgl_get_json_tilemap_property(obj, key, "string", &property));
|
||||||
CATCH(errctx, akgl_get_json_tilemap_property(obj, key, "string", &property));
|
PASS(errctx, akgl_heap_next_string(dest));
|
||||||
CATCH(errctx, akgl_heap_next_string(dest));
|
PASS(errctx, akgl_string_initialize(*dest, NULL));
|
||||||
CATCH(errctx, akgl_string_initialize(*dest, NULL));
|
PASS(errctx, akgl_get_json_string_value(property, "value", dest));
|
||||||
CATCH(errctx, akgl_get_json_string_value(property, "value", dest));
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(errctx) {
|
|
||||||
} FINISH(errctx, true);
|
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,12 +76,8 @@ akerr_ErrorContext *akgl_get_json_properties_integer(json_t *obj, char *key, int
|
|||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
json_t *property = NULL;
|
json_t *property = NULL;
|
||||||
ATTEMPT {
|
PASS(errctx, akgl_get_json_tilemap_property(obj, key, "int", &property));
|
||||||
CATCH(errctx, akgl_get_json_tilemap_property(obj, key, "int", &property));
|
PASS(errctx, akgl_get_json_integer_value(property, "value", dest));
|
||||||
CATCH(errctx, akgl_get_json_integer_value(property, "value", dest));
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(errctx) {
|
|
||||||
} FINISH(errctx, true);
|
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
@@ -91,12 +86,28 @@ akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, floa
|
|||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
json_t *property = NULL;
|
json_t *property = NULL;
|
||||||
ATTEMPT {
|
PASS(errctx, akgl_get_json_tilemap_property(obj, key, "number", &property));
|
||||||
CATCH(errctx, akgl_get_json_tilemap_property(obj, key, "number", &property));
|
PASS(errctx, akgl_get_json_number_value(property, "value", dest));
|
||||||
CATCH(errctx, akgl_get_json_number_value(property, "value", dest));
|
|
||||||
} CLEANUP {
|
SUCCEED_RETURN(errctx);
|
||||||
} PROCESS(errctx) {
|
}
|
||||||
} FINISH(errctx, true);
|
|
||||||
|
akerr_ErrorContext *akgl_get_json_properties_float(json_t *obj, char *key, float *dest)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(errctx);
|
||||||
|
json_t *property = NULL;
|
||||||
|
PASS(errctx, akgl_get_json_tilemap_property(obj, key, "float", &property));
|
||||||
|
PASS(errctx, akgl_get_json_number_value(property, "value", dest));
|
||||||
|
|
||||||
|
SUCCEED_RETURN(errctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_get_json_properties_double(json_t *obj, char *key, double *dest)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(errctx);
|
||||||
|
json_t *property = NULL;
|
||||||
|
PASS(errctx, akgl_get_json_tilemap_property(obj, key, "float", &property));
|
||||||
|
PASS(errctx, akgl_get_json_double_value(property, "value", dest));
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
@@ -135,7 +146,7 @@ akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilema
|
|||||||
} PROCESS(e) {
|
} PROCESS(e) {
|
||||||
} FINISH(e, true);
|
} FINISH(e, true);
|
||||||
|
|
||||||
dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[tsidx].imagefilename);
|
dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer->sdl_renderer, (char *)&dest->tilesets[tsidx].imagefilename);
|
||||||
FAIL_ZERO_RETURN(e, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError());
|
FAIL_ZERO_RETURN(e, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError());
|
||||||
|
|
||||||
SUCCEED_RETURN(e);
|
SUCCEED_RETURN(e);
|
||||||
@@ -280,41 +291,36 @@ akerr_ErrorContext *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *
|
|||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
||||||
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
||||||
|
|
||||||
ATTEMPT {
|
PASS(errctx, akgl_get_json_array_value(root, "objects", &layerdata));
|
||||||
CATCH(errctx, akgl_get_json_array_value(root, "objects", &layerdata));
|
len = json_array_size((json_t *)layerdata);
|
||||||
len = json_array_size((json_t *)layerdata);
|
curlayer = &dest->layers[layerid];
|
||||||
curlayer = &dest->layers[layerid];
|
for ( j = 0; j < len; j++ ) {
|
||||||
for ( j = 0; j < len; j++ ) {
|
PASS(errctx, akgl_get_json_array_index_object((json_t *)layerdata, j, &layerdatavalue));
|
||||||
CATCH(errctx, akgl_get_json_array_index_object((json_t *)layerdata, j, &layerdatavalue));
|
curobj = &curlayer->objects[j];
|
||||||
curobj = &curlayer->objects[j];
|
PASS(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "name", &tmpstr));
|
||||||
CATCH(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "name", &tmpstr));
|
strncpy((char *)curobj->name, tmpstr->data, AKGL_ACTOR_MAX_NAME_LENGTH);
|
||||||
strncpy((char *)curobj->name, tmpstr->data, AKGL_ACTOR_MAX_NAME_LENGTH);
|
PASS(errctx, akgl_heap_release_string(tmpstr));
|
||||||
CATCH(errctx, akgl_heap_release_string(tmpstr));
|
PASS(errctx, akgl_get_json_number_value((json_t *)layerdatavalue, "x", &curobj->x));
|
||||||
CATCH(errctx, akgl_get_json_number_value((json_t *)layerdatavalue, "x", &curobj->x));
|
PASS(errctx, akgl_get_json_number_value((json_t *)layerdatavalue, "y", &curobj->y));
|
||||||
CATCH(errctx, akgl_get_json_number_value((json_t *)layerdatavalue, "y", &curobj->y));
|
PASS(errctx, akgl_get_json_boolean_value((json_t *)layerdatavalue, "visible", &curobj->visible));
|
||||||
CATCH(errctx, akgl_get_json_boolean_value((json_t *)layerdatavalue, "visible", &curobj->visible));
|
|
||||||
|
PASS(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "type", &tmpstr));
|
||||||
CATCH(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "type", &tmpstr));
|
if ( strcmp(tmpstr->data, "actor") == 0 ) {
|
||||||
if ( strcmp(tmpstr->data, "actor") == 0 ) {
|
PASS(errctx, akgl_tilemap_load_layer_object_actor(curobj, layerdatavalue, layerid, dirname));
|
||||||
CATCH(errctx, akgl_tilemap_load_layer_object_actor(curobj, layerdatavalue, layerid, dirname));
|
} else if ( strcmp(tmpstr->data, "perspective") == 0 ) {
|
||||||
} else if ( strcmp(tmpstr->data, "perspective") == 0 ) {
|
curobj->visible = false;
|
||||||
curobj->visible = false;
|
if ( strcmp((char *)curobj->name, "p_foreground") == 0 ) {
|
||||||
if ( strcmp((char *)curobj->name, "p_foreground") == 0 ) {
|
dest->p_foreground_y = curobj->y;
|
||||||
dest->p_foreground_y = curobj->y;
|
PASS(errctx, akgl_get_json_integer_value((json_t *)layerdatavalue, "height", &dest->p_foreground_h));
|
||||||
CATCH(errctx, akgl_get_json_integer_value((json_t *)layerdatavalue, "height", &dest->p_foreground_h));
|
PASS(errctx, akgl_get_json_properties_float((json_t *)layerdatavalue, "scale", &dest->p_foreground_scale));
|
||||||
CATCH(errctx, akgl_get_json_properties_number((json_t *)layerdatavalue, "scale", &dest->p_foreground_scale));
|
} else if ( strcmp((char *)curobj->name, "p_vanishing") == 0 ) {
|
||||||
} else if ( strcmp((char *)curobj->name, "p_vanishing") == 0 ) {
|
dest->p_vanishing_y = curobj->y;
|
||||||
dest->p_vanishing_y = curobj->y;
|
PASS(errctx, akgl_get_json_integer_value((json_t *)layerdatavalue, "height", &dest->p_vanishing_h));
|
||||||
CATCH(errctx, akgl_get_json_integer_value((json_t *)layerdatavalue, "height", &dest->p_vanishing_h));
|
PASS(errctx, akgl_get_json_properties_float((json_t *)layerdatavalue, "scale", &dest->p_vanishing_scale));
|
||||||
CATCH(errctx, akgl_get_json_properties_number((json_t *)layerdatavalue, "scale", &dest->p_vanishing_scale));
|
}
|
||||||
}
|
}
|
||||||
}
|
layerdatavalue = NULL;
|
||||||
|
}
|
||||||
layerdatavalue = NULL;
|
|
||||||
}
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(errctx) {
|
|
||||||
} FINISH(errctx, true);
|
|
||||||
|
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
@@ -372,7 +378,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *ro
|
|||||||
);
|
);
|
||||||
RESTORE_GCC_WARNINGS
|
RESTORE_GCC_WARNINGS
|
||||||
|
|
||||||
dest->layers[layerid].texture = IMG_LoadTexture(renderer, (char *)fpath->data);
|
dest->layers[layerid].texture = IMG_LoadTexture(renderer->sdl_renderer, (char *)fpath->data);
|
||||||
FAIL_ZERO_BREAK(errctx, dest->layers[layerid].texture, AKGL_ERR_SDL, "%s", SDL_GetError());
|
FAIL_ZERO_BREAK(errctx, dest->layers[layerid].texture, AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||||
dest->layers[layerid].width = dest->layers[layerid].texture->w;
|
dest->layers[layerid].width = dest->layers[layerid].texture->w;
|
||||||
dest->layers[layerid].height = dest->layers[layerid].texture->h;
|
dest->layers[layerid].height = dest->layers[layerid].texture->h;
|
||||||
@@ -434,6 +440,88 @@ akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root, a
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_tilemap_load_physics(akgl_Tilemap *dest, json_t *root)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
json_t *props = NULL;
|
||||||
|
akgl_String *tmpval = NULL;
|
||||||
|
double defzero = 0.0;
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
CATCH(e, akgl_heap_next_string(&tmpval));
|
||||||
|
CATCH(e, akgl_get_json_array_value((json_t *)root, "properties", &props));
|
||||||
|
} CLEANUP {
|
||||||
|
IGNORE(akgl_heap_release_string(tmpval));
|
||||||
|
} PROCESS(e) {
|
||||||
|
} HANDLE(e, AKERR_KEY) {
|
||||||
|
// Map has no properties, do nothing
|
||||||
|
SDL_Log("Map has no properties");
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
} FINISH(e, true);
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
CATCH(e, akgl_heap_next_string(&tmpval));
|
||||||
|
CATCH(e, akgl_get_json_properties_string(
|
||||||
|
root,
|
||||||
|
"physics.model",
|
||||||
|
&tmpval
|
||||||
|
)
|
||||||
|
);
|
||||||
|
PASS(e, akgl_physics_factory(&dest->physics, tmpval));
|
||||||
|
dest->use_own_physics = true;
|
||||||
|
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.gravity.x", &dest->physics.gravity_x
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.gravity_x,
|
||||||
|
sizeof(double)));
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.gravity.y", &dest->physics.gravity_y
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.gravity_y,
|
||||||
|
sizeof(double)));
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.gravity.z", &dest->physics.gravity_z
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.gravity_z,
|
||||||
|
sizeof(double)));
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.drag.x", &dest->physics.drag_x
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.drag_x,
|
||||||
|
sizeof(double)));
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.drag.y", &dest->physics.drag_y
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.drag_y,
|
||||||
|
sizeof(double)));
|
||||||
|
CATCH(e, akgl_get_json_with_default(
|
||||||
|
akgl_get_json_properties_double(
|
||||||
|
root, "physics.drag.z", &dest->physics.drag_z
|
||||||
|
),
|
||||||
|
(void *)&defzero,
|
||||||
|
(void *)&dest->physics.drag_z,
|
||||||
|
sizeof(double)));
|
||||||
|
} CLEANUP {
|
||||||
|
IGNORE(akgl_heap_release_string(tmpval));
|
||||||
|
} PROCESS(e) {
|
||||||
|
} HANDLE(e, AKERR_KEY) {
|
||||||
|
SDL_Log("Map uses game physics");
|
||||||
|
} FINISH(e, true);
|
||||||
|
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
@@ -467,6 +555,7 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
|||||||
error.line,
|
error.line,
|
||||||
error.text
|
error.text
|
||||||
);
|
);
|
||||||
|
CATCH(errctx, akgl_tilemap_load_physics(dest, json));
|
||||||
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "tileheight", &dest->tileheight));
|
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "tileheight", &dest->tileheight));
|
||||||
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "tilewidth", &dest->tilewidth));
|
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "tilewidth", &dest->tilewidth));
|
||||||
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "height", &dest->height));
|
CATCH(errctx, akgl_get_json_integer_value((json_t *)json, "height", &dest->height));
|
||||||
@@ -500,7 +589,7 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *map, SDL_FRect *viewport, int layeridx)
|
akerr_ErrorContext *akgl_tilemap_draw(akgl_Tilemap *map, SDL_FRect *viewport, int layeridx)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
SDL_FRect dest = {.x = 0, .y = 0, .w = 0, .h = 0};;
|
SDL_FRect dest = {.x = 0, .y = 0, .w = 0, .h = 0};;
|
||||||
@@ -556,7 +645,7 @@ akerr_ErrorContext *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *map,
|
|||||||
src.h = map->layers[layeridx].height;
|
src.h = map->layers[layeridx].height;
|
||||||
dest.w = map->layers[layeridx].width;
|
dest.w = map->layers[layeridx].width;
|
||||||
dest.h = map->layers[layeridx].height;
|
dest.h = map->layers[layeridx].height;
|
||||||
SDL_RenderTexture(renderer, map->layers[layeridx].texture, &src, &dest);
|
PASS(errctx, renderer->draw_texture(renderer, map->layers[layeridx].texture, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,7 +700,7 @@ akerr_ErrorContext *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *map,
|
|||||||
dest.y,
|
dest.y,
|
||||||
dest.w,
|
dest.w,
|
||||||
dest.h);*/
|
dest.h);*/
|
||||||
SDL_RenderTexture(renderer, map->tilesets[tilesetidx].texture, &src, &dest);
|
PASS(errctx, renderer->draw_texture(renderer, map->tilesets[tilesetidx].texture, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest.x += map->tilewidth;
|
dest.x += map->tilewidth;
|
||||||
@@ -621,14 +710,14 @@ akerr_ErrorContext *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *map,
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_draw_tileset(SDL_Renderer *renderer, akgl_Tilemap *map, int tilesetidx)
|
akerr_ErrorContext *akgl_tilemap_draw_tileset(akgl_Tilemap *map, int tilesetidx)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
SDL_FRect dest;
|
SDL_FRect dest;
|
||||||
SDL_FRect src;
|
SDL_FRect src;
|
||||||
int tilenum = 0;
|
int tilenum = 0;
|
||||||
/*
|
/*
|
||||||
* Render every tile in a tileset to the given renderer
|
* Render every tile in a tileset to the default renderer
|
||||||
* (this is a debugging tool that shows that the recorded tile offsets are correct,
|
* (this is a debugging tool that shows that the recorded tile offsets are correct,
|
||||||
* by proving that we can reconstruct the original tileset image)
|
* by proving that we can reconstruct the original tileset image)
|
||||||
*/
|
*/
|
||||||
@@ -666,7 +755,7 @@ akerr_ErrorContext *akgl_tilemap_draw_tileset(SDL_Renderer *renderer, akgl_Tilem
|
|||||||
dest.y,
|
dest.y,
|
||||||
dest.w,
|
dest.w,
|
||||||
dest.h);*/
|
dest.h);*/
|
||||||
SDL_RenderTexture(renderer, map->tilesets[tilesetidx].texture, &src, &dest);
|
PASS(errctx, renderer->draw_texture(renderer, map->tilesets[tilesetidx].texture, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
}
|
}
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/util.c
28
src/util.c
@@ -202,17 +202,9 @@ akerr_ErrorContext *akgl_render_and_compare(SDL_Texture *t1, SDL_Texture *t2, in
|
|||||||
FAIL_ZERO_BREAK(errctx, t2, AKERR_NULLPOINTER, "NULL texture");
|
FAIL_ZERO_BREAK(errctx, t2, AKERR_NULLPOINTER, "NULL texture");
|
||||||
|
|
||||||
CATCH(errctx, akgl_heap_next_string(&tmpstring));
|
CATCH(errctx, akgl_heap_next_string(&tmpstring));
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer->sdl_renderer);
|
||||||
FAIL_ZERO_BREAK(
|
CATCH(errctx, renderer->draw_texture(renderer, t1, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
errctx,
|
s1 = SDL_RenderReadPixels(renderer->sdl_renderer, &read);
|
||||||
SDL_RenderTexture(
|
|
||||||
renderer,
|
|
||||||
t1,
|
|
||||||
&src,
|
|
||||||
&dest),
|
|
||||||
AKGL_ERR_SDL,
|
|
||||||
"Failed to render test texture");
|
|
||||||
s1 = SDL_RenderReadPixels(renderer, &read);
|
|
||||||
FAIL_ZERO_BREAK(errctx, s1, AKGL_ERR_SDL, "Failed to read pixels from renderer");
|
FAIL_ZERO_BREAK(errctx, s1, AKGL_ERR_SDL, "Failed to read pixels from renderer");
|
||||||
|
|
||||||
if ( writeout != NULL ) {
|
if ( writeout != NULL ) {
|
||||||
@@ -226,18 +218,10 @@ akerr_ErrorContext *akgl_render_and_compare(SDL_Texture *t1, SDL_Texture *t2, in
|
|||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer->sdl_renderer);
|
||||||
|
|
||||||
FAIL_ZERO_BREAK(
|
CATCH(errctx, renderer->draw_texture(renderer, t1, &src, &dest, 0, NULL, SDL_FLIP_NONE));
|
||||||
errctx,
|
s2 = SDL_RenderReadPixels(renderer->sdl_renderer, &read);
|
||||||
SDL_RenderTexture(
|
|
||||||
renderer,
|
|
||||||
t2,
|
|
||||||
&src,
|
|
||||||
&dest),
|
|
||||||
AKGL_ERR_SDL,
|
|
||||||
"Failed to render test texture");
|
|
||||||
s2 = SDL_RenderReadPixels(renderer, &read);
|
|
||||||
FAIL_ZERO_BREAK(errctx, s2, AKGL_ERR_SDL, "Failed to read pixels from renderer");
|
FAIL_ZERO_BREAK(errctx, s2, AKGL_ERR_SDL, "Failed to read pixels from renderer");
|
||||||
|
|
||||||
CATCH(errctx, akgl_compare_sdl_surfaces(s1, s2));
|
CATCH(errctx, akgl_compare_sdl_surfaces(s1, s2));
|
||||||
|
|||||||
Reference in New Issue
Block a user