diff --git a/client/client.pro b/client/client.pro index b62b1d1..1333108 100644 --- a/client/client.pro +++ b/client/client.pro @@ -72,6 +72,7 @@ HEADERS = \ $$SHARED/primes.h \ $$SHARED/packet.h \ $$SHARED/packets.h \ + ../shared/game.h \ ../shared/macros.h \ src/browser.h \ src/config.h \ diff --git a/client/src/browser.c b/client/src/browser.c index aebae23..ed142ad 100644 --- a/client/src/browser.c +++ b/client/src/browser.c @@ -27,28 +27,29 @@ #include "button.h" #include "frame.h" #include "listbox.h" +#include "textbox.h" +#include "timer.h" +#include "db.h" #include "network.h" #include "util.h" static WindowT *_winBrowser = NULL; -static ButtonT *_btnBoxTab = NULL; -static ButtonT *_btnDescriptionTab = NULL; -static ButtonT *_btnInfoTab = NULL; -static ButtonT *_btnScreensTab = NULL; +static TimerT *_timSearchUpdate = NULL; + static ButtonT *_btnSearchTab = NULL; -static uint8_t _channel = 0; -static FrameT *_fraBox = NULL; -static FrameT *_fraDescription = NULL; -static FrameT *_fraInfo = NULL; -static FrameT *_fraScreens = NULL; static FrameT *_fraSearch = NULL; -static ListboxT *_lstDescription = NULL; -static ListboxT *_lstInfo = NULL; +static TextboxT *_txtSearch = NULL; +static ListboxT *_lstResults = NULL; + +static ButtonT *_btnDescriptionTab = NULL; +static FrameT *_fraDescription = NULL; static PictureT *_picBanner = NULL; -static PictureT *_picBox1 = NULL; -static PictureT *_picBox2 = NULL; +static ListboxT *_lstDescription = NULL; + +static ButtonT *_btnScreensTab = NULL; +static FrameT *_fraScreens = NULL; static PictureT *_picThumb1 = NULL; static PictureT *_picThumb2 = NULL; static PictureT *_picThumb3 = NULL; @@ -56,14 +57,36 @@ static PictureT *_picThumb4 = NULL; static PictureT *_picThumb5 = NULL; static PictureT *_picThumb6 = NULL; +static ButtonT *_btnBoxTab = NULL; +static FrameT *_fraBox = NULL; +static PictureT *_picBox1 = NULL; +static PictureT *_picBox2 = NULL; +static ButtonT *_btnInfoTab = NULL; +static FrameT *_fraInfo = NULL; +static ListboxT *_lstInfo = NULL; + +static uint8_t _channel = 0; +static char *_lastSearchText = NULL; + + +static void browserHide(void); static void btnTabClick(WidgetT *widget); static void packetHandler(PacketDecodeDataT *packet); +static void timSearchUpdate(WidgetT *widget); + + +static void browserHide(void) { + timerStop(_timSearchUpdate); + DEL(_lastSearchText); + netChannelRelease(_channel); + guiDelete(D(_winBrowser)); +} void browserShow(void) { - char **lines = NULL; + //char **lines = NULL; TagItemT uiBrowser[] = { T_START, @@ -81,7 +104,18 @@ void browserShow(void) { T_X, 5, T_Y, 32, T_WIDTH, 500, T_HEIGHT, 250, T_TITLE, P("Search"), - T_VISIBLE, T_FALSE, + + T_TEXTBOX, O(_txtSearch), + T_TITLE, P("Game, Publisher, or Developer:"), + T_X, 5, T_Y, 3, + T_WIDTH, 490, + T_LENGTH, 255, + T_TEXTBOX, T_DONE, + T_LISTBOX, O(_lstResults), + T_X, 1, T_Y, 35, + T_WIDTH, 493, T_HEIGHT, 190, // Works out to 57 characters wide, 13 high. + T_LISTBOX, T_DONE, + T_FRAME, T_DONE, // GAME @@ -89,6 +123,7 @@ void browserShow(void) { T_X, 78, T_Y, 5, T_TITLE, P("Game"), T_CLICK, P(btnTabClick), + T_ENABLED, T_FALSE, T_BUTTON, T_DONE, T_FRAME, O(_fraDescription), T_X, 5, T_Y, 32, @@ -98,7 +133,7 @@ void browserShow(void) { T_PICTURE, O(_picBanner), T_X, 1, // 490PX wide - T_FILENAME, P("banner.png"), + T_CACHENAME, P("games:d:descent:banner.png"), // ***TODO*** This needs a "browser:no-banner.png" image. T_PICTURE, T_DONE, T_LISTBOX, O(_lstDescription), T_X, 1, T_Y, 105, @@ -112,6 +147,7 @@ void browserShow(void) { T_X, 135, T_Y, 5, T_TITLE, P("Screens"), T_CLICK, P(btnTabClick), + T_ENABLED, T_FALSE, T_BUTTON, T_DONE, T_FRAME, O(_fraScreens), T_X, 5, T_Y, 32, @@ -121,28 +157,33 @@ void browserShow(void) { T_PICTURE, O(_picThumb1), // Thumbs are 160x100 T_X, 1, T_Y, 5, - T_FILENAME, P("thumb1.png"), + T_CACHENAME, P("browser:no-screen.png"), T_PICTURE, T_DONE, T_PICTURE, O(_picThumb2), T_X, 167, T_Y, 5, - T_FILENAME, P("thumb2.png"), + T_CACHENAME, P("browser:no-screen.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_PICTURE, O(_picThumb3), T_X, 333, T_Y, 5, - T_FILENAME, P("thumb3.png"), + T_CACHENAME, P("browser:no-screen.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_PICTURE, O(_picThumb4), T_X, 1, T_Y, 116, - T_FILENAME, P("thumb4.png"), + T_CACHENAME, P("browser:no-screen.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_PICTURE, O(_picThumb5), T_X, 167, T_Y, 116, - T_FILENAME, P("thumb5.png"), + T_CACHENAME, P("browser:no-screen.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_PICTURE, O(_picThumb6), T_X, 333, T_Y, 116, - T_FILENAME, P("thumb6.png"), + T_CACHENAME, P("browser:no-screen.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_FRAME, T_DONE, @@ -152,6 +193,7 @@ void browserShow(void) { T_X, 216, T_Y, 5, T_TITLE, P("Box"), T_CLICK, P(btnTabClick), + T_ENABLED, T_FALSE, T_BUTTON, T_DONE, T_FRAME, O(_fraBox), T_X, 5, T_Y, 32, @@ -161,11 +203,12 @@ void browserShow(void) { T_PICTURE, O(_picBox1), // Thumbs are 240x210 T_X, 1, T_Y, 5, - T_FILENAME, P("box1.png"), + T_CACHENAME, P("browser:no-box.png"), T_PICTURE, T_DONE, T_PICTURE, O(_picBox2), T_X, 250, T_Y, 5, - T_FILENAME, P("box2.png"), + T_CACHENAME, P("browser:no-box.png"), + T_VISIBLE, T_FALSE, T_PICTURE, T_DONE, T_FRAME, T_DONE, @@ -175,12 +218,13 @@ void browserShow(void) { T_X, 265, T_Y, 5, T_TITLE, P("Info"), T_CLICK, P(btnTabClick), + T_ENABLED, T_FALSE, T_BUTTON, T_DONE, T_FRAME, O(_fraInfo), T_X, 5, T_Y, 32, T_WIDTH, 500, T_HEIGHT, 250, T_TITLE, P("Information"), - T_VISIBLE, T_TRUE, + T_VISIBLE, T_FALSE, T_LISTBOX, O(_lstInfo), T_X, 1, T_Y, 5, @@ -189,19 +233,24 @@ void browserShow(void) { T_FRAME, T_DONE, + T_TIMER, O(_timSearchUpdate), + T_EVENT, P(timSearchUpdate), + T_VALUE, 3, + T_ENABLED, 1, + T_TIMER, T_DONE, T_WINDOW, T_DONE, T_END }; tagListRun(uiBrowser); + guiFocusSet(W(_txtSearch)); _channel = netChannelGet(packetHandler); - guiDebugAreaShow(W(_btnSearchTab)); - guiDebugAreaShow(W(_btnDescriptionTab)); - guiDebugAreaShow(W(_btnScreensTab)); - guiDebugAreaShow(W(_btnBoxTab)); - guiDebugAreaShow(W(_btnInfoTab)); + _lastSearchText = strdup(""); + + /* + guiDebugAreaShow(W(_fraSearch)); lines = utilWrapText( "The Post-Terran Minerals Corporation (PTMC) digs up minerals on all nine planets of the solar system, " @@ -216,23 +265,24 @@ void browserShow(void) { arrdel(lines, 0); } - listboxItemAdd(_lstInfo, "123456789012345678901234567890123456789012345678901234567"); - listboxItemAdd(_lstInfo, "2"); - listboxItemAdd(_lstInfo, "3"); - listboxItemAdd(_lstInfo, "4"); - listboxItemAdd(_lstInfo, "5"); - listboxItemAdd(_lstInfo, "6"); - listboxItemAdd(_lstInfo, "7"); - listboxItemAdd(_lstInfo, "8"); - listboxItemAdd(_lstInfo, "9"); - listboxItemAdd(_lstInfo, "10"); - listboxItemAdd(_lstInfo, "11"); - listboxItemAdd(_lstInfo, "12"); - listboxItemAdd(_lstInfo, "13"); - listboxItemAdd(_lstInfo, "14"); - listboxItemAdd(_lstInfo, "15"); - listboxItemAdd(_lstInfo, "16"); - listboxItemAdd(_lstInfo, "17"); + listboxItemAdd(_lstResults, "123456789012345678901234567890123456789012345678901234567"); + listboxItemAdd(_lstResults, "2"); + listboxItemAdd(_lstResults, "3"); + listboxItemAdd(_lstResults, "4"); + listboxItemAdd(_lstResults, "5"); + listboxItemAdd(_lstResults, "6"); + listboxItemAdd(_lstResults, "7"); + listboxItemAdd(_lstResults, "8"); + listboxItemAdd(_lstResults, "9"); + listboxItemAdd(_lstResults, "10"); + listboxItemAdd(_lstResults, "11"); + listboxItemAdd(_lstResults, "12"); + listboxItemAdd(_lstResults, "13"); + listboxItemAdd(_lstResults, "14"); + listboxItemAdd(_lstResults, "15"); + listboxItemAdd(_lstResults, "16"); + listboxItemAdd(_lstResults, "17"); + */ } @@ -255,3 +305,43 @@ static void btnTabClick(WidgetT *widget) { static void packetHandler(PacketDecodeDataT *packet) { } + + +static void timSearchUpdate(WidgetT *widget) { + char ***records = NULL; + char **fields = NULL; + uint16_t count = 0; + char query[258]; // 255 search characters, two %'s, and the terminating null. + + (void)widget; + + // Are there more than two characters in the search field? + if (textboxValueGet(_txtSearch) && strlen(textboxValueGet(_txtSearch)) > 2) { + // Did the search contents change? + if (strcmp(_lastSearchText, textboxValueGet(_txtSearch))) { + // Remember what was in the search box. + DEL(_lastSearchText); + _lastSearchText = strdup(textboxValueGet(_txtSearch)); + // Clear current search results. + listboxItemsClear(_lstResults); + // Execute search. + snprintf(query, 258, "%%%s%%", _lastSearchText); + dbQueryMultiple(&records, + "SELECT title FROM games WHERE " + "title LIKE ? OR developer LIKE ? OR publisher LIKE ? " + "ORDER BY title", + "vvv", + query, + query, + query); + // Did we get anything? + if (records) { + for (count = 0; count < arrlen(records); count++) { + fields = records[count]; + listboxItemAdd(_lstResults, fields[0]); + } + dbResultRelease(&records); + } + } + } +} diff --git a/client/src/gui/listbox.c b/client/src/gui/listbox.c index ebba214..b6d5ee7 100644 --- a/client/src/gui/listbox.c +++ b/client/src/gui/listbox.c @@ -44,15 +44,8 @@ static void listboxSizesRecalculate(ListboxT *listbox); static void listboxDel(WidgetT **widget) { ListboxT *l = (ListboxT *)*widget; - size_t len = arrlenu(l->values); - size_t x; - if (len > 0) { - for (x=0; xvalues[x]); - } - } - arrfree(l->values); + listboxItemsClear(l); } @@ -102,6 +95,7 @@ void listboxItemRemove(ListboxT *listbox, char *item) { if (len > 0) { for (x=0; xvalues[x]) == 0) { + DEL(listbox->values[x]); arrdel(listbox->values, x); if (listbox->selected > len || listbox->selected > 0) listbox->selected--; GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY); @@ -112,6 +106,17 @@ void listboxItemRemove(ListboxT *listbox, char *item) { } +void listboxItemsClear(ListboxT *listbox) { + while (arrlen(listbox->values) > 0) { + DEL(listbox->values[0]); + arrdel(listbox->values, 0); + } + arrfree(listbox->values); + + listbox->selected = 0; +} + + static void listboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) { ListboxT *l = (ListboxT *)widget; diff --git a/client/src/gui/listbox.h b/client/src/gui/listbox.h index d185c74..165ac87 100644 --- a/client/src/gui/listbox.h +++ b/client/src/gui/listbox.h @@ -41,6 +41,7 @@ void listboxIndexSet(ListboxT *listbox, uint16_t index); WidgetT *listboxInit(WidgetT *widget, char *title); void listboxItemAdd(ListboxT *listbox, char *item); void listboxItemRemove(ListboxT *listbox, char *item); +void listboxItemsClear(ListboxT *listbox); ListboxT *listboxNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title); void listboxStepSet(ListboxT *listbox, int32_t step); void listboxTitleSet(ListboxT *listbox, char *title); diff --git a/client/src/main.c b/client/src/main.c index 28cc092..7022c8e 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -211,6 +211,7 @@ static uint8_t startup(int argc, char *argv[]) { extern void browserShow(void); +extern void updateGameDatabase(void); int main(int argc, char *argv[]) { @@ -221,8 +222,9 @@ int main(int argc, char *argv[]) { // Perform "first run" setup tasks or start the client? if (hasValidSettings()) { // We have what we need, start the client. - welcomeShow(); - //browserShow(); + //welcomeShow(); + updateGameDatabase(); + browserShow(); eventLoop(); } else { // Run the setup. diff --git a/client/src/menu.c b/client/src/menu.c index ee2a77c..da5ad6e 100644 --- a/client/src/menu.c +++ b/client/src/menu.c @@ -21,6 +21,7 @@ #include "network.h" #include "vesa.h" #include "db.h" +#include "game.h" #include "taglist.h" #include "msgbox.h" @@ -44,7 +45,7 @@ static void picForumsClick(WidgetT *widget); static void picGamesClick(WidgetT *widget); static void picLogoffClick(WidgetT *widget); static void picProfileClick(WidgetT *widget); -static void updateGameDatabase(void); +/* static */ void updateGameDatabase(void); static PictureT *_picChat = NULL; @@ -154,6 +155,7 @@ void menuShow(void) { "menu:48profile.png", "generated:games.dat", + // LOAD THE WORLD! This is for debugging the browser. "games:d:descent:banner.png", "games:d:descent:box2.png", "games:d:descent:screen1.png", @@ -355,9 +357,51 @@ static void picProfileClick(WidgetT *widget) { } -static void updateGameDatabase(void) { +uint8_t utilFromFileReadByte(FILE *f, uint8_t *result) { + unsigned char c; + + // Get next byte. + c = fgetc(f); + // End of file? + if (feof(f)) return FAIL; + // Add to result. + *result = c; + return SUCCESS; +} + + +uint8_t utilFromFileReadString(FILE *f, char **result) { + unsigned char c; + char buffer[GAME_MAX_DESCRIPTION]; + uint16_t x = 0; + + // Something already in 'result'? + DEL(*result); + + while (1) { + // Get next byte. + c = fgetc(f); + // End of file? + if (feof(f)) return FAIL; + // Add to result. + buffer[x++] = c; + buffer[x] = 0; + // End of string? + if (c == 0) { + *result = strdup(buffer); + return SUCCESS; + } + } +} + + +/* static */ void updateGameDatabase(void) { FILE *f = NULL; - uint8_t c; + uint8_t result; + GameT game; + + // Clear 'game'. + memset(&game, 0, sizeof(GameT)); // Do we need to create the game database? dbExecute( @@ -372,7 +416,7 @@ static void updateGameDatabase(void) { "origin VARCHAR(255), " "shortName VARCHAR(8) PRIMARY KEY, " "worksWith VARCHAR(255), " - "type VARCHAR(8), " + "type INTEGER, " "maxPlayers INTEGER, " "joinable BOOLEAN, " "screens INTEGER, " @@ -382,22 +426,85 @@ static void updateGameDatabase(void) { NULL); // Mark everything untouched. - dbExecute("UPDATE games SET touced=0", NULL); + dbExecute("UPDATE games SET touched=0", NULL); - /* // Process latest downloaded game list. f = cacheFOpen("generated:games.dat", "rb"); if (f) { + result = FAIL; while (1) { - // Get next byte. - c = fgetc(f); - // End of file? - if (feof(f)) break; + // If this first read fails, we're out of data. Any other read fails, we have problems. + if (!utilFromFileReadString(f, &game.title)) { + result = SUCCESS; + break; + } + if (!utilFromFileReadString(f, &game.publisher)) break; + if (!utilFromFileReadString(f, &game.developer)) break; + if (!utilFromFileReadString(f, &game.description)) break; + if (!utilFromFileReadString(f, &game.releaseDate)) break; + if (!utilFromFileReadString(f, &game.rating)) break; + if (!utilFromFileReadString(f, &game.series)) break; + if (!utilFromFileReadString(f, &game.origin)) break; + if (!utilFromFileReadString(f, &game.shortName)) break; + if (!utilFromFileReadString(f, &game.worksWith)) break; + if (!utilFromFileReadByte(f, (uint8_t *)&game.type)) break; + if (!utilFromFileReadByte(f, &game.maxPlayers)) break; + if (!utilFromFileReadByte(f, &game.joinable)) break; + if (!utilFromFileReadByte(f, &game.screens)) break; + if (!utilFromFileReadByte(f, &game.boxes)) break; + + // Write this to the database. + dbExecute( + "REPLACE INTO games (" + "shortName, title, publisher, developer, description, releaseDate, " + "rating, series, origin, worksWith, type, maxPlayers, joinable, " + "screens, boxes, touched" + ") VALUES (" + "?, ?, ?, ?, ?, ?, " + "?, ?, ?, ?, ?, ?, ?, " + "?, ?, 1 " + ")", + "vvvvvv" + "vvvviii" + "iii", + game.shortName, + game.title, + game.publisher, + game.developer, + game.description, + game.releaseDate, + game.rating, + game.series, + game.origin, + game.worksWith, + game.type, + game.maxPlayers, + game.joinable, + game.screens, + game.boxes + ); } cacheFClose(f); + // Delete anything untouched. - dbExecute("DELETE FROM games WHERE touced=0", NULL); + dbExecute("DELETE FROM games WHERE touched=0", NULL); + + // Free 'game'. + DEL(game.title); + DEL(game.publisher); + DEL(game.developer); + DEL(game.description); + DEL(game.releaseDate); + DEL(game.rating); + DEL(game.series); + DEL(game.origin); + DEL(game.shortName); + DEL(game.worksWith); + + //***TODO*** Did we have problems updating the game database? + if (result == FAIL) { + // Do something here. + } } - */ } diff --git a/client/src/runtime.c b/client/src/runtime.c index 0c32921..dfa3f37 100644 --- a/client/src/runtime.c +++ b/client/src/runtime.c @@ -40,10 +40,9 @@ void runtimeDataLoad(void) { shput(__runtimeData.strings, fields[0], strdup(fields[1])); } } + dbResultRelease(&records); } - dbResultRelease(&records); - /* logWrite("\n\n"); for (int r = 0; r < shlen(__runtimeData.strings); r++) { diff --git a/server/src/client/file.c b/server/src/client/file.c index 5800600..2ace494 100644 --- a/server/src/client/file.c +++ b/server/src/client/file.c @@ -109,6 +109,8 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT * if (!client->authenticated && mustAuth) { logWrite("Unauthenticated user requested file: %s\n", path); clientApiFileFailed(client, data); + DEL(sha256); + DEL(path); return; } @@ -165,13 +167,13 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT * packetSend(client->packetThreadData, &encoded); DEL(packetData); - DEL(sha256); - DEL(path); - // Start sending actual file data. clientApiFileRequestNext(client, data); } + DEL(sha256); + DEL(path); + END } diff --git a/server/src/database.c b/server/src/database.c index b456ed6..ff4c8b8 100644 --- a/server/src/database.c +++ b/server/src/database.c @@ -286,8 +286,8 @@ static void dbFileSha256Create(char *file, char *buf) { } -void dbGameRelease(DbGameT **game) { - DbGameT *g = *game; +void dbGameRelease(GameT **game) { + GameT *g = *game; if (g) { DEL(g->title); @@ -305,15 +305,15 @@ void dbGameRelease(DbGameT **game) { } -DbGameT **dbGamesGet(void) { +GameT **dbGamesGet(void) { char statement[STATEMENT_MAX]; char *p = statement; MYSQL_RES *result = NULL; MYSQL_ROW row = NULL; int32_t count = 0; int32_t i = 0; - DbGameT **gameList = NULL; - DbGameT *game = NULL; + GameT **gameList = NULL; + GameT *game = NULL; char filename[MAX_PATH]; int32_t x = 0; @@ -351,7 +351,7 @@ DbGameT **dbGamesGet(void) { pthread_mutex_unlock(&_mutex); return NULL; } - NEW(DbGameT, game); + NEW(GameT, game); game->title = strdup(row[0]); game->publisher = strdup(row[1]); game->developer = strdup(row[2]); diff --git a/server/src/database.h b/server/src/database.h index 933e4cc..85286e3 100644 --- a/server/src/database.h +++ b/server/src/database.h @@ -23,20 +23,12 @@ #include "os.h" +#include "game.h" #define DB_CONFIG_ITEM_SIZE 1024 -typedef enum DbGameTypeE { - GAME_TYPE_UNKNOWN = 0, - GAME_TYPE_DOOR, - GAME_TYPE_SERIAL, - GAME_TYPE_IPX, - GAME_TYPE_FICTION -} DbGameTypeT; - - typedef struct DbClientConfigS { char *name; char *data; @@ -52,24 +44,6 @@ typedef struct DbFileInfoS { uint8_t touched; } DbFileInfoT; -typedef struct DbGameS { - char *title; - char *publisher; - char *developer; - char *description; - char *releaseDate; - char *rating; - char *series; - char *origin; - char *shortName; - char *worksWith; - DbGameTypeT type; - uint8_t maxPlayers; - uint8_t joinable; - uint8_t screens; - uint8_t boxes; -} DbGameT; - uint8_t dbConnect(char *host, uint16_t port, char *database, char *user, char *password); void dbClientConfigRelease(DbClientConfigT **config); @@ -77,8 +51,8 @@ DbClientConfigT **dbClientConfigGet(void); uint8_t dbDisconnect(void); DbFileInfoT *dbFileInfoGet(char *vpath); void dbFileInfoRelease(DbFileInfoT **info); -void dbGameRelease(DbGameT **game); -DbGameT **dbGamesGet(void); +void dbGameRelease(GameT **game); +GameT **dbGamesGet(void); uint8_t dbSettingsStringGet(char *host, char *key, char *value, uint32_t max); uint8_t dbSettingsValueGet(char *host, char *key, int32_t *value); uint8_t dbUpdateFileData(char *file, uint64_t len, char *time); diff --git a/server/src/update.c b/server/src/update.c index 08250b1..73c54fc 100644 --- a/server/src/update.c +++ b/server/src/update.c @@ -209,8 +209,8 @@ static int32_t updateFileEntry(const char *filepath, const struct stat *info, co static void updateGames(void) { - DbGameT **gameList = NULL; - DbGameT *game = NULL; + GameT **gameList = NULL; + GameT *game = NULL; char file[MAX_PATH] = { 0 }; FILE *f = NULL; uint8_t c = 0; diff --git a/shared/game.h b/shared/game.h new file mode 100644 index 0000000..6d63bea --- /dev/null +++ b/shared/game.h @@ -0,0 +1,59 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef GAME_H +#define GAME_H + + +#include "os.h" + + +#define GAME_MAX_DESCRIPTION 4096 + + +typedef enum GameTypeE { + GAME_TYPE_UNKNOWN = 0, + GAME_TYPE_DOOR, + GAME_TYPE_SERIAL, + GAME_TYPE_IPX, + GAME_TYPE_FICTION +} GameTypeT; + + +typedef struct GameS { // Data type in DAT file sent to client. + char *title; // 255 + char *publisher; // 255 + char *developer; // 255 + char *description; // TEXT + char *releaseDate; // DATETIME + char *rating; // 255 + char *series; // 255 + char *origin; // 255 + char *shortName; // 8 + char *worksWith; // 8 + GameTypeT type; // 1 + uint8_t maxPlayers; // 1 + uint8_t joinable; // 1 + uint8_t screens; // 1 + uint8_t boxes; // 1 +} GameT; + + +#endif // GAME_H diff --git a/shared/macros.h b/shared/macros.h index c95ae02..de763dd 100644 --- a/shared/macros.h +++ b/shared/macros.h @@ -38,7 +38,7 @@ // Allocation helpers. #define NEW(t,v) (v)=(t*)malloc(sizeof(t)) -#define DEL(v) {free(v); v=NULL;} +#define DEL(v) {if(v) {free(v); v=NULL;}} // Some helper defines. #define DIVISIBLE_BY_EIGHT(x) ((((x) >> 3) << 3) == (x))