Clean up the array copying for the new high scores list. It was way
[attac-man.git] / gfx.c
blobe55f96026e5e3ae09879144d753dfa14047ab38c
1 /*
2 Pacman Arena
3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid[] =
21 "$Id: gfx.c,v 1.11 2003/11/22 17:32:09 nsubtil Exp $";
23 #ifdef _WIN32
24 #include <windows.h>
25 #endif
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 #include "linked-lists.h"
34 #include "file.h"
35 #include "gfx.h"
37 struct image_rgba32 *images = NULL;
40 lê um ficheiro TGA não-comprimido de 32bpp
41 XXX - código horripilante
43 struct image_rgba32 *gfx_read_targa(char *fname)
45 FILE *fp;
46 struct raw_targa tga;
47 int c;
48 unsigned char *buf, sb;
49 struct image_rgba32 *bmp;
51 bmp = (struct image_rgba32 *)malloc(sizeof(struct image_rgba32));
52 if(bmp == NULL)
54 perror("malloc()");
55 exit(1);
57 memset(bmp, 0, sizeof(struct image_rgba32));
58 memset(&tga, 0, sizeof(struct raw_targa));
60 if((fp=file_open(fname)) == NULL) return NULL;
61 fread(&tga.id_len, sizeof(tga.id_len), 1, fp);
62 fread(&tga.cl_map, sizeof(tga.cl_map), 1, fp);
64 if(tga.cl_map==1)
66 fprintf(stderr, "read_targa(): color mapped images not supported\n");
67 fclose(fp);
68 return NULL;
71 fseek(fp, 12, SEEK_SET);
72 fread(&tga.width, sizeof(tga.width), 1, fp);
73 fread(&tga.height, sizeof(tga.height), 1, fp);
74 fread(&tga.bpp, sizeof(tga.bpp), 1, fp);
75 fseek(fp, tga.id_len+1, SEEK_CUR);
76 /*
77 bmp->x = tga.width;
78 bmp->y = tga.height;
79 bmp->bpp = (tga.bpp == 24 ? 32 : tga.bpp);
82 bmp->width = tga.width;
83 bmp->height = tga.height;
85 bmp->data=malloc(bmp->width*bmp->height*32/8);
86 /* bmp->data_32 = bmp->data;
87 bmp->data_16 = bmp->data;
88 bmp->data_8 = bmp->data;*/
90 if(bmp->data==NULL)
92 perror("malloc()");
93 exit(1);
95 buf=(unsigned char *)bmp->data;
97 if(tga.bpp==32 || tga.bpp==16)
99 int r;
101 r = ftell(fp);
102 r = fread(bmp->data, 1, 32/8*bmp->width*bmp->height, fp);
103 fclose(fp);
105 else
106 for(c=0;c<bmp->width*bmp->height;c++)
108 fread(&buf[c*4], 3, 1, fp);
109 buf[c*4+3]=0;
112 if(bmp->bpp==24)
114 bmp->bpp=32;
119 for(c=0;c<bmp->x*bmp->y;c++)
121 switch(bmp->bpp)
123 case 32:
124 case 24:
125 sb = bmp->data_32[c] & 0xFF000000;
126 bmp->data_32[c] = bmp->data_32[c] ^ (sb << 24) + bmp->data_32[c] & 0xFFFFFF;
127 bmp->data_32[c] |= (bmp->data_32[c] & 0xFF) << 24;
128 bmp->data_32[c] = bmp->data_32[c] ^ (bmp->data_32[c] & 0xFF) + bmp->data_32[c] & 0xFFFFFF00;
129 bmp->data_32[c] |= sb;
130 break;
135 for(c=0;c<bmp->width*bmp->height;c++)
137 switch(32)
139 case 32:
140 sb=buf[c*4];
141 buf[c*4]=buf[c*4+2];
142 buf[c*4+2]=sb;
143 break;
144 case 24:
145 sb=buf[c*3];
146 buf[c*3]=buf[c*3+2];
147 buf[c*3+2]=sb;
148 break;
152 bmp->name = strdup(fname);
153 bmp->id = -1;
154 bmp->filtered = 0;
155 bmp->next = NULL;
157 return bmp;
161 procura um bitmap já carregado
163 struct image_rgba32 *gfx_find(char *name)
165 struct image_rgba32 *cur;
167 cur = images;
168 while(cur)
170 if(strcmp(cur->name, name) == 0)
171 return cur;
173 cur = cur->next;
176 return NULL;
180 devolve um bitmap, carregando do ficheiro se necessário
182 struct image_rgba32 *gfx_get(char *name)
184 struct image_rgba32 *ret;
186 ret = gfx_find(name);
187 if(ret == NULL)
189 ret = gfx_read_targa(name);
190 if (!ret) {
191 printf("Unable to load graphic %s\n", name);
192 exit(1);
194 LLIST_ADD(struct image_rgba32, images, ret);
197 return ret;
201 altera o canal alpha da textura para a intensidade da cor em cada pixel
203 void gfx_alpha_from_intensity(char *name)
205 int x, y;
206 struct image_rgba32 *img;
208 img = gfx_get(name);
209 if(img == NULL)
210 return;
212 for(x = 0; x < img->width; x++)
213 for(y = 0; y < img->height; y++)
215 unsigned char *ptr;
217 ptr = (unsigned char *)((unsigned long)img->data + (x + y * img->width) * 4);
219 ptr[2] = (ptr[0] + ptr[1] + ptr[2]) / 3;
224 altera o canal alpha da textura para transparente em pixels de uma determinada cor
226 void gfx_alpha_from_key(char *name, unsigned char r, unsigned char g, unsigned char b)
228 int c;
229 struct image_rgba32 *img;
230 unsigned char *ptr;
232 img = gfx_get(name);
233 if(img == NULL)
234 return;
236 ptr = (unsigned char *)img->data;
238 for(c = 0; c < img->width * img->height; c++)
240 if(ptr[0] == r && ptr[1] == g && ptr[2] == b)
241 ptr[3] = 0;
242 else
243 ptr[3] = 0xff;
245 ptr += 4;
250 adiciona uma textura à lista
252 void gfx_add(struct image_rgba32 *new)
254 if(gfx_find(new->name))
256 printf("gfx_add: bitmap repetido: %s\n", new->name);
257 return;
260 LLIST_ADD(struct image_rgba32, images, new);
264 carrega uma textura na placa gráfica
266 GLuint gfx_upload_texture(char *name)
268 struct image_rgba32 *texture;
269 GLuint id;
271 texture = gfx_get(name);
272 if(texture == NULL)
274 printf("gfx_upload_texture: %s não existe\n", name);
275 return -1;
278 texture->filtered = 1;
280 glGenTextures(1, &id);
281 glBindTexture(GL_TEXTURE_2D, id);
283 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
288 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
290 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texture->width, texture->height, GL_RGBA, GL_UNSIGNED_BYTE, texture->data);
292 texture->id = id;
293 return id;
297 carrega uma textura sem filtragem & afins
299 GLuint gfx_upload_texture_nofilter(char *name)
301 struct image_rgba32 *texture;
302 GLuint id;
304 texture = gfx_get(name);
305 if(texture == NULL)
307 printf("gfx_upload_texture_no_filter: %s não existe\n", name);
308 return -1;
311 texture->filtered = 0;
313 glGenTextures(1, &id);
314 glBindTexture(GL_TEXTURE_2D, id);
316 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
317 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
318 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
319 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
321 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width, texture->height,
322 0, GL_RGBA, GL_UNSIGNED_BYTE, texture->data);
324 texture->id = id;
325 return id;
329 liberta todas as texturas na placa gráfica
331 void gfx_unload_all(void)
333 struct image_rgba32 *cur;
335 cur = images;
337 while(cur)
339 if(cur->id != (GLuint)-1)
341 glDeleteTextures(1, &cur->id);
342 cur->id = -1;
345 cur = cur->next;
350 envia todas as texturas para a placa gráfica
352 void gfx_reload_all(void)
354 struct image_rgba32 *cur;
356 cur = images;
357 while(cur)
359 if(cur->filtered)
360 gfx_upload_texture(cur->name);
361 else
362 gfx_upload_texture_nofilter(cur->name);
364 cur = cur->next;