1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: objects.cpp
5 Desc: contains object constructors and deconstructors
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12 #include <new>
13 #include "main.hpp"
14 #include "entity.hpp"
15
16 /*-------------------------------------------------------------------------------
17
18 defaultDeconstructor
19
20 Frees the memory occupied by a typical node's data. Do not use for more
21 complex nodes that malloc extraneous data to themselves!
22
23 -------------------------------------------------------------------------------*/
24
defaultDeconstructor(void * data)25 void defaultDeconstructor(void* data)
26 {
27 if (data != NULL)
28 {
29 free(data);
30 }
31 }
32
33 /*-------------------------------------------------------------------------------
34
35 stringDeconstructor
36
37 Frees the memory occupied by a string.
38
39 -------------------------------------------------------------------------------*/
40
stringDeconstructor(void * data)41 void stringDeconstructor(void* data)
42 {
43 string_t* string;
44 if (data != NULL)
45 {
46 string = (string_t*)data;
47 if ( string->data != NULL )
48 {
49 free(string->data);
50 string->data = NULL;
51 }
52 free(data);
53 }
54 }
55
56 /*-------------------------------------------------------------------------------
57
58 emptyDeconstructor
59
60 Useful to remove a node without deallocating its data.
61
62 -------------------------------------------------------------------------------*/
63
emptyDeconstructor(void * data)64 void emptyDeconstructor(void* data)
65 {
66 return;
67 }
68
69 /*-------------------------------------------------------------------------------
70
71 entityDeconstructor
72
73 Frees the memory occupied by a node pointing to an entity
74
75 -------------------------------------------------------------------------------*/
76
entityDeconstructor(void * data)77 void entityDeconstructor(void* data)
78 {
79 Entity* entity;
80
81 if ( data != nullptr )
82 {
83 entity = (Entity*)data;
84
85 //TODO: If I am part of the creaturelist, remove my node from that list.)
86
87 //free(data);
88 delete entity;
89 }
90 }
91
92 /*-------------------------------------------------------------------------------
93
94 lightDeconstructor
95
96 Frees the memory occupied by a node pointing to a light
97
98 -------------------------------------------------------------------------------*/
99
lightDeconstructor(void * data)100 void lightDeconstructor(void* data)
101 {
102 Sint32 x, y;
103 light_t* light;
104
105 if ( data != NULL)
106 {
107 light = (light_t*)data;
108 if ( light->tiles != NULL )
109 {
110 for (y = 0; y < light->radius * 2; y++)
111 {
112 for (x = 0; x < light->radius * 2; x++)
113 {
114 if ( x + light->x - light->radius >= 0 && x + light->x - light->radius < map.width )
115 if ( y + light->y - light->radius >= 0 && y + light->y - light->radius < map.height )
116 {
117 lightmap[(y + light->y - light->radius) + (x + light->x - light->radius)*map.height] -= light->tiles[y + x * (light->radius * 2 + 1)];
118 }
119 }
120 }
121 free(light->tiles);
122 }
123 free(data);
124 }
125 }
126
127 /*-------------------------------------------------------------------------------
128
129 mapDeconstructor
130
131 Frees the memory occupied by a node pointing to a map
132
133 -------------------------------------------------------------------------------*/
134
mapDeconstructor(void * data)135 void mapDeconstructor(void* data)
136 {
137 map_t* map;
138
139 if ( data != nullptr )
140 {
141 map = (map_t*)data;
142 if ( map->tiles != nullptr )
143 {
144 free(map->tiles);
145 }
146 if ( map->creatures )
147 {
148 list_FreeAll(map->creatures); //TODO: This needed?
149 delete map->creatures;
150 }
151 if ( map->entities != nullptr )
152 {
153 list_FreeAll(map->entities);
154 free(map->entities);
155 }
156 free(data);
157 }
158 }
159
160 /*-------------------------------------------------------------------------------
161
162 listDeconstructor
163
164 Frees the memory occupied by a node pointing to a list
165
166 -------------------------------------------------------------------------------*/
167
listDeconstructor(void * data)168 void listDeconstructor(void* data)
169 {
170 list_t* list;
171
172 if (data != NULL)
173 {
174 list = (list_t*)data;
175 list_FreeAll(list);
176 free(data);
177 }
178 }
179
180 /*-------------------------------------------------------------------------------
181
182 newEntity
183
184 Creates a new entity with empty settings and places it in the entity list
185
186 -------------------------------------------------------------------------------*/
187
newEntity(Sint32 sprite,Uint32 pos,list_t * entlist,list_t * creaturelist)188 Entity* newEntity(Sint32 sprite, Uint32 pos, list_t* entlist, list_t* creaturelist)
189 {
190 Entity* entity = nullptr;
191
192 // allocate memory for entity
193 /*if( (entity = (Entity *) malloc(sizeof(Entity)))==NULL ) {
194 printlog( "failed to allocate memory for new entity!\n" );
195 exit(1);
196 }*/
197 bool failedToAllocate = false;
198 try
199 {
200 entity = new Entity(sprite, pos, entlist, creaturelist);
201 }
202 catch (std::bad_alloc& ba)
203 {
204 failedToAllocate = true;
205 }
206
207 if ( failedToAllocate || !entity )
208 {
209 printlog("failed to allocate memory for new entity!\n");
210 exit(1);
211 }
212
213 return entity;
214 }
215
216 /*-------------------------------------------------------------------------------
217
218 newButton
219
220 Creates a new button and places it in the button list
221
222 -------------------------------------------------------------------------------*/
223
newButton(void)224 button_t* newButton(void)
225 {
226 button_t* button;
227
228 // allocate memory for button
229 if ( (button = (button_t*) malloc(sizeof(button_t))) == NULL )
230 {
231 printlog( "failed to allocate memory for new button!\n" );
232 exit(1);
233 }
234
235 // add the button to the button list
236 button->node = list_AddNodeLast(&button_l);
237 button->node->element = button;
238 button->node->deconstructor = &defaultDeconstructor;
239 button->node->size = sizeof(button_t);
240
241 // now set all of my data elements to ZERO or NULL
242 button->x = 0;
243 button->y = 0;
244 button->sizex = 0;
245 button->sizey = 0;
246 button->visible = 1;
247 button->focused = 0;
248 button->key = 0;
249 button->joykey = -1;
250 button->pressed = false;
251 button->needclick = true;
252 button->action = NULL;
253 strcpy(button->label, "nodef");
254
255 button->outline = false;
256
257 return button;
258 }
259
260 /*-------------------------------------------------------------------------------
261
262 newLight
263
264 Creates a new light and places it in the light list
265
266 -------------------------------------------------------------------------------*/
267
newLight(Sint32 x,Sint32 y,Sint32 radius,Sint32 intensity)268 light_t* newLight(Sint32 x, Sint32 y, Sint32 radius, Sint32 intensity)
269 {
270 light_t* light;
271
272 // allocate memory for light
273 if ( (light = (light_t*) malloc(sizeof(light_t))) == NULL )
274 {
275 printlog( "failed to allocate memory for new light!\n" );
276 exit(1);
277 }
278
279 // add the light to the light list
280 light->node = list_AddNodeLast(&light_l);
281 light->node->element = light;
282 light->node->deconstructor = &lightDeconstructor;
283 light->node->size = sizeof(light_t);
284
285 // now set all of my data elements to ZERO or NULL
286 light->x = x;
287 light->y = y;
288 light->radius = radius;
289 light->intensity = intensity;
290 if ( light->radius > 0 )
291 {
292 light->tiles = (Sint32*) malloc(sizeof(Sint32) * (radius * 2 + 1) * (radius * 2 + 1));
293 memset(light->tiles, 0, sizeof(Sint32) * (radius * 2 + 1) * (radius * 2 + 1));
294 }
295 else
296 {
297 light->tiles = NULL;
298 }
299 return light;
300 }
301
302 /*-------------------------------------------------------------------------------
303
304 newString
305
306 Creates a new string and places it in a list
307
308 -------------------------------------------------------------------------------*/
309
newString(list_t * list,Uint32 color,char const * const content,...)310 string_t* newString(list_t* list, Uint32 color, char const * const content, ...)
311 {
312 string_t* string;
313 char str[1024] = { 0 };
314 va_list argptr;
315 int c, i;
316
317 // allocate memory for string
318 if ( (string = (string_t*) malloc(sizeof(string_t))) == NULL )
319 {
320 printlog( "failed to allocate memory for new string!\n" );
321 exit(1);
322 }
323
324 if ( content )
325 {
326 if ( strlen(content) > 2048 )
327 {
328 printlog( "error creating new string: buffer overflow.\n" );
329 exit(1);
330 }
331 }
332
333 string->color = color;
334 string->lines = 1;
335 if ( content != NULL )
336 {
337 // format the content
338 va_start( argptr, content );
339 i = vsnprintf(str, 1023, content, argptr);
340 va_end( argptr );
341 string->data = (char*) malloc(sizeof(char) * (i + 1));
342 if ( !string->data )
343 {
344 printlog( "error creating new string: couldn't allocate string data.\n" );
345 exit(1);
346 }
347 memset(string->data, 0, sizeof(char) * (i + 1));
348 for ( c = 0; c < i; c++ )
349 {
350 if ( str[c] == 10 ) // line feed
351 {
352 string->lines++;
353 }
354 }
355 strncpy(string->data, str, i);
356 }
357 else
358 {
359 string->data = NULL;
360 }
361
362 // add the string to the list
363 if ( list != NULL )
364 {
365 string->node = list_AddNodeLast(list);
366 string->node->element = string;
367 string->node->deconstructor = &stringDeconstructor;
368 string->node->size = sizeof(string_t);
369 }
370 else
371 {
372 string->node = NULL;
373 }
374
375 return string;
376 }
377
378 /*-------------------------------------------------------------------------------
379
380 newPathnode
381
382 Creates a new pathnode and places it in a list
383
384 -------------------------------------------------------------------------------*/
385
newPathnode(list_t * list,Sint32 x,Sint32 y,pathnode_t * parent,Sint8 pos)386 pathnode_t* newPathnode(list_t* list, Sint32 x, Sint32 y, pathnode_t* parent, Sint8 pos)
387 {
388 pathnode_t* pathnode;
389
390 // allocate memory for pathnode
391 if ( (pathnode = (pathnode_t*) malloc(sizeof(pathnode_t))) == NULL )
392 {
393 printlog( "failed to allocate memory for new pathnode!\n" );
394 exit(1);
395 }
396
397 // assign values
398 pathnode->x = x;
399 pathnode->y = y;
400 pathnode->parent = parent;
401 pathnode->g = 0;
402 pathnode->h = 0;
403
404 // add the pathnode to the list
405 if ( !pos )
406 {
407 pathnode->node = list_AddNodeFirst(list);
408 }
409 else
410 {
411 pathnode->node = list_AddNodeLast(list);
412 }
413 pathnode->node->element = pathnode;
414 pathnode->node->deconstructor = &defaultDeconstructor;
415 pathnode->node->size = sizeof(pathnode_t);
416
417 return pathnode;
418 }
419