Mouse busy pointer support. File transfer bug fixed.
This commit is contained in:
parent
794bd96d3f
commit
88369132e3
20 changed files with 378 additions and 143 deletions
23
LICENSE
23
LICENSE
|
@ -53,11 +53,6 @@ SDL2_image
|
|||
https://www.libsdl.org/
|
||||
BSD 3-Clause
|
||||
|
||||
SHA256
|
||||
------
|
||||
https://github.com/ilvn/SHA256
|
||||
MIT
|
||||
|
||||
SQLite 3.4.2
|
||||
------------
|
||||
https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.2/repos/pkg-html/sqlite.html
|
||||
|
@ -99,6 +94,24 @@ https://github.com/nothings/stb
|
|||
Public Domain
|
||||
|
||||
|
||||
Pre-Cache Builder
|
||||
=================
|
||||
|
||||
MemWatch
|
||||
--------
|
||||
http://www.linkdata.se/sourcecode/memwatch/
|
||||
GPL2
|
||||
|
||||
SHA256
|
||||
------
|
||||
https://github.com/ilvn/SHA256
|
||||
MIT
|
||||
|
||||
stb_image.h
|
||||
-----------
|
||||
https://github.com/nothings/stb
|
||||
Public Domain
|
||||
|
||||
|
||||
Server
|
||||
======
|
||||
|
|
BIN
client/in/gui/wait.png
(Stored with Git LFS)
Normal file
BIN
client/in/gui/wait.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -57,6 +57,7 @@ static TimerT *_timTimer = NULL;
|
|||
|
||||
static void btnMsgBoxOkay(MsgBoxButtonT button);
|
||||
static void fileCheckNext(void);
|
||||
static void fileCurrentUpdate(uint8_t dontCallback);
|
||||
static void fileShowDialog(void);
|
||||
static void fileShowError(char *message);
|
||||
static void packetHandler(PacketDecodeDataT *packet);
|
||||
|
@ -102,12 +103,47 @@ static void fileCheckNext(void) {
|
|||
uint8_t *packetData = NULL;
|
||||
uint16_t length = 0;
|
||||
uint32_t temp = 0;
|
||||
uint8_t doRecheck = 0;
|
||||
char *shaPointer = NULL;
|
||||
static char *badSHA = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
|
||||
|
||||
BEGIN
|
||||
|
||||
fileCurrentUpdate(0);
|
||||
if (_file) {
|
||||
// Check next file.
|
||||
temp = FILE_REQUEST_CHECK;
|
||||
shaPointer = cacheSha256Get(_file);
|
||||
if (!shaPointer) shaPointer = badSHA;
|
||||
packetData = packetContentPack(&length, "iss", temp, shaPointer, _file);
|
||||
encoded.control = PACKET_CONTROL_DAT;
|
||||
encoded.packetType = PACKET_TYPE_FILE_REQUEST;
|
||||
encoded.channel = _channel;
|
||||
encoded.encrypt = 0;
|
||||
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||
packetSend(__packetThreadData, &encoded);
|
||||
DEL(packetData);
|
||||
} else {
|
||||
// Finished with transfers.
|
||||
if (_dialogVisible) guiDelete(D(_winFile));
|
||||
netChannelRelease(_channel);
|
||||
_channel = 0;
|
||||
}
|
||||
|
||||
END
|
||||
}
|
||||
|
||||
|
||||
static void fileCurrentUpdate(uint8_t dontCallback) {
|
||||
uint8_t doRecheck = 0;
|
||||
|
||||
// This function is ugly and happened because a bunch of
|
||||
// code got moved around and this was needed in multiple
|
||||
// places. It updates several global variables. In short,
|
||||
// if '_file' is not null after calling this, there is
|
||||
// more to do.
|
||||
|
||||
BEGIN
|
||||
|
||||
do {
|
||||
// This is ugly since both lists kind of depend on each other.
|
||||
doRecheck = 0;
|
||||
|
@ -118,12 +154,8 @@ static void fileCheckNext(void) {
|
|||
if (arrlen(_fileList) == 0) {
|
||||
logWrite("End of file queue.\n");
|
||||
arrfree(_fileList);
|
||||
if (_dialogVisible) guiDelete(D(_winFile));
|
||||
netChannelRelease(_channel);
|
||||
_channel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next queue entry.
|
||||
_currentLength = 0;
|
||||
_current = _fileList[0];
|
||||
|
@ -138,7 +170,7 @@ static void fileCheckNext(void) {
|
|||
logWrite("End of file list.\n");
|
||||
arrfree(_current->files);
|
||||
// Call with NULL to signify end of transfers.
|
||||
_current->callback(NULL);
|
||||
if (!dontCallback) _current->callback(NULL);
|
||||
DEL(_current);
|
||||
// See if there's more.
|
||||
doRecheck = 1;
|
||||
|
@ -150,19 +182,6 @@ static void fileCheckNext(void) {
|
|||
}
|
||||
} while (doRecheck);
|
||||
|
||||
// Check next file.
|
||||
temp = FILE_REQUEST_CHECK;
|
||||
shaPointer = cacheSha256Get(_file);
|
||||
if (!shaPointer) shaPointer = badSHA;
|
||||
packetData = packetContentPack(&length, "iss", temp, shaPointer, _file);
|
||||
encoded.control = PACKET_CONTROL_DAT;
|
||||
encoded.packetType = PACKET_TYPE_FILE_REQUEST;
|
||||
encoded.channel = _channel;
|
||||
encoded.encrypt = 0;
|
||||
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||
packetSend(__packetThreadData, &encoded);
|
||||
DEL(packetData);
|
||||
|
||||
END
|
||||
}
|
||||
|
||||
|
@ -194,6 +213,9 @@ static void fileShowDialog(void) {
|
|||
static void fileShowError(char *message) {
|
||||
// ***TODO*** This should close all open windows.
|
||||
|
||||
// Reset a possibly busy mouse pointer.
|
||||
guiMouseBusyClear();
|
||||
|
||||
// Show error. This is fatal.
|
||||
if (_dialogVisible) guiDelete(D(_winFile));
|
||||
netChannelRelease(_channel);
|
||||
|
@ -293,20 +315,12 @@ static void timTimerTimeout(WidgetT *widget) {
|
|||
timerStop(_timTimer);
|
||||
|
||||
// If we at least have some version of the file, try to continue.
|
||||
while (arrlen(_fileList) > 0) {
|
||||
while (arrlen(_fileList[0]->files) > 0) {
|
||||
if (cacheFilenameGet(_fileList[0]->files[0])) {
|
||||
arrdel(_fileList[0]->files, 0);
|
||||
} else {
|
||||
missing = 1;
|
||||
}
|
||||
}
|
||||
// If we're good so far, call the callback.
|
||||
if (!missing) _fileList[0]->callback(NULL);
|
||||
arrfree(_fileList[0]->files);
|
||||
arrdel(_fileList, 0);
|
||||
while (_file) {
|
||||
// Passing 'missing' prevents file completion callbacks from
|
||||
// occurring when there are missing files.
|
||||
fileCurrentUpdate(missing);
|
||||
if (_file && !cacheFilenameGet(_file)) missing = 1;
|
||||
}
|
||||
arrfree(_fileList);
|
||||
|
||||
if (missing) fileShowError("Unable to download needed files.");
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ static uint32_t _guiTimerHalfSecondOn = 0;
|
|||
static uint32_t _guiTimerSecondOn = 0;
|
||||
static PendingEventsT **_guiPendingEvents = NULL;
|
||||
static void **_guiPendingFrees = NULL;
|
||||
static uint8_t _guiMouseBusyStack = 0;
|
||||
|
||||
|
||||
static void guiDeleteList(void);
|
||||
|
@ -384,6 +385,26 @@ void guiKeyboardProcess(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8
|
|||
}
|
||||
|
||||
|
||||
void guiMouseBusyClear() {
|
||||
_guiMouseBusyStack = 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t guiMouseBusyGet() {
|
||||
return _guiMouseBusyStack != 0;
|
||||
}
|
||||
|
||||
|
||||
void guiMouseBusyPop() {
|
||||
if (_guiMouseBusyStack > 0) _guiMouseBusyStack--;
|
||||
}
|
||||
|
||||
|
||||
void guiMouseBusyPush() {
|
||||
if (_guiMouseBusyStack < 255) _guiMouseBusyStack++;
|
||||
}
|
||||
|
||||
|
||||
void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y) {
|
||||
RectT r;
|
||||
guiWidgetPositionOnScreenGet(widget, &r);
|
||||
|
|
|
@ -202,6 +202,10 @@ uint8_t guiHasStopped(void);
|
|||
void guiKeyboardProcess(uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt);
|
||||
void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *x, uint16_t *y);
|
||||
void guiMouseProcess(MouseT *mouse);
|
||||
void guiMouseBusyClear();
|
||||
uint8_t guiMouseBusyGet();
|
||||
void guiMouseBusyPop();
|
||||
void guiMouseBusyPush();
|
||||
void guiPaint(WidgetT *widget);
|
||||
void guiParentAndChildrenDirtySet(WidgetT *widget);
|
||||
void guiPendingEventAdd(WidgetT *widget, void *callback);
|
||||
|
|
|
@ -97,7 +97,7 @@ void imageCacheIfNeeded(char *cacheFilename, char *sha256) {
|
|||
temp = (char *)malloc(strlen(cacheFilename) + 5);
|
||||
if (!temp) return;
|
||||
sprintf(temp, "%s.raw", cacheFilename);
|
||||
rawSha = strdup(cacheSha256Get(temp));
|
||||
rawSha = cacheSha256Get(temp);
|
||||
if (!rawSha || strcmp(rawSha, sha256) != 0) {
|
||||
// The decompressed file either does not exist or the SHA does not match the file we're checking.
|
||||
logWrite("Unpacking %s - %s\n", cacheFilenameGet(cacheFilename), cacheFilename);
|
||||
|
|
|
@ -92,6 +92,7 @@ static void timHangupProgress(WidgetT *widget) {
|
|||
// Snooze a bit for the packet to send.
|
||||
_state = S_WAITING;
|
||||
timerQuarterSecondsSet(t, 3 * 4);
|
||||
guiMouseBusyPush();
|
||||
break;
|
||||
|
||||
case S_WAITING:
|
||||
|
@ -102,6 +103,7 @@ static void timHangupProgress(WidgetT *widget) {
|
|||
// On to the next dialog.
|
||||
guiDelete(D(_winHangup));
|
||||
_done(NULL);
|
||||
guiMouseBusyPop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,6 +122,7 @@ static void loginFilesReady(char *updatedFile) {
|
|||
runtimeDataUpdate();
|
||||
} else {
|
||||
// End of cache update. Display UI.
|
||||
guiMouseBusyPop();
|
||||
runtimeDataLoad();
|
||||
|
||||
// ***TODO*** We used to have a FORGOT PASSWORD link here, too.
|
||||
|
@ -191,6 +192,7 @@ void loginShow() {
|
|||
|
||||
BEGIN
|
||||
|
||||
guiMouseBusyPush();
|
||||
fileCacheCheck(loginFilesReady, fileList);
|
||||
|
||||
END
|
||||
|
|
|
@ -60,9 +60,10 @@
|
|||
PacketThreadDataT *__packetThreadData = NULL; // Exported in os.h
|
||||
|
||||
|
||||
static MouseT *_mouse = NULL;
|
||||
static ImageT *_pointer = NULL;
|
||||
static ColorT _alpha = 0;
|
||||
static MouseT *_mouse = NULL;
|
||||
static ImageT *_pointer = NULL;
|
||||
static ImageT *_hourglass = NULL;
|
||||
static ColorT _alpha = 0;
|
||||
|
||||
#ifndef __linux__
|
||||
char *_logName = NULL;
|
||||
|
@ -102,7 +103,11 @@ static void eventLoop(void) {
|
|||
}
|
||||
guiMouseProcess(_mouse);
|
||||
guiComposite();
|
||||
imageRenderWithAlpha(_pointer, _mouse->x, _mouse->y, _alpha);
|
||||
if (guiMouseBusyGet()) {
|
||||
imageRenderWithAlpha(_hourglass, _mouse->x, _mouse->y, _alpha);
|
||||
} else {
|
||||
imageRenderWithAlpha(_pointer, _mouse->x, _mouse->y, _alpha);
|
||||
}
|
||||
vbeVBlankWait();
|
||||
vbePresent();
|
||||
} while (!guiHasStopped());
|
||||
|
@ -123,6 +128,7 @@ static void shutdown(void) {
|
|||
FILE *in = NULL;
|
||||
#endif
|
||||
|
||||
imageUnload(&_hourglass);
|
||||
imageUnload(&_pointer);
|
||||
|
||||
netShutdown();
|
||||
|
@ -196,8 +202,9 @@ static uint8_t startup(int argc, char *argv[]) {
|
|||
guiStartup();
|
||||
netStartup();
|
||||
|
||||
_pointer = imageLoadCache("gui:mouse.png");
|
||||
_alpha = imagePixelGet(_pointer, 5, 0);
|
||||
_hourglass = imageLoadCache("gui:wait.png");
|
||||
_pointer = imageLoadCache("gui:mouse.png");
|
||||
_alpha = imagePixelGet(_pointer, 5, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ static void menuFilesReady(char *updatedFile) {
|
|||
}
|
||||
} else {
|
||||
// Show UI
|
||||
guiMouseBusyPop();
|
||||
x = vbeDisplayWidthGet() - 49;
|
||||
y = vbeDisplayHeightGet() - 49;
|
||||
|
||||
|
@ -152,11 +153,155 @@ void menuShow(void) {
|
|||
"menu:48logoff.png",
|
||||
"menu:48profile.png",
|
||||
"generated:games.dat",
|
||||
|
||||
"games:d:descent:banner.png",
|
||||
"games:d:descent:box2.png",
|
||||
"games:d:descent:screen1.png",
|
||||
"games:d:descent:screen2.png",
|
||||
"games:d:descent:screen3.png",
|
||||
"games:d:descent:screen4.png",
|
||||
"games:d:descent:screen5.png",
|
||||
"games:d:descent:screen6.png",
|
||||
"games:d:descent:box1-thumb.png",
|
||||
"games:d:descent:box1.png",
|
||||
"games:d:descent:box2-thumb.png",
|
||||
"games:d:descent:screen1-thumb.png",
|
||||
"games:d:descent:screen2-thumb.png",
|
||||
"games:d:descent:screen3-thumb.png",
|
||||
"games:d:descent:screen4-thumb.png",
|
||||
"games:d:descent:screen5-thumb.png",
|
||||
"games:d:descent:screen6-thumb.png",
|
||||
"games:d:dm:screen1.png",
|
||||
"games:d:dm:screen2.png",
|
||||
"games:d:dm:screen3.png",
|
||||
"games:d:dm:screen4.png",
|
||||
"games:d:dm:screen5.png",
|
||||
"games:d:dm:screen6.png",
|
||||
"games:d:dm:screen6-thumb.png",
|
||||
"games:d:dm:screen5-thumb.png",
|
||||
"games:d:dm:screen4-thumb.png",
|
||||
"games:d:dm:screen3-thumb.png",
|
||||
"games:d:dm:screen2-thumb.png",
|
||||
"games:d:dm:screen1-thumb.png",
|
||||
"games:d:dm:banner.png",
|
||||
"games:t:tal:screen6.png",
|
||||
"games:t:tal:screen5.png",
|
||||
"games:t:tal:screen4.png",
|
||||
"games:t:tal:screen3.png",
|
||||
"games:t:tal:screen2.png",
|
||||
"games:t:tal:screen1.png",
|
||||
"games:t:tal:screen6-thumb.png",
|
||||
"games:t:tal:screen5-thumb.png",
|
||||
"games:t:tal:screen4-thumb.png",
|
||||
"games:t:tal:screen3-thumb.png",
|
||||
"games:t:tal:screen2-thumb.png",
|
||||
"games:t:tal:screen1-thumb.png",
|
||||
"games:t:tal:banner.png",
|
||||
"games:t:tw2002:screen6.png",
|
||||
"games:t:tw2002:screen5.png",
|
||||
"games:t:tw2002:screen4.png",
|
||||
"games:t:tw2002:screen3.png",
|
||||
"games:t:tw2002:screen2.png",
|
||||
"games:t:tw2002:screen1.png",
|
||||
"games:t:tw2002:screen1-thumb.png",
|
||||
"games:t:tw2002:screen2-thumb.png",
|
||||
"games:t:tw2002:screen3-thumb.png",
|
||||
"games:t:tw2002:screen4-thumb.png",
|
||||
"games:t:tw2002:screen5-thumb.png",
|
||||
"games:t:tw2002:screen6-thumb.png",
|
||||
"games:t:tw2002:banner.png",
|
||||
"games:b:bre:screen1.png",
|
||||
"games:b:bre:screen2.png",
|
||||
"games:b:bre:screen3.png",
|
||||
"games:b:bre:screen4.png",
|
||||
"games:b:bre:screen5.png",
|
||||
"games:b:bre:screen1-thumb.png",
|
||||
"games:b:bre:screen2-thumb.png",
|
||||
"games:b:bre:screen3-thumb.png",
|
||||
"games:b:bre:screen4-thumb.png",
|
||||
"games:b:bre:screen5-thumb.png",
|
||||
"games:b:bre:banner.png",
|
||||
"games:f:fe:screen6.png",
|
||||
"games:f:fe:screen5.png",
|
||||
"games:f:fe:screen4.png",
|
||||
"games:f:fe:screen3.png",
|
||||
"games:f:fe:screen2.png",
|
||||
"games:f:fe:screen1.png",
|
||||
"games:f:fe:screen1-thumb.png",
|
||||
"games:f:fe:screen2-thumb.png",
|
||||
"games:f:fe:screen3-thumb.png",
|
||||
"games:f:fe:screen4-thumb.png",
|
||||
"games:f:fe:screen5-thumb.png",
|
||||
"games:f:fe:screen6-thumb.png",
|
||||
"games:f:fe:banner.png",
|
||||
"games:f:fh:screen1.png",
|
||||
"games:f:fh:screen2.png",
|
||||
"games:f:fh:screen3.png",
|
||||
"games:f:fh:screen4.png",
|
||||
"games:f:fh:screen5.png",
|
||||
"games:f:fh:screen6.png",
|
||||
"games:f:fh:screen6-thumb.png",
|
||||
"games:f:fh:screen5-thumb.png",
|
||||
"games:f:fh:screen4-thumb.png",
|
||||
"games:f:fh:screen3-thumb.png",
|
||||
"games:f:fh:screen2-thumb.png",
|
||||
"games:f:fh:screen1-thumb.png",
|
||||
"games:f:fh:banner.png",
|
||||
"games:g:gbkg:screen3.png",
|
||||
"games:g:gbkg:screen2.png",
|
||||
"games:g:gbkg:screen1.png",
|
||||
"games:g:gbkg:screen1-thumb.png",
|
||||
"games:g:gbkg:screen2-thumb.png",
|
||||
"games:g:gbkg:screen3-thumb.png",
|
||||
"games:g:gbkg:banner.png",
|
||||
"games:g:gwar:screen1.png",
|
||||
"games:g:gwar:screen2.png",
|
||||
"games:g:gwar:screen3.png",
|
||||
"games:g:gwar:screen4.png",
|
||||
"games:g:gwar:screen5.png",
|
||||
"games:g:gwar:screen6.png",
|
||||
"games:g:gwar:screen6-thumb.png",
|
||||
"games:g:gwar:screen5-thumb.png",
|
||||
"games:g:gwar:screen4-thumb.png",
|
||||
"games:g:gwar:screen3-thumb.png",
|
||||
"games:g:gwar:screen2-thumb.png",
|
||||
"games:g:gwar:screen1-thumb.png",
|
||||
"games:g:gwar:banner.png",
|
||||
"games:h:hackn:screen3.png",
|
||||
"games:h:hackn:screen2.png",
|
||||
"games:h:hackn:screen1.png",
|
||||
"games:h:hackn:screen1-thumb.png",
|
||||
"games:h:hackn:screen2-thumb.png",
|
||||
"games:h:hackn:screen3-thumb.png",
|
||||
"games:h:hackn:banner.png",
|
||||
"games:o:odd:screen4.png",
|
||||
"games:o:odd:screen3.png",
|
||||
"games:o:odd:screen2.png",
|
||||
"games:o:odd:screen1.png",
|
||||
"games:o:odd:screen4-thumb.png",
|
||||
"games:o:odd:screen3-thumb.png",
|
||||
"games:o:odd:screen2-thumb.png",
|
||||
"games:o:odd:screen1-thumb.png",
|
||||
"games:o:odd:banner.png",
|
||||
"games:s:sg:screen3.png",
|
||||
"games:s:sg:screen2.png",
|
||||
"games:s:sg:screen1.png",
|
||||
"games:s:sg:screen3-thumb.png",
|
||||
"games:s:sg:screen2-thumb.png",
|
||||
"games:s:sg:screen1-thumb.png",
|
||||
"games:s:sg:banner.png",
|
||||
"games:s:sre:screen1.png",
|
||||
"games:s:sre:screen1-thumb.png",
|
||||
"games:s:sre:banner.png",
|
||||
"browser:no-box.png",
|
||||
"browser:no-screen.png",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
BEGIN
|
||||
|
||||
guiMouseBusyPush();
|
||||
fileCacheCheck(menuFilesReady, fileList);
|
||||
|
||||
END
|
||||
|
@ -239,6 +384,7 @@ static void updateGameDatabase(void) {
|
|||
// Mark everything untouched.
|
||||
dbExecute("UPDATE games SET touced=0", NULL);
|
||||
|
||||
/*
|
||||
// Process latest downloaded game list.
|
||||
f = cacheFOpen("generated:games.dat", "rb");
|
||||
if (f) {
|
||||
|
@ -253,4 +399,5 @@ static void updateGameDatabase(void) {
|
|||
// Delete anything untouched.
|
||||
dbExecute("DELETE FROM games WHERE touced=0", NULL);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ static void timSettingsProgress(WidgetT *widget) {
|
|||
com = 0;
|
||||
selected = 1;
|
||||
_state = S_OPEN_COM;
|
||||
guiMouseBusyPush();
|
||||
break;
|
||||
|
||||
case S_OPEN_COM:
|
||||
|
@ -276,6 +277,7 @@ static void timSettingsProgress(WidgetT *widget) {
|
|||
case S_SCAN_COMPLETE:
|
||||
timerStop(_timProgress);
|
||||
settingsComShow();
|
||||
guiMouseBusyPop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,73 +172,6 @@ FILE *cacheFOpen(char *vpath, char *mode) {
|
|||
}
|
||||
|
||||
|
||||
uint8_t cachePrePack(char *name, CachePreMakeListT *list) {
|
||||
|
||||
FILE *in = NULL;
|
||||
FILE *out = NULL;
|
||||
uint16_t i = 0;
|
||||
uint8_t result = SUCCESS;
|
||||
uint32_t length = 0;
|
||||
uint32_t total = 0;
|
||||
uint32_t temp = 0;
|
||||
int8_t buffer[8192] = { 0 };
|
||||
sha256_context ctx = { 0 };
|
||||
uint8_t hv[32] = { 0 };
|
||||
|
||||
// Prebuilt cache format:
|
||||
// - Virtual Path (zero terminated)
|
||||
// - x bytes hash
|
||||
// - 4 bytes unsigned length of data
|
||||
// - length bytes of data
|
||||
// ... repeat for each file ...
|
||||
// - 4 bytes length of entire cache (used for embedding cache data)
|
||||
|
||||
out = fopen(name, "wb");
|
||||
if (out) {
|
||||
while (list[i].filename != NULL) {
|
||||
in = fopen(list[i].filename, "rb");
|
||||
if (in) {
|
||||
// Get length of file.
|
||||
fseek(in, 0, SEEK_END);
|
||||
length = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// Generate SHA256.
|
||||
sha256_init(&ctx);
|
||||
do {
|
||||
temp = fread(buffer, 1, sizeof(buffer), in);
|
||||
if (temp) sha256_hash(&ctx, (uint8_t *)buffer, temp);
|
||||
} while (temp > 0);
|
||||
sha256_done(&ctx, hv);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// Write header.
|
||||
temp = strlen(list[i].virtualPath) + 1;
|
||||
fwrite(list[i].virtualPath, temp, 1, out);
|
||||
fwrite(hv, sizeof(hv), 1, out);
|
||||
fwrite(&length, sizeof(uint32_t), 1, out);
|
||||
total += temp + sizeof(hv) + sizeof(uint32_t) + length;
|
||||
// Copy data.
|
||||
do {
|
||||
temp = fread(buffer, 1, sizeof(buffer), in);
|
||||
if (temp) fwrite(buffer, 1, temp, out);
|
||||
} while (temp > 0);
|
||||
fclose(in);
|
||||
} else {
|
||||
result = FAIL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Write length of entire block.
|
||||
total += sizeof(uint32_t);
|
||||
fwrite(&total, sizeof(uint32_t), 1, out);
|
||||
fclose(out);
|
||||
} else {
|
||||
result = FAIL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint8_t cachePreUnpack(char *name) {
|
||||
FILE *in = NULL;
|
||||
FILE *out = NULL;
|
||||
|
|
|
@ -28,12 +28,6 @@
|
|||
#define CACHE_VIRTUAL_PATH_MAX 512 // Should match setting in the server's client/file.h
|
||||
|
||||
|
||||
typedef struct CachePreMakeListS {
|
||||
char *filename;
|
||||
char *virtualPath;
|
||||
} CachePreMakeListT;
|
||||
|
||||
|
||||
uint8_t cacheDelete(char *virtualPath);
|
||||
uint8_t cacheEntryAdd(char *sha256, char *entryName, char *virtualPath);
|
||||
char *cacheEntryNameGet(char *virtualPath);
|
||||
|
@ -41,7 +35,6 @@ uint8_t cacheExists(void);
|
|||
void cacheFClose(FILE *handle);
|
||||
char *cacheFilenameGet(char *virtualPath);
|
||||
FILE *cacheFOpen(char *vpath, char *mode);
|
||||
uint8_t cachePrePack(char *name, CachePreMakeListT *list);
|
||||
uint8_t cachePreUnpack(char *name);
|
||||
char *cacheSha256Get(char *virtualPath);
|
||||
void cacheShutdown(void);
|
||||
|
|
|
@ -256,6 +256,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
|
||||
switch (_state) {
|
||||
case S_START_CONNECT:
|
||||
// Hourglass mouse.
|
||||
guiMouseBusyPush();
|
||||
// Ghost all buttons.
|
||||
widgetEnableSet(W(_btnConnect), 0);
|
||||
widgetEnableSet(W(_btnSettings), 0);
|
||||
|
@ -271,6 +273,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
r = comOpen(__configData.serialCom - 1, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
||||
if (r != SER_SUCCESS) {
|
||||
timerStop(t);
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
msgBoxOne("COM Problem", MSGBOX_ICON_ERROR, "Unable to open COM port!\nPlease check settings.", "Okay", btnMsgBox);
|
||||
break;
|
||||
}
|
||||
|
@ -296,6 +300,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
if (strstr(buffer, "OK") == NULL) {
|
||||
comClose(__configData.serialCom - 1);
|
||||
timerStop(t);
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
msgBoxOne("Modem Problem", MSGBOX_ICON_ERROR, "Modem does not support ENET!\nPlease check settings.", "Okay", btnMsgBox);
|
||||
break;
|
||||
}
|
||||
|
@ -336,6 +342,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
if (_timeoutCounter == 0) {
|
||||
comClose(__configData.serialCom - 1);
|
||||
timerStop(t);
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
msgBoxOne("No Connection", MSGBOX_ICON_INFORMATION, "Unable to connect to server!\nPlease check settings or try later.", "Okay", btnMsgBox);
|
||||
}
|
||||
break;
|
||||
|
@ -352,6 +360,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
netPacketHandlerStop();
|
||||
comClose(__configData.serialCom - 1);
|
||||
timerStop(t);
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to negotiate encryption settings!", "Okay", btnMsgBox);
|
||||
}
|
||||
break;
|
||||
|
@ -360,6 +370,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
netPacketHandlerStop();
|
||||
comClose(__configData.serialCom - 1);
|
||||
timerStop(t);
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to fetch client settings!", "Okay", btnMsgBox);
|
||||
break;
|
||||
|
||||
|
@ -368,6 +380,8 @@ static void timWelcomeProgress(WidgetT *widget) {
|
|||
timerStop(t);
|
||||
netChannelSystemRelease(packetHandler);
|
||||
guiDelete(D(_winWelcome));
|
||||
// Restore mouse.
|
||||
guiMouseBusyPop();
|
||||
loginShow();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ DESTDIR = $$OUT_PWD/bin
|
|||
SHARED = $$PWD/../shared
|
||||
CLIENT = $$PWD/../client/src
|
||||
SYSTEM = $$CLIENT/system
|
||||
THIRDP = $$CLIENT/thirdparty
|
||||
THIRDP = $$SHARED/thirdparty
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$CLIENT \
|
||||
|
@ -35,25 +35,10 @@ INCLUDEPATH += \
|
|||
|
||||
HEADERS = \
|
||||
$$SHARED/stddclmr.h \
|
||||
$$SHARED/log.h \
|
||||
$$SHARED/util.h \
|
||||
$$SHARED/thirdparty/memwatch/memwatch.h \
|
||||
$$THIRDP/SHA256/sha256.h \
|
||||
$$SYSTEM/surface.h \
|
||||
$$SYSTEM/os.h \
|
||||
$$SYSTEM/cache.h
|
||||
$$THIRDP/SHA256/sha256.h
|
||||
|
||||
SOURCES = \
|
||||
$$SHARED/thirdparty/memwatch/memwatch.c \
|
||||
$$SHARED/log.c \
|
||||
$$SHARED/util.c \
|
||||
$$THIRDP/SHA256/sha256.c \
|
||||
$$CLIENT/linux/linux.c \
|
||||
$$SYSTEM/surface.c \
|
||||
$$SYSTEM/os.c \
|
||||
$$SYSTEM/cache.c \
|
||||
src/main.c
|
||||
|
||||
LIBS = \
|
||||
-lSDL2 \
|
||||
-lSDL2_image
|
||||
|
|
|
@ -19,19 +19,98 @@
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MEMWATCH
|
||||
#include "memwatch/memwatch.h"
|
||||
|
||||
#include "cache.h"
|
||||
#include "thirdparty/SHA256/sha256.h"
|
||||
|
||||
#include "stddclmr.h"
|
||||
|
||||
|
||||
#define SUCCESS 1
|
||||
#define FAIL 0
|
||||
|
||||
|
||||
#define CLIENT "/home/scott/code/kpmpgsmkii/client/in/"
|
||||
#define FONT "/home/scott/code/kpmpgsmkii/font/out/"
|
||||
#define OUT "/home/scott/code/kpmpgsmkii/precache/out/"
|
||||
|
||||
|
||||
typedef struct CachePreMakeListS {
|
||||
char *filename;
|
||||
char *virtualPath;
|
||||
} CachePreMakeListT;
|
||||
|
||||
|
||||
uint8_t cachePrePack(char *name, CachePreMakeListT *list) {
|
||||
|
||||
FILE *in = NULL;
|
||||
FILE *out = NULL;
|
||||
uint16_t i = 0;
|
||||
uint8_t result = SUCCESS;
|
||||
uint32_t length = 0;
|
||||
uint32_t total = 0;
|
||||
uint32_t temp = 0;
|
||||
int8_t buffer[8192] = { 0 };
|
||||
sha256_context ctx = { 0 };
|
||||
uint8_t hv[32] = { 0 };
|
||||
|
||||
// Prebuilt cache format:
|
||||
// - Virtual Path (zero terminated)
|
||||
// - x bytes hash
|
||||
// - 4 bytes unsigned length of data
|
||||
// - length bytes of data
|
||||
// ... repeat for each file ...
|
||||
// - 4 bytes length of entire cache (used for embedding cache data)
|
||||
|
||||
out = fopen(name, "wb");
|
||||
if (out) {
|
||||
while (list[i].filename != NULL) {
|
||||
in = fopen(list[i].filename, "rb");
|
||||
if (in) {
|
||||
// Get length of file.
|
||||
fseek(in, 0, SEEK_END);
|
||||
length = ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// Generate SHA256.
|
||||
sha256_init(&ctx);
|
||||
do {
|
||||
temp = fread(buffer, 1, sizeof(buffer), in);
|
||||
if (temp) sha256_hash(&ctx, (uint8_t *)buffer, temp);
|
||||
} while (temp > 0);
|
||||
sha256_done(&ctx, hv);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
// Write header.
|
||||
temp = strlen(list[i].virtualPath) + 1;
|
||||
fwrite(list[i].virtualPath, temp, 1, out);
|
||||
fwrite(hv, sizeof(hv), 1, out);
|
||||
fwrite(&length, sizeof(uint32_t), 1, out);
|
||||
total += temp + sizeof(hv) + sizeof(uint32_t) + length;
|
||||
// Copy data.
|
||||
do {
|
||||
temp = fread(buffer, 1, sizeof(buffer), in);
|
||||
if (temp) fwrite(buffer, 1, temp, out);
|
||||
} while (temp > 0);
|
||||
fclose(in);
|
||||
} else {
|
||||
result = FAIL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Write length of entire block.
|
||||
total += sizeof(uint32_t);
|
||||
fwrite(&total, sizeof(uint32_t), 1, out);
|
||||
fclose(out);
|
||||
} else {
|
||||
result = FAIL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
CachePreMakeListT list[] = {
|
||||
|
@ -45,6 +124,7 @@ int main(int argc, char *argv[]) {
|
|||
{ CLIENT"gui/mbiq32.png", "gui:question.png" },
|
||||
{ CLIENT"gui/mbiw32.png", "gui:warning.png" },
|
||||
{ CLIENT"gui/mouse.png", "gui:mouse.png" },
|
||||
{ CLIENT"gui/wait.png", "gui:wait.png" },
|
||||
{ FONT"vga8x14.dat", "gui:vga8x14.dat" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
@ -55,7 +135,7 @@ int main(int argc, char *argv[]) {
|
|||
// Also run optipng -o7 on images.
|
||||
|
||||
cachePrePack(OUT"client.pre", list);
|
||||
cachePreUnpack(OUT"client.pre");
|
||||
//cachePreUnpack(OUT"client.pre");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT *
|
|||
static void clientApiFileRequestNext(ClientThreadT *client, PacketDecodeDataT *data) {
|
||||
uint32_t temp = 0;
|
||||
PacketEncodeDataT encoded = { 0 };
|
||||
uint32_t remaining = 0;
|
||||
uint16_t length = 0;
|
||||
uint8_t packetData[PACKET_MAX];
|
||||
|
||||
|
@ -192,15 +193,16 @@ static void clientApiFileRequestNext(ClientThreadT *client, PacketDecodeDataT *d
|
|||
|
||||
// Add file data.
|
||||
// ***TODO*** We can't send quite a full packet for some reason.
|
||||
length = client->fileSize - ftell(client->handle);
|
||||
if (length > PACKET_MAX - (10 + sizeof(int32_t))) {
|
||||
remaining = client->fileSize - ftell(client->handle);
|
||||
if (remaining > PACKET_MAX - (10 + sizeof(int32_t))) {
|
||||
// File is larger than a packet size.
|
||||
logWrite("Sending file fraction %d bytes\n", length);
|
||||
length = PACKET_MAX - (10 + sizeof(int32_t)); // 4 for integer of response type. 10 more because a full PACKET_MAX causes issues.
|
||||
logWrite("Sending file fraction %d bytes of %d remaining.\n", length, remaining);
|
||||
fread(&packetData[sizeof(int32_t)], length, 1, client->handle);
|
||||
} else {
|
||||
// File remains will fit in this packet.
|
||||
logWrite("Sending file end %d bytes\n", length);
|
||||
length = remaining;
|
||||
logWrite("Sending file end %d bytes of %d remaining.\n", length, remaining);
|
||||
fread(&packetData[sizeof(int32_t)], length, 1, client->handle);
|
||||
fclose(client->handle);
|
||||
client->handle = NULL;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "thirdparty/SHA256/sha256.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "array.h"
|
||||
#include "console.h"
|
||||
#include "settings.h"
|
||||
|
@ -372,14 +373,16 @@ DbGameT **dbGamesGet(void) {
|
|||
// Find screenshot and box image count from filesystem.
|
||||
x = 0;
|
||||
while (1) {
|
||||
snprintf(filename, MAX_PATH, "%s/games/%c/%s/screen%d.png", __settingsFile, game->shortName[0], game->shortName, x + 1);
|
||||
snprintf(filename, MAX_PATH, "%s/files/games/%c/%s/screen%d.png", __settingsFile, game->shortName[0], game->shortName, x + 1);
|
||||
utilStringToLower(filename);
|
||||
if (!utilFileExists(filename)) break;
|
||||
x++;
|
||||
}
|
||||
game->screens = x;
|
||||
x = 0;
|
||||
while (1) {
|
||||
snprintf(filename, MAX_PATH, "%s/games/%c/%s/box%d.png", __settingsFile, game->shortName[0], game->shortName, x + 1);
|
||||
snprintf(filename, MAX_PATH, "%s/files/games/%c/%s/box%d.png", __settingsFile, game->shortName[0], game->shortName, x + 1);
|
||||
utilStringToLower(filename);
|
||||
if (!utilFileExists(filename)) break;
|
||||
x++;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "array.h"
|
||||
|
||||
#include "util.h"
|
||||
|
@ -117,6 +119,13 @@ uint8_t utilFileExists(char *filename) {
|
|||
}
|
||||
|
||||
|
||||
void utilStringToLower(char *string) {
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i<strlen(string); i++) string[i] = tolower(string[i]);
|
||||
}
|
||||
|
||||
|
||||
char **utilWrapText(char *text, uint16_t width) {
|
||||
char **lines = NULL;
|
||||
char *head = text;
|
||||
|
|
|
@ -31,6 +31,7 @@ char *utilCreateString(char *format, ...);
|
|||
char *utilCreateStringVArgs(char *format, va_list args);
|
||||
void utilDie(const char *why, ...);
|
||||
uint8_t utilFileExists(char *filename);
|
||||
void utilStringToLower(char *string);
|
||||
char **utilWrapText(char *text, uint16_t width);
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue