Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <string>
- #include <algorithm>
- #include <gccore.h>
- #include <wiiuse/wpad.h>
- #include <fat.h>
- #include <wiisprite.h>
- #include <hbmenuhead.h>
- // remember, add here, add to the makefile
- #include "bufferredchecker.h"
- #include "bufferredfill.h"
- #include "bufferblackchecker.h"
- #include "bufferblackfill.h"
- #include "bufferemptychecker.h"
- #include "bufferemptyfill.h"
- #include "bufferpressA.h"
- #include "bufferredwins.h"
- #include "bufferblackwins.h"
- #include "bufferemptywins.h"
- /* TODO:
- * add intro - DONE
- * add better end game result - DONE
- * make A button abort intro during it's run - GIVE UP?
- * add homebrew menu - DONE
- * two player support - DONE
- * create settings.ini - DONE
- * create setting for one/two wiimote support - DONE
- * image loading - FIXED
- * better 2player start (a at any time) - DONE
- * allow setiiiings.ini - DONE
- * make it look like its sliding down - DONE
- tolerate different name in path - Mostly done
- redo win()
- nunchuck
- keep track of what was played (for undos)
- create ai for single player game
- make ai smarter
- figure out image loading without extra .c files
- clean up code (big time :P)
- add the other homebrew menu
- sound? simpsons sounds (??)
- rumble?
- * */
- #define EVER ;;
- #define ONEWIIMOTE 1
- #define TWOWIIMOTES 2
- #define NUNCHUCK 3
- #define CPU 0
- #define HUMAN 1
- #define BLACK 0
- #define RED 1
- #define EMPTY -1
- int control = ONEWIIMOTE;
- int numrows = 6;
- int numcols = 7;
- int numwin = 4;
- int firstplayer = BLACK;
- int moves = 0; // moves made in this game. helps spot tie // do NOT merge with whos_turn
- int player2 = HUMAN;
- std::string path;
- // libwiisprite uses wsp as it's namespace
- using namespace wsp;
- GameWindow gwd; // Initializes and renders our scene
- Image redchecker;
- Image redfill;
- Image blackchecker;
- Image blackfill;
- Image emptychecker;
- Image emptyfill;
- Image pressA;
- Image redwins;
- Image blackwins;
- Image emptywins;
- Sprite board[9 +1][13]; // largest board size is 9 x 13
- Sprite label;
- // all our little helpers in the order they were thought of :)
- void composeboard(int num_rows, int num_cols, LayerManager *lm);
- Image *getchecker(int color);
- Image *getfill(int color);
- bool drop(int col, int color, int x, int y, LayerManager *lm);
- bool win(int testcolor);
- void intro();
- Image *getwinner(int color);
- int strtocolor(char *str);
- bool strtobool(char *str);
- int strtocontrol(char *str);
- int getWPADchannel(int whosturn);
- const char *appendpathto(char *argv, const char *str);
- int main(int argc, char **argv)
- {
- char temp[256];
- strcpy(temp, argv[0]);
- char *endofpath = strrchr(temp, '/');
- // it's an init, i'nit?
- WPAD_Init();
- if (fatInitDefault())
- {
- FILE *f = NULL;
- f = fopen(appendpathto(argv[0], "setiiiings.ini"), "rb");
- if (f == NULL)
- f = fopen(appendpathto(argv[0], "settings.ini"), "rb");
- if (f != NULL) // settings parser. if neither of those exist this would still be NULL and we go on with our defaults
- {
- char file_line [25];
- while (fgets (file_line, 25, f) && f != NULL)
- {
- char *temp;
- temp = strtok(file_line, " ");
- if (temp != NULL && temp[0] != '#') // else ignore line
- {
- if (!strcmp(temp, "player2"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- strtobool(temp);
- }
- if (!strcmp(temp, "whostarts"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- firstplayer = strtocolor(temp);
- }
- if (!strcmp(temp, "control"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- control = strtocontrol(temp);
- }
- if (!strcmp(temp, "rows"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- numrows = atoi(temp);
- if (numrows <= 0 || numrows >= 10)
- numrows = 6;
- }
- if (!strcmp(temp, "cols"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- numcols = atoi(temp);
- if (numcols <= 0 || numcols >= 14)
- numcols = 7;
- }
- if (!strcmp(temp, "winlength"))
- {
- temp = strtok (NULL, " ");
- if (temp != NULL)
- numwin = atoi(temp);
- int m = std::max(numcols, numrows);
- if (numwin > m)
- numwin = m;
- if (numwin <= 0)
- numwin = 4;
- }
- }
- }
- fclose(f);
- }
- Image *images[] = { &redchecker,
- &redfill,
- &blackchecker,
- &blackfill,
- &emptychecker,
- &emptyfill,
- &pressA,
- &redwins,
- &blackwins,
- &emptywins
- };
- const char *imagesPaths[] = {"images/redchecker.png",
- "images/redfill.png",
- "images/blackchecker.png",
- "images/blackfill.png",
- "images/emptychecker.png",
- "images/emptyfill.png",
- "images/pressA.png",
- "images/redwins.png",
- "images/blackwins.png",
- "images/emptywins.png"
- };
- for (int i = 0; i < 10; i++)
- {
- strcpy(endofpath, imagesPaths[i]);
- images[i]->LoadImage(temp);
- }
- /*redchecker.LoadImage(appendpathto(argv[0], "images/redchecker.png"));
- redfill.LoadImage(appendpathto(argv[0], "images/redfill.png"));
- blackchecker.LoadImage(appendpathto(argv[0], "images/blackchecker.png"));
- blackfill.LoadImage(appendpathto(argv[0], "images/blackfill.png"));
- //emptychecker.LoadImage(appendpathto(argv[0], "images/emptychecker.png"));
- emptyfill.LoadImage(appendpathto(argv[0], "images/emptyfill.png"));
- pressA.LoadImage(appendpathto(argv[0], "images/pressA.png"));
- redwins.LoadImage(appendpathto(argv[0], "images/redwins.png"));
- blackwins.LoadImage(appendpathto(argv[0], "images/blackwins.png"));
- emptywins.LoadImage(appendpathto(argv[0], "images/emptywins.png"));
- */
- }
- /*test code follows
- static void *xfb = NULL;
- static GXRModeObj *rmode = NULL;
- VIDEO_Init();
- rmode = VIDEO_GetPreferredMode(NULL);
- xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
- console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
- VIDEO_Configure(rmode);
- VIDEO_SetNextFramebuffer(xfb);
- VIDEO_SetBlack(FALSE);
- VIDEO_Flush();
- VIDEO_WaitVSync();
- if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
- printf(temp);
- sleep(5);
- return 0;
- // till here*/
- gwd.InitVideo();
- gwd.SetBackground((GXColor){ 255, 255, 255, 255 });
- LayerManager game((numrows+1)*numcols);
- { // just to roll up default image loading code
- if(!redchecker.IsInitialized())
- if(redchecker.LoadImage(bufferredchecker) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!redfill.IsInitialized())
- if(redfill.LoadImage(bufferredfill) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!blackchecker.IsInitialized())
- if(blackchecker.LoadImage(bufferblackchecker) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!blackfill.IsInitialized())
- if(blackfill.LoadImage(bufferblackfill) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!emptychecker.IsInitialized())
- if(emptychecker.LoadImage(bufferemptychecker) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!emptyfill.IsInitialized())
- if(emptyfill.LoadImage(bufferemptyfill) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!pressA.IsInitialized())
- if(pressA.LoadImage(bufferpressA) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!redwins.IsInitialized())
- if(redwins.LoadImage(bufferredwins) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!blackwins.IsInitialized())
- if(blackwins.LoadImage(bufferblackwins) != IMG_LOAD_ERROR_NONE)
- exit(0);
- if(!emptywins.IsInitialized())
- if(emptywins.LoadImage(bufferemptywins) != IMG_LOAD_ERROR_NONE)
- exit(0);
- }
- intro();
- composeboard(numrows, numcols, &game);
- int centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2; // (screen size - (size of image * numcols)) / 2
- int centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
- int whos_turn = firstplayer;
- int active_col = numcols / 2; // what column the checker is over (center one)
- board[0][active_col].SetImage(getchecker(whos_turn%2));
- bool won = false;
- for(EVER) // playtime loop
- {
- WPAD_ScanPads();
- if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_HOME) // old school exit
- break;
- if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_MINUS) // Arikado and Co.'s homebrew menu
- homemenu(&gwd);
- if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_PLUS) // MetaFight's hombrew menu
- ; // ADD THIS CODE
- if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in late
- control = TWOWIIMOTES;
- if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_LEFT && player2) // move left
- {
- board[0][active_col].SetImage(getchecker(EMPTY));
- active_col -= 1;
- if (active_col < 0) active_col += numcols;
- board[0][active_col].SetImage(getchecker(whos_turn%2));
- }
- if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_RIGHT && player2) // move right
- {
- board[0][active_col].SetImage(getchecker(EMPTY));
- active_col += 1;
- if (active_col > numcols - 1) active_col -= numcols;
- board[0][active_col].SetImage(getchecker(whos_turn%2));
- }
- if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_B && !won && player2) // drop the checker
- {
- bool dropped = drop(active_col, whos_turn%2, centerX, centerY, &game);
- won = win(whos_turn%2);
- if (dropped && !won) // common case
- {
- whos_turn++; // change turns. black is even, red is odd
- moves++;
- }
- if (won) // game over
- {
- label.SetImage(getwinner(whos_turn%2));
- label.SetTransparency(0xFF);
- }
- else if (moves >= (numrows * numcols)) // tie
- {
- label.SetImage(getwinner(EMPTY));
- label.SetTransparency(0xFF);
- }
- board[0][active_col].SetImage(getchecker(whos_turn%2));
- }
- if(WPAD_ButtonsDown(getWPADchannel(whos_turn))&WPAD_BUTTON_1 && player2) // reset game
- { // winner gets to do it, so they have time for gloating
- composeboard(numrows, numcols, &game);
- moves = 0;
- won = false;
- whos_turn = firstplayer;
- active_col = numcols / 2;
- board[0][active_col].SetImage(getchecker(whos_turn%2));
- centerX = (gwd.GetWidth() - (emptychecker.GetWidth() * numcols)) / 2;
- centerY = (gwd.GetHeight() - (emptychecker.GetHeight() * (numrows+1))) / 2;
- label.SetTransparency(0x00);
- }
- if (!player2) // CPU is player 2
- {
- ; // DO AI HERE
- }
- game.Draw(centerX, centerY);
- label.Draw(-2,0);
- gwd.Flush();
- }
- // One last draw and ...
- game.Draw(centerX, centerY);
- gwd.Flush(); // ... flush twice, it's a long way to the kitchen
- // And we return to our loader!
- return 0;
- }
- void composeboard(int num_rows, int num_cols, LayerManager *lm)
- {
- for (int row = 0; row < num_rows + 1; row++) // num_rows and the blank row on top
- {
- for (int col = 0; col < num_cols; col++)
- {
- if (!row)
- board[row][col].SetImage(&emptychecker);
- else
- board[row][col].SetImage(&emptyfill);
- board[row][col].SetPosition(emptychecker.GetWidth()*col, emptychecker.GetHeight()*row);
- lm->Append(&(board[row][col]));
- }
- }
- return;
- }
- Image *getchecker(int color)
- {
- if (color == BLACK)
- return &blackchecker;
- if (color == RED)
- return &redchecker;
- return &emptychecker;
- }
- Image *getfill(int color)
- {
- if (color == BLACK)
- return &blackfill;
- if (color == RED)
- return &redfill;
- return &emptyfill;
- }
- bool drop(int col, int color, int x, int y, LayerManager *lm)
- {
- int row;
- for(row = 0; row < numrows; row++)
- {
- if (row != 0)
- {
- if (row == 1)
- {
- board[row][col].SetImage(getfill(color));
- if (board[row+1][col].GetImage() != &emptyfill)
- return true;
- }
- else
- {
- board[row-1][col].SetImage(getfill(EMPTY));
- board[row][col].SetImage(getfill(color));
- if (board[row+1][col].GetImage() != &emptyfill)
- return true;
- }
- }
- else
- {
- if (board[row+1][col].GetImage() != &emptyfill)
- return false;
- }
- lm->Draw(x, y);
- gwd.Flush();
- }
- board[row-1][col].SetImage(getfill(EMPTY));
- board[row][col].SetImage(getfill(color));
- return true; // got to the bottom
- }
- bool win(int testcolor)
- {
- int row;
- int col;
- int i;
- Image *color = getfill(testcolor); // what color we are trying to find lines of
- // down
- for (row = 0+1; row <= numrows-numwin+1; row++) // the +1 stuff is cuz row 0 is the blank top row
- {
- for (col = 0; col < numcols; col++)
- {
- for (i = 0; i < numwin; i++)
- {
- if (board[row+i][col].GetImage() != color)
- break;
- }
- if (i == numwin)
- return true;
- }
- }
- // right
- for (col = 0; col <= numcols-numwin; col++)
- {
- for (row = 0+1; row < numrows+1; row++)
- {
- for (i = 0; i < numwin; i++)
- {
- if (board[row][col+i].GetImage() != color)
- break;
- }
- if (i == numwin)
- return true;
- }
- }
- // downright
- for (row = 0+1; row <= numrows-numwin+1; row++)
- {
- for (col = 0; col <= numcols-numwin; col++)
- {
- for (i = 0; i < numwin; i++)
- {
- if (board[row+i][col+i].GetImage() != color)
- break;
- }
- if (i == numwin)
- return true;
- }
- }
- // downleft
- for (row = 0+1; row <= numrows-numwin+1; row++)
- {
- for (col = numcols-1; col >= numcols-numwin; col--)
- {
- for (i = 0; i < numwin; i++)
- {
- if (board[row+i][col-i].GetImage() != color)
- break;
- }
- if (i == numwin)
- return true;
- }
- }
- return false;
- }
- void intro()
- {
- LayerManager introlm((6+1)*7);
- composeboard(6, 7, &introlm);
- for (int row = 6; row >= 1; row--)
- {
- for (int col = 6; col >= 0; col--)
- {
- if (row != 2)
- {
- if (col % 2)
- board[row][col].SetImage(getfill(RED));
- else
- board[row][col].SetImage(getfill(BLACK));
- }
- else
- board[row][col].SetImage(getfill(RED));
- introlm.Draw(152, 72);
- gwd.Flush();
- }
- }
- label.SetImage(&pressA);
- for(EVER) // intro loop
- {
- WPAD_ScanPads();
- if(WPAD_ButtonsDown(WPAD_CHAN_1)&WPAD_BUTTON_A) // second controller kicks in
- control = TWOWIIMOTES;
- if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_A)
- {
- label.SetTransparency(0x00);
- return;
- }
- //if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_B)exit(0); // REMOVE?
- introlm.Draw(152, 72);
- label.Draw(189,76);
- gwd.Flush();
- }
- }
- Image *getwinner(int color)
- {
- if (color == BLACK)
- return &blackwins;
- if (color == RED)
- return &redwins;
- return &emptywins;
- }
- int strtocolor(char *str)
- {
- if (!strcmp(str, "RED"))
- return RED;
- return BLACK;
- }
- bool strtobool(char *str)
- {
- if (!strcmp(str, "FALSE"))
- return false;
- return true;
- }
- int strtocontrol(char *str)
- {
- if (!strcmp(str, "TWOWIIMOTES"))
- return TWOWIIMOTES;
- if (!strcmp(str, "NUNCHUCK"))
- return NUNCHUCK;
- return ONEWIIMOTE;
- }
- int getWPADchannel(int whosturn)
- {
- if (control == NUNCHUCK)
- ; // return ?
- if (control == TWOWIIMOTES)
- return whosturn % 2;
- return WPAD_CHAN_0;
- }
- 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.
- {
- // <SquidMan> inspired this
- /*int i;
- int z;
- int numchars = 8; // make this figure itself out
- char result[strlen(argv) - numchars + strlen(str)];
- strcpy(result, argv);
- for(i = strlen(argv) - numchars, z = 0; z < numchars; z++, i++)
- result[i] = str[z];
- return result;*/
- //thanks to TD-Linux & rck`d
- path = argv;
- path.replace(path.size()-8, 8, str);
- return path.c_str();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement