1 //********************************************************************************************
2 //*
3 //* This file is part of Egoboo.
4 //*
5 //* Egoboo is free software: you can redistribute it and/or modify it
6 //* under the terms of the GNU General Public License as published by
7 //* the Free Software Foundation, either version 3 of the License, or
8 //* (at your option) any later version.
9 //*
10 //* Egoboo is distributed in the hope that it will be useful, but
11 //* WITHOUT ANY WARRANTY; without even the implied warranty of
12 //* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 //* General Public License for more details.
14 //*
15 //* You should have received a copy of the GNU General Public License
16 //* along with Egoboo. If not, see <http://www.gnu.org/licenses/>.
17 //*
18 //********************************************************************************************
19
20 /// @file texture.c
21 /// @brief Implementation of code for controlling object texturing
22 /// @details
23
24 #include "texture.h"
25
26 #include "egoboo_fileutil.h"
27 #include "egoboo_math.inl"
28
29 //--------------------------------------------------------------------------------------------
30 //--------------------------------------------------------------------------------------------
31
32 INSTANTIATE_LIST( ACCESS_TYPE_NONE, oglx_texture_t, TxTexture, TX_TEXTURE_COUNT );
33
34 //--------------------------------------------------------------------------------------------
35 //--------------------------------------------------------------------------------------------
TxTexture_clear_data()36 void TxTexture_clear_data()
37 {
38 /// @details BB@> reset the free texture list. Start at TX_LAST so that the global textures/icons are
39 /// can't be allocated by mistake
40
41 int cnt, tnc;
42
43 for ( cnt = TX_LAST, tnc = 0; cnt < TX_TEXTURE_COUNT; cnt++, tnc++ )
44 {
45 TxTexture.free_ref[tnc] = cnt;
46 }
47 TxTexture.free_count = tnc;
48 }
49
50 //--------------------------------------------------------------------------------------------
TxTexture_init_all()51 void TxTexture_init_all()
52 {
53 /// @details ZZ@> This function clears out all of the textures
54
55 TX_REF cnt;
56
57 for ( cnt = 0; cnt < TX_TEXTURE_COUNT; cnt++ )
58 {
59 oglx_texture_ctor( TxTexture.lst + cnt );
60 }
61
62 TxTexture_clear_data();
63 }
64
65 //--------------------------------------------------------------------------------------------
TxTexture_release_all()66 void TxTexture_release_all()
67 {
68 /// @details ZZ@> This function releases all of the textures
69
70 TX_REF cnt;
71
72 for ( cnt = 0; cnt < TX_TEXTURE_COUNT; cnt++ )
73 {
74 oglx_texture_Release( TxTexture.lst + cnt );
75 }
76
77 TxTexture_clear_data();
78 }
79
80 //--------------------------------------------------------------------------------------------
TxTexture_delete_all()81 void TxTexture_delete_all()
82 {
83 /// @details ZZ@> This function clears out all of the textures
84
85 TX_REF cnt;
86
87 for ( cnt = 0; cnt < TX_TEXTURE_COUNT; cnt++ )
88 {
89 oglx_texture_dtor( TxTexture.lst + cnt );
90 }
91
92 TxTexture_clear_data();
93 }
94
95 //--------------------------------------------------------------------------------------------
TxTexture_reload_all()96 void TxTexture_reload_all()
97 {
98 /// @details ZZ@> This function re-loads all the current textures back into
99 /// OpenGL texture memory using the cached SDL surfaces
100
101 TX_REF cnt;
102
103 for ( cnt = 0; cnt < TX_TEXTURE_COUNT; cnt++ )
104 {
105 oglx_texture_t * ptex = TxTexture.lst + cnt;
106
107 if ( ptex->valid )
108 {
109 oglx_texture_Convert( ptex, ptex->surface, INVALID_KEY );
110 }
111 }
112 }
113
114 //--------------------------------------------------------------------------------------------
TxTexture_get_free(const TX_REF itex)115 TX_REF TxTexture_get_free( const TX_REF itex )
116 {
117 TX_REF retval = ( TX_REF )INVALID_TX_TEXTURE;
118
119 if ( itex >= 0 && itex < TX_LAST )
120 {
121 retval = itex;
122 oglx_texture_Release( TxTexture.lst + itex );
123 }
124 else if ( itex < 0 || itex >= TX_TEXTURE_COUNT )
125 {
126 if ( TxTexture.free_count > 0 )
127 {
128 TxTexture.free_count--;
129 TxTexture.update_guid++;
130
131 retval = TxTexture.free_ref[TxTexture.free_count];
132 }
133 else
134 {
135 retval = ( TX_REF )INVALID_TX_TEXTURE;
136 }
137 }
138 else
139 {
140 int i;
141
142 // grab the specified index
143 oglx_texture_Release( TxTexture.lst + ( TX_REF )itex );
144
145 // if this index is on the free stack, remove it
146 for ( i = 0; i < TxTexture.free_count; i++ )
147 {
148 if ( TxTexture.free_ref[i] == itex )
149 {
150 if ( TxTexture.free_count > 0 )
151 {
152 TxTexture.free_count--;
153 TxTexture.update_guid++;
154
155 SWAP( size_t, TxTexture.free_ref[i], TxTexture.free_ref[TxTexture.free_count] );
156 }
157 break;
158 }
159 }
160 }
161
162 return retval;
163 }
164
165 //--------------------------------------------------------------------------------------------
TxTexture_free_one(const TX_REF itex)166 bool_t TxTexture_free_one( const TX_REF itex )
167 {
168 if ( itex < 0 || itex >= TX_TEXTURE_COUNT ) return bfalse;
169
170 // release the texture
171 oglx_texture_Release( TxTexture.lst + itex );
172
173 #if defined(_DEBUG)
174 {
175 int cnt;
176 // determine whether this texture is already in the list of free textures
177 // that is an error
178 for ( cnt = 0; cnt < TxTexture.free_count; cnt++ )
179 {
180 if ( itex == TxTexture.free_ref[cnt] ) return bfalse;
181 }
182 }
183 #endif
184
185 if ( TxTexture.free_count >= TX_TEXTURE_COUNT )
186 return bfalse;
187
188 // do not put anything below TX_LAST back onto the SDL_free stack
189 if ( itex >= TX_LAST )
190 {
191 TxTexture.free_ref[TxTexture.free_count] = REF_TO_INT( itex );
192
193 TxTexture.free_count++;
194 TxTexture.update_guid++;
195 }
196
197 return btrue;
198 }
199
200 //--------------------------------------------------------------------------------------------
TxTexture_load_one_vfs(const char * filename,const TX_REF itex_src,Uint32 key)201 TX_REF TxTexture_load_one_vfs( const char *filename, const TX_REF itex_src, Uint32 key )
202 {
203 /// @details BB@> load a texture into TxTexture.
204 /// If INVALID_TX_TEXTURE == itex, then we just get the next free index
205
206 TX_REF retval;
207
208 // get a texture index.
209 retval = TxTexture_get_free( itex_src );
210
211 // handle an error
212 if ( retval >= 0 && retval < TX_TEXTURE_COUNT )
213 {
214 Uint32 txid = ego_texture_load_vfs( TxTexture.lst + retval, filename, key );
215 if ( INVALID_GL_ID == txid )
216 {
217 TxTexture_free_one( retval );
218 retval = INVALID_TX_TEXTURE;
219 }
220 }
221
222 return retval;
223 }
224
225 //--------------------------------------------------------------------------------------------
TxTexture_get_ptr(const TX_REF itex)226 oglx_texture_t * TxTexture_get_ptr( const TX_REF itex )
227 {
228 oglx_texture_t * ptex;
229
230 if ( itex < 0 || itex >= TX_TEXTURE_COUNT ) return NULL;
231 ptex = TxTexture.lst + itex;
232
233 if ( !oglx_texture_Valid( ptex ) )
234 return NULL;
235
236 return ptex;
237 }
238