summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorP. J. McDermott <pjm@nac.net>2013-02-15 15:28:42 (EST)
committer P. J. McDermott <pjm@nac.net>2013-02-15 15:28:42 (EST)
commitc978f746058497ddd9ddc9cf3e156c4453e487f1 (patch)
treeb7855dd65c735c54ad535f31d4fbd645ca29fc1b
parent80191b41352ad20493fb62e8f3683d69133d0d24 (diff)
downloadoverworld-rpg-c978f746058497ddd9ddc9cf3e156c4453e487f1.zip
overworld-rpg-c978f746058497ddd9ddc9cf3e156c4453e487f1.tar.gz
overworld-rpg-c978f746058497ddd9ddc9cf3e156c4453e487f1.tar.bz2
Add resource manager and move src/image.*.
-rw-r--r--Makefile5
-rw-r--r--src/image.c22
-rw-r--r--src/image.h6
-rw-r--r--src/layer.h2
-rw-r--r--src/main.c27
-rw-r--r--src/map.h2
-rw-r--r--src/resources/image.c48
-rw-r--r--src/resources/image.h14
-rw-r--r--src/resources/resource.c87
-rw-r--r--src/resources/resource.h23
-rw-r--r--src/tileset.h2
-rw-r--r--src/tmx.c4
12 files changed, 200 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 3efdec5..2648c43 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,9 @@
CC = gcc
CFLAGS = -Wall -Wextra -Werror -g
-SRCS = src/main.c src/init.c src/logging.c src/image.c \
- src/base64.c src/compression.c src/tmx.c
+SRCS = src/main.c src/init.c src/logging.c \
+ src/base64.c src/compression.c \
+ src/tmx.c src/resources/resource.c src/resources/image.c
OBJS = $(SRCS:.c=.o)
LIBS = sdl SDL_image zlib expat
diff --git a/src/image.c b/src/image.c
deleted file mode 100644
index 557e1de..0000000
--- a/src/image.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <SDL.h>
-#include <SDL_image.h>
-#include "logging.h"
-#include "image.h"
-
-SDL_Surface *
-load_png(const char *path)
-{
- SDL_RWops *rwops;
- SDL_Surface *img;
-
- debug("Loading PNG image \"%s\"...", path);
-
- rwops = SDL_RWFromFile(path, "rb");
- img = IMG_LoadPNG_RW(rwops);
- if (!img) {
- err(1, "Failed to load image \"%s\" (%s)",
- path, IMG_GetError());
- }
-
- return img;
-}
diff --git a/src/image.h b/src/image.h
deleted file mode 100644
index 0de4083..0000000
--- a/src/image.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef IMAGE_H
-#define IMAGE_H
-
-SDL_Surface *load_png(const char *path);
-
-#endif
diff --git a/src/layer.h b/src/layer.h
index 126c3d9..85558a6 100644
--- a/src/layer.h
+++ b/src/layer.h
@@ -3,6 +3,7 @@
#include <SDL_stdinc.h>
+#if 0
const int LAYER_GROUND = 0;
const int LAYER_OBJ_LOW = 1;
const int LAYER_CHAR_BOT = 2;
@@ -10,6 +11,7 @@ const int LAYER_OBJ_MID = 3;
const int LAYER_CHAR_TOP = 4;
const int LAYER_OBJ_HIGH = 5;
const int LAYER_WEATHER = 6;
+#endif
struct layer {
char *name;
diff --git a/src/main.c b/src/main.c
index b30d0b2..24e9e1e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,20 +1,29 @@
#include <SDL.h>
#include "init.h"
#include "logging.h"
-#include "image.h"
+#include "resources/image.h"
#include "tmx.h"
int
main(void)
{
- SDL_Surface *img;
+ struct image *img;
SDL_Rect imgrect, surfacerect;
init();
tmx_load("data/forest1.tmx");
- img = load_png("../forest-6-layer-test_ground.png");
+ img = img_png_get("../forest-6-layer-test_ground.png");
+ img_png_free(img);
+ img = img_png_get("../forest-6-layer-test_ground.png");
+ img = img_png_get("../forest-6-layer-test_ground.png");
+ img = img_png_get("../forest-6-layer-test_ground.png");
+ img = img_png_get("../forest-6-layer-test_ground.png");
+ img_png_free(img);
+ img_png_free(img);
+ img_png_free(img);
+ img = img_png_get("../forest-6-layer-test_ground.png");
imgrect.w = 240;
imgrect.h = 160;
surfacerect.x = 0;
@@ -24,37 +33,37 @@ main(void)
imgrect.x = 208;
imgrect.y = 480;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
imgrect.x = 208;
imgrect.y = 464;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
imgrect.x = 224;
imgrect.y = 464;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
imgrect.x = 240;
imgrect.y = 464;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
imgrect.x = 256;
imgrect.y = 464;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
imgrect.x = 256;
imgrect.y = 448;
- SDL_BlitSurface(img, &imgrect, screen, &surfacerect);
+ SDL_BlitSurface(img->image, &imgrect, screen, &surfacerect);
SDL_Flip(screen);
SDL_Delay(500);
diff --git a/src/map.h b/src/map.h
index 554b428..925bdd2 100644
--- a/src/map.h
+++ b/src/map.h
@@ -1,6 +1,7 @@
#ifndef MAP_H
#define MAP_H
+#include <SDL_stdinc.h>
#include "tileset.h"
#include "layer.h"
@@ -11,6 +12,7 @@ struct map {
int tileheight;
struct tileset *tilesets;
struct layer *layers;
+ Uint8 *collision;
};
#endif
diff --git a/src/resources/image.c b/src/resources/image.c
new file mode 100644
index 0000000..cd2c317
--- /dev/null
+++ b/src/resources/image.c
@@ -0,0 +1,48 @@
+#include <SDL.h>
+#include <SDL_image.h>
+#include "../logging.h"
+#include "image.h"
+#include "resource.h"
+
+struct resource_table img_res;
+
+struct image *
+img_png_get(const char *path)
+{
+ SDL_RWops *rwops;
+ struct image *img;
+
+ img = (struct image *) resource_get(&img_res, path);
+ if (img != NULL) {
+ resource_use((struct resource *) img);
+ return img;
+ }
+
+ img = resource_alloc(path, sizeof(*img));
+ rwops = SDL_RWFromFile(path, "rb");
+ img->image = IMG_LoadPNG_RW(rwops);
+ if (!img->image) {
+ err(1, "Failed to load image \"%s\" (%s)",
+ path, IMG_GetError());
+ }
+
+ resource_use((struct resource *) img);
+ resource_add(&img_res, path, (struct resource *) img);
+
+ return img;
+}
+
+void
+img_png_free(struct image *image)
+{
+ SDL_Surface *data;
+
+ if (image == NULL) {
+ return;
+ }
+
+ data = image->image;
+ if (resource_free(&img_res, (struct resource *) image)) {
+ SDL_FreeSurface(data);
+ }
+}
diff --git a/src/resources/image.h b/src/resources/image.h
new file mode 100644
index 0000000..92ef040
--- /dev/null
+++ b/src/resources/image.h
@@ -0,0 +1,14 @@
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include "resource.h"
+
+struct image {
+ struct resource res;
+ SDL_Surface *image;
+};
+
+struct image *img_png_get(const char *path);
+void img_png_free(struct image *image);
+
+#endif
diff --git a/src/resources/resource.c b/src/resources/resource.c
new file mode 100644
index 0000000..ebfcf27
--- /dev/null
+++ b/src/resources/resource.c
@@ -0,0 +1,87 @@
+#include <stdlib.h>
+#include <string.h>
+#include "resource.h"
+
+#include "../logging.h"
+
+inline void *
+resource_alloc(const char *path, size_t size)
+{
+ void *new_res;
+
+ debug("Allocating resource \"%s\"...", path);
+ new_res = malloc(size);
+ if (new_res == NULL) {
+ err(1, "Failed to allocate resource \"%s\"", path);
+ return NULL;
+ }
+ memset(new_res, 0, size);
+
+ return new_res;
+}
+
+struct resource *
+resource_get(struct resource_table *resources, const char *path)
+{
+ struct resource *res;
+
+ for (res = resources->head; res != NULL; res = res->next) {
+ if (strcmp(res->path, path) == 0) {
+ debug("Found resource \"%s\"", path);
+ return res;
+ }
+ }
+
+ return NULL;
+}
+
+void
+resource_add(struct resource_table *resources, const char *path,
+ struct resource *new_res)
+{
+ new_res->path = strdup(path);
+ new_res->prev = resources->tail;
+ new_res->next = NULL;
+
+ if (resources->head == NULL) {
+ resources->head = new_res;
+ } else {
+ resources->tail->next = new_res;
+ }
+ resources->tail = new_res;
+}
+
+/* XXX: Not thread-safe. */
+void
+resource_use(struct resource *resource)
+{
+ ++resource->refs;
+}
+
+int
+resource_free(struct resource_table *resources, struct resource *resource)
+{
+ if (resource == NULL) {
+ return -1;
+ }
+
+ debug("Releasing resource with path \"%s\" and %d refs...",
+ resource->path, resource->refs);
+
+ if (--resource->refs == 0) {
+ debug("Freeing resource with path \"%s\"...", resource->path);
+ if (resource->prev == NULL) {
+ resources->head = resource->next;
+ } else {
+ resource->prev->next = resource->next;
+ }
+ if (resource->next == NULL) {
+ resources->tail = resource->prev;
+ } else {
+ resource->next->prev = resource->prev;
+ }
+ free(resource);
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/resources/resource.h b/src/resources/resource.h
new file mode 100644
index 0000000..ada91fd
--- /dev/null
+++ b/src/resources/resource.h
@@ -0,0 +1,23 @@
+#ifndef RESOURCE_H
+#define RESOURCE_H
+
+struct resource_table {
+ struct resource *head;
+ struct resource *tail;
+};
+struct resource {
+ char *path;
+ int refs;
+ struct resource *prev;
+ struct resource *next;
+};
+
+extern inline void *resource_alloc(const char *path, size_t size);
+struct resource *resource_get(struct resource_table *resources,
+ const char *path);
+void resource_add(struct resource_table *resources, const char *path,
+ struct resource *new_res);
+void resource_use(struct resource *resource);
+int resource_free(struct resource_table *resources, struct resource *resource);
+
+#endif
diff --git a/src/tileset.h b/src/tileset.h
index 2fd384a..26aec80 100644
--- a/src/tileset.h
+++ b/src/tileset.h
@@ -5,7 +5,7 @@ struct tileset {
int firstgid;
int tilewidth;
int tileheight;
- SDL_Surface *image;
+ struct image *image;
struct tileset *next;
};
diff --git a/src/tmx.c b/src/tmx.c
index 0e401b3..731f76c 100644
--- a/src/tmx.c
+++ b/src/tmx.c
@@ -7,7 +7,7 @@
#include "base64.h"
#include "compression.h"
#include "map.h"
-#include "image.h"
+#include "resources/image.h"
struct tmx {
char *dirname;
@@ -129,7 +129,7 @@ tmx_start_image(struct tmx *cur_tmx, const char **attr)
err(1, "Failed to allocate resource path string");
}
sprintf(path, "%s/%s", cur_tmx->dirname, source);
- cur_tmx->cur_tileset->image = load_png(path);
+ cur_tmx->cur_tileset->image = img_png_get(path);
free(path);
debug(" Found tileset with firstgid %d and source \"%s\"",