Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
9169 turbocat 1
/*
2
 * OpenTyrian: A modern cross-platform port of Tyrian
3
 * Copyright (C) 2007-2009  The OpenTyrian Development Team
4
 *
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.
9
 *
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.
14
 *
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
 */
19
#include "palette.h"
20
 
21
#include "file.h"
22
#include "nortsong.h"
23
#include "opentyr.h"
24
#include "video.h"
25
 
26
#include 
27
 
28
static Uint32 rgb_to_yuv( int r, int g, int b );
29
 
30
#define PALETTE_COUNT 23
31
 
32
Palette palettes[PALETTE_COUNT];
33
int palette_count;
34
 
35
static Palette palette;
36
Uint32 rgb_palette[256], yuv_palette[256];
37
 
38
Palette colors;
39
 
40
void JE_loadPals( void )
41
{
42
	FILE *f = dir_fopen_die(data_dir(), "palette.dat", "rb");
43
 
44
	palette_count = ftell_eof(f) / (256 * 3);
45
	assert(palette_count == PALETTE_COUNT);
46
 
47
	for (int p = 0; p < palette_count; ++p)
48
	{
49
		for (int i = 0; i < 256; ++i)
50
		{
51
			// The VGA hardware palette used only 6 bits per component, so the values need to be rescaled to
52
			// 8 bits. The naive way to do this is to simply do (c << 2), padding it with 0's, however this
53
			// makes the maximum value 252 instead of the proper 255. A trick to fix this is to use the upper 2
54
			// bits of the original value instead. This ensures that the value goes to 255 as the original goes
55
			// to 63.
56
 
57
			int c = getc(f);
58
			palettes[p][i].r = (c << 2) | (c >> 4);
59
			c = getc(f);
60
			palettes[p][i].g = (c << 2) | (c >> 4);
61
			c = getc(f);
62
			palettes[p][i].b = (c << 2) | (c >> 4);
63
		}
64
	}
65
 
66
	fclose(f);
67
}
68
 
69
void set_palette( Palette colors, unsigned int first_color, unsigned int last_color )
70
{
71
	SDL_Surface *const surface = SDL_GetVideoSurface();
72
	const uint bpp = surface->format->BitsPerPixel;
73
 
74
	for (uint i = first_color; i <= last_color; ++i)
75
	{
76
		palette[i] = colors[i];
77
 
78
		if (bpp != 8)
79
		{
80
			rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
81
			yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
82
		}
83
	}
84
 
85
	if (bpp == 8)
86
		SDL_SetColors(surface, palette, first_color, last_color - first_color + 1);
87
}
88
 
89
void set_colors( SDL_Color color, unsigned int first_color, unsigned int last_color )
90
{
91
	SDL_Surface *const surface = SDL_GetVideoSurface();
92
	const uint bpp = surface->format->BitsPerPixel;
93
 
94
	for (uint i = first_color; i <= last_color; ++i)
95
	{
96
		palette[i] = color;
97
 
98
		if (bpp != 8)
99
		{
100
			rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
101
			yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
102
		}
103
	}
104
 
105
	if (bpp == 8)
106
		SDL_SetColors(surface, palette, first_color, last_color - first_color + 1);
107
}
108
 
109
void init_step_fade_palette( int diff[256][3], Palette colors, unsigned int first_color, unsigned int last_color )
110
{
111
	for (unsigned int i = first_color; i <= last_color; i++)
112
	{
113
		diff[i][0] = (int)colors[i].r - palette[i].r;
114
		diff[i][1] = (int)colors[i].g - palette[i].g;
115
		diff[i][2] = (int)colors[i].b - palette[i].b;
116
	}
117
}
118
 
119
void init_step_fade_solid( int diff[256][3], SDL_Color color, unsigned int first_color, unsigned int last_color )
120
{
121
	for (unsigned int i = first_color; i <= last_color; i++)
122
	{
123
		diff[i][0] = (int)color.r - palette[i].r;
124
		diff[i][1] = (int)color.g - palette[i].g;
125
		diff[i][2] = (int)color.b - palette[i].b;
126
	}
127
}
128
 
129
void step_fade_palette( int diff[256][3], int steps, unsigned int first_color, unsigned int last_color )
130
{
131
	assert(steps > 0);
132
 
133
	SDL_Surface *const surface = SDL_GetVideoSurface();
134
	const uint bpp = surface->format->BitsPerPixel;
135
 
136
	for (unsigned int i = first_color; i <= last_color; i++)
137
	{
138
		int delta[3] = { diff[i][0] / steps, diff[i][1] / steps, diff[i][2] / steps };
139
 
140
		diff[i][0] -= delta[0];
141
		diff[i][1] -= delta[1];
142
		diff[i][2] -= delta[2];
143
 
144
		palette[i].r += delta[0];
145
		palette[i].g += delta[1];
146
		palette[i].b += delta[2];
147
 
148
		if (bpp != 8)
149
		{
150
			rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
151
			yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
152
		}
153
	}
154
 
155
	if (bpp == 8)
156
		SDL_SetColors(surface, palette, 0, 256);
157
}
158
 
159
 
160
void fade_palette( Palette colors, int steps, unsigned int first_color, unsigned int last_color )
161
{
162
	assert(steps > 0);
163
 
164
	SDL_Surface *const surface = SDL_GetVideoSurface();
165
	const uint bpp = surface->format->BitsPerPixel;
166
 
167
	static int diff[256][3];
168
	init_step_fade_palette(diff, colors, first_color, last_color);
169
 
170
	for (; steps > 0; steps--)
171
	{
172
		setdelay(1);
173
 
174
		step_fade_palette(diff, steps, first_color, last_color);
175
 
176
		if (bpp != 8)
177
			JE_showVGA();
178
 
179
		wait_delay();
180
	}
181
}
182
 
183
void fade_solid( SDL_Color color, int steps, unsigned int first_color, unsigned int last_color )
184
{
185
	assert(steps > 0);
186
 
187
	SDL_Surface *const surface = SDL_GetVideoSurface();
188
	const uint bpp = surface->format->BitsPerPixel;
189
 
190
	static int diff[256][3];
191
	init_step_fade_solid(diff, color, first_color, last_color);
192
 
193
	for (; steps > 0; steps--)
194
	{
195
		setdelay(1);
196
 
197
		step_fade_palette(diff, steps, first_color, last_color);
198
 
199
		if (bpp != 8)
200
			JE_showVGA();
201
 
202
		wait_delay();
203
	}
204
}
205
 
206
void fade_black( int steps )
207
{
208
	SDL_Color black = { 0, 0, 0 };
209
	fade_solid(black, steps, 0, 255);
210
}
211
 
212
void fade_white( int steps )
213
{
214
	SDL_Color white = { 255, 255, 255 };
215
	fade_solid(white, steps, 0, 255);
216
}
217
 
218
static Uint32 rgb_to_yuv( int r, int g, int b )
219
{
220
	int y = (r + g + b) >> 2,
221
	    u = 128 + ((r - b) >> 2),
222
	    v = 128 + ((-r + 2 * g - b) >> 3);
223
	return (y << 16) + (u << 8) + v;
224
}
225