Advertisement
Guest User

Yossi

a guest
Apr 17th, 2009
576
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.38 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <string>
  5. #include <algorithm>
  6. #include <gccore.h>
  7. #include <wiiuse/wpad.h>
  8. #include <fat.h>
  9. #include <wiisprite.h>
  10. #include <hbmenuhead.h>
  11. // remember, add here, add to the makefile
  12.  
  13. #include "bufferredchecker.h"
  14. #include "bufferredfill.h"
  15. #include "bufferblackchecker.h"
  16. #include "bufferblackfill.h"
  17. #include "bufferemptychecker.h"
  18. #include "bufferemptyfill.h"
  19. #include "bufferpressA.h"
  20. #include "bufferredwins.h"
  21. #include "bufferblackwins.h"
  22. #include "bufferemptywins.h"
  23.  
  24. /* TODO:
  25.  * add intro - DONE
  26.  * add better end game result - DONE
  27.  * make A button abort intro during it's run - GIVE UP?
  28.  * add homebrew menu - DONE
  29.  * two player support - DONE
  30.  * create settings.ini - DONE
  31.  * create setting for one/two wiimote support - DONE
  32.  * image loading - FIXED
  33.  * better 2player start (a at any time) - DONE
  34.  * allow setiiiings.ini - DONE
  35.  * make it look like its sliding down - DONE
  36.    
  37.    tolerate different name in path - Mostly done
  38.    redo win()
  39.    nunchuck
  40.    keep track of what was played (for undos)
  41.    create ai for single player game
  42.    make ai smarter
  43.    figure out image loading without extra .c files
  44.    clean up code (big time :P)
  45.    add the other homebrew menu
  46.    sound? simpsons sounds (??)
  47.    rumble?
  48.  * */
  49.  
  50. #define EVER ;;
  51.  
  52. #define ONEWIIMOTE 1
  53. #define TWOWIIMOTES 2
  54. #define NUNCHUCK 3
  55.  
  56. #define CPU 0
  57. #define HUMAN 1
  58.  
  59. #define BLACK 0
  60. #define RED 1
  61. #define EMPTY -1
  62.  
  63. int control = ONEWIIMOTE;
  64. int numrows = 6;
  65. int numcols = 7;
  66. int numwin = 4;
  67. int firstplayer = BLACK;
  68. int moves = 0; // moves made in this game. helps spot tie // do NOT merge with whos_turn
  69. int player2 = HUMAN;
  70. std::string path;
  71.  
  72. // libwiisprite uses wsp as it's namespace
  73. using namespace wsp;
  74.  
  75. GameWindow gwd; // Initializes and renders our scene
  76.  
  77. Image redchecker;
  78. Image redfill;
  79. Image blackchecker;
  80. Image blackfill;
  81. Image emptychecker;
  82. Image emptyfill;
  83. Image pressA;
  84. Image redwins;
  85. Image blackwins;
  86. Image emptywins;
  87.  
  88. Sprite board[9 +1][13]; // largest board size is 9 x 13
  89. Sprite label;
  90.  
  91. // all our little helpers in the order they were thought of :)
  92. void composeboard(int num_rows, int num_cols, LayerManager *lm);
  93. Image *getchecker(int color);
  94. Image *getfill(int color);
  95. bool drop(int col, int color, int x, int y, LayerManager *lm);
  96. bool win(int testcolor);
  97. void intro();
  98. Image *getwinner(int color);
  99. int strtocolor(char *str);
  100. bool strtobool(char *str);
  101. int strtocontrol(char *str);
  102. int getWPADchannel(int whosturn);
  103. const char *appendpathto(char *argv, const char *str);
  104.  
  105. int main(int argc, char **argv)
  106. {
  107.     char temp[256];
  108.     strcpy(temp, argv[0]);
  109.     char *endofpath = strrchr(temp, '/');
  110.    
  111.     // it's an init, i'nit?
  112.     WPAD_Init();
  113.    
  114.     if (fatInitDefault())
  115.     {
  116.         FILE *f = NULL;
  117.  
  118.         f = fopen(appendpathto(argv[0], "setiiiings.ini"), "rb");
  119.         if (f == NULL)
  120.             f = fopen(appendpathto(argv[0], "settings.ini"), "rb");
  121.        
  122.         if (f != NULL) // settings parser. if neither of those exist this would still be NULL and we go on with our defaults
  123.         {
  124.             char file_line [25];
  125.             while (fgets (file_line, 25, f) && f != NULL)
  126.             {
  127.                 char *temp;
  128.                 temp = strtok(file_line, " ");
  129.                 if (temp != NULL && temp[0] != '#') // else ignore line
  130.                 {
  131.                     if (!strcmp(temp, "player2"))
  132.                     {
  133.                         temp = strtok (NULL, " ");
  134.                         if (temp != NULL)
  135.                             strtobool(temp);
  136.                     }
  137.                     if (!strcmp(temp, "whostarts"))
  138.                     {
  139.                         temp = strtok (NULL, " ");
  140.                         if (temp != NULL)
  141.                             firstplayer = strtocolor(temp);
  142.                     }
  143.                     if (!strcmp(temp, "control"))
  144.                     {
  145.                         temp = strtok (NULL, " ");
  146.                         if (temp != NULL)
  147.                             control = strtocontrol(temp);
  148.                     }
  149.                     if (!strcmp(temp, "rows"))
  150.                     {
  151.                         temp = strtok (NULL, " ");
  152.                         if (temp != NULL)
  153.                             numrows = atoi(temp);
  154.                         if (numrows <= 0 || numrows >= 10)
  155.                             numrows = 6;
  156.                     }
  157.                     if (!strcmp(temp, "cols"))
  158.                     {
  159.                         temp = strtok (NULL, " ");
  160.                         if (temp != NULL)
  161.                             numcols = atoi(temp);
  162.                         if (numcols <= 0 || numcols >= 14)
  163.                             numcols = 7;
  164.                     }
  165.                     if (!strcmp(temp, "winlength"))
  166.                     {
  167.                         temp = strtok (NULL, " ");
  168.                         if (temp != NULL)
  169.                             numwin = atoi(temp);
  170.                         int m = std::max(numcols, numrows);
  171.                         if (numwin > m)
  172.                             numwin = m;
  173.                         if (numwin <= 0)
  174.                             numwin = 4;
  175.                     }              
  176.                 }
  177.             }
  178.             fclose(f);
  179.         }
  180.                
  181.         Image *images[] = { &redchecker,
  182.             &redfill,
  183.             &blackchecker,
  184.             &blackfill,
  185.             &emptychecker,
  186.             &emptyfill,
  187.             &pressA,
  188.             &redwins,
  189.             &blackwins,
  190.             &emptywins
  191.         };
  192.        
  193.         const char *imagesPaths[] = {"images/redchecker.png",
  194.             "images/redfill.png",
  195.             "images/blackchecker.png",
  196.             "images/blackfill.png",
  197.             "images/emptychecker.png",
  198.             "images/emptyfill.png",
  199.             "images/pressA.png",
  200.             "images/redwins.png",
  201.             "images/blackwins.png",
  202.             "images/emptywins.png"
  203.         };
  204.        
  205.         for (int i = 0; i < 10; i++)
  206.         {
  207.             strcpy(endofpath, imagesPaths[i]);
  208.             images[i]->LoadImage(temp);
  209.         }
  210.        
  211.         /*redchecker.LoadImage(appendpathto(argv[0], "images/redchecker.png"));
  212.         redfill.LoadImage(appendpathto(argv[0], "images/redfill.png"));
  213.         blackchecker.LoadImage(appendpathto(argv[0], "images/blackchecker.png"));
  214.         blackfill.LoadImage(appendpathto(argv[0], "images/blackfill.png"));
  215.         //emptychecker.LoadImage(appendpathto(argv[0], "images/emptychecker.png"));
  216.         emptyfill.LoadImage(appendpathto(argv[0], "images/emptyfill.png"));
  217.         pressA.LoadImage(appendpathto(argv[0], "images/pressA.png"));
  218.         redwins.LoadImage(appendpathto(argv[0], "images/redwins.png"));
  219.         blackwins.LoadImage(appendpathto(argv[0], "images/blackwins.png"));
  220.         emptywins.LoadImage(appendpathto(argv[0], "images/emptywins.png"));
  221.         */
  222.     }
  223.    
  224.     /*test code follows
  225.     static void *xfb = NULL;
  226.     static GXRModeObj *rmode = NULL;
  227.     VIDEO_Init();
  228.     rmode = VIDEO_GetPreferredMode(NULL);
  229.     xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
  230.     console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
  231.     VIDEO_Configure(rmode);
  232.     VIDEO_SetNextFramebuffer(xfb);
  233.     VIDEO_SetBlack(FALSE);
  234.     VIDEO_Flush();
  235.     VIDEO_WaitVSync();
  236.     if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
  237.  
  238.     printf(temp);
  239.     sleep(5);
  240.     return 0;
  241.     // till here*/
  242.  
  243.     gwd.InitVideo();
  244.     gwd.SetBackground((GXColor){ 255, 255, 255, 255 });
  245.    
  246.     LayerManager game((numrows+1)*numcols);
  247.   { // just to roll up default image loading code
  248.     if(!redchecker.IsInitialized())
  249.         if(redchecker.LoadImage(bufferredchecker) != IMG_LOAD_ERROR_NONE)
  250.             exit(0);
  251.  
  252.     if(!redfill.IsInitialized())   
  253.         if(redfill.LoadImage(bufferredfill) != IMG_LOAD_ERROR_NONE)
  254.             exit(0);
  255.  
  256.     if(!blackchecker.IsInitialized())
  257.         if(blackchecker.LoadImage(bufferblackchecker) != IMG_LOAD_ERROR_NONE)
  258.             exit(0);
  259.  
  260.     if(!blackfill.IsInitialized())
  261.         if(blackfill.LoadImage(bufferblackfill) != IMG_LOAD_ERROR_NONE)
  262.             exit(0);
  263.  
  264.     if(!emptychecker.IsInitialized())
  265.         if(emptychecker.LoadImage(bufferemptychecker) != IMG_LOAD_ERROR_NONE)
  266.             exit(0);
  267.  
  268.     if(!emptyfill.IsInitialized())
  269.         if(emptyfill.LoadImage(bufferemptyfill) != IMG_LOAD_ERROR_NONE)
  270.             exit(0);
  271.  
  272.     if(!pressA.IsInitialized())
  273.         if(pressA.LoadImage(bufferpressA) != IMG_LOAD_ERROR_NONE)
  274.             exit(0);
  275.  
  276.     if(!redwins.IsInitialized())
  277.         if(redwins.LoadImage(bufferredwins) != IMG_LOAD_ERROR_NONE)
  278.             exit(0);
  279.  
  280.     if(!blackwins.IsInitialized())
  281.         if(blackwins.LoadImage(bufferblackwins) != IMG_LOAD_ERROR_NONE)
  282.             exit(0);
  283.  
  284.     if(!emptywins.IsInitialized())
  285.         if(emptywins.LoadImage(bufferemptywins) != IMG_LOAD_ERROR_NONE)
  286.             exit(0);
  287.   }
  288.     intro();
  289.     composeboard(numrows, numcols, &game);
  290.  
  291.     int centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2; // (screen size - (size of image * numcols)) / 2
  292.     int centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
  293.    
  294.     int whos_turn = firstplayer;   
  295.     int active_col = numcols / 2; // what column the checker is over (center one)
  296.     board[0][active_col].SetImage(getchecker(whos_turn%2));
  297.  
  298.     bool won = false;
  299.  
  300.     for(EVER) // playtime loop
  301.     {
  302.         WPAD_ScanPads();
  303.            
  304.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_HOME) // old school exit
  305.             break;
  306.  
  307.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_MINUS) // Arikado and Co.'s homebrew menu
  308.             homemenu(&gwd);
  309.            
  310.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_PLUS) // MetaFight's hombrew menu
  311.             ; // ADD THIS CODE
  312.  
  313.         if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in late
  314.             control = TWOWIIMOTES;
  315.            
  316.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_LEFT && player2) // move left
  317.         {
  318.             board[0][active_col].SetImage(getchecker(EMPTY));
  319.             active_col -= 1;
  320.             if (active_col < 0) active_col += numcols;
  321.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  322.         }
  323.  
  324.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_RIGHT && player2) // move right
  325.         {
  326.             board[0][active_col].SetImage(getchecker(EMPTY));
  327.             active_col += 1;
  328.             if (active_col > numcols - 1) active_col -= numcols;
  329.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  330.         }
  331.  
  332.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_B && !won && player2) // drop the checker
  333.         {
  334.             bool dropped = drop(active_col, whos_turn%2, centerX, centerY, &game);
  335.             won = win(whos_turn%2);
  336.            
  337.             if (dropped && !won) // common case
  338.             {
  339.                 whos_turn++; // change turns. black is even, red is odd
  340.                 moves++;
  341.             }
  342.            
  343.             if (won) // game over
  344.             {
  345.                 label.SetImage(getwinner(whos_turn%2));
  346.                 label.SetTransparency(0xFF);
  347.             }
  348.             else if (moves >= (numrows * numcols)) // tie
  349.             {
  350.                 label.SetImage(getwinner(EMPTY));
  351.                 label.SetTransparency(0xFF);
  352.             }
  353.            
  354.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  355.         }
  356.  
  357.         if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_1 && player2) // reset game
  358.         {                              // winner gets to do it, so they have time for gloating
  359.             composeboard(numrows, numcols, &game);
  360.             moves = 0;
  361.             won = false;
  362.             whos_turn = firstplayer;
  363.             active_col = numcols / 2;
  364.             board[0][active_col].SetImage(getchecker(whos_turn%2));
  365.             centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2;
  366.             centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
  367.             label.SetTransparency(0x00);
  368.         }
  369.        
  370.         if (!player2) // CPU is player 2
  371.         {
  372.             ; // DO AI HERE
  373.         }
  374.  
  375.         game.Draw(centerX, centerY);
  376.         label.Draw(-2,0);
  377.         gwd.Flush();
  378.     }
  379.    
  380.     // One last draw and ...
  381.     game.Draw(centerX, centerY);
  382.     gwd.Flush(); // ... flush twice, it's a long way to the kitchen
  383.    
  384.     // And we return to our loader!
  385.     return 0;
  386. }
  387.  
  388. void composeboard(int num_rows, int num_cols, LayerManager *lm)
  389. {
  390.     for (int row = 0; row < num_rows + 1; row++) // num_rows and the blank row on top
  391.     {
  392.         for (int col = 0; col < num_cols; col++)
  393.         {
  394.             if (!row)
  395.                 board[row][col].SetImage(&emptychecker);
  396.             else
  397.                 board[row][col].SetImage(&emptyfill);
  398.             board[row][col].SetPosition(emptychecker.GetWidth()*col, emptychecker.GetHeight()*row);
  399.             lm->Append(&(board[row][col]));
  400.         }
  401.     }
  402.     return;
  403. }
  404.  
  405. Image *getchecker(int color)
  406. {
  407.     if (color == BLACK)
  408.         return &blackchecker;
  409.     if (color == RED)
  410.         return &redchecker;
  411.     return &emptychecker;
  412. }
  413.  
  414. Image *getfill(int color)
  415. {
  416.     if (color == BLACK)
  417.         return &blackfill;
  418.     if (color == RED)
  419.         return &redfill;
  420.     return &emptyfill;
  421. }
  422.  
  423. bool drop(int col, int color, int x, int y, LayerManager *lm)
  424. {
  425.     int row;
  426.     for(row = 0; row < numrows; row++)
  427.     {
  428.         if (row != 0)
  429.         {
  430.             if (row == 1)
  431.             {
  432.                 board[row][col].SetImage(getfill(color));
  433.                 if (board[row+1][col].GetImage() != &emptyfill)
  434.                     return true;
  435.             }
  436.             else
  437.             {
  438.                 board[row-1][col].SetImage(getfill(EMPTY));
  439.                 board[row][col].SetImage(getfill(color));
  440.                 if (board[row+1][col].GetImage() != &emptyfill)
  441.                     return true;
  442.             }
  443.         }
  444.         else
  445.         {
  446.             if (board[row+1][col].GetImage() != &emptyfill)
  447.                 return false;
  448.         }
  449.        
  450.         lm->Draw(x, y);
  451.         gwd.Flush();   
  452.     }
  453.    
  454.     board[row-1][col].SetImage(getfill(EMPTY));
  455.     board[row][col].SetImage(getfill(color));
  456.     return true; // got to the bottom
  457. }
  458.  
  459. bool win(int testcolor)
  460. {
  461.     int row;
  462.     int col;
  463.     int i;
  464.     Image *color = getfill(testcolor); // what color we are trying to find lines of
  465.    
  466.     // down
  467.     for (row = 0+1; row <= numrows-numwin+1; row++) // the +1 stuff is cuz row 0 is the blank top row
  468.     {
  469.         for (col = 0; col < numcols; col++)
  470.         {
  471.             for (i = 0; i < numwin; i++)
  472.             {
  473.                 if (board[row+i][col].GetImage() != color)
  474.                     break;
  475.             }
  476.             if (i == numwin)
  477.                 return true;
  478.         }
  479.     }
  480.    
  481.     // right
  482.     for (col = 0; col <= numcols-numwin; col++)
  483.     {
  484.         for (row = 0+1; row < numrows+1; row++)
  485.         {
  486.             for (i = 0; i < numwin; i++)
  487.             {
  488.                 if (board[row][col+i].GetImage() != color)
  489.                     break;
  490.             }
  491.             if (i == numwin)
  492.                 return true;
  493.         }
  494.     }
  495.    
  496.     // downright
  497.     for (row = 0+1; row <= numrows-numwin+1; row++)
  498.     {
  499.         for (col = 0; col <= numcols-numwin; col++)
  500.         {
  501.             for (i = 0; i < numwin; i++)
  502.             {
  503.                 if (board[row+i][col+i].GetImage() != color)
  504.                     break;
  505.             }
  506.             if (i == numwin)
  507.                 return true;
  508.         }
  509.     }
  510.    
  511.     // downleft
  512.     for (row = 0+1; row <= numrows-numwin+1; row++)
  513.     {
  514.         for (col = numcols-1; col >= numcols-numwin; col--)
  515.         {
  516.             for (i = 0; i < numwin; i++)
  517.             {
  518.                 if (board[row+i][col-i].GetImage() != color)
  519.                     break;
  520.             }
  521.             if (i == numwin)
  522.                 return true;
  523.         }
  524.     }
  525.    
  526.     return false;
  527. }
  528.  
  529. void intro()
  530. {
  531.     LayerManager introlm((6+1)*7);
  532.     composeboard(6, 7, &introlm);
  533.     for (int row = 6; row >= 1; row--)
  534.     {
  535.         for (int col = 6; col >= 0; col--)
  536.         {
  537.             if (row != 2)
  538.             {
  539.                 if (col % 2)
  540.                     board[row][col].SetImage(getfill(RED));
  541.                 else
  542.                     board[row][col].SetImage(getfill(BLACK));
  543.             }
  544.             else
  545.                 board[row][col].SetImage(getfill(RED));
  546.        
  547.             introlm.Draw(152, 72);
  548.             gwd.Flush();
  549.         }
  550.     }
  551.     label.SetImage(&pressA);
  552.     for(EVER) // intro loop
  553.     {
  554.         WPAD_ScanPads();
  555.         if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in
  556.             control = TWOWIIMOTES;
  557.            
  558.         if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A)
  559.         {
  560.             label.SetTransparency(0x00);
  561.             return;
  562.         }
  563.         //if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_B)exit(0); // REMOVE?
  564.         introlm.Draw(152, 72);
  565.         label.Draw(189,76);
  566.         gwd.Flush();
  567.     }
  568. }
  569.  
  570. Image *getwinner(int color)
  571. {
  572.     if (color == BLACK)
  573.         return &blackwins;
  574.     if (color == RED)
  575.         return &redwins;
  576.     return &emptywins;
  577. }
  578.  
  579. int strtocolor(char *str)
  580. {
  581.     if (!strcmp(str, "RED"))
  582.         return RED;
  583.     return BLACK;
  584. }
  585.  
  586. bool strtobool(char *str)
  587. {
  588.     if (!strcmp(str, "FALSE"))
  589.         return false;
  590.     return true;
  591. }
  592.  
  593. int strtocontrol(char *str)
  594. {
  595.     if (!strcmp(str, "TWOWIIMOTES"))
  596.         return TWOWIIMOTES;
  597.     if (!strcmp(str, "NUNCHUCK"))
  598.         return NUNCHUCK;
  599.     return ONEWIIMOTE; 
  600. }
  601.  
  602. int getWPADchannel(int whosturn)
  603. {
  604.     if (control == NUNCHUCK)
  605.         ; // return ?      
  606.     if (control == TWOWIIMOTES)
  607.         return whosturn % 2;
  608.     return WPAD_CHAN_0;
  609. }
  610.  
  611. const char *appendpathto(char *argv, const char *str) // this entire function is being phased out. the settings files still use it, but they wont as soon as i find time to move this forward again.
  612. {
  613.     // <SquidMan> inspired this
  614.     /*int i;
  615.     int z;
  616.     int numchars = 8; // make this figure itself out
  617.     char result[strlen(argv) - numchars + strlen(str)];
  618.     strcpy(result, argv);
  619.     for(i = strlen(argv) - numchars, z = 0; z < numchars; z++, i++)
  620.             result[i] = str[z];
  621.     return result;*/
  622.  
  623.     //thanks to TD-Linux & rck`d
  624.     path = argv;
  625.     path.replace(path.size()-8, 8, str);
  626.     return path.c_str();
  627. }
  628.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement