1 /*
2 * gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
3 *
4 *
5 * Copyright © 2002-2015 Sylvain Rochet
6 *
7 * gtkatlantic is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <glib.h>
28 #include <string.h>
29
30 #include "eng_main.h"
31
32 /* Global handler */
33 _eng *eng;
34
35 /* ---- initialise engine */
eng_init()36 void eng_init() {
37 guint32 alpha, bright;
38
39 #if ENG_DEBUG
40 fprintf(stdout, "Initializing engine...\n");
41 #endif
42
43 eng = g_malloc0( sizeof(_eng) );
44 eng->obj = eng_list_new();
45 eng->frame = eng_list_new();
46
47 /* init alpha tables */
48 eng->alpha = g_malloc( sizeof(eng_alpha) );
49 for(alpha = 0 ; alpha < 256 ; alpha++) {
50 for(bright = 0 ; bright < 256 ; bright++) {
51 guint8 v = (bright * (alpha+1)) >> 8; /* alpha+1: 255*256 >> 8 = 255 */
52 eng->alpha->fg[alpha][bright] = v;
53 eng->alpha->bg[alpha][bright] = bright - v;
54 }
55 }
56 }
57
58 /* ---- close engine */
eng_close()59 void eng_close() {
60
61 if(!eng) return;
62
63 eng_frame_destroy_all();
64 eng_list_destroy(eng->obj);
65 eng_list_destroy(eng->frame);
66 if(eng->alpha) g_free(eng->alpha);
67 g_free(eng);
68
69 #if ENG_DEBUG
70 fprintf(stdout, "Closing engine...\n");
71 #endif
72 }
73
74 /* ---- create a new frame */
eng_frame_create()75 eng_frame* eng_frame_create() {
76
77 eng_frame *f;
78
79 f = g_malloc0( sizeof(eng_frame) );
80 eng_frame_reset(f);
81 f->compute = 1;
82 f->obj = eng_list_new();
83 f->zone_upd = eng_list_new();
84 f->entry = eng_list_append(eng->frame, f);
85
86 #if ENG_DEBUG
87 fprintf(stdout, "New Frame\n");
88 #endif
89
90 return(f);
91 }
92
93
94 /* ---- destroy a frame
95 *
96 * close also all pics
97 */
eng_frame_destroy(eng_frame * f)98 void eng_frame_destroy(eng_frame *f) {
99
100 eng_list_e *lst;
101
102 if(!f) return;
103 eng_list_remove_fast(f->entry);
104 while( (lst = eng_list_first(f->obj)))
105 eng_pic_free(lst->data);
106 eng_frame_reset(f);
107 eng_list_destroy(f->obj);
108 eng_list_destroy(f->zone_upd);
109 g_free(f);
110
111 #if ENG_DEBUG
112 fprintf(stdout, "Destroy frame\n");
113 #endif
114 }
115
116
117 /* ---- destroy all frames */
eng_frame_destroy_all()118 void eng_frame_destroy_all() {
119
120 eng_list_e *lst;
121
122 while( (lst = eng_list_first(eng->frame)))
123 eng_frame_destroy(lst->data);
124 }
125
126
127 /* ---- set to 0 all elements in struct */
eng_frame_reset(eng_frame * f)128 void eng_frame_reset(eng_frame *f) {
129
130 if(!f) return;
131
132 f->compute = 0;
133 f->width = 0;
134 f->height = 0;
135 if(f->memalloc > 0)
136 g_free(f->bufout);
137
138 f->memalloc = 0;
139
140 eng_frame_free_zoneupd(f);
141
142 f->num_zone = 0;
143 f->x_min = 0;
144 f->y_min = 0;
145 f->x_max = 0;
146 f->y_max = 0;
147 }
148
149
150 /* ---- free all zone update */
eng_frame_free_zoneupd(eng_frame * f)151 void eng_frame_free_zoneupd(eng_frame *f) {
152
153 eng_list_e *lst;
154
155 if(!f) return;
156 if(!f->zone_upd) return;
157
158 for(lst = eng_list_first(f->zone_upd) ; lst ; lst=lst->next)
159 g_free(lst->data);
160 eng_list_clean(f->zone_upd);
161 }
162
163
164 /* ---- compute yes this frame (for eng_create_frame_all() ) */
eng_frame_set_compute(eng_frame * f)165 void eng_frame_set_compute(eng_frame *f) {
166
167 if(!f) return;
168
169 f->compute = 1;
170 }
171
172
173 /* ---- compute no this frame (for eng_create_frame_all() ) */
eng_frame_unset_compute(eng_frame * f)174 void eng_frame_unset_compute(eng_frame *f) {
175
176 if(!f) return;
177
178 f->compute = 0;
179 }
180
181
182 /* ---- clean this frame *
183 * *
184 * In the same concept of minimizing memory usage, *
185 * with this function you can clean all memory *
186 * used for out buffer. *
187 * *
188 * Don't use between frame often drawed, *
189 * because engine do remake all frame, and not *
190 * just update this, finally engine can become *
191 * extremely slow. *
192 * *
193 * This is not dependant with minimizing memory mode *
194 * */
eng_frame_clean(eng_frame * f)195 void eng_frame_clean(eng_frame *f) {
196
197 if(!f) return;
198
199 if(f->memalloc > 0)
200 g_free(f->bufout);
201
202 f->memalloc = 0;
203
204 eng_frame_free_zoneupd(f);
205 /*
206 for(i = 1 ; i <= frame[frame_id]->lastpic ; i++ ) {
207
208 if(engine->active_frame[i])
209 frame[frame_id]->obj[i]->change = 1;
210 }
211 */
212 }
213
214
215 /* ---- set HEIGHT of a frame */
eng_frame_set_height(eng_frame * f,guint16 height)216 void eng_frame_set_height(eng_frame *f, guint16 height) {
217
218 if(!f) return;
219
220 f->height = height;
221 }
222
223
224 /* ---- set WIDTH of a frame */
eng_frame_set_width(eng_frame * f,guint16 width)225 void eng_frame_set_width(eng_frame *f, guint16 width) {
226
227 if(!f) return;
228
229 f->width = width;
230 }
231
232 /* ---- put in terminal all arguments of a frame */
eng_frame_showarg(eng_frame * f)233 void eng_frame_showarg(eng_frame *f) {
234
235 if(!f) return;
236
237 fprintf(stdout, "====== FRAME ======\n");
238 fprintf(stdout, " compute -> %d\n", f->compute);
239 fprintf(stdout, " width -> %d\n", f->width);
240 fprintf(stdout, " height -> %d\n", f->height);
241 fprintf(stdout, " ------\n");
242 fprintf(stdout, " memalloc -> %d bytes\n", f->memalloc);
243 fprintf(stdout, " num_zone -> %d\n", f->num_zone);
244 fprintf(stdout, "====================\n");
245 }
246
247
248 /* ---- create a new pic */
eng_pic_create(eng_frame * f)249 eng_obj* eng_pic_create(eng_frame *f) {
250
251 eng_obj *o;
252
253 o = g_malloc0( sizeof(eng_obj) );
254 eng_pic_reset(o);
255 o->show = 1;
256 o->frame = f;
257
258 o->entry_main = eng_list_append(eng->obj, o);
259 o->entry = eng_list_append(f->obj, o);
260
261 #if ENG_DEBUG
262 fprintf(stdout, "New Pic\n");
263 #endif
264
265 return(o);
266 }
267
268
269 /* ---- sent a call to destroy pic */
eng_pic_destroy(eng_obj * o)270 void eng_pic_destroy(eng_obj *o) {
271
272 if(!o) return;
273
274 o->destroy = 1;
275 o->change = 1;
276 }
277
278
279 /* ---- destroy pic */
eng_pic_free(eng_obj * o)280 void eng_pic_free(eng_obj *o) {
281
282 if(!o) return;
283
284 eng_list_remove_fast(o->entry);
285 eng_list_remove_fast(o->entry_main);
286
287 eng_pic_reset(o);
288 g_free(o);
289 o = NULL;
290
291 #if ENG_DEBUG
292 fprintf(stdout, "Destroy pic\n");
293 #endif
294 }
295
296
297 /* ---- set to 0 all elements in struct */
eng_pic_reset(eng_obj * o)298 void eng_pic_reset(eng_obj *o) {
299
300 if(!o) return;
301
302 o->show = 0;
303 o->destroy = 0;
304 o->x = 0;
305 o->y = 0;
306 o->z = 0;
307 o->width = 0;
308 o->height = 0;
309 o->have_alpha = 0;
310 o->have_bgcolor = 0;
311 o->alpha = 0;
312 o->bgcolor[0] = 0;
313 o->bgcolor[1] = 0;
314 o->bgcolor[2] = 0;
315 o->change = 0;
316 o->x_old = 0;
317 o->y_old = 0;
318 o->height_old = 0;
319 o->width_old = 0;
320 }
321
322
323 /* ---- show this pic */
eng_pic_show(eng_obj * o)324 void eng_pic_show(eng_obj *o) {
325
326 if(!o) return;
327
328 if(!o->show) {
329
330 o->show = 1;
331 o->change = 1;
332 }
333 }
334
335
336 /* ---- unshow this pic */
eng_pic_unshow(eng_obj * o)337 void eng_pic_unshow(eng_obj *o) {
338
339 if(!o) return;
340
341 if(o->show) {
342
343 o->show = 0;
344 o->change = 1;
345 }
346 }
347
348
349 /* ---- redraw this pic */
eng_pic_redraw(eng_obj * o)350 void eng_pic_redraw(eng_obj *o) {
351
352 if(!o) return;
353
354 o->change = 1;
355 }
356
357
358 /* ---- set X pos of pic */
eng_pic_set_x(eng_obj * o,guint16 x)359 void eng_pic_set_x(eng_obj *o, guint16 x) {
360
361 if(!o) return;
362
363 if(x != o->x) {
364
365 o->x = x;
366 o->change = 1;
367 }
368 }
369
370
371 /* ---- set Y pos of pic */
eng_pic_set_y(eng_obj * o,guint16 y)372 void eng_pic_set_y(eng_obj *o, guint16 y) {
373
374 if(!o) return;
375
376 if(y != o->y) {
377
378 o->y = y;
379 o->change = 1;
380 }
381 }
382
383
384 /* ---- set Z pos of pic */
eng_pic_set_z(eng_obj * o,guint16 z)385 void eng_pic_set_z(eng_obj *o, guint16 z) {
386
387 if(!o) return;
388
389 if(z != o->z) {
390
391 o->z = z;
392 o->change = 1;
393 }
394 }
395
396
397 /* ---- set HEIGHT of pic */
eng_pic_set_height(eng_obj * o,guint16 height)398 void eng_pic_set_height(eng_obj *o, guint16 height) {
399
400 if(!o) return;
401
402 if(height != o->height) {
403
404 o->height = height;
405 o->change = 1;
406 }
407 }
408
409
410 /* ---- set WIDTH of pic */
eng_pic_set_width(eng_obj * o,guint16 width)411 void eng_pic_set_width(eng_obj *o, guint16 width) {
412
413 if(!o) return;
414
415 if(width != o->width) {
416
417 o->width = width;
418 o->change = 1;
419 }
420 }
421
422
423 /* ---- set ALPHA value */
eng_pic_set_alpha(eng_obj * o,guint8 alpha)424 void eng_pic_set_alpha(eng_obj *o, guint8 alpha) {
425
426 if(!o) return;
427
428 if( !o->have_alpha || alpha != o->alpha) {
429
430 if(alpha == 0xff) { /* 100% opacity */
431
432 eng_pic_unset_alpha(o);
433 return;
434 }
435 o->alpha = alpha;
436 o->have_alpha = 1;
437 o->change = 1;
438 }
439 }
440
441
442 /* ---- UNset ALPHA value */
eng_pic_unset_alpha(eng_obj * o)443 void eng_pic_unset_alpha(eng_obj *o) {
444
445 if(!o) return;
446
447 if(o->have_alpha) {
448
449 o->alpha = 0;
450 o->have_alpha = 0;
451 o->change = 1;
452 }
453 }
454
455
456 /* ---- set BGCOLOR value */
eng_pic_set_bgcolor(eng_obj * o,guint32 bgcolor)457 void eng_pic_set_bgcolor(eng_obj *o, guint32 bgcolor) {
458
459 guint8 rgb[3];
460
461 if(!o) return;
462
463 rgb[0] = (bgcolor >> 16) & 0xff; // red
464 rgb[1] = (bgcolor >> 8) & 0xff; // green
465 rgb[2] = bgcolor & 0xff; // blue
466
467 if( !o->have_bgcolor || memcmp(&rgb, o->bgcolor, 3) ) {
468
469 memcpy(o->bgcolor, &rgb, 3);
470 o->have_bgcolor = 1;
471 o->change = 1;
472 }
473 }
474
475
476 /* ---- UNset BGCOLOR value */
eng_pic_unset_bgcolor(eng_obj * o)477 void eng_pic_unset_bgcolor(eng_obj *o) {
478
479 if(!o) return;
480
481 if(o->have_bgcolor) {
482
483 o->bgcolor[0] = 0;
484 o->bgcolor[1] = 0;
485 o->bgcolor[2] = 0;
486 o->have_bgcolor = 0;
487 o->change = 1;
488 }
489 }
490
491
492 /* ---- set pic buffer */
eng_pic_set_pixbuf(eng_obj * o,GdkPixbuf * pixbuff)493 void eng_pic_set_pixbuf(eng_obj *o, GdkPixbuf *pixbuff) {
494
495 if(!o) return;
496 if(!pixbuff) return;
497
498 o->pixbuf = pixbuff;
499 o->change = 1;
500 }
501
502
503 /* ---- put in terminal all arguments of a pic */
eng_pic_showarg(eng_obj * o)504 void eng_pic_showarg(eng_obj *o) {
505
506 if(!o) return;
507
508 fprintf(stdout, "== PIC ==\n");
509 fprintf(stdout, " show -> %d\n", o->show);
510 fprintf(stdout, " x -> %d\n", o->x);
511 fprintf(stdout, " y -> %d\n", o->y);
512 fprintf(stdout, " z -> %d\n", o->z);
513 fprintf(stdout, " width -> %d\n", o->width);
514 fprintf(stdout, " height -> %d\n", o->height);
515 fprintf(stdout, " have_alpha -> %d\n", o->have_alpha);
516 fprintf(stdout, " have_bgcolor -> %d\n", o->have_bgcolor);
517 fprintf(stdout, " alpha -> %d\n", o->alpha);
518 fprintf(stdout, " bgcolor[R] -> 0x%.2X\n", o->bgcolor[0]);
519 fprintf(stdout, " bgcolor[G] -> 0x%.2X\n", o->bgcolor[1]);
520 fprintf(stdout, " bgcolor[B] -> 0x%.2X\n", o->bgcolor[2]);
521 fprintf(stdout, " ------\n");
522 fprintf(stdout, " change -> %d\n", o->change);
523 fprintf(stdout, " x old -> %d\n", o->x_old);
524 fprintf(stdout, " y old -> %d\n", o->y_old);
525 fprintf(stdout, " width old -> %d\n", o->width_old);
526 fprintf(stdout, " height old -> %d\n", o->height_old);
527 fprintf(stdout, " ------\n");
528 if(eng_pic_test(o) )
529 fprintf(stdout, " test -> SUCCESS\n");
530 else
531 fprintf(stdout, " test -> ERROR\n");
532 fprintf(stdout, "====================\n");
533 }
534
535
536 /* ---- test if pic is good */
eng_pic_test(eng_obj * o)537 gboolean eng_pic_test(eng_obj *o) {
538
539 if(!o) return(FALSE);
540
541 /* test x & width */
542 if(o->x > o->frame->width - o->width) return(FALSE);
543
544 /* test y & height */
545 if(o->y > o->frame->height - o->height) return(FALSE);
546
547 return(TRUE);
548 }
549