1 /*
2  *	acolours.cc
3  *	Allocate and free the application colours.
4  *
5  *	By "application colours", I mean the colours used to draw
6  *	the windows, the menus and the map, as opposed to the
7  *	"game colours" which depend on the game (they're in the
8  *	PLAYPAL lump) and are used to draw the game graphics
9  *	(flats, textures, sprites...).
10  *
11  *	The game colours are handled in gcolour1.cc and gcolour2.cc.
12  *
13  *	AYM 1998-11-29
14  */
15 
16 
17 /*
18 This file is part of Yadex.
19 
20 Yadex incorporates code from DEU 5.21 that was put in the public domain in
21 1994 by Rapha�l Quinet and Brendon Wyber.
22 
23 The rest of Yadex is Copyright � 1997-2003 Andr� Majorel and others.
24 
25 This program is free software; you can redistribute it and/or modify it under
26 the terms of the GNU General Public License as published by the Free Software
27 Foundation; either version 2 of the License, or (at your option) any later
28 version.
29 
30 This program is distributed in the hope that it will be useful, but WITHOUT
31 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
32 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
33 
34 You should have received a copy of the GNU General Public License along with
35 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
36 Place, Suite 330, Boston, MA 02111-1307, USA.
37 */
38 
39 
40 #include "yadex.h"
41 #include "acolours.h"
42 #include "gfx.h"
43 #include "rgb.h"
44 
45 
46 typedef struct
47 {
48   rgb_c rgb;
49   char deleted;
50 } ac_table_entry_t;
51 
52 static ac_table_entry_t *table     = 0;  // The list
53 static acolour_t        table_size = 0;  // The size of the list
54 static acolour_t        ac_count   = 0;  // The number of entries really used
55 
56 
57 /*
58  *	add_app_colour
59  *	Add colour <rgb> to the list of application colours
60  *	and return a brand new application colour# for it.
61  */
add_app_colour(rgb_c rgb)62 pcolour_t add_app_colour (rgb_c rgb)
63 {
64   size_t i;
65 
66   for (i = 0; i < table_size; i++)
67     if (table[i].deleted)
68       break;
69 
70   if (i == table_size)
71   {
72     table_size++;
73     table = (ac_table_entry_t *) realloc (table, table_size * sizeof *table);
74     if (table == NULL)
75       fatal_error (msg_nomem);
76   }
77   ac_count++;
78   table[i].rgb     = rgb;
79   table[i].deleted = 0;
80   return i;
81 }
82 
83 
84 /*
85  *	delete_app_colour
86  *	Remove colour# <acn> from the list of application colours.
87  */
delete_app_colour(acolour_t acn)88 void delete_app_colour (acolour_t acn)
89 {
90   if (acn >= table_size)
91     fatal_error ("delete_app_colour called with non-existent colour %d", acn);
92   if (table[acn].deleted)
93     fatal_error ("colour %d deleted twice", acn);
94   ac_count--;
95   table[acn].deleted = 1;
96 }
97 
98 
99 /* FIXME a very quick-and-dirty way of preventing
100    changes to the list done between commit_() and
101    uncommit_() to corrupt things. */
102 static size_t committed_colours = 0;
103 
104 
105 /*
106  *	commit_app_colours
107  *	Return an array containing the physical colour numbers
108  *	for the application colours in the list.
109  */
commit_app_colours()110 pcolour_t *commit_app_colours ()
111 {
112   verbmsg ("colours: committing %d colours\n", ac_count);
113 
114   /* First create an array of RGB values
115      for all the colours in the list. */
116   verbmsg ("colours: rgb_values %p\n");
117   rgb_c *rgb_values = new rgb_c[ac_count];
118   rgb_c *rgb = rgb_values;
119   int items_on_line = 0;
120   for (size_t n = 0; n < table_size; n++)
121     if (! table[n].deleted)
122     {
123       if (items_on_line == 0)
124 	verbmsg ("colours: committing: ");
125       verbmsg ("%d ", int (rgb - rgb_values));
126       *rgb++ = table[n].rgb;
127       if (++items_on_line == 16)
128       {
129 	verbmsg ("\n");
130 	items_on_line = 0;
131       }
132     }
133   if (items_on_line != 0)
134     verbmsg ("\n");
135 
136   // Then do the actual allocation.
137   committed_colours = ac_count;
138   pcolour_t *app_colours = alloc_colours (rgb_values, committed_colours);
139   delete[] rgb_values;
140   return app_colours;
141 }
142 
143 
144 /*
145  *	uncommit_app_colours
146  *	Free all the colours that were allocated by alloc_app_colours().
147  *	They are _not_ removed from the list !
148  */
uncommit_app_colours(pcolour_t * app_colours)149 void uncommit_app_colours (pcolour_t *app_colours)
150 {
151   free_colours (app_colours, committed_colours);
152   committed_colours = 0;
153 }
154 
155 
156