Compare commits
1 Commits
memorymana
...
exclib_fin
| Author | SHA1 | Date | |
|---|---|---|---|
| 29cc3c341d |
22
Makefile
22
Makefile
@@ -2,37 +2,21 @@ SDLFLAGS_CC:=$(shell PKG_CONFIG_PATH=~/local/lib/pkgconfig pkg-config sdl3 --cfl
|
|||||||
SDLFLAGS_LD:=$(shell PKG_CONFIG_PATH=~/local/lib/pkgconfig pkg-config sdl3 --libs) -lSDL3_image -lSDL3_mixer
|
SDLFLAGS_LD:=$(shell PKG_CONFIG_PATH=~/local/lib/pkgconfig pkg-config sdl3 --libs) -lSDL3_image -lSDL3_mixer
|
||||||
CC:=$(shell which gcc)
|
CC:=$(shell which gcc)
|
||||||
LD:=$(shell which ld)
|
LD:=$(shell which ld)
|
||||||
SRCFILES:=$(shell find src -type f -name '*.c')
|
|
||||||
OBJFILES:=$(patsubst %.c,%.o,$(SRCFILES))
|
|
||||||
PREPFILES:=$(patsubst %.c,%.E,$(SRCFILES))
|
|
||||||
ASMFILES:=$(patsubst %.c,%.S,$(SRCFILES))
|
|
||||||
|
|
||||||
|
|
||||||
CFLAGS:=-ggdb -gstabs
|
CFLAGS:=-ggdb -gstabs
|
||||||
|
|
||||||
|
OBJECTS:=src/util.o src/assets.o src/draw.o src/game.o src/physics.o src/json_helpers.o src/tilemap.o src/sprite.o src/sdl3-gametest.o
|
||||||
DISTFILE:=dist/sdl3-gametest
|
DISTFILE:=dist/sdl3-gametest
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
.PHONY: preprocessor
|
|
||||||
.PHONY: assembler
|
|
||||||
|
|
||||||
all: $(DISTFILE)
|
all: $(DISTFILE)
|
||||||
|
|
||||||
preprocessor: $(PREPFILES)
|
|
||||||
|
|
||||||
assembler: $(ASMFILES)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJFILES) $(PREPFILES) $(ASMFILES) ${DISTFILE}
|
rm -f src/*.o ${DISTFILE}
|
||||||
|
|
||||||
src/%.S: src/%.c
|
|
||||||
$(CC) -S -o $@ $(CFLAGS) $(SDLFLAGS_CC) $?
|
|
||||||
|
|
||||||
src/%.E: src/%.c
|
|
||||||
$(CC) -E -o $@ $(CFLAGS) $(SDLFLAGS_CC) $?
|
|
||||||
|
|
||||||
src/%.o: src/%.c
|
src/%.o: src/%.c
|
||||||
$(CC) -c -o $@ $(CFLAGS) $(SDLFLAGS_CC) $?
|
$(CC) -c -o $@ $(CFLAGS) $(SDLFLAGS_CC) $?
|
||||||
|
|
||||||
$(DISTFILE): $(OBJFILES)
|
$(DISTFILE): $(OBJECTS)
|
||||||
$(CC) -o $@ $^ -lexc -lbox2d -ljansson -lhashmap -lm $(SDLFLAGS_LD)
|
$(CC) -o $@ $^ -lexc -lbox2d -ljansson -lhashmap -lm $(SDLFLAGS_LD)
|
||||||
|
|||||||
31
src/assets.c
31
src/assets.c
@@ -1,7 +1,6 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3_image/SDL_image.h>
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include <SDL3_mixer/SDL_mixer.h>
|
#include <SDL3_mixer/SDL_mixer.h>
|
||||||
#include <SDL3/SDL_stdinc.h>
|
|
||||||
#include <aklabs/exclib.h>
|
#include <aklabs/exclib.h>
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
@@ -13,13 +12,10 @@ void load_frame_from_image(char *fname, GAME_frame *frame)
|
|||||||
THROW_ZERO(frame, EXC_NULLPOINTER, "load_frame_from_image received NULL frame");
|
THROW_ZERO(frame, EXC_NULLPOINTER, "load_frame_from_image received NULL frame");
|
||||||
THROW_ZERO(fname, EXC_NULLPOINTER, "load_frame_from_image received NULL filename");
|
THROW_ZERO(fname, EXC_NULLPOINTER, "load_frame_from_image received NULL filename");
|
||||||
|
|
||||||
TRY {
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
tex = IMG_LoadTexture(renderer, asset_path);
|
||||||
tex = IMG_LoadTexture(renderer, asset_path);
|
|
||||||
THROW_ZERO(tex, EXC_NULLPOINTER, "Failed loading asset");
|
THROW_ZERO(tex, EXC_NULLPOINTER, "Failed loading asset");
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
frame->texture = tex;
|
frame->texture = tex;
|
||||||
SDL_GetTextureSize(tex, &frame->w, &frame->h);
|
SDL_GetTextureSize(tex, &frame->w, &frame->h);
|
||||||
@@ -31,15 +27,12 @@ void load_start_bgm(char *fname)
|
|||||||
|
|
||||||
THROW_ZERO(fname, EXC_NULLPOINTER, "load_start_bgm received NULL filename");
|
THROW_ZERO(fname, EXC_NULLPOINTER, "load_start_bgm received NULL filename");
|
||||||
|
|
||||||
TRY {
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
SDL_Log("Loading music asset from %s", asset_path);
|
||||||
SDL_Log("Loading music asset from %s", asset_path);
|
bgm = Mix_LoadMUS(asset_path);
|
||||||
bgm = Mix_LoadMUS(asset_path);
|
THROW_ZERO(bgm, EXC_NULLPOINTER, "Failed to load music asset");
|
||||||
THROW_ZERO(bgm, EXC_NULLPOINTER, "Failed to load music asset");
|
|
||||||
if (!Mix_PlayMusic(bgm, 0)) {
|
if (!Mix_PlayMusic(bgm, 0)) {
|
||||||
THROW(EXC_SDL_MUSICMIXER, "Failed to play music asset");
|
THROW(EXC_SDL_MUSICMIXER, "Failed to play music asset");
|
||||||
}
|
}
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
}
|
}
|
||||||
|
|||||||
152
src/heap.c
152
src/heap.c
@@ -1,152 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <aklabs/exclib.h>
|
|
||||||
|
|
||||||
#include "game.h"
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "heap.h"
|
|
||||||
#include "registry.h"
|
|
||||||
|
|
||||||
actor HEAP_ACTOR[MAX_HEAP_ACTOR];
|
|
||||||
sprite HEAP_SPRITE[MAX_HEAP_SPRITE];
|
|
||||||
spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET];
|
|
||||||
character HEAP_CHARACTER[MAX_HEAP_CHARACTER];
|
|
||||||
string HEAP_STRING[MAX_HEAP_STRING];
|
|
||||||
|
|
||||||
void heap_init()
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
for ( i = 0; i < MAX_HEAP_ACTOR; i++) {
|
|
||||||
memset(&HEAP_ACTOR[i], 0x00, sizeof(actor));
|
|
||||||
}
|
|
||||||
for ( i = 0; i < MAX_HEAP_SPRITE; i++) {
|
|
||||||
memset(&HEAP_SPRITE[i], 0x00, sizeof(sprite));
|
|
||||||
}
|
|
||||||
for ( i = 0; i < MAX_HEAP_SPRITESHEET; i++) {
|
|
||||||
memset(&HEAP_SPRITESHEET[i], 0x00, sizeof(spritesheet));
|
|
||||||
}
|
|
||||||
for ( i = 0; i < MAX_HEAP_CHARACTER; i++) {
|
|
||||||
memset(&HEAP_CHARACTER[i], 0x00, sizeof(character));
|
|
||||||
}
|
|
||||||
for ( i = 0; i < MAX_HEAP_STRING; i++) {
|
|
||||||
memset(&HEAP_STRING[i], 0x00, sizeof(string));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
actor *heap_next_actor()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_HEAP_ACTOR; i++ ) {
|
|
||||||
if ( HEAP_ACTOR[i].refcount != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &HEAP_ACTOR[i];
|
|
||||||
}
|
|
||||||
THROW(EXC_HEAPERROR, "Unable to find unused actor on the heap");
|
|
||||||
}
|
|
||||||
|
|
||||||
sprite *heap_next_sprite()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_HEAP_SPRITE; i++ ) {
|
|
||||||
if ( HEAP_SPRITE[i].refcount != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &HEAP_SPRITE[i];
|
|
||||||
}
|
|
||||||
THROW(EXC_HEAPERROR, "Unable to find unused sprite on the heap");
|
|
||||||
}
|
|
||||||
|
|
||||||
spritesheet *heap_next_spritesheet()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_HEAP_SPRITESHEET; i++ ) {
|
|
||||||
if ( HEAP_SPRITESHEET[i].refcount != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &HEAP_SPRITESHEET[i];
|
|
||||||
}
|
|
||||||
THROW(EXC_HEAPERROR, "Unable to find unused spritesheet on the heap");
|
|
||||||
}
|
|
||||||
|
|
||||||
character *heap_next_character()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_HEAP_CHARACTER; i++ ) {
|
|
||||||
if ( HEAP_CHARACTER[i].refcount != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &HEAP_CHARACTER[i];
|
|
||||||
}
|
|
||||||
THROW(EXC_HEAPERROR, "Unable to find unused character on the heap");
|
|
||||||
}
|
|
||||||
|
|
||||||
string *heap_next_string()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < MAX_HEAP_STRING; i++ ) {
|
|
||||||
if ( HEAP_STRING[i].refcount != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return &HEAP_STRING[i];
|
|
||||||
}
|
|
||||||
THROW(EXC_HEAPERROR, "Unable to find unused string on the heap");
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_release_actor(actor *ptr)
|
|
||||||
{
|
|
||||||
THROW_ZERO(ptr, EXC_NULLPOINTER, "NULL character reference");
|
|
||||||
if ( ptr->refcount > 0 ) {
|
|
||||||
ptr->refcount -= 1;
|
|
||||||
}
|
|
||||||
if ( ptr->refcount == 0 ) {
|
|
||||||
heap_release_character(ptr->basechar);
|
|
||||||
SDL_ClearProperty(REGISTRY_ACTOR, (char *)&ptr->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_release_character(character *basechar)
|
|
||||||
{
|
|
||||||
iterator opflags;
|
|
||||||
THROW_ZERO(basechar, EXC_NULLPOINTER, "NULL character reference");
|
|
||||||
BITMASK_CLEAR(opflags.flags);
|
|
||||||
BITMASK_ADD(opflags.flags, ITERATOR_OP_RELEASE);
|
|
||||||
|
|
||||||
if ( basechar->refcount > 0 ) {
|
|
||||||
basechar->refcount -= 1;
|
|
||||||
}
|
|
||||||
if ( basechar->refcount == 0 ) {
|
|
||||||
SDL_EnumerateProperties(basechar->state_sprites, &character_state_sprites_iterate, (void *)&opflags);
|
|
||||||
SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&basechar->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_release_sprite(sprite *ptr)
|
|
||||||
{
|
|
||||||
THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL sprite reference");
|
|
||||||
if ( ptr->refcount > 0 ) {
|
|
||||||
ptr->refcount -= 1;
|
|
||||||
}
|
|
||||||
if ( ptr->refcount == 0 ) {
|
|
||||||
heap_release_spritesheet(ptr->sheet);
|
|
||||||
SDL_ClearProperty(REGISTRY_SPRITE, (char *)&ptr->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_release_spritesheet(spritesheet *ptr)
|
|
||||||
{
|
|
||||||
THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference");
|
|
||||||
if ( ptr->refcount > 0 ) {
|
|
||||||
ptr->refcount -= 1;
|
|
||||||
}
|
|
||||||
if ( ptr->refcount == 0 ) {
|
|
||||||
// TODO : If we go threaded, make sure this is only happening on the main thread
|
|
||||||
SDL_DestroyTexture(ptr->texture);
|
|
||||||
SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&ptr->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void heap_release_string(string *ptr)
|
|
||||||
{
|
|
||||||
THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference");
|
|
||||||
if ( ptr->refcount > 0 ) {
|
|
||||||
ptr->refcount -= 1;
|
|
||||||
}
|
|
||||||
if ( ptr->refcount == 0 ) {
|
|
||||||
memset(ptr->data, 0x00, MAX_STRING_LENGTH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
31
src/heap.h
31
src/heap.h
@@ -1,31 +0,0 @@
|
|||||||
#ifndef _HEAP_H_
|
|
||||||
#define _HEAP_H_
|
|
||||||
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
#define MAX_HEAP_ACTOR 64
|
|
||||||
#define MAX_HEAP_SPRITE (MAX_HEAP_ACTOR * 16)
|
|
||||||
#define MAX_HEAP_SPRITESHEET MAX_HEAP_SPRITE
|
|
||||||
#define MAX_HEAP_CHARACTER 256
|
|
||||||
#define MAX_HEAP_STRING 256
|
|
||||||
|
|
||||||
extern actor HEAP_ACTOR[MAX_HEAP_ACTOR];
|
|
||||||
extern sprite HEAP_SPRITE[MAX_HEAP_SPRITE];
|
|
||||||
extern spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET];
|
|
||||||
extern character HEAP_CHARACTER[MAX_HEAP_CHARACTER];
|
|
||||||
extern string HEAP_STRING[MAX_HEAP_STRING];
|
|
||||||
|
|
||||||
void heap_init();
|
|
||||||
actor *heap_next_actor();
|
|
||||||
sprite *heap_next_sprite();
|
|
||||||
spritesheet *heap_next_spritesheet();
|
|
||||||
character *heap_next_character();
|
|
||||||
string *heap_next_string();
|
|
||||||
void heap_release_actor(actor *ptr);
|
|
||||||
void heap_release_sprite(sprite *ptr);
|
|
||||||
void heap_release_spritesheet(spritesheet *ptr);
|
|
||||||
void heap_release_character(character *ptr);
|
|
||||||
void heap_release_string(string *ptr);
|
|
||||||
|
|
||||||
#endif //_HEAP_H_
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "json_helpers.h"
|
#include "json_helpers.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "string.h"
|
|
||||||
#include "heap.h"
|
|
||||||
|
|
||||||
json_t *get_json_object_value(json_t *obj, char *key)
|
json_t *get_json_object_value(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
@@ -12,14 +10,12 @@ json_t *get_json_object_value(json_t *obj, char *key)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_json_boolean_value(json_t *obj, char *key)
|
int get_json_boolean_value(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
json_t *value = json_object_get(obj, key);
|
json_t *value = json_object_get(obj, key);
|
||||||
THROW_ZERO(value, EXC_KEYERROR, "");
|
THROW_ZERO(value, EXC_KEYERROR, "");
|
||||||
THROW_ZERO(json_is_boolean(value), EXC_ATTRIBUTEERROR, "");
|
THROW_ZERO(json_is_boolean(value), EXC_ATTRIBUTEERROR, "");
|
||||||
bool i = json_boolean_value(value);
|
return json_boolean_value(value);
|
||||||
json_decref(value);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_json_integer_value(json_t *obj, char *key)
|
int get_json_integer_value(json_t *obj, char *key)
|
||||||
@@ -27,38 +23,30 @@ int get_json_integer_value(json_t *obj, char *key)
|
|||||||
json_t *value = json_object_get(obj, key);
|
json_t *value = json_object_get(obj, key);
|
||||||
THROW_ZERO(value, EXC_KEYERROR, "");
|
THROW_ZERO(value, EXC_KEYERROR, "");
|
||||||
THROW_ZERO(json_is_integer(value), EXC_ATTRIBUTEERROR, "");
|
THROW_ZERO(json_is_integer(value), EXC_ATTRIBUTEERROR, "");
|
||||||
int i = json_integer_value(value);
|
return json_integer_value(value);
|
||||||
json_decref(value);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_json_number_value(json_t *obj, char *key)
|
float get_json_number_value(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
json_t *value = json_object_get(obj, key);
|
json_t *value = json_object_get(obj, key);
|
||||||
float f;
|
|
||||||
THROW_ZERO(value, EXC_KEYERROR, "");
|
THROW_ZERO(value, EXC_KEYERROR, "");
|
||||||
THROW_ZERO(json_is_number(value), EXC_ATTRIBUTEERROR, "");
|
THROW_ZERO(json_is_number(value), EXC_ATTRIBUTEERROR, "");
|
||||||
f = json_number_value(value);
|
return json_number_value(value);
|
||||||
json_decref(value);
|
|
||||||
return f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string *get_json_string_value(json_t *obj, char *key)
|
const char *get_json_string_value(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
string *s = heap_next_string();
|
|
||||||
json_t *value = json_object_get(obj, key);
|
json_t *value = json_object_get(obj, key);
|
||||||
THROW_ZERO(value, EXC_KEYERROR, key);
|
THROW_ZERO(value, EXC_KEYERROR, "");
|
||||||
THROW_ZERO(json_is_string(value), EXC_ATTRIBUTEERROR, key);
|
THROW_ZERO(json_is_string(value), EXC_ATTRIBUTEERROR, "");
|
||||||
strncpy(s->data, (char *)json_string_value(value), MAX_STRING_LENGTH);
|
return json_string_value(value);
|
||||||
json_decref(value);
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json_t *get_json_array_value(json_t *obj, char *key)
|
json_t *get_json_array_value(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
json_t *value = json_object_get(obj, key);
|
json_t *value = json_object_get(obj, key);
|
||||||
THROW_ZERO(value, EXC_KEYERROR, key);
|
THROW_ZERO(value, EXC_KEYERROR, "");
|
||||||
THROW_ZERO(json_is_array(value), EXC_ATTRIBUTEERROR, key);
|
THROW_ZERO(json_is_array(value), EXC_ATTRIBUTEERROR, "");
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +60,8 @@ json_t *get_json_array_index_object(json_t *array, int index)
|
|||||||
|
|
||||||
int get_json_array_index_integer(json_t *array, int index)
|
int get_json_array_index_integer(json_t *array, int index)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
json_t *value = json_array_get(array, index);
|
json_t *value = json_array_get(array, index);
|
||||||
THROW_ZERO(value, EXC_INDEXERROR, "");
|
THROW_ZERO(value, EXC_INDEXERROR, "");
|
||||||
THROW_ZERO(json_is_integer(value), EXC_ATTRIBUTEERROR, "");
|
THROW_ZERO(json_is_integer(value), EXC_ATTRIBUTEERROR, "");
|
||||||
i = json_integer_value(value);
|
return json_integer_value(value);
|
||||||
json_decref(value);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
#ifndef _JSON_HELPERS_H_
|
#ifndef _JSON_HELPERS_H_
|
||||||
#define _JSON_HELPERS_H_
|
#define _JSON_HELPERS_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
json_t *get_json_object_value(json_t *obj, char *key);
|
json_t *get_json_object_value(json_t *obj, char *key);
|
||||||
bool get_json_boolean_value(json_t *obj, char *key);
|
int get_json_boolean_value(json_t *obj, char *key);
|
||||||
int get_json_integer_value(json_t *obj, char *key);
|
int get_json_integer_value(json_t *obj, char *key);
|
||||||
float get_json_number_value(json_t *obj, char *key);
|
float get_json_number_value(json_t *obj, char *key);
|
||||||
string *get_json_string_value(json_t *obj, char *key);
|
const char *get_json_string_value(json_t *obj, char *key);
|
||||||
json_t *get_json_array_value(json_t *obj, char *key);
|
json_t *get_json_array_value(json_t *obj, char *key);
|
||||||
json_t *get_json_array_index_object(json_t *array, int index);
|
json_t *get_json_array_index_object(json_t *array, int index);
|
||||||
int get_json_array_index_integer(json_t *array, int index);
|
int get_json_array_index_integer(json_t *array, int index);
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#include <aklabs/exclib.h>
|
|
||||||
#include "sprite.h"
|
|
||||||
#include "registry.h"
|
|
||||||
|
|
||||||
SDL_PropertiesID REGISTRY_ACTOR;
|
|
||||||
SDL_PropertiesID REGISTRY_SPRITE;
|
|
||||||
SDL_PropertiesID REGISTRY_SPRITESHEET;
|
|
||||||
SDL_PropertiesID REGISTRY_CHARACTER;
|
|
||||||
|
|
||||||
void registry_init_actor()
|
|
||||||
{
|
|
||||||
REGISTRY_ACTOR = SDL_CreateProperties();
|
|
||||||
THROW_ZERO(REGISTRY_ACTOR, EXC_NULLPOINTER, "Error initializing actor registry");
|
|
||||||
}
|
|
||||||
|
|
||||||
void registry_init_sprite()
|
|
||||||
{
|
|
||||||
REGISTRY_SPRITE = SDL_CreateProperties();
|
|
||||||
THROW_ZERO(REGISTRY_SPRITE, EXC_NULLPOINTER, "Error initializing sprite registry");
|
|
||||||
}
|
|
||||||
|
|
||||||
void registry_init_spritesheet()
|
|
||||||
{
|
|
||||||
REGISTRY_SPRITESHEET = SDL_CreateProperties();
|
|
||||||
THROW_ZERO(REGISTRY_SPRITESHEET, EXC_NULLPOINTER, "Error initializing spritesheet registry");
|
|
||||||
}
|
|
||||||
|
|
||||||
void registry_init_character()
|
|
||||||
{
|
|
||||||
REGISTRY_CHARACTER = SDL_CreateProperties();
|
|
||||||
THROW_ZERO(REGISTRY_CHARACTER, EXC_NULLPOINTER, "Error initializing character registry");
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#ifndef _REGISTRY_H_
|
|
||||||
#define _REGISTRY_H_
|
|
||||||
|
|
||||||
extern SDL_PropertiesID REGISTRY_ACTOR;
|
|
||||||
extern SDL_PropertiesID REGISTRY_SPRITE;
|
|
||||||
extern SDL_PropertiesID REGISTRY_SPRITESHEET;
|
|
||||||
extern SDL_PropertiesID REGISTRY_CHARACTER;
|
|
||||||
|
|
||||||
void registry_init_actor();
|
|
||||||
void registry_iterate_actor(void *userdata, SDL_PropertiesID registry, const char *name);
|
|
||||||
void registry_init_sprite();
|
|
||||||
void registry_init_spritesheet();
|
|
||||||
void registry_init_character();
|
|
||||||
|
|
||||||
|
|
||||||
#endif //_REGISTRY_H_
|
|
||||||
@@ -13,8 +13,6 @@
|
|||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "assets.h"
|
#include "assets.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "heap.h"
|
|
||||||
#include "registry.h"
|
|
||||||
|
|
||||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -83,6 +81,18 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
|||||||
return SDL_APP_FAILURE;
|
return SDL_APP_FAILURE;
|
||||||
} ETRY;
|
} ETRY;
|
||||||
|
|
||||||
|
/*TRY {
|
||||||
|
actorptr = heap_next_actor();
|
||||||
|
actor_initialize(actorptr, "npc");
|
||||||
|
actorptr->basechar = characterptr;
|
||||||
|
actorptr->x = 0;
|
||||||
|
actorptr->y = 0;
|
||||||
|
actorptr->state = (ACTOR_STATE_ALIVE | ACTOR_STATE_FACE_LEFT | ACTOR_STATE_MOVING_LEFT);
|
||||||
|
} CATCH(EXC_NULLPOINTER) {
|
||||||
|
SDL_Log("Attempting to setup npc: %s (%s)", EXCLIB_EXCEPTION->description, SDL_GetError());
|
||||||
|
return SDL_APP_FAILURE;
|
||||||
|
} ETRY;*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TRY {
|
TRY {
|
||||||
//load_start_bgm("../assets/nutcracker.mid");
|
//load_start_bgm("../assets/nutcracker.mid");
|
||||||
|
|||||||
229
src/sprite.c
229
src/sprite.c
@@ -1,16 +1,108 @@
|
|||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3/SDL_stdinc.h>
|
|
||||||
#include <SDL3_image/SDL_image.h>
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include <box2d/box2d.h>
|
#include <box2d/box2d.h>
|
||||||
#include <aklabs/exclib.h>
|
#include <aklabs/exclib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "string.h"
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "json_helpers.h"
|
#include "json_helpers.h"
|
||||||
#include "heap.h"
|
|
||||||
#include "registry.h"
|
SDL_PropertiesID REGISTRY_ACTOR;
|
||||||
|
SDL_PropertiesID REGISTRY_SPRITE;
|
||||||
|
SDL_PropertiesID REGISTRY_SPRITESHEET;
|
||||||
|
SDL_PropertiesID REGISTRY_CHARACTER;
|
||||||
|
|
||||||
|
actor HEAP_ACTOR[MAX_HEAP_ACTOR];
|
||||||
|
sprite HEAP_SPRITE[MAX_HEAP_SPRITE];
|
||||||
|
spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET];
|
||||||
|
character HEAP_CHARACTER[MAX_HEAP_CHARACTER];
|
||||||
|
|
||||||
|
void heap_init()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for ( i = 0; i < MAX_HEAP_ACTOR; i++) {
|
||||||
|
memset(&HEAP_ACTOR[i], 0x00, sizeof(actor));
|
||||||
|
}
|
||||||
|
for ( i = 0; i < MAX_HEAP_SPRITE; i++) {
|
||||||
|
memset(&HEAP_SPRITE[i], 0x00, sizeof(sprite));
|
||||||
|
}
|
||||||
|
for ( i = 0; i < MAX_HEAP_SPRITESHEET; i++) {
|
||||||
|
memset(&HEAP_SPRITESHEET[i], 0x00, sizeof(spritesheet));
|
||||||
|
}
|
||||||
|
for ( i = 0; i < MAX_HEAP_CHARACTER; i++) {
|
||||||
|
memset(&HEAP_CHARACTER[i], 0x00, sizeof(character));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actor *heap_next_actor()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_HEAP_ACTOR; i++ ) {
|
||||||
|
if ( HEAP_ACTOR[i].refcount != 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return &HEAP_ACTOR[i];
|
||||||
|
}
|
||||||
|
THROW(EXC_HEAPERROR, "Unable to find unused actor on the heap");
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite *heap_next_sprite()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_HEAP_SPRITE; i++ ) {
|
||||||
|
if ( HEAP_SPRITE[i].refcount != 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return &HEAP_SPRITE[i];
|
||||||
|
}
|
||||||
|
THROW(EXC_HEAPERROR, "Unable to find unused sprite on the heap");
|
||||||
|
}
|
||||||
|
|
||||||
|
spritesheet *heap_next_spritesheet()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_HEAP_SPRITESHEET; i++ ) {
|
||||||
|
if ( HEAP_SPRITESHEET[i].refcount != 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return &HEAP_SPRITESHEET[i];
|
||||||
|
}
|
||||||
|
THROW(EXC_HEAPERROR, "Unable to find unused spritesheet on the heap");
|
||||||
|
}
|
||||||
|
|
||||||
|
character *heap_next_character()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_HEAP_CHARACTER; i++ ) {
|
||||||
|
if ( HEAP_CHARACTER[i].refcount != 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return &HEAP_CHARACTER[i];
|
||||||
|
}
|
||||||
|
THROW(EXC_HEAPERROR, "Unable to find unused character on the heap");
|
||||||
|
}
|
||||||
|
|
||||||
|
void registry_init_actor()
|
||||||
|
{
|
||||||
|
REGISTRY_ACTOR = SDL_CreateProperties();
|
||||||
|
THROW_ZERO(REGISTRY_ACTOR, EXC_NULLPOINTER, "Error initializing actor registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
void registry_init_sprite()
|
||||||
|
{
|
||||||
|
REGISTRY_SPRITE = SDL_CreateProperties();
|
||||||
|
THROW_ZERO(REGISTRY_SPRITE, EXC_NULLPOINTER, "Error initializing sprite registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
void registry_init_spritesheet()
|
||||||
|
{
|
||||||
|
REGISTRY_SPRITESHEET = SDL_CreateProperties();
|
||||||
|
THROW_ZERO(REGISTRY_SPRITESHEET, EXC_NULLPOINTER, "Error initializing spritesheet registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
void registry_init_character()
|
||||||
|
{
|
||||||
|
REGISTRY_CHARACTER = SDL_CreateProperties();
|
||||||
|
THROW_ZERO(REGISTRY_CHARACTER, EXC_NULLPOINTER, "Error initializing character registry");
|
||||||
|
}
|
||||||
|
|
||||||
void actor_initialize(actor *obj, char *name)
|
void actor_initialize(actor *obj, char *name)
|
||||||
{
|
{
|
||||||
@@ -143,7 +235,6 @@ void character_load_json(char *filename)
|
|||||||
json_t *mappings;
|
json_t *mappings;
|
||||||
json_t *curmapping;
|
json_t *curmapping;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
string *s;
|
|
||||||
sprite *spriteptr = NULL;
|
sprite *spriteptr = NULL;
|
||||||
char *asset_path = NULL;
|
char *asset_path = NULL;
|
||||||
character *obj = NULL;
|
character *obj = NULL;
|
||||||
@@ -151,32 +242,29 @@ void character_load_json(char *filename)
|
|||||||
|
|
||||||
THROW_ZERO(filename, EXC_NULLPOINTER, "Received null filename");
|
THROW_ZERO(filename, EXC_NULLPOINTER, "Received null filename");
|
||||||
obj = heap_next_character();
|
obj = heap_next_character();
|
||||||
TRY {
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
json = json_load_file(asset_path, 0, &error);
|
||||||
json = json_load_file(asset_path, 0, &error);
|
if (!json) {
|
||||||
if (!json) {
|
SDL_Log("Error while loading character from %s on line %d: %s", asset_path, error.line, error.text);
|
||||||
SDL_Log("Error while loading character from %s on line %d: %s", asset_path, error.line, error.text);
|
THROW(EXC_NULLPOINTER, "Loading JSON sprite failed");
|
||||||
THROW(EXC_NULLPOINTER, "Loading JSON sprite failed");
|
}
|
||||||
}
|
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
|
character_initialize(obj, (char *)get_json_string_value(json, "name"));
|
||||||
TRY {
|
TRY {
|
||||||
s = get_json_string_value(json, "name");
|
|
||||||
character_initialize(obj, s->data);
|
|
||||||
heap_release_string(s);
|
|
||||||
mappings = get_json_array_value(json, "sprite_mappings");
|
mappings = get_json_array_value(json, "sprite_mappings");
|
||||||
TRY {
|
TRY {
|
||||||
for ( i = 0; i < json_array_size(mappings) ; i++ ) {
|
for ( i = 0; i < json_array_size(mappings) ; i++ ) {
|
||||||
curmapping = get_json_array_index_object(mappings, i);
|
curmapping = get_json_array_index_object(mappings, i);
|
||||||
s = get_json_string_value(curmapping, "sprite");
|
|
||||||
spriteptr = SDL_GetPointerProperty(
|
spriteptr = SDL_GetPointerProperty(
|
||||||
REGISTRY_SPRITE,
|
REGISTRY_SPRITE,
|
||||||
s->data,
|
get_json_string_value(curmapping, "sprite"),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
heap_release_string(s);
|
SDL_Log("Character %s for state %d references sprite %s",
|
||||||
|
(char *)get_json_string_value(json, "name"),
|
||||||
|
get_json_integer_value(curmapping, "state"),
|
||||||
|
(char *)get_json_string_value(curmapping, "sprite")
|
||||||
|
);
|
||||||
THROW_ZERO(spriteptr, EXC_NULLPOINTER, "Character references sprite that does not exist");
|
THROW_ZERO(spriteptr, EXC_NULLPOINTER, "Character references sprite that does not exist");
|
||||||
character_sprite_add(
|
character_sprite_add(
|
||||||
obj,
|
obj,
|
||||||
@@ -186,9 +274,9 @@ void character_load_json(char *filename)
|
|||||||
}
|
}
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
json_decref(curmapping);
|
json_decref(curmapping);
|
||||||
|
json_decref(mappings);
|
||||||
} ETRY;
|
} ETRY;
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
json_decref(mappings);
|
|
||||||
json_decref(json);
|
json_decref(json);
|
||||||
} ETRY;
|
} ETRY;
|
||||||
}
|
}
|
||||||
@@ -199,7 +287,6 @@ void sprite_load_json(char *filename)
|
|||||||
json_t *spritesheet_json;
|
json_t *spritesheet_json;
|
||||||
json_t *frames;
|
json_t *frames;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
string *s;
|
|
||||||
spritesheet *sheet = NULL;
|
spritesheet *sheet = NULL;
|
||||||
char *asset_path = NULL;
|
char *asset_path = NULL;
|
||||||
sprite *obj = NULL;
|
sprite *obj = NULL;
|
||||||
@@ -207,43 +294,34 @@ void sprite_load_json(char *filename)
|
|||||||
|
|
||||||
THROW_ZERO(filename, EXC_NULLPOINTER, "Received null filename");
|
THROW_ZERO(filename, EXC_NULLPOINTER, "Received null filename");
|
||||||
obj = heap_next_sprite();
|
obj = heap_next_sprite();
|
||||||
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
||||||
TRY {
|
json = json_load_file(asset_path, 0, &error);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
if (!json) {
|
||||||
json = json_load_file(asset_path, 0, &error);
|
SDL_Log("Error while loading sprite from %s on line %d: %s", asset_path, error.line, error.text);
|
||||||
if (!json) {
|
THROW(EXC_NULLPOINTER, "Loading JSON sprite failed");
|
||||||
SDL_Log("Error while loading sprite from %s on line %d: %s", asset_path, error.line, error.text);
|
}
|
||||||
THROW(EXC_NULLPOINTER, "Loading JSON sprite failed");
|
|
||||||
}
|
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
TRY {
|
TRY {
|
||||||
spritesheet_json = get_json_object_value(json, "spritesheet");
|
spritesheet_json = get_json_object_value(json, "spritesheet");
|
||||||
s = get_json_string_value(spritesheet_json, "filename");
|
|
||||||
sheet = SDL_GetPointerProperty(
|
sheet = SDL_GetPointerProperty(
|
||||||
REGISTRY_SPRITESHEET,
|
REGISTRY_SPRITESHEET,
|
||||||
s->data,
|
get_json_string_value(spritesheet_json, "filename"),
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
if ( sheet == NULL ) {
|
||||||
|
sheet = heap_next_spritesheet();
|
||||||
|
spritesheet_initialize(
|
||||||
|
sheet,
|
||||||
|
get_json_integer_value(spritesheet_json, "frame_width"),
|
||||||
|
get_json_integer_value(spritesheet_json, "frame_height"),
|
||||||
|
(char *)get_json_string_value(spritesheet_json, "filename")
|
||||||
|
);
|
||||||
|
}
|
||||||
TRY {
|
TRY {
|
||||||
if ( sheet == NULL ) {
|
|
||||||
sheet = heap_next_spritesheet();
|
|
||||||
spritesheet_initialize(
|
|
||||||
sheet,
|
|
||||||
get_json_integer_value(spritesheet_json, "frame_width"),
|
|
||||||
get_json_integer_value(spritesheet_json, "frame_height"),
|
|
||||||
s->data
|
|
||||||
);
|
|
||||||
}
|
|
||||||
heap_release_string(s);
|
|
||||||
s = get_json_string_value(json, "name");
|
|
||||||
sprite_initialize(
|
sprite_initialize(
|
||||||
obj,
|
obj,
|
||||||
s->data,
|
(char *)get_json_string_value(json, "name"),
|
||||||
sheet);
|
sheet);
|
||||||
heap_release_string(s);
|
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
json_decref(spritesheet_json);
|
json_decref(spritesheet_json);
|
||||||
} ETRY;
|
} ETRY;
|
||||||
@@ -289,13 +367,8 @@ void spritesheet_initialize(spritesheet *sheet, short sprite_w, short sprite_h,
|
|||||||
THROW_ZERO(sheet, EXC_NULLPOINTER, "Null spritesheet pointer");
|
THROW_ZERO(sheet, EXC_NULLPOINTER, "Null spritesheet pointer");
|
||||||
THROW_ZERO(filename, EXC_NULLPOINTER, "Null filename pointer");
|
THROW_ZERO(filename, EXC_NULLPOINTER, "Null filename pointer");
|
||||||
|
|
||||||
TRY {
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), filename);
|
sheet->texture = IMG_LoadTexture(renderer, asset_path);
|
||||||
sheet->texture = IMG_LoadTexture(renderer, asset_path);
|
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
strncpy(sheet->name, filename, SPRITE_SHEET_MAX_FILENAME_LENGTH);
|
strncpy(sheet->name, filename, SPRITE_SHEET_MAX_FILENAME_LENGTH);
|
||||||
|
|
||||||
THROW_ZERO(sheet->texture, EXC_NULLPOINTER, "Failed loading asset");
|
THROW_ZERO(sheet->texture, EXC_NULLPOINTER, "Failed loading asset");
|
||||||
@@ -371,4 +444,48 @@ void character_state_sprites_iterate(void *userdata, SDL_PropertiesID registry,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void heap_release_actor(actor *ptr)
|
||||||
|
{
|
||||||
|
THROW_ZERO(ptr, EXC_NULLPOINTER, "NULL character reference");
|
||||||
|
ptr->refcount -= 1;
|
||||||
|
if ( ptr->refcount == 0 ) {
|
||||||
|
heap_release_character(ptr->basechar);
|
||||||
|
SDL_ClearProperty(REGISTRY_ACTOR, (char *)&ptr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_release_character(character *basechar)
|
||||||
|
{
|
||||||
|
iterator opflags;
|
||||||
|
THROW_ZERO(basechar, EXC_NULLPOINTER, "NULL character reference");
|
||||||
|
BITMASK_CLEAR(opflags.flags);
|
||||||
|
BITMASK_ADD(opflags.flags, ITERATOR_OP_RELEASE);
|
||||||
|
|
||||||
|
basechar->refcount -= 1;
|
||||||
|
if ( basechar->refcount == 0 ) {
|
||||||
|
SDL_EnumerateProperties(basechar->state_sprites, &character_state_sprites_iterate, (void *)&opflags);
|
||||||
|
SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&basechar->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_release_sprite(sprite *ptr)
|
||||||
|
{
|
||||||
|
THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL sprite reference");
|
||||||
|
ptr->refcount -= 1;
|
||||||
|
if ( ptr->refcount == 0 ) {
|
||||||
|
heap_release_spritesheet(ptr->sheet);
|
||||||
|
SDL_ClearProperty(REGISTRY_SPRITE, (char *)&ptr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_release_spritesheet(spritesheet *ptr)
|
||||||
|
{
|
||||||
|
THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference");
|
||||||
|
ptr->refcount -= 1;
|
||||||
|
if ( ptr->refcount == 0 ) {
|
||||||
|
// TODO : If we go threaded, make sure this is only happening on the main thread
|
||||||
|
SDL_DestroyTexture(ptr->texture);
|
||||||
|
SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&ptr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
32
src/sprite.h
32
src/sprite.h
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <box2d/box2d.h>
|
#include <box2d/box2d.h>
|
||||||
#include <SDL3/SDL_properties.h>
|
#include <SDL3/SDL_properties.h>
|
||||||
#include <SDL3/SDL.h>
|
|
||||||
|
|
||||||
#define ACTOR_STATE_FACE_DOWN 1 // 1
|
#define ACTOR_STATE_FACE_DOWN 1 // 1
|
||||||
#define ACTOR_STATE_FACE_LEFT 1 << 1 // 2
|
#define ACTOR_STATE_FACE_LEFT 1 << 1 // 2
|
||||||
@@ -45,6 +44,11 @@
|
|||||||
#define SPRITE_MAX_ACTOR_NAME_LENGTH 128
|
#define SPRITE_MAX_ACTOR_NAME_LENGTH 128
|
||||||
#define SPRITE_MAX_CHARACTER_NAME_LENGTH 128
|
#define SPRITE_MAX_CHARACTER_NAME_LENGTH 128
|
||||||
|
|
||||||
|
#define MAX_HEAP_ACTOR 64
|
||||||
|
#define MAX_HEAP_SPRITE (MAX_HEAP_ACTOR * 16)
|
||||||
|
#define MAX_HEAP_SPRITESHEET MAX_HEAP_SPRITE
|
||||||
|
#define MAX_HEAP_CHARACTER 256
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int refcount;
|
int refcount;
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
@@ -89,6 +93,16 @@ typedef struct {
|
|||||||
int y;
|
int y;
|
||||||
} actor;
|
} actor;
|
||||||
|
|
||||||
|
extern SDL_PropertiesID REGISTRY_ACTOR;
|
||||||
|
extern SDL_PropertiesID REGISTRY_SPRITE;
|
||||||
|
extern SDL_PropertiesID REGISTRY_SPRITESHEET;
|
||||||
|
extern SDL_PropertiesID REGISTRY_CHARACTER;
|
||||||
|
|
||||||
|
extern actor HEAP_ACTOR[MAX_HEAP_ACTOR];
|
||||||
|
extern sprite HEAP_SPRITE[MAX_HEAP_SPRITE];
|
||||||
|
extern spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET];
|
||||||
|
extern character HEAP_CHARACTER[MAX_HEAP_CHARACTER];
|
||||||
|
|
||||||
void actor_initialize(actor *obj, char *name);
|
void actor_initialize(actor *obj, char *name);
|
||||||
void actor_set_character(actor *obj, char *basecharname);
|
void actor_set_character(actor *obj, char *basecharname);
|
||||||
void actor_render(actor *obj, SDL_Renderer *renderer);
|
void actor_render(actor *obj, SDL_Renderer *renderer);
|
||||||
@@ -106,4 +120,20 @@ void sprite_initialize(sprite *spr, char *name, spritesheet *sheet);
|
|||||||
void spritesheet_initialize(spritesheet *sheet, short sprite_w, short sprite_h, char *filename);
|
void spritesheet_initialize(spritesheet *sheet, short sprite_w, short sprite_h, char *filename);
|
||||||
void sprite_load_json(char *filename);
|
void sprite_load_json(char *filename);
|
||||||
|
|
||||||
|
void registry_init_actor();
|
||||||
|
void registry_iterate_actor(void *userdata, SDL_PropertiesID registry, const char *name);
|
||||||
|
void registry_init_sprite();
|
||||||
|
void registry_init_spritesheet();
|
||||||
|
void registry_init_character();
|
||||||
|
|
||||||
|
void heap_init();
|
||||||
|
actor *heap_next_actor();
|
||||||
|
sprite *heap_next_sprite();
|
||||||
|
spritesheet *heap_next_spritesheet();
|
||||||
|
character *heap_next_character();
|
||||||
|
void heap_release_actor(actor *ptr);
|
||||||
|
void heap_release_sprite(sprite *ptr);
|
||||||
|
void heap_release_spritesheet(spritesheet *ptr);
|
||||||
|
void heap_release_character(character *ptr);
|
||||||
|
|
||||||
#endif //_SPRITE_H_
|
#endif //_SPRITE_H_
|
||||||
|
|||||||
12
src/string.c
12
src/string.c
@@ -1,12 +0,0 @@
|
|||||||
#include "string.h"
|
|
||||||
#include <aklabs/exclib.h>
|
|
||||||
|
|
||||||
void string_initialize(string *obj, char *init)
|
|
||||||
{
|
|
||||||
THROW_ZERO(obj, EXC_NULLPOINTER, "Attempted to initialize NULL string reference");
|
|
||||||
if ( init != NULL ) {
|
|
||||||
strncpy(obj->data, init, MAX_STRING_LENGTH);
|
|
||||||
} else {
|
|
||||||
memset(obj->data, 0x00, sizeof(string));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
src/string.h
14
src/string.h
@@ -1,14 +0,0 @@
|
|||||||
#ifndef _STRING_H_
|
|
||||||
#define _STRING_H_
|
|
||||||
|
|
||||||
#define MAX_STRING_LENGTH 256
|
|
||||||
|
|
||||||
typedef struct string
|
|
||||||
{
|
|
||||||
int refcount;
|
|
||||||
char data[MAX_STRING_LENGTH];
|
|
||||||
} string;
|
|
||||||
|
|
||||||
void string_initialize(string *obj, char *init);
|
|
||||||
|
|
||||||
#endif //_STRING_H_
|
|
||||||
145
src/tilemap.c
145
src/tilemap.c
@@ -5,9 +5,6 @@
|
|||||||
#include "tilemap.h"
|
#include "tilemap.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "heap.h"
|
|
||||||
#include "registry.h"
|
|
||||||
#include "string.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "json_helpers.h"
|
#include "json_helpers.h"
|
||||||
@@ -16,53 +13,36 @@ static json_t *get_json_tilemap_property(json_t *obj, char *key, char *type)
|
|||||||
{
|
{
|
||||||
json_t *properties;
|
json_t *properties;
|
||||||
json_t *property;
|
json_t *property;
|
||||||
string *s;
|
|
||||||
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.
|
||||||
THROW_ZERO(obj, EXC_NULLPOINTER, "NULL json obj reference");
|
THROW_ZERO(obj, EXC_NULLPOINTER, "NULL json obj reference");
|
||||||
THROW_ZERO(key, EXC_NULLPOINTER, "NULL key string");
|
THROW_ZERO(key, EXC_NULLPOINTER, "NULL key string");
|
||||||
properties = get_json_array_value(obj, "properties");
|
properties = get_json_array_value(obj, "properties");
|
||||||
TRY {
|
for (i = 0; i < json_array_size(properties); i++) {
|
||||||
for (i = 0; i < json_array_size(properties); i++) {
|
property = get_json_array_index_object(properties, i);
|
||||||
property = get_json_array_index_object(properties, i);
|
if ( strcmp(get_json_string_value(property, "name"), key) != 0 ) {
|
||||||
s = get_json_string_value(property, "name");
|
continue;
|
||||||
if ( strcmp(s->data, key) != 0 ) {
|
|
||||||
heap_release_string(s);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
heap_release_string(s);
|
|
||||||
s = get_json_string_value(property, "type");
|
|
||||||
if ( strcmp(s->data, type) != 0 ) {
|
|
||||||
THROW(EXC_ATTRIBUTEERROR, "Character property is present but is incorrect type");
|
|
||||||
}
|
|
||||||
heap_release_string(s);
|
|
||||||
json_decref(properties);
|
|
||||||
return property;
|
|
||||||
}
|
}
|
||||||
} FINALLY {
|
if ( strcmp(get_json_string_value(property, "type"), type) != 0 ) {
|
||||||
heap_release_string(s);
|
THROW(EXC_ATTRIBUTEERROR, "Character property is present but is incorrect type");
|
||||||
json_decref(properties);
|
}
|
||||||
} ETRY;
|
return property;
|
||||||
|
}
|
||||||
THROW(EXC_KEYERROR, "Property not found in properties map");
|
THROW(EXC_KEYERROR, "Property not found in properties map");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static string *get_json_properties_string(json_t *obj, char *key)
|
static const char *get_json_properties_string(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
json_t *property = get_json_tilemap_property(obj, key, "string");
|
json_t *property = get_json_tilemap_property(obj, key, "string");
|
||||||
string *s = get_json_string_value(property, "value");;
|
return get_json_string_value(property, "value");
|
||||||
json_decref(property);
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_json_properties_integer(json_t *obj, char *key)
|
static int get_json_properties_integer(json_t *obj, char *key)
|
||||||
{
|
{
|
||||||
|
|
||||||
json_t *property = get_json_tilemap_property(obj, key, "int");
|
json_t *property = get_json_tilemap_property(obj, key, "int");
|
||||||
int i = get_json_integer_value(property, "value");
|
return get_json_integer_value(property, "value");
|
||||||
json_decref(property);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tilemap_load_tilesets(tilemap *dest, json_t *root)
|
static void tilemap_load_tilesets(tilemap *dest, json_t *root)
|
||||||
@@ -70,7 +50,6 @@ static void tilemap_load_tilesets(tilemap *dest, json_t *root)
|
|||||||
THROW_ZERO(dest, EXC_NULLPOINTER, "Received NULL tilemap pointer");
|
THROW_ZERO(dest, EXC_NULLPOINTER, "Received NULL tilemap pointer");
|
||||||
THROW_ZERO(root, EXC_NULLPOINTER, "Received NULL json object pointer");
|
THROW_ZERO(root, EXC_NULLPOINTER, "Received NULL json object pointer");
|
||||||
char *asset_path;
|
char *asset_path;
|
||||||
string *s;
|
|
||||||
json_t *tilesets = get_json_array_value(root, "tilesets");
|
json_t *tilesets = get_json_array_value(root, "tilesets");
|
||||||
json_t *tileset;
|
json_t *tileset;
|
||||||
int i;
|
int i;
|
||||||
@@ -93,21 +72,17 @@ static void tilemap_load_tilesets(tilemap *dest, json_t *root)
|
|||||||
dest->tilesets[i].tileheight = get_json_integer_value(tileset, "tileheight");
|
dest->tilesets[i].tileheight = get_json_integer_value(tileset, "tileheight");
|
||||||
dest->tilesets[i].tilewidth = get_json_integer_value(tileset, "tilewidth");
|
dest->tilesets[i].tilewidth = get_json_integer_value(tileset, "tilewidth");
|
||||||
|
|
||||||
s = get_json_string_value(tileset, "name");
|
|
||||||
strncpy((char *)&dest->tilesets[i].name,
|
strncpy((char *)&dest->tilesets[i].name,
|
||||||
s->data,
|
get_json_string_value(tileset, "name"),
|
||||||
TILEMAP_MAX_TILESET_NAME_SIZE
|
TILEMAP_MAX_TILESET_NAME_SIZE
|
||||||
);
|
);
|
||||||
heap_release_string(s);
|
|
||||||
|
|
||||||
s = get_json_string_value(tileset, "image");
|
|
||||||
snprintf((char *)&dest->tilesets[i].imagefilename,
|
snprintf((char *)&dest->tilesets[i].imagefilename,
|
||||||
TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
||||||
"%s%s",
|
"%s%s",
|
||||||
SDL_GetBasePath(),
|
SDL_GetBasePath(),
|
||||||
s->data
|
get_json_string_value(tileset, "image")
|
||||||
);
|
);
|
||||||
heap_release_string(s);
|
|
||||||
dest->tilesets[i].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[i].imagefilename);
|
dest->tilesets[i].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[i].imagefilename);
|
||||||
THROW_ZERO(dest->tilesets[i].texture, EXC_NULLPOINTER, "Failed loading tileset image");
|
THROW_ZERO(dest->tilesets[i].texture, EXC_NULLPOINTER, "Failed loading tileset image");
|
||||||
|
|
||||||
@@ -155,10 +130,8 @@ static void tilemap_load_tilesets(tilemap *dest, json_t *root)
|
|||||||
y_offset);*/
|
y_offset);*/
|
||||||
}
|
}
|
||||||
// SDL_Log("Processed %d total tiles for tileset", j);
|
// SDL_Log("Processed %d total tiles for tileset", j);
|
||||||
json_decref(tileset);
|
|
||||||
dest->numtilesets += 1;
|
dest->numtilesets += 1;
|
||||||
}
|
}
|
||||||
json_decref(tilesets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
||||||
@@ -168,8 +141,6 @@ static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
|||||||
int j;
|
int j;
|
||||||
int len;
|
int len;
|
||||||
actor *actorobj;
|
actor *actorobj;
|
||||||
string *s;
|
|
||||||
string *sc;
|
|
||||||
tilemap_layer *curlayer;
|
tilemap_layer *curlayer;
|
||||||
tilemap_object *curobj;
|
tilemap_object *curobj;
|
||||||
const char *charptr;
|
const char *charptr;
|
||||||
@@ -184,14 +155,11 @@ static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
|||||||
for ( j = 0; j < len; j++ ) {
|
for ( j = 0; j < len; j++ ) {
|
||||||
layerdatavalue = get_json_array_index_object(layerdata, j);
|
layerdatavalue = get_json_array_index_object(layerdata, j);
|
||||||
curobj = &curlayer->objects[j];
|
curobj = &curlayer->objects[j];
|
||||||
s = get_json_string_value(layerdatavalue, "name");
|
strncpy(curobj->name, get_json_string_value(layerdatavalue, "name"), SPRITE_MAX_ACTOR_NAME_LENGTH);
|
||||||
strncpy(curobj->name, s->data, SPRITE_MAX_ACTOR_NAME_LENGTH);
|
|
||||||
heap_release_string(s);
|
|
||||||
curobj->x = (int) get_json_number_value(layerdatavalue, "x");
|
curobj->x = (int) get_json_number_value(layerdatavalue, "x");
|
||||||
curobj->y = (int) get_json_number_value(layerdatavalue, "y");
|
curobj->y = (int) get_json_number_value(layerdatavalue, "y");
|
||||||
curobj->visible = get_json_boolean_value(layerdatavalue, "visible");
|
curobj->visible = get_json_boolean_value(layerdatavalue, "visible");
|
||||||
s = get_json_string_value(layerdatavalue, "type");
|
if ( strcmp((char *)get_json_string_value(layerdatavalue, "type"), "actor") == 0 ) {
|
||||||
if ( strcmp(s->data, "actor") == 0 ) {
|
|
||||||
curobj->type = TILEMAP_OBJECT_TYPE_ACTOR;
|
curobj->type = TILEMAP_OBJECT_TYPE_ACTOR;
|
||||||
if ( strlen((char *)&curobj->name) == 0 ) {
|
if ( strlen((char *)&curobj->name) == 0 ) {
|
||||||
THROW(EXC_KEYERROR, "Actor in tile object layer cannot have empty name");
|
THROW(EXC_KEYERROR, "Actor in tile object layer cannot have empty name");
|
||||||
@@ -199,10 +167,8 @@ static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
|||||||
actorobj = SDL_GetPointerProperty(REGISTRY_ACTOR, (char *)&curobj->name, NULL);
|
actorobj = SDL_GetPointerProperty(REGISTRY_ACTOR, (char *)&curobj->name, NULL);
|
||||||
if ( actorobj == NULL ) {
|
if ( actorobj == NULL ) {
|
||||||
actorobj = heap_next_actor();
|
actorobj = heap_next_actor();
|
||||||
sc = get_json_properties_string(layerdatavalue, "character");
|
|
||||||
actor_initialize(actorobj, (char *)&curobj->name);
|
actor_initialize(actorobj, (char *)&curobj->name);
|
||||||
actor_set_character(actorobj, sc->data);
|
actor_set_character(actorobj, (char *)get_json_properties_string(layerdatavalue, "character"));
|
||||||
heap_release_string(sc);
|
|
||||||
} else {
|
} else {
|
||||||
actorobj->refcount += 1;
|
actorobj->refcount += 1;
|
||||||
}
|
}
|
||||||
@@ -216,7 +182,6 @@ static void tilemap_load_layer_objects(tilemap *dest, json_t *root, int layerid)
|
|||||||
json_decref(layerdatavalue);
|
json_decref(layerdatavalue);
|
||||||
}
|
}
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
heap_release_string(s);
|
|
||||||
if ( layerdatavalue != NULL ) {
|
if ( layerdatavalue != NULL ) {
|
||||||
json_decref(layerdatavalue);
|
json_decref(layerdatavalue);
|
||||||
}
|
}
|
||||||
@@ -243,7 +208,6 @@ static void tilemap_load_layer_tile(tilemap *dest, json_t *root, int layerid)
|
|||||||
json_decref(layerdata);
|
json_decref(layerdata);
|
||||||
THROW(EXC_OUTOFBOUNDS, "Map layer exceeds the maximum size");
|
THROW(EXC_OUTOFBOUNDS, "Map layer exceeds the maximum size");
|
||||||
}
|
}
|
||||||
TRY {
|
|
||||||
for ( j = 0; j < layerdatalen; j++ ) {
|
for ( j = 0; j < layerdatalen; j++ ) {
|
||||||
layerdatavalue = json_array_get(layerdata, j);
|
layerdatavalue = json_array_get(layerdata, j);
|
||||||
if (!json_is_integer(layerdatavalue)) {
|
if (!json_is_integer(layerdatavalue)) {
|
||||||
@@ -254,12 +218,7 @@ static void tilemap_load_layer_tile(tilemap *dest, json_t *root, int layerid)
|
|||||||
dest->layers[layerid].data[j] = json_integer_value(layerdatavalue);
|
dest->layers[layerid].data[j] = json_integer_value(layerdatavalue);
|
||||||
json_decref(layerdatavalue);
|
json_decref(layerdatavalue);
|
||||||
}
|
}
|
||||||
} FINALLY {
|
json_decref(layerdata);
|
||||||
if ( layerdatavalue != NULL ) {
|
|
||||||
json_decref(layerdatavalue);
|
|
||||||
json_decref(layerdata);
|
|
||||||
}
|
|
||||||
} ETRY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tilemap_load_layers(tilemap *dest, json_t *root)
|
static void tilemap_load_layers(tilemap *dest, json_t *root)
|
||||||
@@ -268,47 +227,41 @@ static void tilemap_load_layers(tilemap *dest, json_t *root)
|
|||||||
THROW_ZERO(root, EXC_NULLPOINTER, "tilemap_load_layers received NULL json object pointer");
|
THROW_ZERO(root, EXC_NULLPOINTER, "tilemap_load_layers received NULL json object pointer");
|
||||||
json_t *layers = get_json_array_value(root, "layers");
|
json_t *layers = get_json_array_value(root, "layers");
|
||||||
json_t *layer;
|
json_t *layer;
|
||||||
string *s;
|
|
||||||
const char *layertype = NULL;
|
const char *layertype = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dest->numlayers = json_array_size(layers);
|
dest->numlayers = json_array_size(layers);
|
||||||
TRY {
|
for ( i = 0; i < dest->numlayers; i++) {
|
||||||
for ( i = 0; i < dest->numlayers; i++) {
|
if ( i >= TILEMAP_MAX_LAYERS ) {
|
||||||
if ( i >= TILEMAP_MAX_LAYERS ) {
|
json_decref(layers);
|
||||||
THROW(EXC_OUTOFBOUNDS, "Map exceeds the maximum number of layers");
|
THROW(EXC_OUTOFBOUNDS, "Map exceeds the maximum number of layers");
|
||||||
}
|
}
|
||||||
layer = get_json_array_index_object(layers, i);
|
layer = get_json_array_index_object(layers, i);
|
||||||
if ( (get_json_integer_value(layer, "id") - 1) != i ) {
|
if ( (get_json_integer_value(layer, "id") - 1) != i ) {
|
||||||
// TileD's map layer IDs start at 1, not 0, and are sequential but not necessarily contiguous. We may have a gap in IDs.
|
// TileD's map layer IDs start at 1, not 0, and are sequential but not necessarily contiguous. We may have a gap in IDs.
|
||||||
json_decref(layer);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dest->layers[i].opacity = get_json_number_value(layer, "opacity");
|
dest->layers[i].opacity = get_json_number_value(layer, "opacity");
|
||||||
dest->layers[i].visible = get_json_boolean_value(layer, "visible");
|
dest->layers[i].visible = get_json_boolean_value(layer, "visible");
|
||||||
dest->layers[i].id = get_json_integer_value(layer, "id");
|
dest->layers[i].id = get_json_integer_value(layer, "id");
|
||||||
dest->layers[i].x = get_json_integer_value(layer, "x");
|
dest->layers[i].x = get_json_integer_value(layer, "x");
|
||||||
dest->layers[i].y = get_json_integer_value(layer, "y");
|
dest->layers[i].y = get_json_integer_value(layer, "y");
|
||||||
|
|
||||||
TRY {
|
TRY {
|
||||||
s = get_json_string_value(layer, "type");
|
layertype = get_json_string_value(layer, "type");
|
||||||
if ( strncmp(s->data, "objectgroup", strlen(s->data)) == 0 ) {
|
if ( strncmp(layertype, "objectgroup", strlen(layertype)) == 0 ) {
|
||||||
dest->layers[i].type = TILEMAP_LAYER_TYPE_OBJECTS;
|
dest->layers[i].type = TILEMAP_LAYER_TYPE_OBJECTS;
|
||||||
tilemap_load_layer_objects(dest, layer, i);
|
tilemap_load_layer_objects(dest, layer, i);
|
||||||
} else if ( strncmp(s->data, "tilelayer", strlen(s->data)) == 0 ) {
|
} else if ( strncmp(layertype, "tilelayer", strlen(layertype)) == 0 ) {
|
||||||
dest->layers[i].type = TILEMAP_LAYER_TYPE_TILES;
|
dest->layers[i].type = TILEMAP_LAYER_TYPE_TILES;
|
||||||
tilemap_load_layer_tile(dest, layer, i);
|
tilemap_load_layer_tile(dest, layer, i);
|
||||||
}
|
}
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
heap_release_string(s);
|
|
||||||
json_decref(layer);
|
json_decref(layer);
|
||||||
} ETRY;
|
json_decref(layers);
|
||||||
}
|
} ETRY;
|
||||||
} FINALLY {
|
}
|
||||||
json_decref(layers);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tilemap_load(char *fname, tilemap *dest)
|
void tilemap_load(char *fname, tilemap *dest)
|
||||||
@@ -322,16 +275,12 @@ void tilemap_load(char *fname, tilemap *dest)
|
|||||||
|
|
||||||
memset(dest, 0x00, sizeof(tilemap));
|
memset(dest, 0x00, sizeof(tilemap));
|
||||||
|
|
||||||
TRY {
|
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
||||||
SDL_asprintf(&asset_path, "%s%s", SDL_GetBasePath(), fname);
|
json = json_load_file(asset_path, 0, &error);
|
||||||
json = json_load_file(asset_path, 0, &error);
|
if (!json) {
|
||||||
if (!json) {
|
SDL_Log("Error while loading tilemap from %s on line %d: %s", asset_path, error.line, error.text);
|
||||||
SDL_Log("Error while loading tilemap from %s on line %d: %s", asset_path, error.line, error.text);
|
THROW(EXC_NULLPOINTER, "Loading JSON tilemap failed");
|
||||||
THROW(EXC_NULLPOINTER, "Loading JSON tilemap failed");
|
}
|
||||||
}
|
|
||||||
} FINALLY {
|
|
||||||
SDL_free(asset_path);
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
TRY {
|
TRY {
|
||||||
dest->tileheight = get_json_integer_value(json, "tileheight");
|
dest->tileheight = get_json_integer_value(json, "tileheight");
|
||||||
|
|||||||
Reference in New Issue
Block a user