aboutsummaryrefslogtreecommitdiff
path: root/asset.c
blob: 5ae54193c6d5944d801e188ee2164a02dad31525 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>

#include "asset.h"
#include "error.h"
#include "platform.h"
#include "standard.h"

static const char* const asset_vpaths[] = {
	/* asset_id_usr    */ "data/usr.img",
	/* asset_id_char   */ "data/char.img",
	/* asset_id_bullet */ "data/bullet.img",
	/* asset_id_enemy  */ "data/enemy.img"
};

static struct {
	FILE* pack;
	int pack_count;

	unsigned char memory[asset_memory];
	int memory_ptr;

	Bitmap bitmaps[bitmap_asset_count];
	int bitmap_count;
} asset_manager;

void* asset_mgr_alloc(int size) {
	void* a;

	a = &asset_manager.memory[asset_manager.memory_ptr];
	asset_manager.memory_ptr += size;

#ifdef DEBUG
	if (asset_manager.memory_ptr > asset_memory) {
		platform_err("Out of asset memory.\n");
		platform_abort(error_out_of_memory);
	}
#endif

	return a;
}

/* Loading assets isn't that efficient. Too bad. */
int get_asset_info(const char* name, int* offset, int* size) {
	int head_size = 8, i;
	char buf[56];

	fseek(asset_manager.pack, head_size, SEEK_SET);

	for (i = 0; i < asset_manager.pack_count; i++) {
		fread(size,   4, 1,          asset_manager.pack);
		fread(offset, 4, 1,          asset_manager.pack);
		fread(buf,    1, sizeof buf, asset_manager.pack);

		if (string_equal(buf, name)) {
			return 1;
		}
	}

	return 0;
}

void load_assets() {
	int i, offset, size;
	const char* name;
	Bitmap* bmp;
	FILE* pack;
	char magic[4];

	asset_manager.bitmap_count = 0;

	pack = fopen("pack", "rb");
	if (!pack) {
		platform_err("Failed to open 'pack'. Did you delete it?");
		platform_abort(error_file_not_found);
	}

	asset_manager.pack = pack;

	fread(&asset_manager.pack_count, 4, 1, pack);

#define gi(e_) \
		name = asset_vpaths[i]; \
		if (get_asset_info(name, &offset, &size)) { \
			fseek(pack, offset, SEEK_SET); \
			e_ \
		} else { \
			platform_err( \
				"%s doesn't exist in the pack. " \
				"Is the pack corrupt?\n", \
				name \
			); \
			platform_abort(error_file_not_found); \
		}

	for (i = 0; i < bitmap_asset_count; i++) {
		gi({
			bmp = &asset_manager.bitmaps[asset_manager.bitmap_count++];
			fread(magic,   4, 1, pack);

			if (!string_equal(magic, "IMAG")) {
				platform_err("Invalid asset\n");
				platform_abort(error_invalid_asset);
			}

			fread(&bmp->w, 4, 1, pack);
			fread(&bmp->h, 4, 1, pack);
			size = bmp->w * bmp->h * sizeof *bmp->pixels;
			bmp->pixels = asset_mgr_alloc(size);
			fread(bmp->pixels, 1, size, pack);
		});
	}

#undef gi

	fclose(pack);
}

const Bitmap* get_bitmap(Asset_ID id) {
	return &asset_manager.bitmaps[id];
}