diff options
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | chlstate.cpp | 6 | ||||
| -rw-r--r-- | gamestate.cpp | 83 | ||||
| -rw-r--r-- | gamestate.h | 4 | ||||
| -rw-r--r-- | hsglobal.cpp | 63 | ||||
| -rw-r--r-- | hsglobal.h | 18 | ||||
| -rw-r--r-- | hslist.cpp | 113 | ||||
| -rw-r--r-- | hslist.h | 12 | ||||
| -rw-r--r-- | hslocal.cpp | 2 | ||||
| -rw-r--r-- | hsnew.cpp | 5 | ||||
| -rw-r--r-- | hssubmit.cpp | 226 | ||||
| -rw-r--r-- | hssubmit.h | 34 | ||||
| -rw-r--r-- | htpstate.cpp | 2 | ||||
| -rw-r--r-- | includes.h | 6 | ||||
| -rw-r--r-- | mazeoflife.cpp | 23 | ||||
| -rw-r--r-- | mazeoflife.h | 2 | ||||
| -rw-r--r-- | titlestate.cpp | 2 |
17 files changed, 545 insertions, 60 deletions
| diff --git a/Makefile b/Makefile index b4a9b9b..27d70a9 100644 --- a/Makefile +++ b/Makefile | |||
| @@ -12,9 +12,9 @@ WINSRC = $(addsuffix win,$(SOURCES)) | |||
| 12 | RES = $(wildcard resources/*) | 12 | RES = $(wildcard resources/*) |
| 13 | CRES = $(patsubst resources/%,build/%,$(addsuffix .o,$(RES))) | 13 | CRES = $(patsubst resources/%,build/%,$(addsuffix .o,$(RES))) |
| 14 | LINCCFL = `sdl-config --cflags` | 14 | LINCCFL = `sdl-config --cflags` |
| 15 | LINLDFL = `sdl-config --libs` -lSDL_ttf | 15 | LINLDFL = `sdl-config --libs` -lSDL_ttf -lSDL_net |
| 16 | WINCCFL = `/opt/SDL-1.2.9/bin/i386-mingw32msvc-sdl-config --cflags` -DWINDOWS | 16 | WINCCFL = `/opt/SDL-1.2.9/bin/i386-mingw32msvc-sdl-config --cflags` -DWINDOWS |
| 17 | WINLDFL = `/opt/SDL-1.2.9/bin/i386-mingw32msvc-sdl-config --libs` -lSDL_ttf | 17 | WINLDFL = `/opt/SDL-1.2.9/bin/i386-mingw32msvc-sdl-config --libs` -lSDL_ttf -lSDL_net |
| 18 | 18 | ||
| 19 | all: init $(LTARGET) $(WTARGET) | 19 | all: init $(LTARGET) $(WTARGET) |
| 20 | linux: init $(LTARGET) | 20 | linux: init $(LTARGET) |
| diff --git a/chlstate.cpp b/chlstate.cpp index 3f3000d..14182a2 100644 --- a/chlstate.cpp +++ b/chlstate.cpp | |||
| @@ -6,8 +6,6 @@ ChooseHighscoreListState::ChooseHighscoreListState() | |||
| 6 | LOADIMAGE(pointer,pointer) | 6 | LOADIMAGE(pointer,pointer) |
| 7 | 7 | ||
| 8 | selection = 0; | 8 | selection = 0; |
| 9 | |||
| 10 | SDL_WM_SetCaption("Maze Of Life - Choose Highscore List", NULL); | ||
| 11 | } | 9 | } |
| 12 | 10 | ||
| 13 | void ChooseHighscoreListState::input(SDL_keysym key) | 11 | void ChooseHighscoreListState::input(SDL_keysym key) |
| @@ -26,7 +24,9 @@ void ChooseHighscoreListState::input(SDL_keysym key) | |||
| 26 | changeState(new LocalHighscoreListState(false)); | 24 | changeState(new LocalHighscoreListState(false)); |
| 27 | 25 | ||
| 28 | break; | 26 | break; |
| 29 | case 1: // Go to global highscore list | 27 | case 1: |
| 28 | changeState(new GlobalHighscoreListState()); | ||
| 29 | |||
| 30 | break; | 30 | break; |
| 31 | case 2: | 31 | case 2: |
| 32 | changeState(new TitleState()); | 32 | changeState(new TitleState()); |
| diff --git a/gamestate.cpp b/gamestate.cpp index 9a50b32..95d1769 100644 --- a/gamestate.cpp +++ b/gamestate.cpp | |||
| @@ -7,35 +7,34 @@ GameState::GameState() | |||
| 7 | 7 | ||
| 8 | newGame = false; | 8 | newGame = false; |
| 9 | 9 | ||
| 10 | info.playerx = 1; | 10 | info = new Info(); |
| 11 | info.playery = 1; | 11 | info->playerx = 1; |
| 12 | info.level = Level(); | 12 | info->playery = 1; |
| 13 | info.doneMaking = false; | 13 | info->level = Level(); |
| 14 | board = Board(&info); | 14 | info->doneMaking = false; |
| 15 | 15 | board = Board(info); | |
| 16 | SDL_WM_SetCaption("Maze Of Life - Level 1", NULL); | ||
| 17 | } | 16 | } |
| 18 | 17 | ||
| 19 | void GameState::input(SDL_keysym key) | 18 | void GameState::input(SDL_keysym key) |
| 20 | { | 19 | { |
| 21 | if (info.doneMaking) | 20 | if (info->doneMaking) |
| 22 | { | 21 | { |
| 23 | switch (key.sym) | 22 | switch (key.sym) |
| 24 | { | 23 | { |
| 25 | case SDLK_LEFT: | 24 | case SDLK_LEFT: |
| 26 | move(info.playerx-1, info.playery); | 25 | move(info->playerx-1, info->playery); |
| 27 | 26 | ||
| 28 | break; | 27 | break; |
| 29 | case SDLK_RIGHT: | 28 | case SDLK_RIGHT: |
| 30 | move(info.playerx+1, info.playery); | 29 | move(info->playerx+1, info->playery); |
| 31 | 30 | ||
| 32 | break; | 31 | break; |
| 33 | case SDLK_UP: | 32 | case SDLK_UP: |
| 34 | move(info.playerx, info.playery-1); | 33 | move(info->playerx, info->playery-1); |
| 35 | 34 | ||
| 36 | break; | 35 | break; |
| 37 | case SDLK_DOWN: | 36 | case SDLK_DOWN: |
| 38 | move(info.playerx, info.playery+1); | 37 | move(info->playerx, info->playery+1); |
| 39 | 38 | ||
| 40 | break; | 39 | break; |
| 41 | case SDLK_ESCAPE: | 40 | case SDLK_ESCAPE: |
| @@ -52,7 +51,7 @@ void GameState::input(SDL_keysym key) | |||
| 52 | { | 51 | { |
| 53 | fclose(hslist); | 52 | fclose(hslist); |
| 54 | 53 | ||
| 55 | changeState(new NewHighscoreState(info.level.getLevel())); | 54 | changeState(new NewHighscoreState(info->level.getLevel())); |
| 56 | } else { | 55 | } else { |
| 57 | for (int i=0; i<scores; i++) | 56 | for (int i=0; i<scores; i++) |
| 58 | { | 57 | { |
| @@ -71,15 +70,15 @@ void GameState::input(SDL_keysym key) | |||
| 71 | 70 | ||
| 72 | fclose(hslist); | 71 | fclose(hslist); |
| 73 | 72 | ||
| 74 | if (h->getLevel() < info.level.getLevel()) | 73 | if (h->getLevel() < info->level.getLevel()) |
| 75 | { | 74 | { |
| 76 | changeState(new NewHighscoreState(info.level.getLevel())); | 75 | changeState(new NewHighscoreState(info->level.getLevel())); |
| 77 | } else { | 76 | } else { |
| 78 | changeState(new LocalHighscoreListState(true)); | 77 | changeState(new LocalHighscoreListState(true)); |
| 79 | } | 78 | } |
| 80 | } | 79 | } |
| 81 | } else { | 80 | } else { |
| 82 | changeState(new NewHighscoreState(info.level.getLevel())); | 81 | changeState(new NewHighscoreState(info->level.getLevel())); |
| 83 | } | 82 | } |
| 84 | 83 | ||
| 85 | break; | 84 | break; |
| @@ -93,20 +92,17 @@ void GameState::tick() | |||
| 93 | { | 92 | { |
| 94 | switch (rand()%4) | 93 | switch (rand()%4) |
| 95 | { | 94 | { |
| 96 | case 0: info.playerx = 1; info.playery = 1; break; | 95 | case 0: info->playerx = 1; info->playery = 1; break; |
| 97 | case 1: info.playerx = 1; info.playery = HEIGHT-2; break; | 96 | case 1: info->playerx = 1; info->playery = HEIGHT-2; break; |
| 98 | case 2: info.playerx = WIDTH-2; info.playery = HEIGHT-2; break; | 97 | case 2: info->playerx = WIDTH-2; info->playery = HEIGHT-2; break; |
| 99 | case 3: info.playerx = WIDTH-2; info.playery = 1; break; | 98 | case 3: info->playerx = WIDTH-2; info->playery = 1; break; |
| 100 | } | 99 | } |
| 101 | 100 | ||
| 102 | info.level.incrementLevel(); | 101 | info->level.incrementLevel(); |
| 103 | info.doneMaking = false; | 102 | info->doneMaking = false; |
| 104 | board = Board(&info); | 103 | info->gens = 0; |
| 104 | board = Board(info); | ||
| 105 | newGame = false; | 105 | newGame = false; |
| 106 | |||
| 107 | char title[32]; | ||
| 108 | sprintf(title, "Maze Of Life - Level %d", info.level.getLevel()); | ||
| 109 | SDL_WM_SetCaption(title, NULL); | ||
| 110 | } | 106 | } |
| 111 | 107 | ||
| 112 | board.tick(); | 108 | board.tick(); |
| @@ -119,8 +115,8 @@ void GameState::move(int x, int y) | |||
| 119 | if (board.isObstructed(x,y)) return; | 115 | if (board.isObstructed(x,y)) return; |
| 120 | if ((x==15)&&(y==15)) newGame = true; | 116 | if ((x==15)&&(y==15)) newGame = true; |
| 121 | 117 | ||
| 122 | info.playerx = x; | 118 | info->playerx = x; |
| 123 | info.playery = y; | 119 | info->playery = y; |
| 124 | } | 120 | } |
| 125 | 121 | ||
| 126 | void GameState::render(SDL_Surface* screen) | 122 | void GameState::render(SDL_Surface* screen) |
| @@ -128,20 +124,31 @@ void GameState::render(SDL_Surface* screen) | |||
| 128 | // Paint maze | 124 | // Paint maze |
| 129 | board.render(screen); | 125 | board.render(screen); |
| 130 | 126 | ||
| 131 | // Paint player | 127 | // Paint event |
| 132 | SDL_Rect block; | 128 | SDL_Rect block; |
| 133 | block.x = info.playerx*16; | 129 | block.x = 15*16; |
| 134 | block.y = info.playery*16; | 130 | block.y = 15*16; |
| 135 | block.w = 16; | 131 | block.w = 16; |
| 136 | block.h = 16; | 132 | block.h = 16; |
| 137 | 133 | ||
| 138 | SDL_FillRect(screen, &block, player_color); | 134 | SDL_FillRect(screen, &block, event_color); |
| 139 | 135 | ||
| 140 | // Paint event | 136 | if (!info->doneMaking) |
| 141 | block.x = 15*16; | 137 | { |
| 142 | block.y = 15*16; | 138 | SDL_Color fontColor = {0, 0, 0, 0}; |
| 139 | char levelnum[8]; | ||
| 140 | sprintf(levelnum, "%d", info->level.getLevel()); | ||
| 141 | SDL_Surface* title = TTF_RenderText_Solid(loadFont(100), levelnum, fontColor); | ||
| 142 | SDL_Rect tSpace = {240-(title->w/2), 240-(title->h/2), title->w, title->h}; | ||
| 143 | SDL_FillRect(screen, NULL, info->level.getDeadColor()); | ||
| 144 | SDL_BlitSurface(title, NULL, screen, &tSpace); | ||
| 145 | } | ||
| 143 | 146 | ||
| 144 | SDL_FillRect(screen, &block, event_color); | 147 | // Paint player |
| 148 | block.x = info->playerx*16; | ||
| 149 | block.y = info->playery*16; | ||
| 150 | |||
| 151 | SDL_FillRect(screen, &block, player_color); | ||
| 145 | } | 152 | } |
| 146 | 153 | ||
| 147 | GameState::Level::Level() | 154 | GameState::Level::Level() |
| @@ -292,7 +299,7 @@ void GameState::Board::tick() | |||
| 292 | } | 299 | } |
| 293 | } | 300 | } |
| 294 | 301 | ||
| 295 | if (!info->doneMaking && ++gens > 100) info->doneMaking = true; | 302 | if (!info->doneMaking && ++info->gens > 50) info->doneMaking = true; |
| 296 | } | 303 | } |
| 297 | 304 | ||
| 298 | void GameState::Board::incrementIfNeighbor(int x, int y, bool temp[WIDTH][HEIGHT], int* tick) | 305 | void GameState::Board::incrementIfNeighbor(int x, int y, bool temp[WIDTH][HEIGHT], int* tick) |
| diff --git a/gamestate.h b/gamestate.h index d1b90ad..28b85c0 100644 --- a/gamestate.h +++ b/gamestate.h | |||
| @@ -29,6 +29,7 @@ class GameState : public State { | |||
| 29 | int playerx, playery; | 29 | int playerx, playery; |
| 30 | Level level; | 30 | Level level; |
| 31 | bool doneMaking; | 31 | bool doneMaking; |
| 32 | int gens; | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | class Board | 35 | class Board |
| @@ -37,7 +38,6 @@ class GameState : public State { | |||
| 37 | bool blocks[WIDTH][HEIGHT]; | 38 | bool blocks[WIDTH][HEIGHT]; |
| 38 | void incrementIfNeighbor(int x, int y, bool temp[WIDTH][HEIGHT], int* tick); | 39 | void incrementIfNeighbor(int x, int y, bool temp[WIDTH][HEIGHT], int* tick); |
| 39 | GameState::Info* info; | 40 | GameState::Info* info; |
| 40 | int gens; | ||
| 41 | 41 | ||
| 42 | public: | 42 | public: |
| 43 | Board(); | 43 | Board(); |
| @@ -51,7 +51,7 @@ class GameState : public State { | |||
| 51 | Uint32 player_color; | 51 | Uint32 player_color; |
| 52 | Uint32 event_color; | 52 | Uint32 event_color; |
| 53 | bool newGame; | 53 | bool newGame; |
| 54 | Info info; | 54 | Info* info; |
| 55 | Board board; | 55 | Board board; |
| 56 | void move(int x, int y); | 56 | void move(int x, int y); |
| 57 | }; | 57 | }; |
| diff --git a/hsglobal.cpp b/hsglobal.cpp new file mode 100644 index 0000000..37db44b --- /dev/null +++ b/hsglobal.cpp | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | #include "includes.h" | ||
| 2 | |||
| 3 | GlobalHighscoreListState::GlobalHighscoreListState() | ||
| 4 | { | ||
| 5 | LOADIMAGE(options,hlo_rtm) | ||
| 6 | LOADIMAGE(pointer,pointer) | ||
| 7 | |||
| 8 | list = SDL_CreateRGBSurface(SDL_SWSURFACE || SDL_SRCCOLORKEY, 480, 480, 32, 0,0,0,0); | ||
| 9 | Uint32 bgColor = SDL_MapRGB(list->format, 255, 255, 255); | ||
| 10 | SDL_FillRect(list, NULL, bgColor); | ||
| 11 | SDL_SetColorKey(list, SDL_SRCCOLORKEY, bgColor); | ||
| 12 | TTF_Font* dataFont = loadFont(25); | ||
| 13 | SDL_Color fontColor = {0, 0, 0, 0}; | ||
| 14 | SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Fetching highscores....", fontColor); | ||
| 15 | SDL_Rect aSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; | ||
| 16 | SDL_BlitSurface(text, NULL, list, &aSpace); | ||
| 17 | |||
| 18 | SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); | ||
| 19 | SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; | ||
| 20 | SDL_BlitSurface(title, NULL, list, &tSpace); | ||
| 21 | |||
| 22 | SDL_Rect oSpace = {0, 440, options->w, options->h}; | ||
| 23 | SDL_BlitSurface(options, NULL, list, &oSpace); | ||
| 24 | |||
| 25 | SDL_CreateThread(&LoadHighscoreList, this); | ||
| 26 | } | ||
| 27 | |||
| 28 | int GlobalHighscoreListState::LoadHighscoreList(void* pParam) | ||
| 29 | { | ||
| 30 | GlobalHighscoreList* lhl = new GlobalHighscoreList(); | ||
| 31 | ((GlobalHighscoreListState*)pParam)->list = lhl->render(); | ||
| 32 | |||
| 33 | SDL_Color fontColor = {0, 0, 0, 0}; | ||
| 34 | SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); | ||
| 35 | SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; | ||
| 36 | SDL_BlitSurface(title, NULL, ((GlobalHighscoreListState*)pParam)->list, &tSpace); | ||
| 37 | |||
| 38 | SDL_Rect oSpace = {0, 440, ((GlobalHighscoreListState*)pParam)->options->w, ((GlobalHighscoreListState*)pParam)->options->h}; | ||
| 39 | SDL_BlitSurface(((GlobalHighscoreListState*)pParam)->options, NULL, ((GlobalHighscoreListState*)pParam)->list, &oSpace); | ||
| 40 | } | ||
| 41 | |||
| 42 | void GlobalHighscoreListState::input(SDL_keysym key) | ||
| 43 | { | ||
| 44 | if (key.sym == SDLK_RETURN) | ||
| 45 | { | ||
| 46 | changeState(new ChooseHighscoreListState()); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | void GlobalHighscoreListState::render(SDL_Surface* screen) | ||
| 51 | { | ||
| 52 | SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); | ||
| 53 | |||
| 54 | SDL_BlitSurface(list, NULL, screen, NULL); | ||
| 55 | |||
| 56 | SDL_Rect pSpace; | ||
| 57 | pSpace.x = 137; | ||
| 58 | pSpace.y = 449; | ||
| 59 | pSpace.w = pointer->w; | ||
| 60 | pSpace.h = pointer->h; | ||
| 61 | |||
| 62 | SDL_BlitSurface(pointer, NULL, screen, &pSpace); | ||
| 63 | } | ||
| diff --git a/hsglobal.h b/hsglobal.h new file mode 100644 index 0000000..5b92b0e --- /dev/null +++ b/hsglobal.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | #ifndef HSGLOBAL_H | ||
| 2 | #define HSGLOBAL_H | ||
| 3 | |||
| 4 | class GlobalHighscoreListState : public State { | ||
| 5 | public: | ||
| 6 | GlobalHighscoreListState(); | ||
| 7 | void input(SDL_keysym key); | ||
| 8 | void render(SDL_Surface* screen); | ||
| 9 | |||
| 10 | private: | ||
| 11 | static int LoadHighscoreList(void* pParam); | ||
| 12 | |||
| 13 | SDL_Surface* list; | ||
| 14 | SDL_Surface* options; | ||
| 15 | SDL_Surface* pointer; | ||
| 16 | }; | ||
| 17 | |||
| 18 | #endif | ||
| diff --git a/hslist.cpp b/hslist.cpp index d2901b4..ec99a77 100644 --- a/hslist.cpp +++ b/hslist.cpp | |||
| @@ -76,10 +76,123 @@ std::vector<Highscore> HighscoreList::getLocalHighscores() | |||
| 76 | 76 | ||
| 77 | std::vector<Highscore> HighscoreList::getGlobalHighscores() | 77 | std::vector<Highscore> HighscoreList::getGlobalHighscores() |
| 78 | { | 78 | { |
| 79 | IPaddress ipaddress; | ||
| 79 | 80 | ||
| 81 | if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1) | ||
| 82 | { | ||
| 83 | printf("Could not resolve host \"other.fourisland.com\": %s\n", SDLNet_GetError()); | ||
| 84 | throw 1; | ||
| 85 | } | ||
| 86 | |||
| 87 | TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress); | ||
| 88 | if (!tcpsock) | ||
| 89 | { | ||
| 90 | printf("Could not connect to host \"other.fourisland.com\": %s\n", SDLNet_GetError()); | ||
| 91 | throw 2; | ||
| 92 | } | ||
| 93 | |||
| 94 | char* headers = "GET /mol/hslist.php HTTP/1.1\nHost: other.fourisland.com\nUser-Agent: Maze Of Life v2.0\nAccept: text/plain\nKeep-Alive: 300\nConnection: keep-alive\n\n"; | ||
| 95 | if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers)+1) < strlen(headers)) | ||
| 96 | { | ||
| 97 | printf("Connection closed by peer: %s\n", SDLNet_GetError()); | ||
| 98 | throw 3; | ||
| 99 | } | ||
| 100 | |||
| 101 | std::stringstream download(std::stringstream::in | std::stringstream::out); | ||
| 102 | char hslist[1024]; | ||
| 103 | SDLNet_TCP_Recv(tcpsock, hslist, 1024); | ||
| 104 | download << hslist; | ||
| 105 | SDLNet_TCP_Close(tcpsock); | ||
| 106 | |||
| 107 | char temps[256]; | ||
| 108 | download.getline(temps,256); | ||
| 109 | while (strlen(temps) != 1) | ||
| 110 | { | ||
| 111 | download.getline(temps,256); | ||
| 112 | } | ||
| 113 | |||
| 114 | std::vector<Highscore> temp = std::vector<Highscore>(); | ||
| 115 | int scores; | ||
| 116 | download.getline(temps, 256); | ||
| 117 | if (sscanf(temps, "%d%*c", &scores) != 1) | ||
| 118 | { | ||
| 119 | printf("Recieved data is of an invalid format: %s\n", temps); | ||
| 120 | throw 4; | ||
| 121 | } | ||
| 122 | |||
| 123 | for (int i=0; i<scores; i++) | ||
| 124 | { | ||
| 125 | int namelen; | ||
| 126 | char namelens[13]; | ||
| 127 | char* name = (char*) calloc(25, sizeof(char)); | ||
| 128 | int score; | ||
| 129 | download.getline(temps, 256); | ||
| 130 | |||
| 131 | if (sscanf(temps, "%d", &namelen) != 1) | ||
| 132 | { | ||
| 133 | printf("Recieved data is of an invalid format: %s\n", temps); | ||
| 134 | throw 4; | ||
| 135 | } | ||
| 136 | |||
| 137 | sprintf(namelens, "%%*d%%%dc", namelen); | ||
| 138 | |||
| 139 | if (sscanf(temps, namelens, name) != 1) | ||
| 140 | { | ||
| 141 | printf("Recieved data is of an invalid format: %s\n", temps); | ||
| 142 | throw 4; | ||
| 143 | } | ||
| 144 | |||
| 145 | sprintf(namelens, "%%*d%%*%dc%%d%%*c", namelen); | ||
| 146 | |||
| 147 | if (sscanf(temps, namelens, &score) != 1) | ||
| 148 | { | ||
| 149 | printf("Recieved data is of an invalid format: %s\n", temps); | ||
| 150 | throw 4; | ||
| 151 | } | ||
| 152 | |||
| 153 | Highscore h = Highscore(name, score); | ||
| 154 | h.setRank(i+1); | ||
| 155 | |||
| 156 | temp.push_back(h); | ||
| 157 | } | ||
| 158 | |||
| 159 | return temp; | ||
| 80 | } | 160 | } |
| 81 | 161 | ||
| 82 | LocalHighscoreList::LocalHighscoreList() | 162 | LocalHighscoreList::LocalHighscoreList() |
| 83 | { | 163 | { |
| 84 | this->hslist = getLocalHighscores(); | 164 | this->hslist = getLocalHighscores(); |
| 85 | } | 165 | } |
| 166 | |||
| 167 | GlobalHighscoreList::GlobalHighscoreList() | ||
| 168 | { | ||
| 169 | fail = false; | ||
| 170 | |||
| 171 | try | ||
| 172 | { | ||
| 173 | this->hslist = getGlobalHighscores(); | ||
| 174 | } catch (int e) | ||
| 175 | { | ||
| 176 | fail = true; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | SDL_Surface* GlobalHighscoreList::render() | ||
| 181 | { | ||
| 182 | if (fail) | ||
| 183 | { | ||
| 184 | SDL_Surface* tmp = SDL_CreateRGBSurface(SDL_SWSURFACE || SDL_SRCCOLORKEY, 480, 480, 32, 0,0,0,0); | ||
| 185 | Uint32 bgColor = SDL_MapRGB(tmp->format, 255, 255, 255); | ||
| 186 | SDL_FillRect(tmp, NULL, bgColor); | ||
| 187 | SDL_SetColorKey(tmp, SDL_SRCCOLORKEY, bgColor); | ||
| 188 | TTF_Font* dataFont = loadFont(25); | ||
| 189 | SDL_Color fontColor = {0, 0, 0, 0}; | ||
| 190 | SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Error retrieving highscores", fontColor); | ||
| 191 | SDL_Rect tSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; | ||
| 192 | SDL_BlitSurface(text, NULL, tmp, &tSpace); | ||
| 193 | |||
| 194 | return tmp; | ||
| 195 | } else { | ||
| 196 | return super::render(); | ||
| 197 | } | ||
| 198 | } | ||
| diff --git a/hslist.h b/hslist.h index 88c47c4..bebb85a 100644 --- a/hslist.h +++ b/hslist.h | |||
| @@ -18,4 +18,16 @@ class LocalHighscoreList : public HighscoreList { | |||
| 18 | LocalHighscoreList(); | 18 | LocalHighscoreList(); |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | class GlobalHighscoreList : public HighscoreList { | ||
| 22 | public: | ||
| 23 | GlobalHighscoreList(); | ||
| 24 | SDL_Surface* render(); | ||
| 25 | |||
| 26 | private: | ||
| 27 | typedef HighscoreList super; | ||
| 28 | |||
| 29 | protected: | ||
| 30 | bool fail; | ||
| 31 | }; | ||
| 32 | |||
| 21 | #endif | 33 | #endif |
| diff --git a/hslocal.cpp b/hslocal.cpp index 17cae1b..c53f397 100644 --- a/hslocal.cpp +++ b/hslocal.cpp | |||
| @@ -25,8 +25,6 @@ LocalHighscoreListState::LocalHighscoreListState(bool fromGame) | |||
| 25 | SDL_BlitSurface(options, NULL, list, &oSpace); | 25 | SDL_BlitSurface(options, NULL, list, &oSpace); |
| 26 | 26 | ||
| 27 | selection = 0; | 27 | selection = 0; |
| 28 | |||
| 29 | SDL_WM_SetCaption("Maze Of Life - Highscore List", NULL); | ||
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | void LocalHighscoreListState::input(SDL_keysym key) | 30 | void LocalHighscoreListState::input(SDL_keysym key) |
| diff --git a/hsnew.cpp b/hsnew.cpp index 3bec468..8b752a6 100644 --- a/hsnew.cpp +++ b/hsnew.cpp | |||
| @@ -38,7 +38,6 @@ NewHighscoreState::NewHighscoreState(int level) | |||
| 38 | rntSpace.w = newName->w; | 38 | rntSpace.w = newName->w; |
| 39 | rntSpace.h = newName->h; | 39 | rntSpace.h = newName->h; |
| 40 | 40 | ||
| 41 | SDL_WM_SetCaption("Maze Of Life - New Highscore!", NULL); | ||
| 42 | SDL_EnableUNICODE(1); | 41 | SDL_EnableUNICODE(1); |
| 43 | } | 42 | } |
| 44 | 43 | ||
| @@ -99,7 +98,9 @@ void NewHighscoreState::input(SDL_keysym key) | |||
| 99 | changeState(new GameState()); | 98 | changeState(new GameState()); |
| 100 | 99 | ||
| 101 | break; | 100 | break; |
| 102 | case 1: // Submit score to Global highscore list | 101 | case 1: |
| 102 | changeState(new SubmitHighscoreListState(hsname, level)); | ||
| 103 | |||
| 103 | break; | 104 | break; |
| 104 | case 2: | 105 | case 2: |
| 105 | changeState(new TitleState()); | 106 | changeState(new TitleState()); |
| diff --git a/hssubmit.cpp b/hssubmit.cpp new file mode 100644 index 0000000..690749a --- /dev/null +++ b/hssubmit.cpp | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | #include "includes.h" | ||
| 2 | |||
| 3 | SubmitHighscoreListState::SubmitHighscoreListState(char* hsname, int level) | ||
| 4 | { | ||
| 5 | LOADIMAGE(pointer,pointer) | ||
| 6 | |||
| 7 | this->hsname = hsname; | ||
| 8 | this->level = level; | ||
| 9 | this->scoreSent = false; | ||
| 10 | this->selection = 0; | ||
| 11 | |||
| 12 | list = SDL_CreateRGBSurface(SDL_SWSURFACE || SDL_SRCCOLORKEY, 480, 480, 32, 0,0,0,0); | ||
| 13 | Uint32 bgColor = SDL_MapRGB(list->format, 255, 255, 255); | ||
| 14 | SDL_FillRect(list, NULL, bgColor); | ||
| 15 | SDL_SetColorKey(list, SDL_SRCCOLORKEY, bgColor); | ||
| 16 | TTF_Font* dataFont = loadFont(25); | ||
| 17 | SDL_Color fontColor = {0, 0, 0, 0}; | ||
| 18 | SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Sending highscore....", fontColor); | ||
| 19 | SDL_Rect aSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; | ||
| 20 | SDL_BlitSurface(text, NULL, list, &aSpace); | ||
| 21 | |||
| 22 | SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); | ||
| 23 | SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; | ||
| 24 | SDL_BlitSurface(title, NULL, list, &tSpace); | ||
| 25 | |||
| 26 | SDL_CreateThread(&LoadHighscoreList, this); | ||
| 27 | } | ||
| 28 | |||
| 29 | int SubmitHighscoreListState::LoadHighscoreList(void* pParam) | ||
| 30 | { | ||
| 31 | SubmitHighscoreList* lhl = new SubmitHighscoreList(((SubmitHighscoreListState*)pParam)->hsname, ((SubmitHighscoreListState*)pParam)->level); | ||
| 32 | ((SubmitHighscoreListState*)pParam)->list = lhl->render(); | ||
| 33 | |||
| 34 | SDL_Color fontColor = {0, 0, 0, 0}; | ||
| 35 | SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); | ||
| 36 | SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; | ||
| 37 | SDL_BlitSurface(title, NULL, ((SubmitHighscoreListState*)pParam)->list, &tSpace); | ||
| 38 | |||
| 39 | if (lhl->hasFailed()) | ||
| 40 | { | ||
| 41 | LOADIMAGE(((SubmitHighscoreListState*)pParam)->options,hlo_passartm) | ||
| 42 | } else { | ||
| 43 | LOADIMAGE(((SubmitHighscoreListState*)pParam)->options,hlo_paartm) | ||
| 44 | } | ||
| 45 | |||
| 46 | SDL_Rect oSpace = {0, 440, ((SubmitHighscoreListState*)pParam)->options->w, ((SubmitHighscoreListState*)pParam)->options->h}; | ||
| 47 | SDL_BlitSurface(((SubmitHighscoreListState*)pParam)->options, NULL, ((SubmitHighscoreListState*)pParam)->list, &oSpace); | ||
| 48 | |||
| 49 | ((SubmitHighscoreListState*)pParam)->fail = lhl->hasFailed(); | ||
| 50 | ((SubmitHighscoreListState*)pParam)->newpos = lhl->getNewPos(); | ||
| 51 | ((SubmitHighscoreListState*)pParam)->scoreSent = true; | ||
| 52 | } | ||
| 53 | |||
| 54 | void SubmitHighscoreListState::input(SDL_keysym key) | ||
| 55 | { | ||
| 56 | if (scoreSent) | ||
| 57 | { | ||
| 58 | if ((key.sym == SDLK_LEFT) && (selection != 0)) | ||
| 59 | { | ||
| 60 | selection--; | ||
| 61 | } else if ((key.sym == SDLK_RIGHT) && (selection != (fail?2:1))) | ||
| 62 | { | ||
| 63 | selection++; | ||
| 64 | } else if (key.sym == SDLK_RETURN) | ||
| 65 | { | ||
| 66 | if (fail) | ||
| 67 | { | ||
| 68 | switch (selection) | ||
| 69 | { | ||
| 70 | case 0: | ||
| 71 | changeState(new GameState()); | ||
| 72 | |||
| 73 | break; | ||
| 74 | case 1: | ||
| 75 | changeState(new SubmitHighscoreListState(hsname, level)); | ||
| 76 | |||
| 77 | break; | ||
| 78 | case 2: | ||
| 79 | changeState(new TitleState()); | ||
| 80 | |||
| 81 | break; | ||
| 82 | } | ||
| 83 | } else { | ||
| 84 | switch (selection) | ||
| 85 | { | ||
| 86 | case 0: | ||
| 87 | changeState(new GameState()); | ||
| 88 | |||
| 89 | break; | ||
| 90 | case 1: | ||
| 91 | changeState(new TitleState()); | ||
| 92 | |||
| 93 | break; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | void SubmitHighscoreListState::render(SDL_Surface* screen) | ||
| 101 | { | ||
| 102 | SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); | ||
| 103 | |||
| 104 | if (scoreSent) | ||
| 105 | { | ||
| 106 | SDL_Rect pSpace; | ||
| 107 | if (fail) | ||
| 108 | { | ||
| 109 | pSpace.x = (selection==0?13:(selection==1?138:284)); | ||
| 110 | pSpace.y = 448; | ||
| 111 | } else { | ||
| 112 | pSpace.x = (selection==0?52:225); | ||
| 113 | pSpace.y = 447; | ||
| 114 | } | ||
| 115 | pSpace.w = pointer->w; | ||
| 116 | pSpace.h = pointer->h; | ||
| 117 | |||
| 118 | SDL_BlitSurface(pointer, NULL, screen, &pSpace); | ||
| 119 | |||
| 120 | SDL_Rect eSpace = {0, newpos*40, 480, 40}; | ||
| 121 | SDL_FillRect(screen, &eSpace, SDL_MapRGB(screen->format, 255, 255, 0)); | ||
| 122 | } | ||
| 123 | |||
| 124 | SDL_BlitSurface(list, NULL, screen, NULL); | ||
| 125 | } | ||
| 126 | |||
| 127 | SubmitHighscoreListState::SubmitHighscoreList::SubmitHighscoreList(char* hsname, int level) | ||
| 128 | { | ||
| 129 | fail = false; | ||
| 130 | |||
| 131 | try | ||
| 132 | { | ||
| 133 | IPaddress ipaddress; | ||
| 134 | |||
| 135 | if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1) | ||
| 136 | { | ||
| 137 | printf("Could not resolve host \"other.fourisland.com\": %s\n", SDLNet_GetError()); | ||
| 138 | throw 1; | ||
| 139 | } | ||
| 140 | |||
| 141 | TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress); | ||
| 142 | if (!tcpsock) | ||
| 143 | { | ||
| 144 | printf("Could not connect to host \"other.fourisland.com\": %s\n", SDLNet_GetError()); | ||
| 145 | throw 2; | ||
| 146 | } | ||
| 147 | |||
| 148 | char body[256]; | ||
| 149 | sprintf(body, "name=%s&level=%d", hsname, level); | ||
| 150 | char headers[256]; | ||
| 151 | sprintf(headers, "POST /mol/hslist.php?add HTTP/1.1\nHost: other.fourisland.com\nUser-Agent: Maze Of Life v2.0\nAccept: text/plain\nKeep-Alive: 300\nConnection: keep-alive\nContent-Type: application/x-www-form-urlencoded\nContent-Length: %d\n\n%s\n", strlen(body), body); | ||
| 152 | if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers)+1) < strlen(headers)) | ||
| 153 | { | ||
| 154 | printf("Connection closed by peer: %s\n", SDLNet_GetError()); | ||
| 155 | throw 3; | ||
| 156 | } | ||
| 157 | |||
| 158 | std::stringstream download(std::stringstream::in | std::stringstream::out); | ||
| 159 | char hslist[1024]; | ||
| 160 | SDLNet_TCP_Recv(tcpsock, hslist, 1024); | ||
| 161 | download << hslist; | ||
| 162 | SDLNet_TCP_Close(tcpsock); | ||
| 163 | |||
| 164 | char temps[256]; | ||
| 165 | download.getline(temps,256); | ||
| 166 | while (strlen(temps) != 1) | ||
| 167 | { | ||
| 168 | download.getline(temps,256); | ||
| 169 | } | ||
| 170 | |||
| 171 | int rank; | ||
| 172 | download.getline(temps, 256); | ||
| 173 | if (sscanf(temps, "%d%*c", &rank) != 1) | ||
| 174 | { | ||
| 175 | printf("Recieved data is of an invalid format: %s\n", temps); | ||
| 176 | throw 4; | ||
| 177 | } | ||
| 178 | |||
| 179 | this->hslist = getGlobalHighscores(); | ||
| 180 | |||
| 181 | if (this->hslist.empty()) | ||
| 182 | { | ||
| 183 | printf("Global Highscore List cannot be empty after adding a score to it.\n"); | ||
| 184 | throw 5; | ||
| 185 | } | ||
| 186 | |||
| 187 | if (rank > 10) | ||
| 188 | { | ||
| 189 | Highscore temph(hsname, level); | ||
| 190 | temph.setRank(rank); | ||
| 191 | |||
| 192 | this->hslist[9] = temph; | ||
| 193 | this->newpos = 10; | ||
| 194 | } else { | ||
| 195 | std::vector<Highscore>::iterator it; | ||
| 196 | bool found = false; | ||
| 197 | |||
| 198 | for (it=this->hslist.begin(); it<this->hslist.end(); it++) | ||
| 199 | { | ||
| 200 | Highscore h = *it; | ||
| 201 | |||
| 202 | if (!found) | ||
| 203 | { | ||
| 204 | if ((strcmp(h.getName(),hsname) == 0) && (h.getLevel() == level)) | ||
| 205 | { | ||
| 206 | this->newpos = h.getRank(); | ||
| 207 | found = true; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } catch (int e) | ||
| 213 | { | ||
| 214 | fail = true; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | int SubmitHighscoreListState::SubmitHighscoreList::getNewPos() | ||
| 219 | { | ||
| 220 | return newpos; | ||
| 221 | } | ||
| 222 | |||
| 223 | bool SubmitHighscoreListState::SubmitHighscoreList::hasFailed() | ||
| 224 | { | ||
| 225 | return fail; | ||
| 226 | } | ||
| diff --git a/hssubmit.h b/hssubmit.h new file mode 100644 index 0000000..243dab8 --- /dev/null +++ b/hssubmit.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #ifndef HSSUBMIT_H | ||
| 2 | #define HSSUBMIT_H | ||
| 3 | |||
| 4 | class SubmitHighscoreListState : public State { | ||
| 5 | public: | ||
| 6 | SubmitHighscoreListState(char* hsname, int level); | ||
| 7 | void input(SDL_keysym key); | ||
| 8 | void render(SDL_Surface* screen); | ||
| 9 | |||
| 10 | private: | ||
| 11 | static int LoadHighscoreList(void* pParam); | ||
| 12 | |||
| 13 | class SubmitHighscoreList : public GlobalHighscoreList { | ||
| 14 | public: | ||
| 15 | SubmitHighscoreList(char* hsname, int level); | ||
| 16 | int getNewPos(); | ||
| 17 | bool hasFailed(); | ||
| 18 | |||
| 19 | private: | ||
| 20 | int newpos; | ||
| 21 | }; | ||
| 22 | |||
| 23 | SDL_Surface* list; | ||
| 24 | SDL_Surface* options; | ||
| 25 | SDL_Surface* pointer; | ||
| 26 | char* hsname; | ||
| 27 | int level; | ||
| 28 | bool scoreSent; | ||
| 29 | int selection; | ||
| 30 | int newpos; | ||
| 31 | bool fail; | ||
| 32 | }; | ||
| 33 | |||
| 34 | #endif | ||
| diff --git a/htpstate.cpp b/htpstate.cpp index da4b6a2..03d02c6 100644 --- a/htpstate.cpp +++ b/htpstate.cpp | |||
| @@ -8,8 +8,6 @@ HowToPlayState::HowToPlayState() | |||
| 8 | 8 | ||
| 9 | secondPage = false; | 9 | secondPage = false; |
| 10 | selection = 0; | 10 | selection = 0; |
| 11 | |||
| 12 | SDL_WM_SetCaption("Maze Of Life - How To Play", NULL); | ||
| 13 | } | 11 | } |
| 14 | 12 | ||
| 15 | void HowToPlayState::input(SDL_keysym key) | 13 | void HowToPlayState::input(SDL_keysym key) |
| diff --git a/includes.h b/includes.h index cd5c1e9..b7c0d56 100644 --- a/includes.h +++ b/includes.h | |||
| @@ -1,10 +1,14 @@ | |||
| 1 | #include <SDL.h> | 1 | #include <SDL.h> |
| 2 | #include <SDL_ttf.h> | 2 | #include <SDL_ttf.h> |
| 3 | #include <SDL_net.h> | ||
| 4 | #include <SDL_thread.h> | ||
| 3 | #include <stdio.h> | 5 | #include <stdio.h> |
| 4 | #include <time.h> | 6 | #include <time.h> |
| 5 | #include <string> | 7 | #include <string> |
| 6 | #include <vector> | 8 | #include <vector> |
| 7 | #include <fstream> | 9 | #include <fstream> |
| 10 | #include <sstream> | ||
| 11 | #include <exception> | ||
| 8 | #include "state.h" | 12 | #include "state.h" |
| 9 | #include "mazeoflife.h" | 13 | #include "mazeoflife.h" |
| 10 | #include "resources.h" | 14 | #include "resources.h" |
| @@ -16,3 +20,5 @@ | |||
| 16 | #include "hslist.h" | 20 | #include "hslist.h" |
| 17 | #include "hslocal.h" | 21 | #include "hslocal.h" |
| 18 | #include "hsnew.h" | 22 | #include "hsnew.h" |
| 23 | #include "hsglobal.h" | ||
| 24 | #include "hssubmit.h" | ||
| diff --git a/mazeoflife.cpp b/mazeoflife.cpp index c744b28..45fc377 100644 --- a/mazeoflife.cpp +++ b/mazeoflife.cpp | |||
| @@ -19,9 +19,16 @@ int main(int argc, char *argv[]) | |||
| 19 | exit(-1); | 19 | exit(-1); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | if (SDLNet_Init() == -1) | ||
| 23 | { | ||
| 24 | printf("Cound not initalize SDL_net: %s.\n", SDLNet_GetError()); | ||
| 25 | exit(-1); | ||
| 26 | } | ||
| 27 | |||
| 22 | /* Clean up on exit */ | 28 | /* Clean up on exit */ |
| 23 | atexit(SDL_Quit); | 29 | atexit(SDL_Quit); |
| 24 | atexit(TTF_Quit); | 30 | atexit(TTF_Quit); |
| 31 | atexit(SDLNet_Quit); | ||
| 25 | 32 | ||
| 26 | SDL_WM_SetCaption("Maze Of Life", NULL); | 33 | SDL_WM_SetCaption("Maze Of Life", NULL); |
| 27 | 34 | ||
| @@ -39,7 +46,7 @@ int main(int argc, char *argv[]) | |||
| 39 | exit(1); | 46 | exit(1); |
| 40 | } | 47 | } |
| 41 | 48 | ||
| 42 | SDL_EnableKeyRepeat(100, 50); | 49 | SDL_EnableKeyRepeat(100, 70); |
| 43 | 50 | ||
| 44 | state = new TitleState(); | 51 | state = new TitleState(); |
| 45 | 52 | ||
| @@ -57,15 +64,16 @@ int main(int argc, char *argv[]) | |||
| 57 | 64 | ||
| 58 | break; | 65 | break; |
| 59 | case SDL_KEYDOWN: | 66 | case SDL_KEYDOWN: |
| 60 | state->input(anEvent.key.keysym); | 67 | if (anEvent.key.keysym.sym == SDLK_F4) |
| 68 | { | ||
| 69 | SDL_WM_ToggleFullScreen(screen); | ||
| 70 | } else { | ||
| 71 | state->input(anEvent.key.keysym); | ||
| 72 | } | ||
| 61 | 73 | ||
| 62 | break; | 74 | break; |
| 63 | } | 75 | } |
| 64 | } | 76 | } |
| 65 | |||
| 66 | state->render(screen); | ||
| 67 | |||
| 68 | SDL_Flip(screen); | ||
| 69 | } | 77 | } |
| 70 | 78 | ||
| 71 | exit(0); | 79 | exit(0); |
| @@ -101,6 +109,9 @@ void changeState(State* nState) | |||
| 101 | Uint32 tick(Uint32 interval, void *param) | 109 | Uint32 tick(Uint32 interval, void *param) |
| 102 | { | 110 | { |
| 103 | state->tick(); | 111 | state->tick(); |
| 112 | state->render(screen); | ||
| 113 | |||
| 114 | SDL_Flip(screen); | ||
| 104 | 115 | ||
| 105 | return interval; | 116 | return interval; |
| 106 | } | 117 | } |
| diff --git a/mazeoflife.h b/mazeoflife.h index 411a87b..00a31cf 100644 --- a/mazeoflife.h +++ b/mazeoflife.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | const int WIDTH = 30; | 4 | const int WIDTH = 30; |
| 5 | const int HEIGHT = 30; | 5 | const int HEIGHT = 30; |
| 6 | const int TICKDELAY = 10; | 6 | const int TICKDELAY = 5; |
| 7 | 7 | ||
| 8 | void wrap(int* x, int* y); | 8 | void wrap(int* x, int* y); |
| 9 | Uint32 getColor(int r, int g, int b); | 9 | Uint32 getColor(int r, int g, int b); |
| diff --git a/titlestate.cpp b/titlestate.cpp index ae18c48..2622caa 100644 --- a/titlestate.cpp +++ b/titlestate.cpp | |||
| @@ -6,8 +6,6 @@ TitleState::TitleState() | |||
| 6 | LOADIMAGE(pointer,pointer) | 6 | LOADIMAGE(pointer,pointer) |
| 7 | 7 | ||
| 8 | selection = 0; | 8 | selection = 0; |
| 9 | |||
| 10 | SDL_WM_SetCaption("Maze Of Life", NULL); | ||
| 11 | } | 9 | } |
| 12 | 10 | ||
| 13 | void TitleState::input(SDL_keysym key) | 11 | void TitleState::input(SDL_keysym key) |
