00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <gcmodplay.h>
00057 #include <fat.h>
00058
00059 #include "main.h"
00060 #include "tcyc_input.h"
00061 #include "tcyc_menu.h"
00062 #include "audio.h"
00063 #include "menu.h"
00064 #include "Options.h"
00065 #include "Player.h"
00066
00067
00068 #include "tetris_mod.h"
00069 #include "pieces_bin.h"
00070
00071 extern TetrisPieceDesc g_pieceDesc[TETRISPIECE_ID_MAX][4];
00072 extern ColorGradient g_cubeGradients[COLOR_ID_MAX];
00073 extern Player *g_players;
00074 extern u32 *g_xfb[2];
00075 extern GXRModeObj *g_vmode;
00076 extern Mtx GXmodelView2D;
00077 extern Mtx44 orthographic;
00078 extern Mtx g_view;
00079 extern Options *g_options;
00080 extern MODPlay g_modPlay;
00081 extern bool g_isEditMode;
00082 extern int g_tcycMenu;
00083
00084 extern GuiWindow *mainWindow;
00085 extern GuiTrigger *trigA;
00086 extern GuiSound *btnSoundOver;
00087 extern GuiSound *g_tetrisCheerSound;
00088 extern GuiImageData *btnData40x40Square;
00089 extern GuiImageData *btnData40x40SquareOver;
00090 extern GuiImageData *grabber[MAX_PLAYERS];
00091 extern GuiImageData *debug_grabber1;
00092 extern GuiImageData *debug_grabber2;
00093 extern GuiImageData *debug_grabber3;
00094 extern GuiImageData *debug_grabber4;
00095 extern GuiImageData *pointer[MAX_PLAYERS];
00096
00097 static Mtx44 projection;
00098
00099
00100 static void TCYC_Update();
00101 static void TCYC_Draw();
00102 static void TCYC_DrawPlayfieldBoundary();
00103 static void TCYC_DrawTetriCycle();
00104 static void TCYC_DrawPowerups();
00105 static void TCYC_DrawPowerupBorders();
00106 static void TCYC_DrawPowerupTextures();
00107 static void TCYC_DrawPowerupTexture(int upperLeftX, int upperLeftY, GuiImageData *imgData, u8 alpha);
00108 static void TCYC_Render();
00109
00110 static void TCYC_DrawEditMode();
00111 static void TCYC_DrawTetriCycleEditMode();
00112 static void TCYC_DrawEditPlayfieldMenu();
00113
00114
00115 static void TCYC_InitPieceDescriptions();
00116 static void TCYC_GameInit();
00117 static void TCYC_GameOnExit();
00118
00119 int main()
00120 {
00121
00122
00123
00124 InitVideo();
00125 SetupPads();
00126 InitAudio();
00127 fatInitDefault();
00128 InitFreeType((u8*)font_ttf, font_ttf_size);
00129 InitGUIThreads();
00130
00131
00132
00133 guVector cam = {0.0F, 0.0F, 0.0F};
00134 guVector up = {0.0F, 1.0F, 0.0F};
00135 guVector look = {0.0F, 0.0F, -1.0F};
00136 guLookAt(g_view, &cam, &up, &look);
00137
00138
00139
00140
00141 f32 w = g_vmode->viWidth;
00142 f32 h = g_vmode->viHeight;
00143 guPerspective(projection, 45, (f32)w/h, 0.1F, 300.0F);
00144
00145
00146 mainWindow = new GuiWindow(screenwidth, screenheight);
00147 pointer[0] = new GuiImageData(player1_point_png);
00148 pointer[1] = new GuiImageData(player2_point_png);
00149 pointer[2] = new GuiImageData(player3_point_png);
00150 pointer[3] = new GuiImageData(player4_point_png);
00151
00152
00153
00154 TCYC_InitPieceDescriptions();
00155 MODPlay_Init(&g_modPlay);
00156 MODPlay_SetMOD(&g_modPlay, tetris_mod);
00157 g_totalPowerups = PowerupUtils::GetTotalPowerups();
00158
00159
00160 g_options = &Options::GetInstance();
00161 g_players = new Player[MAX_PLAYERS];
00162 for (int i = 0; i < MAX_PLAYERS; ++i)
00163 g_players[i].id = i;
00164
00165
00166 TCYC_MenuLoop();
00167 }
00168
00169
00170 void TCYC_Game()
00171 {
00172 TCYC_GameInit();
00173
00174 while (true)
00175 {
00176 TCYC_Update();
00177
00178
00179 if (g_tcycMenu != TCYC_MENU_NONE)
00180 break;
00181
00182 TCYC_Draw();
00183 TCYC_Render();
00184 }
00185
00186 TCYC_GameOnExit();
00187 }
00188
00189
00190 void TCYC_Update()
00191 {
00192 ALL_ScanPads();
00193 TCYC_ProcessInput();
00194
00195 for (int i = 0; i < g_options->players; ++i)
00196 g_players[i].Update();
00197
00198 if (!g_tetrisCheerSound->IsPlaying())
00199 MODPlay_Pause(&g_modPlay, 0);
00200 }
00201
00202
00203 void TCYC_Draw()
00204 {
00205 TCYC_SetUp2D();
00206 TCYC_DrawPlayfieldBoundary();
00207 TCYC_DrawText();
00208
00209 TCYC_DrawTetriCycle();
00210
00211 if (g_options->players > 1)
00212 {
00213 TCYC_SetUp2D();
00214 TCYC_DrawPowerups();
00215 }
00216 }
00217
00218
00219 void TCYC_SetUp2D()
00220 {
00221
00222 GX_SetZMode(GX_FALSE, GX_LEQUAL, GX_TRUE);
00223 GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0);
00224 GX_LoadProjectionMtx(orthographic, GX_ORTHOGRAPHIC);
00225 }
00226
00227
00228 void TCYC_DrawPlayfieldBoundary()
00229 {
00230 switch (g_options->players)
00231 {
00232 case 1:
00233 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00234
00235 GX_Position3f32(0, 0, 0);
00236 GX_Color4u8(0, 0, 20, 255);
00237 GX_Position3f32(640, 0, 0);
00238 GX_Color4u8(88, 88, 108, 255);
00239 GX_Position3f32(640, 480, 0);
00240 GX_Color4u8(195, 195, 215, 255);
00241 GX_Position3f32(0, 480, 0);
00242 GX_Color4u8(88, 88, 108, 255);
00243 GX_End();
00244 break;
00245
00246 case 2:
00247 GX_Begin(GX_QUADS, GX_VTXFMT0, 8);
00248
00249 GX_Position3f32(0, 0, 0);
00250 GX_Color4u8(0, 0, 20, 255);
00251 GX_Position3f32(P2_X_BORDER, 0, 0);
00252 GX_Color4u8(88, 88, 108, 255);
00253 GX_Position3f32(P2_X_BORDER, 480, 0);
00254 GX_Color4u8(195, 195, 215, 255);
00255 GX_Position3f32(0, 480, 0);
00256 GX_Color4u8(88, 88, 108, 255);
00257
00258
00259 GX_Position3f32(P2_X_BORDER, 0, 0);
00260 GX_Color4u8(0, 0, 20, 255);
00261 GX_Position3f32(640, 0, 0);
00262 GX_Color4u8(88, 88, 108, 255);
00263 GX_Position3f32(640, 480, 0);
00264 GX_Color4u8(195, 195, 215, 255);
00265 GX_Position3f32(P2_X_BORDER, 480, 0);
00266 GX_Color4u8(88, 88, 108, 255);
00267 GX_End();
00268 break;
00269
00270 case 3:
00271 GX_Begin(GX_QUADS, GX_VTXFMT0, 12);
00272
00273 GX_Position3f32(0, 0, 0);
00274 GX_Color4u8(0, 0, 20, 255);
00275 GX_Position3f32(P3_X_BORDER_1, 0, 0);
00276 GX_Color4u8(88, 88, 108, 255);
00277 GX_Position3f32(P3_X_BORDER_1, 480, 0);
00278 GX_Color4u8(195, 195, 215, 255);
00279 GX_Position3f32(0, 480, 0);
00280 GX_Color4u8(88, 88, 108, 255);
00281
00282
00283 GX_Position3f32(P3_X_BORDER_1, 0, 0);
00284 GX_Color4u8(0, 0, 20, 255);
00285 GX_Position3f32(P3_X_BORDER_2, 0, 0);
00286 GX_Color4u8(88, 88, 108, 255);
00287 GX_Position3f32(P3_X_BORDER_2, 480, 0);
00288 GX_Color4u8(195, 195, 215, 255);
00289 GX_Position3f32(P3_X_BORDER_1, 480, 0);
00290 GX_Color4u8(88, 88, 108, 255);
00291
00292
00293 GX_Position3f32(P3_X_BORDER_2, 0, 0);
00294 GX_Color4u8(0, 0, 20, 255);
00295 GX_Position3f32(640, 0, 0);
00296 GX_Color4u8(88, 88, 108, 255);
00297 GX_Position3f32(640, 480, 0);
00298 GX_Color4u8(195, 195, 215, 255);
00299 GX_Position3f32(P3_X_BORDER_2, 480, 0);
00300 GX_Color4u8(88, 88, 108, 255);
00301 GX_End();
00302 break;
00303
00304 case 4:
00305 GX_Begin(GX_QUADS, GX_VTXFMT0, 16);
00306
00307 GX_Position3f32(0, 0, 0);
00308 GX_Color4u8(0, 0, 20, 255);
00309 GX_Position3f32(P4_X_BORDER_1, 0, 0);
00310 GX_Color4u8(88, 88, 108, 255);
00311 GX_Position3f32(P4_X_BORDER_1, 480, 0);
00312 GX_Color4u8(195, 195, 215, 255);
00313 GX_Position3f32(0, 480, 0);
00314 GX_Color4u8(88, 88, 108, 255);
00315
00316
00317 GX_Position3f32(P4_X_BORDER_1, 0, 0);
00318 GX_Color4u8(0, 0, 20, 255);
00319 GX_Position3f32(P4_X_BORDER_2, 0, 0);
00320 GX_Color4u8(88, 88, 108, 255);
00321 GX_Position3f32(P4_X_BORDER_2, 480, 0);
00322 GX_Color4u8(195, 195, 215, 255);
00323 GX_Position3f32(P4_X_BORDER_1, 480, 0);
00324 GX_Color4u8(88, 88, 108, 255);
00325
00326
00327 GX_Position3f32(P4_X_BORDER_2, 0, 0);
00328 GX_Color4u8(0, 0, 20, 255);
00329 GX_Position3f32(P4_X_BORDER_3, 0, 0);
00330 GX_Color4u8(88, 88, 108, 255);
00331 GX_Position3f32(P4_X_BORDER_3, 480, 0);
00332 GX_Color4u8(195, 195, 215, 255);
00333 GX_Position3f32(P4_X_BORDER_2, 480, 0);
00334 GX_Color4u8(88, 88, 108, 255);
00335
00336
00337 GX_Position3f32(P4_X_BORDER_3, 0, 0);
00338 GX_Color4u8(0, 0, 20, 255);
00339 GX_Position3f32(640, 0, 0);
00340 GX_Color4u8(88, 88, 108, 255);
00341 GX_Position3f32(640, 480, 0);
00342 GX_Color4u8(195, 195, 215, 255);
00343 GX_Position3f32(P4_X_BORDER_3, 480, 0);
00344 GX_Color4u8(88, 88, 108, 255);
00345 GX_End();
00346 break;
00347 }
00348 }
00349
00350
00351 void TCYC_DrawText()
00352 {
00353
00354 static const u8 a = 64;
00355 GXColor txtColor = !g_options->isPaused ?
00356 (GXColor){255, 255, 255, a} : (GXColor){255, 255, 255, 255};
00357 GXColor deadColor = (GXColor){200, 0, 0, 255};
00358
00359 GuiText txt(NULL, 28, txtColor);
00360 txt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
00361
00362 char buf[5];
00363 int player_x = 10, txt_dx = 100, y = 0, dy = 32;
00364 int player_dx = screenwidth / g_options->players;
00365
00366 for (int i = 0; i < g_options->players; ++i, player_x += player_dx)
00367 {
00368 y = 0;
00369 txt.SetColor(!g_players[i].gameData.isDead ? txtColor : deadColor);
00370
00371
00372 txt.SetText("lines:");
00373 txt.SetPosition(player_x, y += dy);
00374 txt.Draw();
00375 sprintf(buf, "%d", g_players[i].gameData.lines);
00376 txt.SetText(buf);
00377 txt.SetPosition(player_x + txt_dx, y);
00378 txt.Draw();
00379
00380 txt.SetText("score:");
00381 txt.SetPosition(player_x, y += dy);
00382 txt.Draw();
00383 sprintf(buf, "%d", g_players[i].gameData.score);
00384 txt.SetText(buf);
00385 txt.SetPosition(player_x + txt_dx, y);
00386 txt.Draw();
00387
00388 txt.SetText("level:");
00389 txt.SetPosition(player_x, y += dy);
00390 txt.Draw();
00391 sprintf(buf, "%d", g_players[i].gameData.level);
00392 txt.SetText(buf);
00393 txt.SetPosition(player_x + txt_dx, y);
00394 txt.Draw();
00395 }
00396 }
00397
00398
00399 int TCYC_GetTargetPlayer(int x)
00400 {
00401 switch (g_options->players)
00402 {
00403 case 2: return x < P2_X_BORDER ? 0 : 1;
00404 case 3: return x < P3_X_BORDER_1 ? 0 : (x < P3_X_BORDER_2 ? 1 : 2);
00405 case 4: return x < P4_X_BORDER_1 ? 0 : (x < P4_X_BORDER_2 ? 1 : (x < P4_X_BORDER_3 ? 2 : 3));
00406 }
00407
00408 TCYC_MenuError("Error in function TCYC_GetTargetPlayer.");
00409 return 0;
00410 }
00411
00412
00413
00414 int TCYC_GetTargetPowerupSlot(int player, int x, int y)
00415 {
00416 int borders[MAX_PLAYERS+1];
00417 borders[0] = 0;
00418 borders[g_options->players] = 640;
00419
00420 switch (g_options->players)
00421 {
00422 case 2:
00423 borders[1] = P2_X_BORDER;
00424 break;
00425 case 3:
00426 borders[1] = P3_X_BORDER_1;
00427 borders[2] = P3_X_BORDER_2;
00428 break;
00429 case 4:
00430 borders[1] = P4_X_BORDER_1;
00431 borders[2] = P4_X_BORDER_2;
00432 borders[3] = P4_X_BORDER_3;
00433 break;
00434 }
00435
00436
00437 if (x >= borders[player+1] - POWERUP_WIDTH - 2 * POWERUP_X_OFFSET && x <= borders[player+1])
00438 {
00439
00440 int py = POWERUP_Y_OFFSET + POWERUP_WIDTH;
00441 for (int i = 0; i < MAX_ACQUIRED_POWERUPS - 1; ++i, py += POWERUP_WIDTH)
00442 {
00443 if (y < py)
00444 return i;
00445 }
00446
00447 if (y < py + POWERUP_Y_OFFSET)
00448 return MAX_ACQUIRED_POWERUPS - 1;
00449 }
00450
00451 return -1;
00452 }
00453
00454
00455 void TCYC_DrawPowerupBorders()
00456 {
00457 int borders[MAX_PLAYERS+1];
00458 borders[0] = 0;
00459 borders[g_options->players] = 640;
00460
00461 switch (g_options->players)
00462 {
00463 case 2:
00464 borders[1] = P2_X_BORDER;
00465 break;
00466 case 3:
00467 borders[1] = P3_X_BORDER_1;
00468 borders[2] = P3_X_BORDER_2;
00469 break;
00470 case 4:
00471 borders[1] = P4_X_BORDER_1;
00472 borders[2] = P4_X_BORDER_2;
00473 borders[3] = P4_X_BORDER_3;
00474 break;
00475 }
00476
00477 int x;
00478 int y;
00479
00480 for (int i = 0; i < g_options->players; ++i)
00481 {
00482 x = 0;
00483 y = 0;
00484
00485
00486 GX_Begin(GX_LINESTRIP, GX_VTXFMT0, 2);
00487 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET - POWERUP_WIDTH, POWERUP_Y_OFFSET, 0);
00488 GX_Color4u8(0, 0, 0, 255);
00489 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET, POWERUP_Y_OFFSET, 0);
00490 GX_Color4u8(0, 0, 0, 255);
00491 GX_End();
00492
00493 for (int j = 0; j < MAX_ACQUIRED_POWERUPS; ++j, y += POWERUP_WIDTH)
00494 {
00495 GX_Begin(GX_LINESTRIP, GX_VTXFMT0, 4);
00496 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET - POWERUP_WIDTH, y + POWERUP_Y_OFFSET, 0);
00497 GX_Color4u8(0, 0, 0, 255);
00498 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET - POWERUP_WIDTH, y + POWERUP_Y_OFFSET + POWERUP_WIDTH, 0);
00499 GX_Color4u8(0, 0, 0, 255);
00500 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET, y + POWERUP_Y_OFFSET + POWERUP_WIDTH, 0);
00501 GX_Color4u8(0, 0, 0, 255);
00502 GX_Position3f32(borders[i+1] - POWERUP_X_OFFSET, y + POWERUP_Y_OFFSET, 0);
00503 GX_Color4u8(0, 0, 0, 255);
00504 GX_End();
00505 }
00506
00507
00508 GX_Begin(GX_LINESTRIP, GX_VTXFMT0, 2);
00509 GX_Position3f32(borders[i] + POWERUP_X_OFFSET, 480 - POWERUP_Y_OFFSET - POWERUP_WIDTH, 0);
00510 GX_Color4u8(0, 0, 0, 255);
00511 GX_Position3f32(borders[i] + POWERUP_X_OFFSET, 480 - POWERUP_Y_OFFSET, 0);
00512 GX_Color4u8(0, 0, 0, 255);
00513 GX_End();
00514
00515 for (int j = 0; j < MAX_POWERUP_EFFECTS; ++j, x += POWERUP_WIDTH)
00516 {
00517 GX_Begin(GX_LINESTRIP, GX_VTXFMT0, 4);
00518 GX_Position3f32(borders[i] + POWERUP_X_OFFSET + x, 480 - POWERUP_Y_OFFSET - POWERUP_WIDTH, 0);
00519 GX_Color4u8(0, 0, 0, 255);
00520 GX_Position3f32(borders[i] + POWERUP_X_OFFSET + POWERUP_WIDTH + x, 480 - POWERUP_Y_OFFSET - POWERUP_WIDTH, 0);
00521 GX_Color4u8(0, 0, 0, 255);
00522 GX_Position3f32(borders[i] + POWERUP_X_OFFSET + POWERUP_WIDTH + x, 480 - POWERUP_Y_OFFSET, 0);
00523 GX_Color4u8(0, 0, 0, 255);
00524 GX_Position3f32(borders[i] + POWERUP_X_OFFSET + x, 480 - POWERUP_Y_OFFSET, 0);
00525 GX_Color4u8(0, 0, 0, 255);
00526 GX_End();
00527 }
00528 }
00529 }
00530
00531
00532
00533 void TCYC_DrawPowerupTexture(int x, int y, GuiImageData *imgData, u8 alpha)
00534 {
00535 GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
00536 GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
00537
00538 GXTexObj texObj;
00539 GX_InitTexObj(&texObj, imgData->GetImage(), imgData->GetWidth(), imgData->GetHeight(), GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
00540 GX_LoadTexObj(&texObj, GX_TEXMAP0);
00541 GX_InvalidateTexAll();
00542
00543 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00544 GX_Position3f32(x, y, 0);
00545 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00546 GX_TexCoord2f32(0, 0);
00547 GX_Position3f32(x + POWERUP_WIDTH, y, 0);
00548 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00549 GX_TexCoord2f32(1, 0);
00550 GX_Position3f32(x + POWERUP_WIDTH, y + POWERUP_WIDTH, 0);
00551 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00552 GX_TexCoord2f32(1, 1);
00553 GX_Position3f32(x, y + POWERUP_WIDTH, 0);
00554 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00555 GX_TexCoord2f32(0, 1);
00556 GX_End();
00557
00558 GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
00559 GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
00560 }
00561
00562
00563 void TCYC_DrawPowerupTextures()
00564 {
00565 static const int yoffset = POWERUP_Y_OFFSET;
00566 static const int xoffset = POWERUP_X_OFFSET;
00567 static const int width = POWERUP_WIDTH;
00568
00569 int x;
00570 int y;
00571 u8 alpha;
00572 Powerup *powerup;
00573 GuiImageData *imgData;
00574 GXTexObj texObj;
00575
00576 int borders[MAX_PLAYERS+1];
00577 borders[0] = 0;
00578 borders[g_options->players] = 640;
00579
00580 switch (g_options->players)
00581 {
00582 case 2:
00583 borders[1] = P2_X_BORDER;
00584 break;
00585 case 3:
00586 borders[1] = P3_X_BORDER_1;
00587 borders[2] = P3_X_BORDER_2;
00588 break;
00589 case 4:
00590 borders[1] = P4_X_BORDER_1;
00591 borders[2] = P4_X_BORDER_2;
00592 borders[3] = P4_X_BORDER_3;
00593 break;
00594 }
00595
00596 GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
00597 GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
00598
00599 for (int i = 0; i < g_options->players; ++i)
00600 {
00601 x = 0;
00602 y = 0;
00603 alpha = 128;
00604
00605
00606 for (int j = 0; j < MAX_ACQUIRED_POWERUPS; ++j, y += width)
00607 {
00608 powerup = g_players[i].gameData.powerupQueue[j];
00609 if (powerup)
00610 {
00611 imgData = powerup->GetImageData();
00612 GX_InitTexObj(&texObj, imgData->GetImage(), imgData->GetWidth(), imgData->GetHeight(), GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
00613 GX_LoadTexObj(&texObj, GX_TEXMAP0);
00614 GX_InvalidateTexAll();
00615
00616 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00617 GX_Position3f32(borders[i+1] - xoffset - width, y + yoffset, 0);
00618 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00619 GX_TexCoord2f32(0, 0);
00620 GX_Position3f32(borders[i+1] - xoffset, y + yoffset, 0);
00621 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00622 GX_TexCoord2f32(1, 0);
00623 GX_Position3f32(borders[i+1] - xoffset, y + yoffset + width, 0);
00624 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00625 GX_TexCoord2f32(1, 1);
00626 GX_Position3f32(borders[i+1] - xoffset - width, y + yoffset + width, 0);
00627 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00628 GX_TexCoord2f32(0, 1);
00629 GX_End();
00630 }
00631 }
00632
00633 alpha = 64;
00634
00635
00636 for (int j = 0; j < MAX_POWERUP_EFFECTS; ++j, x += width)
00637 {
00638 powerup = g_players[i].gameData.powerupEffects[j];
00639 if (powerup)
00640 {
00641 imgData = powerup->GetImageData();
00642 GX_InitTexObj(&texObj, imgData->GetImage(), imgData->GetWidth(), imgData->GetHeight(), GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
00643 GX_LoadTexObj(&texObj, GX_TEXMAP0);
00644 GX_InvalidateTexAll();
00645
00646 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00647 GX_Position3f32(borders[i] + xoffset + x, 480 - yoffset - width, 0);
00648 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00649 GX_TexCoord2f32(0, 0);
00650 GX_Position3f32(borders[i] + xoffset + width + x, 480 - yoffset - width, 0);
00651 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00652 GX_TexCoord2f32(1, 0);
00653 GX_Position3f32(borders[i] + xoffset + width + x, 480 - yoffset, 0);
00654 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00655 GX_TexCoord2f32(1, 1);
00656 GX_Position3f32(borders[i] + xoffset + x, 480 - yoffset, 0);
00657 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00658 GX_TexCoord2f32(0, 1);
00659 GX_End();
00660 }
00661 }
00662 }
00663
00664 GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
00665 GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
00666 }
00667
00668
00669 void TCYC_DrawPowerups()
00670 {
00671 TCYC_DrawPowerupBorders();
00672 TCYC_DrawPowerupTextures();
00673
00674 for (int i = g_options->players - 1; i >= 0; --i)
00675 {
00676 if (userInput[i].wpad->ir.valid)
00677 {
00678 int x = userInput[i].wpad->ir.x;
00679 int y = userInput[i].wpad->ir.y;
00680 u8 alpha = (TCYC_GetTargetPlayer(x) == i) ? 255 : 32;
00681 Powerup *powerup = g_players[i].gameData.grabbedPowerup;
00682
00683 if (powerup)
00684 TCYC_DrawPowerupTexture(x - (POWERUP_WIDTH >> 1), y - (POWERUP_WIDTH >> 1), powerup->GetImageData(), alpha);
00685
00686 GuiImageData *imgData = GRAB_HELD(i) ? grabber[i] : pointer[i];
00687 float scale = 1;
00688
00689 if (g_players[i].gameData.powerupData.isBigHand)
00690 {
00691 scale = BIG_HAND_SCALE;
00692 alpha = 255;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 switch (i)
00706 {
00707 case 0:
00708 imgData = GRAB_HELD(i) ? debug_grabber1 : pointer[i];
00709 break;
00710 case 1:
00711 imgData = GRAB_HELD(i) ? debug_grabber2 : pointer[i];
00712 break;
00713 case 2:
00714 imgData = GRAB_HELD(i) ? debug_grabber3 : pointer[i];
00715 break;
00716 case 3:
00717 imgData = GRAB_HELD(i) ? debug_grabber4 : pointer[i];
00718 break;
00719 }
00720 Menu_DrawImg(x - 48, y - 48, 96, 96, imgData->GetImage(), userInput[i].wpad->ir.angle, scale, scale, alpha);
00721 }
00722
00723 DoRumble(i);
00724 }
00725 }
00726
00727
00728 void TCYC_DrawTetriCycle()
00729 {
00730
00731 GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
00732 GX_LoadProjectionMtx(projection, GX_PERSPECTIVE);
00733
00734 for (int i = 0; i < g_options->players; ++i)
00735 {
00736 Player &player = g_players[i];
00737 player.DrawPlayfield();
00738 player.DrawNextPiece();
00739 player.DrawPiece();
00740 player.DrawPieceShadow();
00741 player.DrawBase();
00742 }
00743 }
00744
00745
00746 void TCYC_Render()
00747 {
00748 static int currFrame = 0;
00749 currFrame ^= 1;
00750
00751 GX_CopyDisp(g_xfb[currFrame], GX_TRUE);
00752 GX_DrawDone();
00753
00754 VIDEO_SetNextFramebuffer(g_xfb[currFrame]);
00755 VIDEO_Flush();
00756 VIDEO_WaitVSync();
00757
00758 for (int i = 0; i < g_options->players; ++i)
00759 g_players[i].gameData.frame++;
00760 }
00761
00762
00763 void GX_Cube(int colorIdx, u8 alpha, GuiImageData *imgData)
00764 {
00765 ColorGradient &gradient = g_cubeGradients[colorIdx];
00766
00767 u8 lightR = gradient.light.r;
00768 u8 lightG = gradient.light.g;
00769 u8 lightB = gradient.light.b;
00770
00771 u8 mediumR = gradient.medium.r;
00772 u8 mediumG = gradient.medium.g;
00773 u8 mediumB = gradient.medium.b;
00774
00775 u8 darkR = gradient.dark.r;
00776 u8 darkG = gradient.dark.g;
00777 u8 darkB = gradient.dark.b;
00778
00779 static const float unit = 0.5;
00780
00781 GX_Begin(GX_QUADS, GX_VTXFMT0, 8);
00782
00783 GX_Position3f32(-unit, unit, -unit);
00784 GX_Color4u8(lightR, lightG, lightB, alpha);
00785 GX_Position3f32(unit, unit, -unit);
00786 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00787 GX_Position3f32(unit, unit, unit);
00788 GX_Color4u8(darkR, darkG, darkB, alpha);
00789 GX_Position3f32(-unit, unit, unit);
00790 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00791
00792
00793 GX_Position3f32(-unit, -unit, unit);
00794 GX_Color4u8(lightR, lightG, lightB, alpha);
00795 GX_Position3f32(unit, -unit, unit);
00796 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00797 GX_Position3f32(unit, -unit, -unit);
00798 GX_Color4u8(darkR, darkG, darkB, alpha);
00799 GX_Position3f32(-unit, -unit, -unit);
00800 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00801 GX_End();
00802
00803
00804 if (!imgData)
00805 {
00806 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00807 GX_Position3f32(-unit, unit, unit);
00808 GX_Color4u8(lightR, lightG, lightB, alpha);
00809 GX_Position3f32(unit, unit, unit);
00810 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00811 GX_Position3f32(unit, -unit, unit);
00812 GX_Color4u8(darkR, darkG, darkB, alpha);
00813 GX_Position3f32(-unit, -unit, unit);
00814 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00815 GX_End();
00816 }
00817 else
00818 {
00819 GXTexObj texObj;
00820
00821 int width = imgData->GetWidth();
00822 int height = imgData->GetHeight();
00823 GX_InitTexObj(&texObj, imgData->GetImage(), width, height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
00824 GX_LoadTexObj(&texObj, GX_TEXMAP0);
00825 GX_InvalidateTexAll();
00826
00827 GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
00828 GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
00829
00830 GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
00831 GX_Position3f32(-unit, unit, unit);
00832 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00833 GX_TexCoord2f32(0, 0);
00834 GX_Position3f32(unit, unit, unit);
00835 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00836 GX_TexCoord2f32(1, 0);
00837 GX_Position3f32(unit, -unit, unit);
00838 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00839 GX_TexCoord2f32(1, 1);
00840 GX_Position3f32(-unit, -unit, unit);
00841 GX_Color4u8(0xFF, 0xFF, 0xFF, alpha);
00842 GX_TexCoord2f32(0, 1);
00843 GX_End();
00844
00845 GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
00846 GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);
00847 }
00848
00849 GX_Begin(GX_QUADS, GX_VTXFMT0, 12);
00850
00851 GX_Position3f32(unit, -unit, -unit);
00852 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00853 GX_Position3f32(-unit, -unit, -unit);
00854 GX_Color4u8(darkR, darkG, darkB, alpha);
00855 GX_Position3f32(-unit, unit, -unit);
00856 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00857 GX_Position3f32(unit, unit, -unit);
00858 GX_Color4u8(lightR, lightG, lightB, alpha);
00859
00860
00861 GX_Position3f32(-unit, unit, unit);
00862 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00863 GX_Position3f32(-unit, unit, -unit);
00864 GX_Color4u8(lightR, lightG, lightB, alpha);
00865 GX_Position3f32(-unit, -unit, -unit);
00866 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00867 GX_Position3f32(-unit, -unit, unit);
00868 GX_Color4u8(darkR, darkG, darkB, alpha);
00869
00870
00871 GX_Position3f32(unit, unit, -unit);
00872 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00873 GX_Position3f32(unit, unit, unit);
00874 GX_Color4u8(lightR, lightG, lightB, alpha);
00875 GX_Position3f32(unit, -unit, unit);
00876 GX_Color4u8(mediumR, mediumG, mediumB, alpha);
00877 GX_Position3f32(unit, -unit, -unit);
00878 GX_Color4u8(darkR, darkG, darkB, alpha);
00879 GX_End();
00880 }
00881
00882
00883 void TCYC_EditPlayfield()
00884 {
00885 GXColor white = (GXColor){255, 255, 255, 255};
00886 GXColor green = (GXColor){0, 255, 0, 255};
00887
00888 char buf[7 + 5];
00889 int player_x = 10, y = 0, dy = 32;
00890 int player_dx = screenwidth / g_options->players;
00891
00892 GuiWindow window(screenwidth, screenheight);
00893
00894
00895 GuiButton confirmBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00896 GuiText confirmBtnTxt("OK", 22, (GXColor){0, 0, 255, 255});
00897 GuiImage confirmBtnImg(btnData40x40Square);
00898 GuiImage confirmBtnImgOver(btnData40x40SquareOver);
00899
00900 confirmBtn.SetAlignment(ALIGN_RIGHT, ALIGN_BOTTOM);
00901 confirmBtn.SetPosition(-10, -20);
00902 confirmBtn.SetLabel(&confirmBtnTxt);
00903 confirmBtn.SetImage(&confirmBtnImg);
00904 confirmBtn.SetImageOver(&confirmBtnImgOver);
00905 confirmBtn.SetSoundOver(btnSoundOver);
00906 confirmBtn.SetTrigger(trigA);
00907 confirmBtn.SetEffectGrow();
00908
00909
00910 GuiButton cancelBtn(btnData40x40Square->GetWidth(), btnData40x40Square->GetHeight());
00911 GuiText cancelBtnTxt("X", 22, (GXColor){255, 0, 0, 255});
00912 GuiImage cancelBtnImg(btnData40x40Square);
00913 GuiImage cancelBtnImgOver(btnData40x40SquareOver);
00914
00915 cancelBtn.SetAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
00916 cancelBtn.SetPosition(10, -20);
00917 cancelBtn.SetLabel(&cancelBtnTxt);
00918 cancelBtn.SetImage(&cancelBtnImg);
00919 cancelBtn.SetImageOver(&cancelBtnImgOver);
00920 cancelBtn.SetSoundOver(btnSoundOver);
00921 cancelBtn.SetTrigger(trigA);
00922 cancelBtn.SetEffectGrow();
00923
00924
00925 GuiButton p1widthBtn((9 + 1) * 14, 28);
00926 GuiText p1widthTxt(NULL, 28, white);
00927 GuiText p1widthTxtOver(NULL, 28, green);
00928
00929
00930 GuiButton p2widthBtn((9 + 1) * 14, 28);
00931 GuiText p2widthTxt(NULL, 28, white);
00932 GuiText p2widthTxtOver(NULL, 28, green);
00933
00934
00935 GuiButton p3widthBtn((9 + 1) * 14, 28);
00936 GuiText p3widthTxt(NULL, 28, white);
00937 GuiText p3widthTxtOver(NULL, 28, green);
00938
00939
00940 GuiButton p4widthBtn((9 + 1) * 14, 28);
00941 GuiText p4widthTxt(NULL, 28, white);
00942 GuiText p4widthTxtOver(NULL, 28, green);
00943
00944
00945 GuiButton p1scaleBtn((9 + 1) * 14, 28);
00946 GuiText p1scaleTxt(NULL, 28, white);
00947 GuiText p1scaleTxtOver(NULL, 28, green);
00948
00949
00950 GuiButton p2scaleBtn((9 + 1) * 14, 28);
00951 GuiText p2scaleTxt(NULL, 28, white);
00952 GuiText p2scaleTxtOver(NULL, 28, green);
00953
00954
00955 GuiButton p3scaleBtn((9 + 1) * 14, 28);
00956 GuiText p3scaleTxt(NULL, 28, white);
00957 GuiText p3scaleTxtOver(NULL, 28, green);
00958
00959
00960 GuiButton p4scaleBtn((9 + 1) * 14, 28);
00961 GuiText p4scaleTxt(NULL, 28, white);
00962 GuiText p4scaleTxtOver(NULL, 28, green);
00963
00964
00965 GuiButton p1angleBtn((9 + 1) * 14, 28);
00966 GuiText p1angleTxt(NULL, 28, white);
00967 GuiText p1angleTxtOver(NULL, 28, green);
00968
00969
00970 GuiButton p2angleBtn((9 + 1) * 14, 28);
00971 GuiText p2angleTxt(NULL, 28, white);
00972 GuiText p2angleTxtOver(NULL, 28, green);
00973
00974
00975 GuiButton p3angleBtn((9 + 1) * 14, 28);
00976 GuiText p3angleTxt(NULL, 28, white);
00977 GuiText p3angleTxtOver(NULL, 28, green);
00978
00979
00980 GuiButton p4angleBtn((9 + 1) * 14, 28);
00981 GuiText p4angleTxt(NULL, 28, white);
00982 GuiText p4angleTxtOver(NULL, 28, green);
00983
00984
00985 GuiButton p1dxBtn((7 + 1) * 14, 28);
00986 GuiText p1dxTxt(NULL, 28, white);
00987 GuiText p1dxTxtOver(NULL, 28, green);
00988
00989
00990 GuiButton p2dxBtn((7 + 1) * 14, 28);
00991 GuiText p2dxTxt(NULL, 28, white);
00992 GuiText p2dxTxtOver(NULL, 28, green);
00993
00994
00995 GuiButton p3dxBtn((7 + 1) * 14, 28);
00996 GuiText p3dxTxt(NULL, 28, white);
00997 GuiText p3dxTxtOver(NULL, 28, green);
00998
00999
01000 GuiButton p4dxBtn((7 + 1) * 14, 28);
01001 GuiText p4dxTxt(NULL, 28, white);
01002 GuiText p4dxTxtOver(NULL, 28, green);
01003
01004
01005 GuiButton p1dyBtn((7 + 1) * 14, 28);
01006 GuiText p1dyTxt(NULL, 28, white);
01007 GuiText p1dyTxtOver(NULL, 28, green);
01008
01009
01010 GuiButton p2dyBtn((7 + 1) * 14, 28);
01011 GuiText p2dyTxt(NULL, 28, white);
01012 GuiText p2dyTxtOver(NULL, 28, green);
01013
01014
01015 GuiButton p3dyBtn((7 + 1) * 14, 28);
01016 GuiText p3dyTxt(NULL, 28, white);
01017 GuiText p3dyTxtOver(NULL, 28, green);
01018
01019
01020 GuiButton p4dyBtn((7 + 1) * 14, 28);
01021 GuiText p4dyTxt(NULL, 28, white);
01022 GuiText p4dyTxtOver(NULL, 28, green);
01023
01024
01025 GuiButton *widthButtons[MAX_PLAYERS] = {&p1widthBtn, &p2widthBtn, &p3widthBtn, &p4widthBtn};
01026 GuiText *widthTexts[MAX_PLAYERS] = {&p1widthTxt, &p2widthTxt, &p3widthTxt, &p4widthTxt};
01027 GuiText *widthTextsOver[MAX_PLAYERS] = {&p1widthTxtOver, &p2widthTxtOver, &p3widthTxtOver, &p4widthTxtOver};
01028
01029 GuiButton *scaleButtons[MAX_PLAYERS] = {&p1scaleBtn, &p2scaleBtn, &p3scaleBtn, &p4scaleBtn};
01030 GuiText *scaleTexts[MAX_PLAYERS] = {&p1scaleTxt, &p2scaleTxt, &p3scaleTxt, &p4scaleTxt};
01031 GuiText *scaleTextsOver[MAX_PLAYERS] = {&p1scaleTxtOver, &p2scaleTxtOver, &p3scaleTxtOver, &p4scaleTxtOver};
01032
01033 GuiButton *angleButtons[MAX_PLAYERS] = {&p1angleBtn, &p2angleBtn, &p3angleBtn, &p4angleBtn};
01034 GuiText *angleTexts[MAX_PLAYERS] = {&p1angleTxt, &p2angleTxt, &p3angleTxt, &p4angleTxt};
01035 GuiText *angleTextsOver[MAX_PLAYERS] = {&p1angleTxtOver, &p2angleTxtOver, &p3angleTxtOver, &p4angleTxtOver};
01036
01037 GuiButton *dxButtons[MAX_PLAYERS] = {&p1dxBtn, &p2dxBtn, &p3dxBtn, &p4dxBtn};
01038 GuiText *dxTexts[MAX_PLAYERS] = {&p1dxTxt, &p2dxTxt, &p3dxTxt, &p4dxTxt};
01039 GuiText *dxTextsOver[MAX_PLAYERS] = {&p1dxTxtOver, &p2dxTxtOver, &p3dxTxtOver, &p4dxTxtOver};
01040
01041 GuiButton *dyButtons[MAX_PLAYERS] = {&p1dyBtn, &p2dyBtn, &p3dyBtn, &p4dyBtn};
01042 GuiText *dyTexts[MAX_PLAYERS] = {&p1dyTxt, &p2dyTxt, &p3dyTxt, &p4dyTxt};
01043 GuiText *dyTextsOver[MAX_PLAYERS] = {&p1dyTxtOver, &p2dyTxtOver, &p3dyTxtOver, &p4dyTxtOver};
01044
01045
01046 u8 prevWidth[MAX_PLAYERS];
01047 u8 prevScale[MAX_PLAYERS];
01048 float prevAngle[MAX_PLAYERS];
01049 s16 prevDX[MAX_PLAYERS];
01050 s16 prevDY[MAX_PLAYERS];
01051
01052 for (int i = 0; i < g_options->players; ++i, player_x += player_dx)
01053 {
01054 y = 0;
01055
01056 widthButtons[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01057 widthButtons[i]->SetPosition(player_x, y += dy);
01058 widthButtons[i]->SetLabel(widthTexts[i]);
01059 widthButtons[i]->SetLabelOver(widthTextsOver[i]);
01060 widthButtons[i]->SetEffectGrow();
01061 sprintf(buf, "width: %d", g_players[i].playfieldWidth);
01062 widthTexts[i]->SetText(buf);
01063 widthTextsOver[i]->SetText(buf);
01064
01065 scaleButtons[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01066 scaleButtons[i]->SetPosition(player_x, y += dy);
01067 scaleButtons[i]->SetLabel(scaleTexts[i]);
01068 scaleButtons[i]->SetLabelOver(scaleTextsOver[i]);
01069 scaleButtons[i]->SetEffectGrow();
01070 sprintf(buf, "scale: %d", g_players[i].playfieldScale);
01071 scaleTexts[i]->SetText(buf);
01072 scaleTextsOver[i]->SetText(buf);
01073
01074 angleButtons[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01075 angleButtons[i]->SetPosition(player_x, y += dy);
01076 angleButtons[i]->SetLabel(angleTexts[i]);
01077 angleButtons[i]->SetLabelOver(angleTextsOver[i]);
01078 angleButtons[i]->SetEffectGrow();
01079 sprintf(buf, "angle: %d", (int)g_players[i].cubeAngle);
01080 angleTexts[i]->SetText(buf);
01081 angleTextsOver[i]->SetText(buf);
01082
01083 dxButtons[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01084 dxButtons[i]->SetPosition(player_x, y += dy);
01085 dxButtons[i]->SetLabel(dxTexts[i]);
01086 dxButtons[i]->SetLabelOver(dxTextsOver[i]);
01087 dxButtons[i]->SetEffectGrow();
01088 sprintf(buf, "dx: %d", g_players[i].playfieldDX);
01089 dxTexts[i]->SetText(buf);
01090 dxTextsOver[i]->SetText(buf);
01091
01092 dyButtons[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
01093 dyButtons[i]->SetPosition(player_x, y += dy);
01094 dyButtons[i]->SetLabel(dyTexts[i]);
01095 dyButtons[i]->SetLabelOver(dyTextsOver[i]);
01096 dyButtons[i]->SetEffectGrow();
01097 sprintf(buf, "dy: %d", g_players[i].playfieldDY);
01098 dyTexts[i]->SetText(buf);
01099 dyTextsOver[i]->SetText(buf);
01100
01101 window.Append(widthButtons[i]);
01102 window.Append(scaleButtons[i]);
01103 window.Append(angleButtons[i]);
01104 window.Append(dxButtons[i]);
01105 window.Append(dyButtons[i]);
01106
01107 prevWidth[i] = g_players[i].playfieldWidth;
01108 prevScale[i] = g_players[i].playfieldScale;
01109 prevAngle[i] = g_players[i].cubeAngle;
01110 prevDX[i] = g_players[i].playfieldDX;
01111 prevDY[i] = g_players[i].playfieldDY;
01112 }
01113
01114 window.Append(&confirmBtn);
01115 window.Append(&cancelBtn);
01116 mainWindow->Append(&window);
01117
01118 g_tcycMenu = TCYC_MENU_NONE;
01119
01120 while (g_tcycMenu == TCYC_MENU_NONE)
01121 {
01122 ALL_ScanPads();
01123 TCYC_ProcessEditModeInput();
01124 TCYC_DrawEditMode();
01125 TCYC_Render();
01126
01127 if (confirmBtn.GetState() == STATE_CLICKED)
01128 {
01129 g_tcycMenu = TCYC_MENU_MAIN;
01130 break;
01131 }
01132 else if (cancelBtn.GetState() == STATE_CLICKED)
01133 {
01134 for (int i = 0; i < g_options->players; ++i)
01135 {
01136 g_players[i].playfieldWidth = prevWidth[i];
01137 g_players[i].playfieldScale = prevScale[i];
01138 g_players[i].cubeAngle = prevAngle[i];
01139 g_players[i].playfieldDX = prevDX[i];
01140 g_players[i].playfieldDY = prevDY[i];
01141 }
01142
01143 g_tcycMenu = TCYC_MENU_MAIN;
01144 break;
01145 }
01146
01147 for (int i = 0; i < g_options->players; ++i)
01148 {
01149 if (widthButtons[i]->GetState() == STATE_SELECTED)
01150 {
01151 int incr = 0;
01152
01153 if (A_PRESSED(i))
01154 incr = 2;
01155 else if (B_PRESSED(i))
01156 incr = -2;
01157
01158 if (incr)
01159 {
01160 g_players[i].playfieldWidth += incr;
01161
01162 if (g_players[i].playfieldWidth > MAX_PLAYFIELD_WIDTH)
01163 g_players[i].playfieldWidth = MAX_PLAYFIELD_WIDTH;
01164 else if (g_players[i].playfieldWidth < MIN_PLAYFIELD_WIDTH)
01165 g_players[i].playfieldWidth = MIN_PLAYFIELD_WIDTH;
01166
01167 sprintf(buf, "width: %d", g_players[i].playfieldWidth);
01168 widthTexts[i]->SetText(buf);
01169 widthTextsOver[i]->SetText(buf);
01170
01171 float maxAngle = 360 / (float)g_players[i].playfieldWidth;
01172 if (g_players[i].cubeAngle > maxAngle)
01173 {
01174 g_players[i].cubeAngle = maxAngle;
01175 sprintf(buf, "angle: %d", (int)g_players[i].cubeAngle);
01176 angleTexts[i]->SetText(buf);
01177 angleTextsOver[i]->SetText(buf);
01178 }
01179 }
01180 }
01181 else if (scaleButtons[i]->GetState() == STATE_SELECTED)
01182 {
01183 int incr = 0;
01184
01185 if (A_PRESSED(i))
01186 incr = 1;
01187 else if (B_PRESSED(i))
01188 incr = -1;
01189
01190 if (incr)
01191 {
01192 g_players[i].playfieldScale += incr;
01193
01194 if (g_players[i].playfieldScale > MAX_PLAYFIELD_SCALE)
01195 g_players[i].playfieldScale = MAX_PLAYFIELD_SCALE;
01196 else if (g_players[i].playfieldScale < MIN_PLAYFIELD_SCALE)
01197 g_players[i].playfieldScale = MIN_PLAYFIELD_SCALE;
01198
01199 sprintf(buf, "scale: %d", g_players[i].playfieldScale);
01200 scaleTexts[i]->SetText(buf);
01201 scaleTextsOver[i]->SetText(buf);
01202 }
01203 }
01204 else if (angleButtons[i]->GetState() == STATE_SELECTED)
01205 {
01206 int incr = 0;
01207
01208 if (A_PRESSED(i))
01209 incr = 1;
01210 else if (B_PRESSED(i))
01211 incr = -1;
01212
01213 if (incr)
01214 {
01215 g_players[i].cubeAngle += incr;
01216
01217 float maxAngle = 360 / (float)g_players[i].playfieldWidth;
01218 if (g_players[i].cubeAngle > maxAngle)
01219 {
01220 g_players[i].cubeAngle = maxAngle;
01221 }
01222 else if (g_players[i].cubeAngle < MIN_CUBE_ANGLE)
01223 {
01224 g_players[i].cubeAngle = MIN_CUBE_ANGLE;
01225 }
01226 else
01227 {
01228 g_players[i].cubeAngle = (int)g_players[i].cubeAngle;
01229 }
01230
01231 sprintf(buf, "angle: %d", (int)g_players[i].cubeAngle);
01232 angleTexts[i]->SetText(buf);
01233 angleTextsOver[i]->SetText(buf);
01234 }
01235 }
01236 else if (dxButtons[i]->GetState() == STATE_SELECTED)
01237 {
01238 int incr = 0;
01239
01240 if (A_PRESSED(i))
01241 incr = 5;
01242 else if (B_PRESSED(i))
01243 incr = -5;
01244
01245 if (incr)
01246 {
01247 g_players[i].playfieldDX += incr;
01248
01249 if (g_players[i].playfieldDX > MAX_PLAYFIELD_DELTA)
01250 g_players[i].playfieldDX = MAX_PLAYFIELD_DELTA;
01251 else if (g_players[i].playfieldDX < -MAX_PLAYFIELD_DELTA)
01252 g_players[i].playfieldDX = -MAX_PLAYFIELD_DELTA;
01253
01254 sprintf(buf, "dx: %d", g_players[i].playfieldDX);
01255 dxTexts[i]->SetText(buf);
01256 dxTextsOver[i]->SetText(buf);
01257 }
01258 }
01259 else if (dyButtons[i]->GetState() == STATE_SELECTED)
01260 {
01261 int incr = 0;
01262
01263 if (A_PRESSED(i))
01264 incr = 5;
01265 else if (B_PRESSED(i))
01266 incr = -5;
01267
01268 if (incr)
01269 {
01270 g_players[i].playfieldDY += incr;
01271
01272 if (g_players[i].playfieldDY > MAX_PLAYFIELD_DELTA)
01273 g_players[i].playfieldDY = MAX_PLAYFIELD_DELTA;
01274 else if (g_players[i].playfieldDY < -MAX_PLAYFIELD_DELTA)
01275 g_players[i].playfieldDY = -MAX_PLAYFIELD_DELTA;
01276
01277 sprintf(buf, "dy: %d", g_players[i].playfieldDY);
01278 dyTexts[i]->SetText(buf);
01279 dyTextsOver[i]->SetText(buf);
01280 }
01281 }
01282 }
01283 }
01284
01285 mainWindow->Remove(&window);
01286 }
01287
01288
01289 void TCYC_DrawEditMode()
01290 {
01291 TCYC_SetUp2D();
01292 TCYC_DrawPlayfieldBoundary();
01293
01294 TCYC_DrawTetriCycleEditMode();
01295
01296 TCYC_SetUp2D();
01297 TCYC_DrawEditPlayfieldMenu();
01298 }
01299
01300
01301 void TCYC_DrawTetriCycleEditMode()
01302 {
01303
01304 GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
01305 GX_LoadProjectionMtx(projection, GX_PERSPECTIVE);
01306
01307 int width;
01308 int height;
01309 int ci;
01310 int top;
01311
01312 for (int i = 0; i < g_options->players; ++i)
01313 {
01314 Player &player = g_players[i];
01315
01316 width = player.playfieldWidth;
01317 ci = player.gameData.cycleIdx;
01318 top = 0;
01319
01320 for (int x = 0; x < width; ++x)
01321 {
01322 height = player.playfieldHeight;
01323
01324 for (int y = height - 1; y >= top; --y)
01325 {
01326 int offset = (x - ci >= 0) ? x - ci : width - (ci - x);
01327 player.DrawBlockAsCube(offset, y, COLOR_ID_RED);
01328 }
01329
01330 if (top < height - 1)
01331 ++top;
01332 }
01333
01334 player.DrawBase();
01335 }
01336 }
01337
01338
01339 void TCYC_DrawEditPlayfieldMenu()
01340 {
01341 mainWindow->Draw();
01342
01343 for (int i = MAX_PLAYERS - 1; i >= 0; --i)
01344 {
01345 if (userInput[i].wpad->ir.valid)
01346 {
01347 Menu_DrawImg(userInput[i].wpad->ir.x - 48, userInput[i].wpad->ir.y - 48,
01348 96, 96, pointer[i]->GetImage(), userInput[i].wpad->ir.angle,
01349 1, 1, 255);
01350 }
01351
01352 DoRumble(i);
01353 }
01354
01355 for (int i = 0; i < MAX_PLAYERS; ++i)
01356 mainWindow->Update(&userInput[i]);
01357 }
01358
01359
01360 void TCYC_GameInit()
01361 {
01362 MODPlay_Start(&g_modPlay);
01363 sgenrand(time(NULL));
01364 g_tcycMenu = TCYC_MENU_NONE;
01365
01366 for (int i = 0; i < g_options->players; ++i)
01367 g_players[i].Reset();
01368 }
01369
01370
01371 void TCYC_GameOnExit()
01372 {
01373 MODPlay_Stop(&g_modPlay);
01374
01375
01376
01377 PowerupUtils::DeleteAllPowerups();
01378 }
01379
01380
01381 void TCYC_InitPieceDescriptions()
01382 {
01383
01384 for (int i = 0; i < TETRISPIECE_ID_RAND_MAX; ++i)
01385 {
01386
01387 for (int rot = 0; rot < 4; ++rot)
01388 {
01389 TetrisPieceDesc &desc = g_pieceDesc[i][rot];
01390
01391
01392 for (int y = 0; y < 4; ++y)
01393 {
01394 for (int x = 0; x < 4; ++x)
01395 {
01396
01397 desc.map[x][y] = pieces_bin[i * 4 * 4 * 4 + rot * 4 * 4 + y * 4 + x];
01398 }
01399 }
01400 }
01401 }
01402
01403
01404 TetrisPieceDesc &desc = g_pieceDesc[TETRISPIECE_ID_JUNK][0];
01405 desc.map[1][1] = desc.map[2][1] = desc.map[3][1] =
01406 desc.map[1][2] = desc.map[3][2] =
01407 desc.map[1][3] = desc.map[2][3] = desc.map[3][3] = 1;
01408
01409 for (int rot = 1; rot < 4; ++rot)
01410 memcpy(&g_pieceDesc[TETRISPIECE_ID_JUNK][rot], &desc, sizeof(TetrisPieceDesc));
01411 }