Dynamic screenshot display working in browser.
This commit is contained in:
parent
377e40f28f
commit
f477ee15d0
23 changed files with 460 additions and 176 deletions
|
@ -131,6 +131,7 @@ SOURCES = \
|
||||||
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
|
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
|
||||||
$$SHARED/thirdparty/SHA256/sha256.c \
|
$$SHARED/thirdparty/SHA256/sha256.c \
|
||||||
$$SHARED/memory.c \
|
$$SHARED/memory.c \
|
||||||
|
../shared/game.c \
|
||||||
src/browser.c \
|
src/browser.c \
|
||||||
src/file.c \
|
src/file.c \
|
||||||
src/gui/msgbox.c \
|
src/gui/msgbox.c \
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "game.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
|
||||||
static WindowT *_winBrowser = NULL;
|
static WindowT *_winBrowser = NULL;
|
||||||
|
@ -50,17 +52,11 @@ static ListboxT *_lstDescription = NULL;
|
||||||
|
|
||||||
static ButtonT *_btnScreensTab = NULL;
|
static ButtonT *_btnScreensTab = NULL;
|
||||||
static FrameT *_fraScreens = NULL;
|
static FrameT *_fraScreens = NULL;
|
||||||
static PictureT *_picThumb1 = NULL;
|
static PictureT *_picThumb[6];
|
||||||
static PictureT *_picThumb2 = NULL;
|
|
||||||
static PictureT *_picThumb3 = NULL;
|
|
||||||
static PictureT *_picThumb4 = NULL;
|
|
||||||
static PictureT *_picThumb5 = NULL;
|
|
||||||
static PictureT *_picThumb6 = NULL;
|
|
||||||
|
|
||||||
static ButtonT *_btnBoxTab = NULL;
|
static ButtonT *_btnBoxTab = NULL;
|
||||||
static FrameT *_fraBox = NULL;
|
static FrameT *_fraBox = NULL;
|
||||||
static PictureT *_picBox1 = NULL;
|
static PictureT *_picBox[2];
|
||||||
static PictureT *_picBox2 = NULL;
|
|
||||||
|
|
||||||
static ButtonT *_btnInfoTab = NULL;
|
static ButtonT *_btnInfoTab = NULL;
|
||||||
static FrameT *_fraInfo = NULL;
|
static FrameT *_fraInfo = NULL;
|
||||||
|
@ -69,14 +65,22 @@ static ListboxT *_lstInfo = NULL;
|
||||||
static uint8_t _channel = 0;
|
static uint8_t _channel = 0;
|
||||||
static char *_lastSearchText = NULL;
|
static char *_lastSearchText = NULL;
|
||||||
|
|
||||||
|
static GameT _selectedGame = { 0 };
|
||||||
|
|
||||||
|
|
||||||
static void browserHide(void);
|
|
||||||
static void btnTabClick(WidgetT *widget);
|
static void btnTabClick(WidgetT *widget);
|
||||||
|
static void fraBoxShow(void);
|
||||||
|
static void fraDescriptionShow(void);
|
||||||
|
static void fraInfoShow(void);
|
||||||
|
static void fraScreensShow(void);
|
||||||
|
static void fraScreensReady(char *file);
|
||||||
static void packetHandler(PacketDecodeDataT *packet);
|
static void packetHandler(PacketDecodeDataT *packet);
|
||||||
|
static void tabsBusySet(uint8_t busy);
|
||||||
static void timSearchUpdate(WidgetT *widget);
|
static void timSearchUpdate(WidgetT *widget);
|
||||||
|
static void updateSelectedGame(void);
|
||||||
|
|
||||||
|
|
||||||
static void browserHide(void) {
|
void browserHide(void) {
|
||||||
timerStop(_timSearchUpdate);
|
timerStop(_timSearchUpdate);
|
||||||
DEL(_lastSearchText);
|
DEL(_lastSearchText);
|
||||||
netChannelRelease(_channel);
|
netChannelRelease(_channel);
|
||||||
|
@ -106,7 +110,7 @@ void browserShow(void) {
|
||||||
T_TITLE, P("Search"),
|
T_TITLE, P("Search"),
|
||||||
|
|
||||||
T_TEXTBOX, O(_txtSearch),
|
T_TEXTBOX, O(_txtSearch),
|
||||||
T_TITLE, P("Game, Publisher, or Developer:"),
|
T_TITLE, P("Filter:"),
|
||||||
T_X, 5, T_Y, 3,
|
T_X, 5, T_Y, 3,
|
||||||
T_WIDTH, 490,
|
T_WIDTH, 490,
|
||||||
T_LENGTH, 255,
|
T_LENGTH, 255,
|
||||||
|
@ -155,38 +159,33 @@ void browserShow(void) {
|
||||||
T_TITLE, P("Screenshots"),
|
T_TITLE, P("Screenshots"),
|
||||||
T_VISIBLE, T_FALSE,
|
T_VISIBLE, T_FALSE,
|
||||||
|
|
||||||
T_PICTURE, O(_picThumb1), // Thumbs are 160x100
|
T_PICTURE, O(_picThumb[0]), // Thumbs are 160x100
|
||||||
T_X, 1, T_Y, 5,
|
T_X, 1, T_Y, 5,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
T_PICTURE, O(_picThumb2),
|
T_PICTURE, O(_picThumb[1]),
|
||||||
T_X, 167, T_Y, 5,
|
T_X, 167, T_Y, 5,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
T_PICTURE, O(_picThumb3),
|
T_PICTURE, O(_picThumb[2]),
|
||||||
T_X, 333, T_Y, 5,
|
T_X, 333, T_Y, 5,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
|
|
||||||
T_PICTURE, O(_picThumb4),
|
T_PICTURE, O(_picThumb[3]),
|
||||||
T_X, 1, T_Y, 116,
|
T_X, 1, T_Y, 116,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
T_PICTURE, O(_picThumb5),
|
T_PICTURE, O(_picThumb[4]),
|
||||||
T_X, 167, T_Y, 116,
|
T_X, 167, T_Y, 116,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
T_PICTURE, O(_picThumb6),
|
T_PICTURE, O(_picThumb[5]),
|
||||||
T_X, 333, T_Y, 116,
|
T_X, 333, T_Y, 116,
|
||||||
T_CACHENAME, P("browser:no-screen.png"),
|
T_CACHENAME, P("browser:no-screen.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
|
|
||||||
T_FRAME, T_DONE,
|
T_FRAME, T_DONE,
|
||||||
|
|
||||||
// BOX
|
// BOX
|
||||||
T_BUTTON, O(_btnBoxTab),
|
T_BUTTON, O(_btnBoxTab),
|
||||||
|
@ -201,17 +200,16 @@ void browserShow(void) {
|
||||||
T_TITLE, P("Packaging"),
|
T_TITLE, P("Packaging"),
|
||||||
T_VISIBLE, T_FALSE,
|
T_VISIBLE, T_FALSE,
|
||||||
|
|
||||||
T_PICTURE, O(_picBox1), // Thumbs are 240x210
|
T_PICTURE, O(_picBox[0]), // Thumbs are 240x210
|
||||||
T_X, 1, T_Y, 5,
|
T_X, 1, T_Y, 5,
|
||||||
T_CACHENAME, P("browser:no-box.png"),
|
T_CACHENAME, P("browser:no-box.png"),
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
T_PICTURE, O(_picBox2),
|
T_PICTURE, O(_picBox[1]),
|
||||||
T_X, 250, T_Y, 5,
|
T_X, 250, T_Y, 5,
|
||||||
T_CACHENAME, P("browser:no-box.png"),
|
T_CACHENAME, P("browser:no-box.png"),
|
||||||
T_VISIBLE, T_FALSE,
|
|
||||||
T_PICTURE, T_DONE,
|
T_PICTURE, T_DONE,
|
||||||
|
|
||||||
T_FRAME, T_DONE,
|
T_FRAME, T_DONE,
|
||||||
|
|
||||||
// INFO
|
// INFO
|
||||||
T_BUTTON, O(_btnInfoTab),
|
T_BUTTON, O(_btnInfoTab),
|
||||||
|
@ -247,7 +245,7 @@ void browserShow(void) {
|
||||||
guiFocusSet(W(_txtSearch));
|
guiFocusSet(W(_txtSearch));
|
||||||
_channel = netChannelGet(packetHandler);
|
_channel = netChannelGet(packetHandler);
|
||||||
|
|
||||||
_lastSearchText = strdup("");
|
_lastSearchText = strdup("x");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
guiDebugAreaShow(W(_fraSearch));
|
guiDebugAreaShow(W(_fraSearch));
|
||||||
|
@ -288,17 +286,101 @@ void browserShow(void) {
|
||||||
|
|
||||||
static void btnTabClick(WidgetT *widget) {
|
static void btnTabClick(WidgetT *widget) {
|
||||||
|
|
||||||
|
tabsBusySet(1);
|
||||||
|
|
||||||
|
// Hide everything.
|
||||||
widgetVisibleSet(W(_fraBox), 0);
|
widgetVisibleSet(W(_fraBox), 0);
|
||||||
widgetVisibleSet(W(_fraDescription), 0);
|
widgetVisibleSet(W(_fraDescription), 0);
|
||||||
widgetVisibleSet(W(_fraInfo), 0);
|
widgetVisibleSet(W(_fraInfo), 0);
|
||||||
widgetVisibleSet(W(_fraScreens), 0);
|
widgetVisibleSet(W(_fraScreens), 0);
|
||||||
widgetVisibleSet(W(_fraSearch), 0);
|
widgetVisibleSet(W(_fraSearch), 0);
|
||||||
|
|
||||||
if (widget == W(_btnBoxTab)) widgetVisibleSet(W(_fraBox), 1);
|
updateSelectedGame();
|
||||||
if (widget == W(_btnDescriptionTab)) widgetVisibleSet(W(_fraDescription), 1);
|
|
||||||
if (widget == W(_btnInfoTab)) widgetVisibleSet(W(_fraInfo), 1);
|
// Show selected frame.
|
||||||
if (widget == W(_btnScreensTab)) widgetVisibleSet(W(_fraScreens), 1);
|
if (widget == W(_btnBoxTab)) fraBoxShow();
|
||||||
if (widget == W(_btnSearchTab)) widgetVisibleSet(W(_fraSearch), 1);
|
if (widget == W(_btnDescriptionTab)) fraDescriptionShow();
|
||||||
|
if (widget == W(_btnInfoTab)) fraInfoShow();
|
||||||
|
if (widget == W(_btnScreensTab)) fraScreensShow();
|
||||||
|
if (widget == W(_btnSearchTab)) {
|
||||||
|
widgetVisibleSet(W(_fraSearch), 1);
|
||||||
|
tabsBusySet(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fraBoxShow(void) {
|
||||||
|
widgetVisibleSet(W(_fraBox), 1);
|
||||||
|
tabsBusySet(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fraDescriptionShow(void) {
|
||||||
|
widgetVisibleSet(W(_fraDescription), 1);
|
||||||
|
tabsBusySet(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fraInfoShow(void) {
|
||||||
|
widgetVisibleSet(W(_fraInfo), 1);
|
||||||
|
tabsBusySet(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fraScreensShow(void) {
|
||||||
|
char **fileList = NULL;
|
||||||
|
char *temp;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
// Build list of screen filenames needed.
|
||||||
|
for (i=0; i<_selectedGame.screens; i++) {
|
||||||
|
temp = utilCreateString("games:%c:%s:screen%d.png", _selectedGame.shortName[0], _selectedGame.shortName, i + 1);
|
||||||
|
utilStringToLower(temp);
|
||||||
|
arrput(fileList, temp);
|
||||||
|
temp = utilCreateString("games:%c:%s:screen%d-thumb.png", _selectedGame.shortName[0], _selectedGame.shortName, i + 1);
|
||||||
|
utilStringToLower(temp);
|
||||||
|
arrput(fileList, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileList) {
|
||||||
|
fileCacheCheckArr(fraScreensReady, fileList);
|
||||||
|
} else {
|
||||||
|
fraScreensReady(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fraScreensReady(char *file) {
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
// Is this a file update notice? If so, exit.
|
||||||
|
if (file) return;
|
||||||
|
|
||||||
|
// Are there screenshots?
|
||||||
|
if (_selectedGame.screens == 0) {
|
||||||
|
// Nope.
|
||||||
|
pictureReplace(_picThumb[0], "browser:no-screen.png");
|
||||||
|
for (i=1; i<6; i++) {
|
||||||
|
widgetVisibleSet(W(_picThumb[i]), 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i=0; i<6; i++) {
|
||||||
|
if (i < _selectedGame.screens) {
|
||||||
|
snprintf(_scratch, SCRATCH_SIZE, "games:%c:%s:screen%d-thumb.png", _selectedGame.shortName[0], _selectedGame.shortName, i + 1);
|
||||||
|
utilStringToLower(_scratch);
|
||||||
|
logWrite("Loading screen: %s\n", _scratch);
|
||||||
|
pictureReplace(_picThumb[i], _scratch);
|
||||||
|
widgetVisibleSet(W(_picThumb[i]), 1);
|
||||||
|
} else {
|
||||||
|
widgetVisibleSet(W(_picThumb[i]), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display us.
|
||||||
|
widgetVisibleSet(W(_fraScreens), 1);
|
||||||
|
tabsBusySet(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,39 +389,113 @@ static void packetHandler(PacketDecodeDataT *packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void tabsBusySet(uint8_t busy) {
|
||||||
|
uint8_t enabled = busy ? 0 : 1;
|
||||||
|
|
||||||
|
if (busy) {
|
||||||
|
guiMouseBusyPush();
|
||||||
|
} else {
|
||||||
|
guiMouseBusyPop();
|
||||||
|
}
|
||||||
|
|
||||||
|
widgetEnableSet(W(_btnSearchTab), enabled);
|
||||||
|
widgetEnableSet(W(_btnDescriptionTab), enabled);
|
||||||
|
widgetEnableSet(W(_btnScreensTab), enabled);
|
||||||
|
widgetEnableSet(W(_btnBoxTab), enabled);
|
||||||
|
widgetEnableSet(W(_btnInfoTab), enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void timSearchUpdate(WidgetT *widget) {
|
static void timSearchUpdate(WidgetT *widget) {
|
||||||
char ***records = NULL;
|
char ***records = NULL;
|
||||||
char **fields = NULL;
|
char **fields = NULL;
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
char query[258]; // 255 search characters, two %'s, and the terminating null.
|
|
||||||
|
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
// Are there more than two characters in the search field?
|
// Did the search contents change?
|
||||||
if (textboxValueGet(_txtSearch) && strlen(textboxValueGet(_txtSearch)) > 2) {
|
if (strcmp(_lastSearchText, textboxValueGet(_txtSearch))) {
|
||||||
// Did the search contents change?
|
// Remember what was in the search box.
|
||||||
if (strcmp(_lastSearchText, textboxValueGet(_txtSearch))) {
|
DEL(_lastSearchText);
|
||||||
// Remember what was in the search box.
|
_lastSearchText = strdup(textboxValueGet(_txtSearch));
|
||||||
DEL(_lastSearchText);
|
// Clear current search results.
|
||||||
_lastSearchText = strdup(textboxValueGet(_txtSearch));
|
listboxItemsClear(_lstResults);
|
||||||
// Clear current search results.
|
// Is there something in the search field?
|
||||||
listboxItemsClear(_lstResults);
|
if (textboxValueGet(_txtSearch) && strlen(textboxValueGet(_txtSearch)) > 0) {
|
||||||
// Execute search.
|
// Yes. Filter based on what is in the search field.
|
||||||
snprintf(query, 258, "%%%s%%", _lastSearchText);
|
snprintf(_scratch, SCRATCH_SIZE, "%%%s%%", _lastSearchText);
|
||||||
dbQueryMultiple(&records,
|
dbQueryMultiple(&records,
|
||||||
"SELECT title FROM games WHERE "
|
"SELECT ROWID, title FROM games WHERE "
|
||||||
"title LIKE ? OR developer LIKE ? OR publisher LIKE ? "
|
"title LIKE ? "
|
||||||
"ORDER BY title",
|
"ORDER BY title",
|
||||||
"vvv",
|
"v",
|
||||||
query,
|
_scratch);
|
||||||
query,
|
} else {
|
||||||
query);
|
// No. Display ALL games.
|
||||||
// Did we get anything?
|
dbQueryMultiple(&records,
|
||||||
|
"SELECT ROWID, title FROM games "
|
||||||
|
"ORDER BY title",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
// Did we get anything?
|
||||||
|
if (records) {
|
||||||
|
for (count = 0; count < arrlen(records); count++) {
|
||||||
|
fields = records[count];
|
||||||
|
listboxItemAddWithData(_lstResults, fields[1], atol(fields[0]));
|
||||||
|
}
|
||||||
|
dbResultRelease(&records);
|
||||||
|
}
|
||||||
|
// Ghost or enable tab buttons depending on if the listbox has an item highlighted or not.
|
||||||
|
count = listboxItemsCountGet(_lstResults) > 0; // Reusing count.
|
||||||
|
widgetEnableSet(W(_btnDescriptionTab), count);
|
||||||
|
widgetEnableSet(W(_btnScreensTab), count);
|
||||||
|
widgetEnableSet(W(_btnBoxTab), count);
|
||||||
|
widgetEnableSet(W(_btnInfoTab), count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void updateSelectedGame(void) {
|
||||||
|
char ***records = NULL;
|
||||||
|
char **fields = NULL;
|
||||||
|
|
||||||
|
// If a game is selected...
|
||||||
|
if (listboxItemsCountGet(_lstResults) > 0) {
|
||||||
|
// Is it a different game?
|
||||||
|
if (listboxDataGet(_lstResults) != _selectedGame.ROWID) {
|
||||||
|
// Clear last loadead game.
|
||||||
|
gameClear(&_selectedGame);
|
||||||
|
|
||||||
|
logWrite("Loading game details: %d = '%s'\n", listboxDataGet(_lstResults), listboxValueGet(_lstResults));
|
||||||
|
|
||||||
|
// Load the details from the SQL database.
|
||||||
|
dbQueryMultiple(&records,
|
||||||
|
"SELECT title, publisher, developer, description, "
|
||||||
|
"releaseDate, rating, series, origin, shortName, "
|
||||||
|
"worksWith, type, maxPlayers, joinable, screens, "
|
||||||
|
"boxes, ROWID "
|
||||||
|
"FROM games WHERE "
|
||||||
|
"ROWID=?",
|
||||||
|
"i",
|
||||||
|
listboxDataGet(_lstResults));
|
||||||
if (records) {
|
if (records) {
|
||||||
for (count = 0; count < arrlen(records); count++) {
|
fields = records[0];
|
||||||
fields = records[count];
|
_selectedGame.title = strdup(fields[0]);
|
||||||
listboxItemAdd(_lstResults, fields[0]);
|
_selectedGame.publisher = strdup(fields[1]);
|
||||||
}
|
_selectedGame.developer = strdup(fields[2]);
|
||||||
|
_selectedGame.description = strdup(fields[3]);
|
||||||
|
_selectedGame.releaseDate = strdup(fields[4]);
|
||||||
|
_selectedGame.rating = strdup(fields[5]);
|
||||||
|
_selectedGame.series = strdup(fields[6]);
|
||||||
|
_selectedGame.origin = strdup(fields[7]);
|
||||||
|
_selectedGame.shortName = strdup(fields[8]);
|
||||||
|
_selectedGame.worksWith = strdup(fields[9]);
|
||||||
|
_selectedGame.type = atoi(fields[10]);
|
||||||
|
_selectedGame.maxPlayers = atoi(fields[11]);
|
||||||
|
_selectedGame.joinable = atoi(fields[12]);
|
||||||
|
_selectedGame.screens = atoi(fields[13]);
|
||||||
|
_selectedGame.boxes = atoi(fields[14]);
|
||||||
|
_selectedGame.ROWID = atol(fields[15]);
|
||||||
dbResultRelease(&records);
|
dbResultRelease(&records);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
|
void browserHide(void);
|
||||||
void browserShow(void);
|
void browserShow(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,20 +70,46 @@ static void btnMsgBoxOkay(MsgBoxButtonT button) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// List of character array.
|
||||||
void fileCacheCheck(fileCallback callback, char *vpaths[]) {
|
void fileCacheCheck(fileCallback callback, char *vpaths[]) {
|
||||||
|
uint16_t i = 0;
|
||||||
|
char **files = NULL;
|
||||||
|
|
||||||
|
// Used during development & debugging.
|
||||||
|
if (!netPacketHandlerIsRunning()) {
|
||||||
|
callback(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
while (vpaths[i] != NULL) {
|
||||||
|
arrput(files, strdup(vpaths[i]));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileCacheCheckArr(callback, files);
|
||||||
|
|
||||||
|
END
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// List of dynamic array.
|
||||||
|
void fileCacheCheckArr(fileCallback callback, char **vpathArr) {
|
||||||
FileListT *newList = NULL;
|
FileListT *newList = NULL;
|
||||||
uint16_t i = 0;
|
|
||||||
|
// Used during development & debugging.
|
||||||
|
if (!netPacketHandlerIsRunning()) {
|
||||||
|
callback(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
// Add new entries to anything already in the queue.
|
// Add new entries to anything already in the queue.
|
||||||
NEW(FileListT, newList);
|
NEW(FileListT, newList);
|
||||||
newList->callback = callback;
|
newList->callback = callback;
|
||||||
newList->files = NULL;
|
newList->files = vpathArr;
|
||||||
while (vpaths[i] != NULL) {
|
|
||||||
arrput(newList->files, strdup(vpaths[i]));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
arrput(_fileList, newList);
|
arrput(_fileList, newList);
|
||||||
|
|
||||||
// New queue?
|
// New queue?
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef void (*fileCallback)(char *updatedFile);
|
||||||
|
|
||||||
|
|
||||||
void fileCacheCheck(fileCallback callback, char *vpaths[]);
|
void fileCacheCheck(fileCallback callback, char *vpaths[]);
|
||||||
|
void fileCacheCheckArr(fileCallback callback, char **vpathArr);
|
||||||
|
|
||||||
|
|
||||||
#endif // FILE_H
|
#endif // FILE_H
|
||||||
|
|
|
@ -218,6 +218,7 @@ void guiDelayedFree(void **pointer) {
|
||||||
// Delayed Free allows freeing of data that may be in use by the
|
// Delayed Free allows freeing of data that may be in use by the
|
||||||
// GUI system at a safe time. (After compositing.)
|
// GUI system at a safe time. (After compositing.)
|
||||||
arrput(_guiPendingFrees, *pointer);
|
arrput(_guiPendingFrees, *pointer);
|
||||||
|
*pointer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,6 +231,7 @@ void guiDelete(WidgetT **widget) {
|
||||||
// that is also handled in the paint event.
|
// that is also handled in the paint event.
|
||||||
|
|
||||||
arrput(_guiDeleteList, widget);
|
arrput(_guiDeleteList, widget);
|
||||||
|
*widget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,11 @@ static void listboxScrollUp(ListboxT *listbox);
|
||||||
static void listboxSizesRecalculate(ListboxT *listbox);
|
static void listboxSizesRecalculate(ListboxT *listbox);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t listboxDataGet(ListboxT *listbox) {
|
||||||
|
return listbox->values[listbox->selected]->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void listboxDel(WidgetT **widget) {
|
static void listboxDel(WidgetT **widget) {
|
||||||
ListboxT *l = (ListboxT *)*widget;
|
ListboxT *l = (ListboxT *)*widget;
|
||||||
|
|
||||||
|
@ -83,7 +88,19 @@ WidgetT *listboxInit(WidgetT *widget, char *title) {
|
||||||
|
|
||||||
|
|
||||||
void listboxItemAdd(ListboxT *listbox, char *item) {
|
void listboxItemAdd(ListboxT *listbox, char *item) {
|
||||||
arrput(listbox->values, strdup(item));
|
listboxItemAddWithData(listbox, item, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void listboxItemAddWithData(ListboxT *listbox, char *item, uint32_t data) {
|
||||||
|
ListboxItemT *i;
|
||||||
|
|
||||||
|
NEW(ListboxItemT, i);
|
||||||
|
|
||||||
|
i->text = strdup(item);
|
||||||
|
i->data = data;
|
||||||
|
arrput(listbox->values, i);
|
||||||
|
|
||||||
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +111,8 @@ void listboxItemRemove(ListboxT *listbox, char *item) {
|
||||||
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
for (x=0; x<len; x++) {
|
for (x=0; x<len; x++) {
|
||||||
if (strcmp(item, listbox->values[x]) == 0) {
|
if (strcmp(item, listbox->values[x]->text) == 0) {
|
||||||
|
DEL(listbox->values[x]->text);
|
||||||
DEL(listbox->values[x]);
|
DEL(listbox->values[x]);
|
||||||
arrdel(listbox->values, x);
|
arrdel(listbox->values, x);
|
||||||
if (listbox->selected > len || listbox->selected > 0) listbox->selected--;
|
if (listbox->selected > len || listbox->selected > 0) listbox->selected--;
|
||||||
|
@ -108,12 +126,20 @@ void listboxItemRemove(ListboxT *listbox, char *item) {
|
||||||
|
|
||||||
void listboxItemsClear(ListboxT *listbox) {
|
void listboxItemsClear(ListboxT *listbox) {
|
||||||
while (arrlen(listbox->values) > 0) {
|
while (arrlen(listbox->values) > 0) {
|
||||||
|
DEL(listbox->values[0]->text);
|
||||||
DEL(listbox->values[0]);
|
DEL(listbox->values[0]);
|
||||||
arrdel(listbox->values, 0);
|
arrdel(listbox->values, 0);
|
||||||
}
|
}
|
||||||
arrfree(listbox->values);
|
arrfree(listbox->values);
|
||||||
|
|
||||||
listbox->selected = 0;
|
listbox->selected = 0;
|
||||||
|
|
||||||
|
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t listboxItemsCountGet(ListboxT *listbox) {
|
||||||
|
return arrlen(listbox->values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,9 +304,9 @@ static void listboxPaint(WidgetT *widget, uint8_t enabled, RectT pos) {
|
||||||
for (i=0; i<items; i++) {
|
for (i=0; i<items; i++) {
|
||||||
if (i == l->selected) {
|
if (i == l->selected) {
|
||||||
surfaceRectangleFilledDraw(pos.x + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(__guiFont) - 1, __guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]);
|
surfaceRectangleFilledDraw(pos.x + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o, pos.x + _valueWidth - __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o + fontHeightGet(__guiFont) - 1, __guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND]);
|
||||||
fontRender(__guiFont, l->values[l->offset + i], __guiColor[COLOR_LISTBOX_SELECTED_TEXT], __guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND], pos.x + 1 + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
|
fontRender(__guiFont, l->values[l->offset + i]->text, __guiColor[COLOR_LISTBOX_SELECTED_TEXT], __guiColor[COLOR_LISTBOX_SELECTED_BACKGROUND], pos.x + 1 + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
|
||||||
} else {
|
} else {
|
||||||
fontRender(__guiFont, l->values[l->offset + i], __guiColor[COLOR_LISTBOX_TEXT], __guiColor[COLOR_LISTBOX_BACKGROUND], pos.x + 1 + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
|
fontRender(__guiFont, l->values[l->offset + i]->text, __guiColor[COLOR_LISTBOX_TEXT], __guiColor[COLOR_LISTBOX_BACKGROUND], pos.x + 1 + __guiMetric[METRIC_LISTBOX_HORIZONTAL_PADDING], o);
|
||||||
}
|
}
|
||||||
o += fontHeightGet(__guiFont);
|
o += fontHeightGet(__guiFont);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +415,7 @@ void listboxTitleSet(ListboxT *listbox, char *title) {
|
||||||
|
|
||||||
|
|
||||||
char *listboxValueGet(ListboxT *listbox) {
|
char *listboxValueGet(ListboxT *listbox) {
|
||||||
return listbox->values[listbox->selected];
|
return listbox->values[listbox->selected]->text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -399,7 +425,7 @@ void listboxValueSet(ListboxT *listbox, char *value) {
|
||||||
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
for (x=0; x<len; x++) {
|
for (x=0; x<len; x++) {
|
||||||
if (strcmp(value, listbox->values[x]) == 0) {
|
if (strcmp(value, listbox->values[x]->text) == 0) {
|
||||||
listbox->selected = x;
|
listbox->selected = x;
|
||||||
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -26,22 +26,30 @@
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ListboxItemS {
|
||||||
|
char *text;
|
||||||
|
uint32_t data;
|
||||||
|
} ListboxItemT;
|
||||||
|
|
||||||
typedef struct ListboxS {
|
typedef struct ListboxS {
|
||||||
WidgetT base; // Must be first in every widget
|
WidgetT base; // Must be first in every widget
|
||||||
char *title;
|
char *title;
|
||||||
char **values;
|
ListboxItemT **values;
|
||||||
uint16_t selected; // values[offset + selected]
|
uint16_t selected; // values[offset + selected]
|
||||||
int32_t step;
|
int32_t step;
|
||||||
int32_t offset;
|
int32_t offset;
|
||||||
} ListboxT;
|
} ListboxT;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t listboxDataGet(ListboxT *listbox);
|
||||||
uint16_t listboxIndexGet(ListboxT *listbox);
|
uint16_t listboxIndexGet(ListboxT *listbox);
|
||||||
void listboxIndexSet(ListboxT *listbox, uint16_t index);
|
void listboxIndexSet(ListboxT *listbox, uint16_t index);
|
||||||
WidgetT *listboxInit(WidgetT *widget, char *title);
|
WidgetT *listboxInit(WidgetT *widget, char *title);
|
||||||
void listboxItemAdd(ListboxT *listbox, char *item);
|
void listboxItemAdd(ListboxT *listbox, char *item);
|
||||||
|
void listboxItemAddWithData(ListboxT *listbox, char *item, uint32_t data);
|
||||||
void listboxItemRemove(ListboxT *listbox, char *item);
|
void listboxItemRemove(ListboxT *listbox, char *item);
|
||||||
void listboxItemsClear(ListboxT *listbox);
|
void listboxItemsClear(ListboxT *listbox);
|
||||||
|
uint16_t listboxItemsCountGet(ListboxT *listbox);
|
||||||
ListboxT *listboxNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
|
ListboxT *listboxNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
|
||||||
void listboxStepSet(ListboxT *listbox, int32_t step);
|
void listboxStepSet(ListboxT *listbox, int32_t step);
|
||||||
void listboxTitleSet(ListboxT *listbox, char *title);
|
void listboxTitleSet(ListboxT *listbox, char *title);
|
||||||
|
|
|
@ -117,6 +117,21 @@ static void picturePaint(WidgetT *widget, uint8_t enabled, RectT pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pictureReplace(PictureT *picture, char *filename) {
|
||||||
|
ImageT *newImage = NULL;
|
||||||
|
|
||||||
|
newImage = imageLoadCache(filename);
|
||||||
|
if (newImage) {
|
||||||
|
DEL(picture->filename);
|
||||||
|
picture->filename = strdup(filename);
|
||||||
|
imageUnload(&picture->image);
|
||||||
|
picture->image = newImage;
|
||||||
|
GUI_SET_FLAG(W(picture), WIDGET_FLAG_DIRTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void pictureZoomSet(PictureT *picture, PictureZoomT zoom) {
|
void pictureZoomSet(PictureT *picture, PictureZoomT zoom) {
|
||||||
picture->zoom = zoom;
|
picture->zoom = zoom;
|
||||||
GUI_SET_FLAG(W(picture), WIDGET_FLAG_DIRTY);
|
GUI_SET_FLAG(W(picture), WIDGET_FLAG_DIRTY);
|
||||||
|
|
|
@ -45,6 +45,7 @@ typedef struct PictureS {
|
||||||
void pictureClickHandlerSet(PictureT *picture, widgetCallback callback);
|
void pictureClickHandlerSet(PictureT *picture, widgetCallback callback);
|
||||||
WidgetT *pictureInit(WidgetT *widget, char *filename);
|
WidgetT *pictureInit(WidgetT *widget, char *filename);
|
||||||
PictureT *pictureNew(uint16_t x, uint16_t y, char *filename);
|
PictureT *pictureNew(uint16_t x, uint16_t y, char *filename);
|
||||||
|
void pictureReplace(PictureT *picture, char *filename);
|
||||||
void pictureZoomSet(PictureT *picture, PictureZoomT zoom);
|
void pictureZoomSet(PictureT *picture, PictureZoomT zoom);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,16 @@ static void menuFilesReady(char *updatedFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void menuHide(void) {
|
||||||
|
guiDelete(D(_picChat));
|
||||||
|
guiDelete(D(_picEmail));
|
||||||
|
guiDelete(D(_picForums));
|
||||||
|
guiDelete(D(_picGames));
|
||||||
|
guiDelete(D(_picLogoff));
|
||||||
|
guiDelete(D(_picProfile));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void menuShow(void) {
|
void menuShow(void) {
|
||||||
char *fileList[] = {
|
char *fileList[] = {
|
||||||
"menu:48chat.png",
|
"menu:48chat.png",
|
||||||
|
@ -154,6 +164,9 @@ void menuShow(void) {
|
||||||
"menu:48logoff.png",
|
"menu:48logoff.png",
|
||||||
"menu:48profile.png",
|
"menu:48profile.png",
|
||||||
"generated:games.dat",
|
"generated:games.dat",
|
||||||
|
"browser:no-box.png",
|
||||||
|
"browser:no-screen.png",
|
||||||
|
// "browser:no-banner.png",
|
||||||
|
|
||||||
// LOAD THE WORLD! This is for debugging the browser.
|
// LOAD THE WORLD! This is for debugging the browser.
|
||||||
"games:d:descent:banner.png",
|
"games:d:descent:banner.png",
|
||||||
|
@ -295,8 +308,6 @@ void menuShow(void) {
|
||||||
"games:s:sre:screen1.png",
|
"games:s:sre:screen1.png",
|
||||||
"games:s:sre:screen1-thumb.png",
|
"games:s:sre:screen1-thumb.png",
|
||||||
"games:s:sre:banner.png",
|
"games:s:sre:banner.png",
|
||||||
"browser:no-box.png",
|
|
||||||
"browser:no-screen.png",
|
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -357,44 +368,6 @@ static void picProfileClick(WidgetT *widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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) {
|
/* static */ void updateGameDatabase(void) {
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
|
@ -491,16 +464,7 @@ uint8_t utilFromFileReadString(FILE *f, char **result) {
|
||||||
dbExecute("DELETE FROM games WHERE touched=0", NULL);
|
dbExecute("DELETE FROM games WHERE touched=0", NULL);
|
||||||
|
|
||||||
// Free 'game'.
|
// Free 'game'.
|
||||||
DEL(game.title);
|
gameClear(&game);
|
||||||
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?
|
//***TODO*** Did we have problems updating the game database?
|
||||||
if (result == FAIL) {
|
if (result == FAIL) {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
|
void menuHide(void);
|
||||||
void menuShow(void);
|
void menuShow(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,50 +55,37 @@ void runtimeDataLoad(void) {
|
||||||
|
|
||||||
void runtimeDataUpdate(void) {
|
void runtimeDataUpdate(void) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
uint8_t c;
|
char *name = NULL;
|
||||||
char name[33];
|
char *data = NULL;
|
||||||
char data[1025];
|
uint8_t result = FAIL;
|
||||||
uint8_t which = 0; // 0 = Reading name, 1 = Reading data.
|
|
||||||
uint16_t x = 0;
|
|
||||||
|
|
||||||
f = cacheFOpen("generated:client.dat", "rb");
|
f = cacheFOpen("generated:client.dat", "rb");
|
||||||
if (f) {
|
if (f) {
|
||||||
while (1) {
|
while (1) {
|
||||||
// Get next byte.
|
// If this first read fails, we're out of data. Any other read fails, we have problems.
|
||||||
c = fgetc(f);
|
if (!utilFromFileReadString(f, &name)) {
|
||||||
// End of file?
|
result = SUCCESS;
|
||||||
if (feof(f)) break;
|
break;
|
||||||
// End of string?
|
|
||||||
if (c == 0) {
|
|
||||||
if (which == 0) {
|
|
||||||
// Got the name, move on to data.
|
|
||||||
which++;
|
|
||||||
name[x] = 0;
|
|
||||||
x = 0;
|
|
||||||
} else {
|
|
||||||
// Got data. Write both to database and start over.
|
|
||||||
which = 0;
|
|
||||||
data[x] = 0;
|
|
||||||
x = 0;
|
|
||||||
dbExecute(
|
|
||||||
"REPLACE INTO data (name, data) VALUES (?, ?)",
|
|
||||||
"vv",
|
|
||||||
name, data
|
|
||||||
);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Got byte.
|
|
||||||
if (which == 0) {
|
|
||||||
name[x++] = c;
|
|
||||||
} else {
|
|
||||||
data[x++] = c;
|
|
||||||
}
|
}
|
||||||
|
if (!utilFromFileReadString(f, &data)) break;
|
||||||
|
// Write this to the database.
|
||||||
|
dbExecute(
|
||||||
|
"REPLACE INTO data (name, data) VALUES (?, ?)",
|
||||||
|
"vv",
|
||||||
|
name, data
|
||||||
|
);
|
||||||
|
DEL(name);
|
||||||
|
DEL(data);
|
||||||
}
|
}
|
||||||
cacheFClose(f);
|
cacheFClose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDataLoad();
|
//***TODO*** Did we have problems updating the runtime data?
|
||||||
|
if (result == FAIL) {
|
||||||
|
// Do something here.
|
||||||
|
} else {
|
||||||
|
runtimeDataLoad();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,6 @@ static void settingsComShow(void) {
|
||||||
|
|
||||||
|
|
||||||
static void timSettingsProgress(WidgetT *widget) {
|
static void timSettingsProgress(WidgetT *widget) {
|
||||||
char buffer[1024];
|
|
||||||
int32_t rc;
|
int32_t rc;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|
||||||
|
@ -224,8 +223,8 @@ static void timSettingsProgress(WidgetT *widget) {
|
||||||
case S_OPEN_COM:
|
case S_OPEN_COM:
|
||||||
rc = comOpen(com, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
rc = comOpen(com, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
||||||
if (rc == SER_SUCCESS) {
|
if (rc == SER_SUCCESS) {
|
||||||
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
|
snprintf(_scratch, SCRATCH_SIZE, "%s%c", "AT+SOCK1", 13);
|
||||||
comWrite(com, buffer, strlen(buffer));
|
comWrite(com, _scratch, strlen(_scratch));
|
||||||
timerQuarterSecondsSet((TimerT *)widget, 4);
|
timerQuarterSecondsSet((TimerT *)widget, 4);
|
||||||
_state = S_WAIT_FOR_INIT;
|
_state = S_WAIT_FOR_INIT;
|
||||||
} else {
|
} else {
|
||||||
|
@ -243,16 +242,16 @@ static void timSettingsProgress(WidgetT *widget) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_WAIT_FOR_INIT:
|
case S_WAIT_FOR_INIT:
|
||||||
len = comRead(com, buffer, 1023);
|
len = comRead(com, _scratch, SCRATCH_SIZE);
|
||||||
buffer[len] = 0;
|
_scratch[len] = 0;
|
||||||
if (strstr(buffer, "OK")) {
|
if (strstr(_scratch, "OK")) {
|
||||||
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Modem Found!", com + 1);
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Modem Found!", com + 1);
|
||||||
_port[com].status = PORT_GOOD_MODEM;
|
_port[com].status = PORT_GOOD_MODEM;
|
||||||
_port[com].selected = selected;
|
_port[com].selected = selected;
|
||||||
_port[com].enabled = 1;
|
_port[com].enabled = 1;
|
||||||
selected = 0;
|
selected = 0;
|
||||||
} else {
|
} else {
|
||||||
if (strstr(buffer, "ERROR")) {
|
if (strstr(_scratch, "ERROR")) {
|
||||||
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Incompatable Modem", com + 1);
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Incompatable Modem", com + 1);
|
||||||
_port[com].status = PORT_BAD_MODEM;
|
_port[com].status = PORT_BAD_MODEM;
|
||||||
_port[com].selected = 0;
|
_port[com].selected = 0;
|
||||||
|
|
|
@ -82,6 +82,11 @@ void netChannelSystemRelease(netPacketHandler handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t netPacketHandlerIsRunning(void) {
|
||||||
|
return _netRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void netPacketHandlerStart(void) {
|
void netPacketHandlerStart(void) {
|
||||||
_netRunning = 1;
|
_netRunning = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ uint8_t netChannelGet(netPacketHandler handler);
|
||||||
void netChannelRelease(uint8_t channel);
|
void netChannelRelease(uint8_t channel);
|
||||||
void netChannelSystemGet(netPacketHandler handler);
|
void netChannelSystemGet(netPacketHandler handler);
|
||||||
void netChannelSystemRelease(netPacketHandler handler);
|
void netChannelSystemRelease(netPacketHandler handler);
|
||||||
|
uint8_t netPacketHandlerIsRunning(void);
|
||||||
void netPacketHandlerStart(void);
|
void netPacketHandlerStart(void);
|
||||||
void netPacketHandlerStop(void);
|
void netPacketHandlerStop(void);
|
||||||
void netProcess(void);
|
void netProcess(void);
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
|
char _scratch[SCRATCH_SIZE];
|
||||||
|
|
||||||
|
|
||||||
uint8_t osFileExists(char *filename) {
|
uint8_t osFileExists(char *filename) {
|
||||||
FILE *f = fopen(filename, "rb");
|
FILE *f = fopen(filename, "rb");
|
||||||
if (f) {
|
if (f) {
|
||||||
|
|
|
@ -42,7 +42,8 @@
|
||||||
#define TICKS_PER_SECOND 18.2
|
#define TICKS_PER_SECOND 18.2
|
||||||
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
|
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
|
||||||
|
|
||||||
#define OS_PATH_MAX 256
|
#define OS_PATH_MAX 256
|
||||||
|
#define SCRATCH_SIZE 4096
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
@ -79,11 +80,14 @@ void linuxOsStartup(void);
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef PacketThreadDataT
|
#ifndef PacketThreadDataT
|
||||||
typedef struct PacketThreadDataS PacketThreadDataT;
|
typedef struct PacketThreadDataS PacketThreadDataT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern PacketThreadDataT *__packetThreadData; // Declared in main.c
|
extern PacketThreadDataT *__packetThreadData; // Declared in main.c
|
||||||
|
extern char _scratch[SCRATCH_SIZE]; // Declared in os.c
|
||||||
|
|
||||||
|
|
||||||
uint8_t osFileExists(char *filename);
|
uint8_t osFileExists(char *filename);
|
||||||
|
|
|
@ -249,7 +249,6 @@ static void timWelcomeProgress(WidgetT *widget) {
|
||||||
TimerT *t = (TimerT *)widget;
|
TimerT *t = (TimerT *)widget;
|
||||||
int32_t r = 0;
|
int32_t r = 0;
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
static char buffer[1024] = { 0 };
|
|
||||||
static uint16_t offset = 0;
|
static uint16_t offset = 0;
|
||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -279,25 +278,25 @@ static void timWelcomeProgress(WidgetT *widget) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Send a CR to clear anything in the modem.
|
// Send a CR to clear anything in the modem.
|
||||||
snprintf(buffer, 1023, "%c", 13);
|
snprintf(_scratch, SCRATCH_SIZE, "%c", 13);
|
||||||
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
comWrite(__configData.serialCom - 1, _scratch, strlen(_scratch));
|
||||||
timerQuarterSecondsSet(t, 4);
|
timerQuarterSecondsSet(t, 4);
|
||||||
_state = S_INIT_MODEM;
|
_state = S_INIT_MODEM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_INIT_MODEM:
|
case S_INIT_MODEM:
|
||||||
// Just read anything to clear the buffer.
|
// Just read anything to clear the buffer.
|
||||||
comRead(__configData.serialCom - 1, buffer, 1023);
|
comRead(__configData.serialCom - 1, _scratch, SCRATCH_SIZE);
|
||||||
// Send actual init
|
// Send actual init
|
||||||
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
|
snprintf(_scratch, SCRATCH_SIZE, "%s%c", "AT+SOCK1", 13);
|
||||||
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
comWrite(__configData.serialCom - 1, _scratch, strlen(_scratch));
|
||||||
_state = S_INIT_RESULT;
|
_state = S_INIT_RESULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_INIT_RESULT:
|
case S_INIT_RESULT:
|
||||||
len = comRead(__configData.serialCom - 1, buffer, 1023);
|
len = comRead(__configData.serialCom - 1, _scratch, SCRATCH_SIZE);
|
||||||
buffer[len] = 0;
|
_scratch[len] = 0;
|
||||||
if (strstr(buffer, "OK") == NULL) {
|
if (strstr(_scratch, "OK") == NULL) {
|
||||||
comClose(__configData.serialCom - 1);
|
comClose(__configData.serialCom - 1);
|
||||||
timerStop(t);
|
timerStop(t);
|
||||||
// Restore mouse.
|
// Restore mouse.
|
||||||
|
@ -312,8 +311,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_DIAL:
|
case S_DIAL:
|
||||||
snprintf(buffer, 1023, "ATDT%s:%d%c", __configData.serverHost, __configData.serverPort, 13);
|
snprintf(_scratch, SCRATCH_SIZE, "ATDT%s:%d%c", __configData.serverHost, __configData.serverPort, 13);
|
||||||
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
comWrite(__configData.serialCom - 1, _scratch, strlen(_scratch));
|
||||||
timerQuarterSecondsSet(t, 0); // Run as fast as we can so we don't miss any data.
|
timerQuarterSecondsSet(t, 0); // Run as fast as we can so we don't miss any data.
|
||||||
offset = 0;
|
offset = 0;
|
||||||
_timeoutCounter = 7 * 4; // Seven seconds.
|
_timeoutCounter = 7 * 4; // Seven seconds.
|
||||||
|
@ -322,11 +321,11 @@ static void timWelcomeProgress(WidgetT *widget) {
|
||||||
|
|
||||||
case S_WAIT_FOR_BANNER:
|
case S_WAIT_FOR_BANNER:
|
||||||
// Process incoming bytes one at a time so we don't accidentally eat the first packet after the banner.
|
// Process incoming bytes one at a time so we don't accidentally eat the first packet after the banner.
|
||||||
len = comRead(__configData.serialCom - 1, &buffer[offset], 1);
|
len = comRead(__configData.serialCom - 1, &_scratch[offset], 1);
|
||||||
offset += len;
|
offset += len;
|
||||||
buffer[offset] = 0;
|
_scratch[offset] = 0;
|
||||||
// ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
|
// ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
|
||||||
if (strstr(buffer, "KPMPGSMKII\rOKAY\r") != NULL) {
|
if (strstr(_scratch, "KPMPGSMKII\rOKAY\r") != NULL) {
|
||||||
// Connect! Start packet handler and negotiate encryption.
|
// Connect! Start packet handler and negotiate encryption.
|
||||||
netPacketHandlerStart();
|
netPacketHandlerStart();
|
||||||
packetEncryptionSetup(__packetThreadData);
|
packetEncryptionSetup(__packetThreadData);
|
||||||
|
|
41
shared/game.c
Normal file
41
shared/game.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
|
||||||
|
void gameClear(GameT *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);
|
||||||
|
game->type = GAME_TYPE_UNKNOWN;
|
||||||
|
game->maxPlayers = 0;
|
||||||
|
game->joinable = 0;
|
||||||
|
game->screens = 0;
|
||||||
|
game->boxes = 0;
|
||||||
|
game->ROWID = 0;
|
||||||
|
}
|
|
@ -53,7 +53,11 @@ typedef struct GameS { // Data type in DAT file sent to client.
|
||||||
uint8_t joinable; // 1
|
uint8_t joinable; // 1
|
||||||
uint8_t screens; // 1
|
uint8_t screens; // 1
|
||||||
uint8_t boxes; // 1
|
uint8_t boxes; // 1
|
||||||
|
uint64_t ROWID; // Provided by SQLite.
|
||||||
} GameT;
|
} GameT;
|
||||||
|
|
||||||
|
|
||||||
|
void gameClear(GameT *game);
|
||||||
|
|
||||||
|
|
||||||
#endif // GAME_H
|
#endif // GAME_H
|
||||||
|
|
|
@ -119,6 +119,43 @@ uint8_t utilFileExists(char *filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
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.
|
||||||
|
_scratch[x++] = c;
|
||||||
|
_scratch[x] = 0;
|
||||||
|
// End of string?
|
||||||
|
if (c == 0) {
|
||||||
|
*result = strdup(_scratch);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void utilStringToLower(char *string) {
|
void utilStringToLower(char *string) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ char *utilCreateString(char *format, ...);
|
||||||
char *utilCreateStringVArgs(char *format, va_list args);
|
char *utilCreateStringVArgs(char *format, va_list args);
|
||||||
void utilDie(const char *why, ...);
|
void utilDie(const char *why, ...);
|
||||||
uint8_t utilFileExists(char *filename);
|
uint8_t utilFileExists(char *filename);
|
||||||
|
uint8_t utilFromFileReadByte(FILE *f, uint8_t *result);
|
||||||
|
uint8_t utilFromFileReadString(FILE *f, char **result);
|
||||||
void utilStringToLower(char *string);
|
void utilStringToLower(char *string);
|
||||||
char **utilWrapText(char *text, uint16_t width);
|
char **utilWrapText(char *text, uint16_t width);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue