-
Notifications
You must be signed in to change notification settings - Fork 11
/
rolnfade.c
281 lines (235 loc) · 7.55 KB
/
rolnfade.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#include <stdlib.h>
#include <string.h>
#include "handy.h"
#include "acidwarp.h"
#include "rolnfade.h"
#include "palinit.h"
#include "display.h"
static int RedRollDirection = 0, GrnRollDirection = 0, BluRollDirection = 0;
static UINT FadeCompleteFlag = 0;
static UCHAR MainPalArray [256 * 3];
static UCHAR TargetPalArray [256 * 3];
static int paletteTypeNum = 0;
static int fade_dir = TRUE;
static void roll_rgb_palArray (UCHAR *MainpalArray);
static void maybeInvertSubPalRollDirection(void);
static int fadePalArrayToWhite (UCHAR *MainpalArray);
static int fadePalArrayToBlack (UCHAR *MainpalArray);
static int fadePalArrayToTarget (UCHAR *palArrayBeingChanged,
UCHAR *targetPalArray);
static void rotatebackward(int color, UCHAR *Pal)
{
int temp;
int x;
temp = Pal[((254)*3)+3+color];
for(x=(254); x >= 1; --x)
Pal[(x*3)+3+color] = Pal[(x*3)+color];
Pal[(1*3)+color] = temp;
}
static void rotateforward(int color, UCHAR *Pal)
{
int temp;
int x;
temp = Pal[(1*3)+color];
for(x=1; x < (256) ; ++x)
Pal[x*3+color] = Pal[(x*3)+3+color];
Pal[((256)*3)-3+color] = temp;
}
static void rollMainPalArrayAndLoadDACRegs(UCHAR *MainPalArray)
{
maybeInvertSubPalRollDirection();
roll_rgb_palArray(MainPalArray);
disp_setPalette(MainPalArray);
}
static void rolNFadeWhtMainPalArrayNLoadDAC(UCHAR *MainPalArray)
{
/* Fade to white, and keep the palette rolling while the fade is in progress. */
if (!FadeCompleteFlag)
{
if (fadePalArrayToWhite(MainPalArray) == DONE)
FadeCompleteFlag = 1;
rollMainPalArrayAndLoadDACRegs(MainPalArray);
}
}
static void rolNFadeBlkMainPalArrayNLoadDAC(UCHAR *MainPalArray)
{
/* Fade to black, and keep the palette rolling while the fade is in progress. */
if (!FadeCompleteFlag)
{
if (fadePalArrayToBlack (MainPalArray) == DONE)
FadeCompleteFlag = 1;
rollMainPalArrayAndLoadDACRegs(MainPalArray);
}
}
static void rolNFadeMainPalAryToTargNLodDAC(UCHAR *MainPalArray, UCHAR *TargetPalArray)
{
/* Fade from one palette to a new palette, and keep the palette rolling while the fade is in progress. */
if (!FadeCompleteFlag)
{
if (fadePalArrayToTarget (MainPalArray, TargetPalArray) == DONE)
FadeCompleteFlag = 1;
maybeInvertSubPalRollDirection();
roll_rgb_palArray ( MainPalArray);
roll_rgb_palArray (TargetPalArray);
disp_setPalette(MainPalArray);
}
else
rollMainPalArrayAndLoadDACRegs(MainPalArray);
}
/* WARNING! This is the function that handles the case of the SPECIAL PALETTE TYPE.
This palette type is special in that there is no specific palette assigned to its
palette number. Rather the palette is morphed from one static palette to another.
The effect is quite interesting.
*/
static void rolNFadMainPalAry2RndTargNLdDAC(UCHAR *MainPalArray,
UCHAR *TargetPalArray)
{
if (fadePalArrayToTarget (MainPalArray, TargetPalArray) == DONE)
initPalArray (TargetPalArray, RANDOM (NUM_PALETTE_TYPES));
maybeInvertSubPalRollDirection();
roll_rgb_palArray ( MainPalArray);
roll_rgb_palArray (TargetPalArray);
disp_setPalette(MainPalArray);
}
/**********************************************************************************/
/* These routines do the actual fading of a palette array to white, black,
or to the values of another ("target") palette array.
*/
static int fadePalArrayToWhite (UCHAR *palArray)
{
/* Returns DONE if the entire palette is white, else NOT_DONE */
int palByteNum, num_white = 0;
for (palByteNum = 3; palByteNum < 768; ++palByteNum)
{
if (palArray[palByteNum] < 63) /* Increment every color in the palette array until it becomes white. */
++palArray[palByteNum];
else
++num_white;
}
return ((num_white >= 765) ? DONE : NOT_DONE);
}
static int fadePalArrayToBlack (UCHAR *palArray)
{ /* Returns DONE if the entire palette is black, else NOT_DONE */
int palByteNum, num_black = 0;
for (palByteNum = 3; palByteNum < 768; ++palByteNum)
{
if (palArray[palByteNum] > 0) /* Decrement every color in the palette array until it becomes black. */
--palArray[palByteNum];
else
++num_black;
}
return ((num_black >= 765) ? DONE : NOT_DONE);
}
/* Increments (fades) every color in palArrayBeingChanged closer to the corresponding color in targetPalArray. */
static int fadePalArrayToTarget (UCHAR *palArrayBeingChanged,
UCHAR *targetPalArray)
{ /* Returns DONE if the two palette arrays are equal, else NOT_DONE. */
int palByteNum, num_equal = 0;
for (palByteNum = 3; palByteNum < 768; ++palByteNum)
{
if (palArrayBeingChanged[palByteNum] < targetPalArray[palByteNum])
++palArrayBeingChanged[palByteNum];
else if (palArrayBeingChanged[palByteNum] > targetPalArray[palByteNum])
--palArrayBeingChanged[palByteNum];
else
++num_equal;
}
return ((num_equal >= 765) ? DONE : NOT_DONE);
}
/**********************************************************************************/
/* Rolls the R, G, and B components of the palette ONE place in the direction specified by r, g, and b. */
static void roll_rgb_palArray(UCHAR *Pal)
{
if (!RedRollDirection)
rotateforward(RED,Pal);
else
rotatebackward(RED,Pal);
if(!GrnRollDirection)
rotateforward(GREEN,Pal);
else
rotatebackward(GREEN,Pal);
if(!BluRollDirection)
rotateforward(BLUE,Pal);
else
rotatebackward(BLUE,Pal);
}
/* This routine switches the current direction of one of the sub-palettes (R, G, or B) with probability
* 1/DIRECTN_CHANGE_PERIOD_IN_TICKS, when it is called by the timer ISR. Only one color direction can change at a time.
*/
static void maybeInvertSubPalRollDirection(void)
{
switch (RANDOM(DIRECTN_CHANGE_PERIOD_IN_TICKS))
{
case 0 :
RedRollDirection = !RedRollDirection;
break;
case 1 :
GrnRollDirection = !GrnRollDirection;
break;
case 2 :
BluRollDirection = !BluRollDirection;
break;
}
}
void newPalette(void)
{
paletteTypeNum = RANDOM(NUM_PALETTE_TYPES + 1);
if (paletteTypeNum >= NUM_PALETTE_TYPES) {
/* Beginning special morphing palette */
initPalArray(TargetPalArray, RANDOM(NUM_PALETTE_TYPES));
} else {
/* Fading to specific constant palette */
initPalArray(TargetPalArray, paletteTypeNum);
FadeCompleteFlag = FALSE; /* Fade-in needed next */
}
}
/* This does not return status because a constantly
* morphing palette never finishes morphing.
*/
void fadeInAndRotate(void)
{
if (paletteTypeNum == NUM_PALETTE_TYPES) {
rolNFadMainPalAry2RndTargNLdDAC(MainPalArray,TargetPalArray);
} else if (!FadeCompleteFlag) {
rolNFadeMainPalAryToTargNLodDAC(MainPalArray,TargetPalArray);
} else {
rollMainPalArrayAndLoadDACRegs(MainPalArray);
}
}
void beginFadeOut(int toblack)
{
if (toblack || RANDOM(2) == 0) {
fade_dir = 1;
} else {
fade_dir = 0;
}
FadeCompleteFlag = 0;
}
/* Returns 1 when faded completely to white or black */
int fadeOut(void)
{
if (fade_dir) {
rolNFadeBlkMainPalArrayNLoadDAC(MainPalArray);
} else {
rolNFadeWhtMainPalArrayNLoadDAC(MainPalArray);
}
return FadeCompleteFlag;
}
/* Normally, palette is applied automatically. This only needs to be
* called from outside rolnfade.c when a new SDL surface is created
* and colour cycling is paused.
*/
void applyPalette(void)
{
disp_setPalette(MainPalArray);
}
void initRolNFade(int logo)
{
if (logo) {
initPalArray(MainPalArray, RGBW_LIGHTNING_PAL);
memcpy(TargetPalArray, MainPalArray, sizeof(TargetPalArray));
} else {
memset(MainPalArray, 0, sizeof(MainPalArray));
}
applyPalette();
}