Compare commits
2 Commits
memorymana
...
registry_h
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f57710c36 | |||
| 29cc3c341d |
22
Makefile
22
Makefile
@@ -2,21 +2,37 @@ 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 src/*.o ${DISTFILE}
|
rm -f $(OBJFILES) $(PREPFILES) $(ASMFILES) ${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): $(OBJECTS)
|
$(DISTFILE): $(OBJFILES)
|
||||||
$(CC) -o $@ $^ -lexc -lbox2d -ljansson -lhashmap -lm $(SDLFLAGS_LD)
|
$(CC) -o $@ $^ -lexc -lbox2d -ljansson -lhashmap -lm $(SDLFLAGS_LD)
|
||||||
|
|||||||
152
src/heap.c
Normal file
152
src/heap.c
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
#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
Normal file
31
src/heap.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#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_
|
||||||
32
src/registry.c
Normal file
32
src/registry.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#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");
|
||||||
|
}
|
||||||
16
src/registry.h
Normal file
16
src/registry.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#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,6 +13,8 @@
|
|||||||
#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[])
|
||||||
{
|
{
|
||||||
|
|||||||
139
src/sdl3-pong.c
139
src/sdl3-pong.c
@@ -1,139 +0,0 @@
|
|||||||
#define SDL_MAIN_USE_CALLBACKS
|
|
||||||
#include <SDL3/SDL.h>
|
|
||||||
#include <SDL3/SDL_main.h>
|
|
||||||
#include <SDL3_image/SDL_image.h>
|
|
||||||
#include <SDL3_mixer/SDL_mixer.h>
|
|
||||||
#include <aklabs/exclib.h>
|
|
||||||
#include <box2d/box2d.h>
|
|
||||||
|
|
||||||
#include "game.h"
|
|
||||||
#include "physics.h"
|
|
||||||
#include "draw.h"
|
|
||||||
#include "assets.h"
|
|
||||||
|
|
||||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
|
||||||
{
|
|
||||||
SDL_AudioSpec spec;
|
|
||||||
/* Initialize variables */
|
|
||||||
spec.freq = MIX_DEFAULT_FREQUENCY;
|
|
||||||
spec.format = MIX_DEFAULT_FORMAT;
|
|
||||||
spec.channels = MIX_DEFAULT_CHANNELS;
|
|
||||||
|
|
||||||
exclib_name_exception(EXC_SDL_INIT, "SDL Initialization Failure");
|
|
||||||
exclib_name_exception(EXC_SDL_MUSICMIXER, "SDL Music Mixer Failure");
|
|
||||||
|
|
||||||
SDL_SetAppMetadata("SDL3-Pong", "0.1", "net.aklabs.sdl3-pong");
|
|
||||||
|
|
||||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO )) {
|
|
||||||
SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
|
|
||||||
return SDL_APP_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SDL_CreateWindowAndRenderer("net/aklabs/sdl3-pong", 640, 480, 0, &window, &renderer)) {
|
|
||||||
SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
|
|
||||||
return SDL_APP_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GAME_init_physics();
|
|
||||||
|
|
||||||
if (!Mix_OpenAudio(0, &spec)) {
|
|
||||||
SDL_Log("Couldn't initialize the audio subsystem: %s", SDL_GetError());
|
|
||||||
return SDL_APP_FAILURE;
|
|
||||||
} else {
|
|
||||||
Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels);
|
|
||||||
SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq,
|
|
||||||
(spec.format&0xFF),
|
|
||||||
(SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""),
|
|
||||||
(spec.channels > 2) ? "surround" : (spec.channels > 1) ? "stereo" : "mono");
|
|
||||||
}
|
|
||||||
|
|
||||||
TRY {
|
|
||||||
load_frame_from_image("../assets/ball.png", &ball);
|
|
||||||
load_frame_from_image("../assets/paddle-green.png", &paddle1);
|
|
||||||
load_frame_from_image("../assets/paddle-red.png", &paddle2);
|
|
||||||
load_frame_from_image("../assets/table.jpg", &table);
|
|
||||||
} CATCH(EXC_NULLPOINTER) {
|
|
||||||
SDL_Log("Attempting to load asset: %s", EXCLIB_EXCEPTION->description);
|
|
||||||
return SDL_APP_FAILURE;
|
|
||||||
} ETRY;
|
|
||||||
|
|
||||||
/*
|
|
||||||
TRY {
|
|
||||||
//load_start_bgm("../assets/nutcracker.mid");
|
|
||||||
load_start_bgm("../assets/memories.mp3");
|
|
||||||
} CATCH(EXC_NULLPOINTER) {
|
|
||||||
} CATCH_GROUP(EXC_SDL_INIT) {
|
|
||||||
} CATCH_GROUP(EXC_SDL_MUSICMIXER) {
|
|
||||||
SDL_Log("Attempting to load and play background music: %s (%s)", EXCLIB_EXCEPTION->description, SDL_GetError());
|
|
||||||
return SDL_APP_FAILURE;
|
|
||||||
} ETRY;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return SDL_APP_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
|
||||||
{
|
|
||||||
if (event->type == SDL_EVENT_QUIT) {
|
|
||||||
return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */
|
|
||||||
} else if (event->type == SDL_EVENT_JOYSTICK_BUTTON_UP) {
|
|
||||||
GAME_handle_joystick_button_up(appstate, event);
|
|
||||||
} else if (event->type == SDL_EVENT_JOYSTICK_ADDED) {
|
|
||||||
GAME_handle_joystick_added(appstate, event);
|
|
||||||
} else if (event->type == SDL_EVENT_JOYSTICK_REMOVED) {
|
|
||||||
GAME_handle_joystick_removed(appstate, event);
|
|
||||||
}
|
|
||||||
return SDL_APP_CONTINUE; /* carry on with the program! */
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_AppResult SDL_AppIterate(void *appstate)
|
|
||||||
{
|
|
||||||
SDL_FRect dest;
|
|
||||||
b2Vec2 position;
|
|
||||||
|
|
||||||
GAME_draw_background(640, 480);
|
|
||||||
|
|
||||||
b2World_Step(physicsWorldId, physicsTimeStep, physicsSubStepCount);
|
|
||||||
|
|
||||||
dest.x = 0;
|
|
||||||
dest.y = 0;
|
|
||||||
dest.w = table.w;
|
|
||||||
dest.h = table.h;
|
|
||||||
SDL_RenderTexture(renderer, table.texture, NULL, &dest);
|
|
||||||
|
|
||||||
dest.x = 16;
|
|
||||||
dest.y = 200;
|
|
||||||
dest.w = paddle1.w;
|
|
||||||
dest.h = paddle1.h;
|
|
||||||
SDL_RenderTexture(renderer, paddle1.texture, NULL, &dest);
|
|
||||||
|
|
||||||
dest.x = (640-32);
|
|
||||||
dest.y = 200;
|
|
||||||
dest.w = paddle1.w;
|
|
||||||
dest.h = paddle1.h;
|
|
||||||
SDL_RenderTexture(renderer, paddle2.texture, NULL, &dest);
|
|
||||||
|
|
||||||
position = b2Body_GetPosition(physicsBallBodyId);
|
|
||||||
dest.x = (int)SCREEN_PHYSICS_SCALE(position.x);
|
|
||||||
dest.y = (int)SCREEN_PHYSICS_SCALE(position.y);
|
|
||||||
dest.w = 16;
|
|
||||||
dest.h = 16;
|
|
||||||
SDL_RenderTexture(renderer, ball.texture, NULL, &dest);
|
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
|
||||||
return SDL_APP_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_AppQuit(void *appstate, SDL_AppResult result)
|
|
||||||
{
|
|
||||||
/* SDL will clean up the window/renderer for us. */
|
|
||||||
SDL_DestroyTexture(ball.texture);
|
|
||||||
b2DestroyWorld(physicsWorldId);
|
|
||||||
SDL_Log("Freeing music resources");
|
|
||||||
if ( bgm != NULL ) {
|
|
||||||
Mix_FreeMusic(bgm);
|
|
||||||
}
|
|
||||||
SDL_Log("Quitting mixer");
|
|
||||||
Mix_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
142
src/sprite.c
142
src/sprite.c
@@ -8,101 +8,8 @@
|
|||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "json_helpers.h"
|
#include "json_helpers.h"
|
||||||
|
#include "heap.h"
|
||||||
SDL_PropertiesID REGISTRY_ACTOR;
|
#include "registry.h"
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -444,48 +351,3 @@ 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,6 +3,7 @@
|
|||||||
|
|
||||||
#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
|
||||||
@@ -44,11 +45,6 @@
|
|||||||
#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;
|
||||||
@@ -93,16 +89,6 @@ 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);
|
||||||
@@ -120,20 +106,4 @@ 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
Normal file
12
src/string.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#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(MAX_STRING_LENGTH));
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/string.h
Normal file
14
src/string.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#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_
|
||||||
@@ -2,12 +2,16 @@
|
|||||||
#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 <aklabs/exclib.h>
|
#include <aklabs/exclib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
|
||||||
#include "tilemap.h"
|
#include "tilemap.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include <string.h>
|
|
||||||
#include <jansson.h>
|
|
||||||
#include "json_helpers.h"
|
#include "json_helpers.h"
|
||||||
|
#include "heap.h"
|
||||||
|
#include "string.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
static json_t *get_json_tilemap_property(json_t *obj, char *key, char *type)
|
static json_t *get_json_tilemap_property(json_t *obj, char *key, char *type)
|
||||||
{
|
{
|
||||||
@@ -239,6 +243,7 @@ static void tilemap_load_layers(tilemap *dest, json_t *root)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,9 +264,9 @@ static void tilemap_load_layers(tilemap *dest, json_t *root)
|
|||||||
}
|
}
|
||||||
} FINALLY {
|
} FINALLY {
|
||||||
json_decref(layer);
|
json_decref(layer);
|
||||||
json_decref(layers);
|
|
||||||
} ETRY;
|
} ETRY;
|
||||||
}
|
}
|
||||||
|
json_decref(layers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tilemap_load(char *fname, tilemap *dest)
|
void tilemap_load(char *fname, tilemap *dest)
|
||||||
|
|||||||
Reference in New Issue
Block a user