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