00001
00002 #include "revolt.h"
00003 #include "piano.h"
00004 #include "draw.h"
00005 #include "geom.h"
00006 #include "trigger.h"
00007 #include "sfx.h"
00008 #include "ctrlread.h"
00009 #include "object.h"
00010 #include "player.h"
00011
00012
00013
00014 static float PianoKeys[PIANO_KEY_NUM];
00015 static float BlackPianoKeys[BLACK_PIANO_KEY_NUM];
00016
00017 static long KeyTypeTable[] = {
00018 1, 0, 0, 2,
00019 1, 0, 2,
00020 1, 0, 0, 2,
00021 1, 0, 2,
00022 1, 0, 0, 2,
00023 1, 0, 2,
00024 1, 0, 0, 2,
00025 1, 0, 2,
00026 1, 0, 0, 2,
00027 };
00028
00029 static float KeyTexTable[] = {
00030 PIANO_TU1, PIANO_TU2, PIANO_TU3,
00031 };
00032
00033 static long BlackKeyNumbers[] = {
00034 1, 2, 3,
00035 5, 6,
00036 8, 9, 10,
00037 12, 13,
00038 15, 16, 17,
00039 19, 20,
00040 22, 23, 24,
00041 26, 27,
00042 29, 30, 31,
00043 };
00044
00045 static long RainbowCols[] = {
00046 0xff0c07,
00047 0xff4700,
00048 0xffe300,
00049 0x09c31f,
00050 0x0282ff,
00051 0x1000b9,
00052 0xa000e1,
00053 };
00054
00055 static long RgbCols[] = {
00056 0xff0000,
00057 0x00ff00,
00058 0x0000ff,
00059 };
00060
00062
00064
00065 void TriggerPiano(PLAYER *player, long flag, long n, VEC *vec)
00066 {
00067 long i, j, key, col, gotblack;
00068 float x, z, f;
00069 DRAW_3D_POLY *poly;
00070 CAR *car;
00071
00072 car = &player->car;
00073
00074
00075
00076 if (flag & TRIGGER_GLOBAL_FIRST)
00077 for (i = 0 ; i < PIANO_KEY_NUM ; i++)
00078 PianoKeys[i] = 0;
00079
00080
00081
00082 for (i = 0 ; i < CAR_NWHEELS ; i++) if (IsWheelPresent(&car->Wheel[i]))
00083 {
00084
00085
00086
00087 if (IsWheelInContact(&car->Wheel[i]))
00088 {
00089
00090
00091
00092 x = car->Wheel[i].WPos.v[X] - PIANO_XPOS;
00093 z = car->Wheel[i].WPos.v[Z] - PIANO_ZPOS;
00094
00095 if (x >= 0 && x <= PIANO_WIDTH && z >= 0 && z <= PIANO_DEPTH)
00096 {
00097
00098
00099
00100 gotblack = FALSE;
00101 if (z > (PIANO_DEPTH - BLACK_PIANO_DEPTH))
00102 {
00103 key = (long)((x + PIANO_KEY_WIDTH / 2) / PIANO_KEY_WIDTH);
00104 f = x / PIANO_KEY_WIDTH - (float)key;
00105 if (f > -BLACK_PIANO_PER_WIDTH && f < BLACK_PIANO_PER_WIDTH)
00106 {
00107 for (j = 0 ; j < BLACK_PIANO_KEY_NUM ; j++) if (BlackKeyNumbers[j] == key)
00108 {
00109 if (!BlackPianoKeys[j]) PlayPianoNote(&car->Wheel[i].WPos, key, TRUE);
00110 BlackPianoKeys[j] = PIANO_KEY_SET;
00111 gotblack = TRUE;
00112 break;
00113 }
00114 }
00115 }
00116
00117 if (!gotblack)
00118 {
00119 key = (long)(x / PIANO_KEY_WIDTH);
00120 if (!PianoKeys[key]) PlayPianoNote(&car->Wheel[i].WPos, key, FALSE);
00121 PianoKeys[key] = PIANO_KEY_SET;
00122 }
00123 }
00124 }
00125 }
00126
00127
00128
00129 if (flag & TRIGGER_FRAME_FIRST)
00130 {
00131
00132
00133
00134 for (i = 0 ; i < PIANO_KEY_NUM ; i++)
00135 {
00136
00137
00138
00139 if (PianoKeys[i])
00140 {
00141
00142
00143
00144 poly = Get3dPoly();
00145 if (poly)
00146 {
00147 x = (float)i;
00148
00149 FTOL(PianoKeys[i], col);
00150 col *= 12;
00151 col <<= 24;
00152 col |= RainbowCols[i % 7];
00153
00154 poly->VertNum = 4;
00155 poly->Tpage = 5;
00156 poly->Fog = FALSE;
00157 poly->SemiType = 0;
00158
00159 poly->Verts[0].color = col;
00160 poly->Verts[1].color = col;
00161 poly->Verts[2].color = col;
00162 poly->Verts[3].color = col;
00163
00164 poly->Verts[0].tu = poly->Verts[3].tu = KeyTexTable[KeyTypeTable[i]];
00165 poly->Verts[1].tu = poly->Verts[2].tu = KeyTexTable[KeyTypeTable[i]] + PIANO_TEX_WIDTH;
00166 poly->Verts[0].tv = poly->Verts[1].tv = PIANO_TV;
00167 poly->Verts[2].tv = poly->Verts[3].tv = PIANO_TV + PIANO_TEX_HEIGHT;
00168
00169 poly->Pos[0].v[X] = poly->Pos[3].v[X] = (x * PIANO_KEY_WIDTH) + PIANO_XPOS;
00170 poly->Pos[1].v[X] = poly->Pos[2].v[X] = ((x + 1) * PIANO_KEY_WIDTH) + PIANO_XPOS;
00171
00172 poly->Pos[0].v[Y] = poly->Pos[1].v[Y] = poly->Pos[2].v[Y] = poly->Pos[3].v[Y] = PIANO_YPOS;
00173
00174 poly->Pos[0].v[Z] = poly->Pos[1].v[Z] = PIANO_ZPOS;
00175 poly->Pos[2].v[Z] = poly->Pos[3].v[Z] = PIANO_ZPOS + PIANO_DEPTH;
00176
00177 if (!i)
00178 {
00179 poly->Pos[0].v[X] += PIANO_KEY_WIDTH / 2;
00180 poly->Pos[3].v[X] += PIANO_KEY_WIDTH / 2;
00181 poly->Verts[0].tu += PIANO_TEX_WIDTH / 2;
00182 poly->Verts[3].tu += PIANO_TEX_WIDTH / 2;
00183 }
00184 }
00185
00186
00187
00188 PianoKeys[i] -= TimeFactor;
00189 if (PianoKeys[i] < 0) PianoKeys[i] = 0;
00190 }
00191 }
00192
00193
00194
00195 for (i = 0 ; i < BLACK_PIANO_KEY_NUM ; i++)
00196 {
00197
00198
00199
00200 if (BlackPianoKeys[i])
00201 {
00202
00203
00204
00205 poly = Get3dPoly();
00206 if (poly)
00207 {
00208 x = (float)(BlackKeyNumbers[i] - 1) * PIANO_KEY_WIDTH + PIANO_XPOS + BLACK_PIANO_XOFFSET;
00209
00210 FTOL(BlackPianoKeys[i], col);
00211 col *= 12;
00212 col <<= 24;
00213 col |= RgbCols[i % 3];
00214
00215 poly->VertNum = 4;
00216 poly->Tpage = 5;
00217 poly->Fog = FALSE;
00218 poly->SemiType = 0;
00219
00220 poly->Verts[0].color = col;
00221 poly->Verts[1].color = col;
00222 poly->Verts[2].color = col;
00223 poly->Verts[3].color = col;
00224
00225 poly->Verts[0].tu = poly->Verts[3].tu = BLACK_PIANO_TU;
00226 poly->Verts[1].tu = poly->Verts[2].tu = BLACK_PIANO_TU + BLACK_PIANO_TEX_WIDTH;
00227 poly->Verts[0].tv = poly->Verts[1].tv = BLACK_PIANO_TV;
00228 poly->Verts[2].tv = poly->Verts[3].tv = BLACK_PIANO_TV + BLACK_PIANO_TEX_HEIGHT;
00229
00230 poly->Pos[0].v[X] = poly->Pos[3].v[X] = x;
00231 poly->Pos[1].v[X] = poly->Pos[2].v[X] = x + BLACK_PIANO_WIDTH;
00232
00233 poly->Pos[0].v[Y] = poly->Pos[1].v[Y] = poly->Pos[2].v[Y] = poly->Pos[3].v[Y] = PIANO_YPOS;
00234
00235 poly->Pos[0].v[Z] = poly->Pos[1].v[Z] = PIANO_ZPOS + (PIANO_DEPTH - BLACK_PIANO_DEPTH);
00236 poly->Pos[2].v[Z] = poly->Pos[3].v[Z] = PIANO_ZPOS + PIANO_DEPTH;
00237 }
00238
00239
00240
00241 BlackPianoKeys[i] -= TimeFactor;
00242 if (BlackPianoKeys[i] < 0) BlackPianoKeys[i] = 0;
00243 }
00244 }
00245 }
00246 }
00247
00249
00251
00252 void PlayPianoNote(VEC *pos, long key, long black)
00253 {
00254 long c;
00255
00256
00257
00258 c = 0;
00259 while (BlackKeyNumbers[c] <= key) c++;
00260
00261 c += key;
00262 c -= black;
00263
00264
00265
00266 PlaySfx3D(SFX_TOY_PIANO, SFX_MAX_VOL, c * 800 + 12000, pos);
00267 }