]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/md3model/mdlimage.cpp
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / plugins / md3model / mdlimage.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant 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    GtkRadiant 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 GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "mdlimage.h"
23
24 #include <math.h>
25 #include <stdlib.h>
26
27 #include "ifilesystem.h"
28 #include "bytestreamutils.h"
29
30 #include "stream/textstream.h"
31 #include "imagelib.h"
32
33 #include "mdlformat.h"
34 #include "ident.h"
35
36
37 unsigned char mdl_palette[768];
38
39 /*
40    ==============
41    Texture_InitPalette
42    ==============
43  */
44 void Texture_InitPalette(byte *pal)
45 {
46     int r, g, b;
47     int i;
48     int inf;
49     byte gammatable[256];
50     double gamma;
51
52     gamma = 1.0; //g_qeglobals.d_savedinfo.fGamma;
53
54     if (gamma == 1.0) {
55         for (i = 0; i < 256; i++) {
56             gammatable[i] = i;
57         }
58     } else {
59         for (i = 0; i < 256; i++) {
60             inf = (int) (255 * pow((i + 0.5) / 255.5, gamma) + 0.5);
61             if (inf < 0) {
62                 inf = 0;
63             }
64             if (inf > 255) {
65                 inf = 255;
66             }
67             gammatable[i] = inf;
68         }
69     }
70
71     for (i = 0; i < 256; i++) {
72         r = gammatable[pal[0]];
73         g = gammatable[pal[1]];
74         b = gammatable[pal[2]];
75         pal += 3;
76
77         //v = (r<<24) + (g<<16) + (b<<8) + 255;
78         //v = BigLong (v);
79
80         //mdl_palette[i] = v;
81         mdl_palette[i * 3 + 0] = r;
82         mdl_palette[i * 3 + 1] = g;
83         mdl_palette[i * 3 + 2] = b;
84     }
85 }
86
87 bool LoadPalette()
88 {
89     unsigned char *buffer;
90     //int len =
91     vfsLoadFile("gfx/palette.lmp", (void **) &buffer);
92     if (buffer == 0) {
93         return false;
94     }
95
96     Texture_InitPalette(buffer);
97
98     vfsFreeFile(buffer);
99
100     return true;
101 }
102
103 Image *LoadMDLImageBuff(byte *buffer)
104 {
105     if (!LoadPalette()) {
106         return 0;
107     }
108
109     if (!ident_equal(buffer, MDL_IDENT)) {
110         globalErrorStream() << "LoadMDLImage: data has wrong ident\n";
111         return 0;
112     }
113
114     PointerInputStream inputStream(buffer);
115     inputStream.seek(4 + 4 + 12 + 12 + 4 + 12);
116     //int numskins =
117     istream_read_int32_le(inputStream);
118     int skinwidth = istream_read_int32_le(inputStream);
119     int skinheight = istream_read_int32_le(inputStream);
120     inputStream.seek(4 + 4 + 4 + 4 + 4 + 4);
121
122     switch (istream_read_int32_le(inputStream)) {
123         case MDL_SKIN_SINGLE:
124             break;
125         case MDL_SKIN_GROUP:
126             int numskins = istream_read_int32_le(inputStream);
127             inputStream.seek(numskins * 4);
128             break;
129     }
130
131     RGBAImage *image = new RGBAImage(skinwidth, skinheight);
132     unsigned char *pRGBA = image->getRGBAPixels();
133
134     for (int i = 0; i < (skinheight); i++) {
135         for (int j = 0; j < (skinwidth); j++) {
136             byte index = istream_read_byte(inputStream);
137             *pRGBA++ = mdl_palette[index * 3 + 0];
138             *pRGBA++ = mdl_palette[index * 3 + 1];
139             *pRGBA++ = mdl_palette[index * 3 + 2];
140             *pRGBA++ = 255;
141         }
142     }
143
144     return image;
145 }
146
147 Image *LoadMDLImage(ArchiveFile &file)
148 {
149     ScopedArchiveBuffer buffer(file);
150     return LoadMDLImageBuff(buffer.buffer);
151 }
152
153 void MDLImage_Destroy(byte *pic)
154 {
155     free(pic);
156 }