1 /*
2  * enigma/memory.c - memory management routines.
3  *
4  * Copyright 2000 Simon Tatham. All rights reserved.
5  *
6  * Enigma is licensed under the MIT licence. See the file LICENCE for
7  * details.
8  *
9  * - we are all amf -
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <assert.h>
15 #include <string.h>
16 
17 #include "enigma.h"
18 
smalloc(size_t size)19 void *smalloc(size_t size) {
20     void *p = malloc(size);
21     if (!p)
22 	fatal("Out of memory");
23     return p;
24 }
25 
srealloc(void * q,size_t size)26 void *srealloc(void *q, size_t size) {
27     void *p = realloc(q, size);
28     if (!p)
29 	fatal("Out of memory");
30     return p;
31 }
32 
sfree(void * q)33 void sfree(void *q) {
34     if (q)
35 	free(q);
36 }
37 
dupstr(char * str)38 char *dupstr(char *str) {
39     char *p = (char *)smalloc(1+strlen(str));
40     strcpy(p, str);
41     return p;
42 }
43 
44 #define mknew(type) ( (type *)smalloc(sizeof(type)) )
45 #define mknewn(type, n) ( (type *)smalloc(sizeof(type) * n) )
46 #define renewn(p, type, n) ( (type *)srealloc(p, sizeof(type) * n) )
47 
gamestate_new(int width,int height,int flags)48 gamestate *gamestate_new(int width, int height, int flags) {
49     gamestate *p;
50 
51     p = mknew(gamestate);
52     p->leveldata = mknewn(char, width * height);
53     p->width = width;
54     p->height = height;
55     p->flags = flags;
56     p->sequence = NULL;
57     p->sequence_size = 0;
58 
59     return p;
60 }
61 
gamestate_copy(gamestate * state)62 gamestate *gamestate_copy(gamestate *state) {
63     gamestate *ret;
64 
65     ret = gamestate_new(state->width, state->height, state->flags);
66     ret->status = state->status;
67     memcpy(ret->leveldata, state->leveldata, ret->width * ret->height);
68     ret->player_x = state->player_x;
69     ret->player_y = state->player_y;
70     ret->gold_got = state->gold_got;
71     ret->gold_total = state->gold_total;
72     ret->levnum = state->levnum;
73     ret->title = state->title;
74     ret->movenum = state->movenum;
75     ret->sequence = smalloc(state->sequence_size);
76     memcpy(ret->sequence, state->sequence, state->movenum);
77     ret->sequence_size = state->sequence_size;
78 
79     return ret;
80 }
81 
gamestate_free(gamestate * p)82 void gamestate_free(gamestate *p) {
83     if (p) {
84 	if (p->leveldata) free(p->leveldata);
85 	if (p->sequence) free(p->sequence);
86 	free(p);
87     }
88 }
89 
level_new(void)90 level *level_new(void) {
91     level *p;
92 
93     p = mknew(level);
94     p->leveldata = NULL;
95 
96     return p;
97 }
98 
level_setsize(level * p,int width,int height)99 void level_setsize(level *p, int width, int height) {
100     assert(p != NULL);
101     if (p) {
102 	p->leveldata = mknewn(char, width * height);
103 	p->width = width;
104 	p->height = height;
105     }
106 }
107 
level_free(level * p)108 void level_free(level *p) {
109     if (p) {
110 	if (p->leveldata) free(p->leveldata);
111 	free(p);
112     }
113 }
114 
levelset_new(void)115 levelset *levelset_new(void) {
116     levelset *p;
117 
118     p = mknew(levelset);
119     p->levels = NULL;
120     p->nlevels = 0;
121 
122     return p;
123 }
124 
levelset_nlevels(levelset * p,int n)125 void levelset_nlevels(levelset *p, int n) {
126     p->levels = renewn(p->levels, level *, n);
127     while (p->nlevels < n)
128 	p->levels[p->nlevels++] = NULL;
129 }
130 
levelset_free(levelset * p)131 void levelset_free(levelset *p) {
132     if (p) {
133 	if (p->levels) {
134 	    int i;
135 	    for (i = 0; i < p->nlevels; i++)
136 		level_free(p->levels[i]);
137 	}
138 	free(p);
139     }
140 }
141