diff --git a/.gitattributes b/.gitattributes
index fc0668d..b35322f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,3 +3,4 @@
*.xcf filter=lfs diff=lfs merge=lfs -text
*.odg filter=lfs diff=lfs merge=lfs -text
*.xlsx filter=lfs diff=lfs merge=lfs -text
+*.dat filter=lfs diff=lfs merge=lfs -text
diff --git a/buildPrerequisites.sh b/buildPrerequisites.sh
new file mode 100755
index 0000000..76f7338
--- /dev/null
+++ b/buildPrerequisites.sh
@@ -0,0 +1,86 @@
+#!/bin/bash -ex
+
+#
+# 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 .
+#
+
+
+function createEmbeddedBinary() {
+ local BINFILE=$1
+ local BINEXTENSION=$2
+ local TARGETDIR=$3
+ local SOURCEFILE="$3/${1,,}.h"
+ local BLOCKER="${1^^}_${2^^}_H"
+
+ outputLicense > ${SOURCEFILE}
+ outputHeader ${BLOCKER} >> ${SOURCEFILE}
+ printf "\n#ifdef EMBED_HERE\n\n" >> ${SOURCEFILE}
+ xxd -i ${BINFILE}.${BINEXTENSION} >> ${SOURCEFILE}
+ printf "\n#else // EMBED_HERE\n\n" >> ${SOURCEFILE}
+ printf "extern unsigned char ${BINFILE}_${BINEXTENSION}[];\n" >> ${SOURCEFILE}
+ printf "extern unsigned int ${BINFILE}_${BINEXTENSION}_len;\n" >> ${SOURCEFILE}
+ printf "\n#endif // EMBED_HERE\n\n" >> ${SOURCEFILE}
+ outputFooter ${BLOCKER} >> ${SOURCEFILE}
+}
+
+
+function outputFooter() {
+ local BLOCKER=$1
+
+ printf "\n#pragma GCC diagnostic pop\n\n\n#endif // ${BLOCKER}\n"
+}
+
+
+function outputHeader() {
+ local BLOCKER=$1
+
+ printf "\n\n#ifndef ${BLOCKER}\n#define ${BLOCKER}\n\n\n"
+ printf "// ===== THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT =====\n\n\n"
+ printf "#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-variable\"\n"
+}
+
+
+function outputLicense() {
+ cat <<-LICENSE
+ /*
+ * 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 .
+ *
+ */
+ LICENSE
+}
+
+
+pushd font/data
+
+createEmbeddedBinary vga8x14 dat ../../client/src/embedded
+
+popd
+
diff --git a/client/data/IconError.png b/client/assets/IconError.png
similarity index 100%
rename from client/data/IconError.png
rename to client/assets/IconError.png
diff --git a/client/data/IconInformation.png b/client/assets/IconInformation.png
similarity index 100%
rename from client/data/IconInformation.png
rename to client/assets/IconInformation.png
diff --git a/client/data/IconMessage.png b/client/assets/IconMessage.png
similarity index 100%
rename from client/data/IconMessage.png
rename to client/assets/IconMessage.png
diff --git a/client/data/IconQuestion.png b/client/assets/IconQuestion.png
similarity index 100%
rename from client/data/IconQuestion.png
rename to client/assets/IconQuestion.png
diff --git a/client/data/IconWarning.png b/client/assets/IconWarning.png
similarity index 100%
rename from client/data/IconWarning.png
rename to client/assets/IconWarning.png
diff --git a/client/data/MessageBoxIcon.png b/client/assets/MessageBoxIcon.png
similarity index 100%
rename from client/data/MessageBoxIcon.png
rename to client/assets/MessageBoxIcon.png
diff --git a/client/data/kanga.ans b/client/assets/kanga.ans
similarity index 100%
rename from client/data/kanga.ans
rename to client/assets/kanga.ans
diff --git a/client/data/kanga.png b/client/assets/kanga.png
similarity index 100%
rename from client/data/kanga.png
rename to client/assets/kanga.png
diff --git a/client/data/logo.xcf b/client/assets/logo.xcf
similarity index 100%
rename from client/data/logo.xcf
rename to client/assets/logo.xcf
diff --git a/client/client.pro b/client/client.pro
index d6cc631..4bcb464 100644
--- a/client/client.pro
+++ b/client/client.pro
@@ -68,6 +68,8 @@ HEADERS = \
$$SHARED/packets.h \
src/config.h \
$$SHARED/util.h \
+ src/embedded/vga8x14.h \
+ src/firstrun.h \
src/gui/msgbox.h \
src/login.h \
src/menu.h \
@@ -117,6 +119,8 @@ SOURCES = \
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
src/config.c \
$$SHARED/memory.c \
+ src/embedded/embedded.c \
+ src/firstrun.c \
src/gui/msgbox.c \
src/login.c \
src/menu.c \
@@ -158,10 +162,8 @@ LIBS = \
OTHER_FILES = \
$$DOS_HEADERS \
$$DOS_SOURCES \
- ../Makefile.djgpp \
- ../build.sh \
- ../test.sh \
- ../test.conf \
postBuild.sh
QMAKE_POST_LINK = $$PWD/postBuild.sh "$$PWD" "$$DESTDIR"
+
+DISTFILES +=
diff --git a/client/src/embedded/embedded.c b/client/src/embedded/embedded.c
new file mode 100644
index 0000000..d96da36
--- /dev/null
+++ b/client/src/embedded/embedded.c
@@ -0,0 +1,22 @@
+/*
+ * 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 .
+ *
+ */
+
+
+#define EMBED_HERE
+#include "vga8x14.h"
diff --git a/client/src/embedded/vga8x14.h b/client/src/embedded/vga8x14.h
new file mode 100644
index 0000000..7a18a3f
--- /dev/null
+++ b/client/src/embedded/vga8x14.h
@@ -0,0 +1,347 @@
+/*
+ * 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 VGA8X14_DAT_H
+#define VGA8X14_DAT_H
+
+
+// ===== THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT =====
+
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+
+#ifdef EMBED_HERE
+
+unsigned char vga8x14_dat[] = {
+ 0x08, 0x0e, 0x10, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7e, 0x7e, 0x00, 0x00, 0x18, 0x18, 0x00, 0xff, 0x00, 0xff, 0x1e,
+ 0x3c, 0x3f, 0x7f, 0x18, 0x00, 0x81, 0xff, 0x6c, 0x10, 0x3c, 0x3c, 0x00,
+ 0xff, 0x00, 0xff, 0x0e, 0x66, 0x33, 0x63, 0x18, 0x00, 0xa5, 0xdb, 0xfe,
+ 0x38, 0x3c, 0x7e, 0x00, 0xff, 0x3c, 0xc3, 0x1a, 0x66, 0x3f, 0x7f, 0xdb,
+ 0x00, 0x81, 0xff, 0xfe, 0x7c, 0xe7, 0xff, 0x18, 0xe7, 0x66, 0x99, 0x32,
+ 0x66, 0x30, 0x63, 0x3c, 0x00, 0x81, 0xff, 0xfe, 0xfe, 0xe7, 0xff, 0x3c,
+ 0xc3, 0x42, 0xbd, 0x78, 0x3c, 0x30, 0x63, 0xe7, 0x00, 0xbd, 0xc3, 0xfe,
+ 0x7c, 0xe7, 0x7e, 0x3c, 0xc3, 0x42, 0xbd, 0xcc, 0x18, 0x30, 0x63, 0x3c,
+ 0x00, 0x99, 0xe7, 0x7c, 0x38, 0x18, 0x18, 0x18, 0xe7, 0x66, 0x99, 0xcc,
+ 0x7e, 0x70, 0x67, 0xdb, 0x00, 0x81, 0xff, 0x38, 0x10, 0x18, 0x18, 0x00,
+ 0xff, 0x3c, 0xc3, 0xcc, 0x18, 0xf0, 0xe7, 0x18, 0x00, 0x7e, 0x7e, 0x10,
+ 0x00, 0x3c, 0x3c, 0x00, 0xff, 0x00, 0xff, 0x78, 0x18, 0xe0, 0xe6, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x18, 0x66,
+ 0x7f, 0xc6, 0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x06, 0x3c, 0x66, 0xdb, 0x60, 0x00, 0x3c, 0x3c, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0xfe, 0xe0, 0x0e, 0x7e, 0x66, 0xdb, 0x38, 0x00, 0x7e,
+ 0x7e, 0x18, 0x18, 0x30, 0x00, 0x28, 0x38, 0xfe, 0xf8, 0x3e, 0x18, 0x66,
+ 0xdb, 0x6c, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x60, 0xc0, 0x6c, 0x38, 0x7c,
+ 0xfe, 0xfe, 0x18, 0x66, 0x7b, 0xc6, 0x00, 0x18, 0x18, 0x18, 0xfe, 0xfe,
+ 0xc0, 0xfe, 0x7c, 0x7c, 0xf8, 0x3e, 0x18, 0x66, 0x1b, 0xc6, 0x00, 0x18,
+ 0x18, 0x18, 0x0c, 0x60, 0xc0, 0x6c, 0x7c, 0x38, 0xe0, 0x0e, 0x7e, 0x00,
+ 0x1b, 0x6c, 0xfe, 0x7e, 0x18, 0x7e, 0x18, 0x30, 0xfe, 0x28, 0xfe, 0x38,
+ 0xc0, 0x06, 0x3c, 0x66, 0x1b, 0x38, 0xfe, 0x3c, 0x18, 0x3c, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x10, 0x80, 0x02, 0x18, 0x66, 0x1b, 0x0c, 0xfe, 0x18,
+ 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x6c, 0x7c, 0x00, 0x38, 0x30,
+ 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3c, 0x66, 0x6c,
+ 0xc6, 0x00, 0x6c, 0x30, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x00, 0x3c, 0x24, 0xfe, 0xc2, 0xc2, 0x6c, 0x60, 0x30, 0x0c, 0x66, 0x18,
+ 0x00, 0x00, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0x6c, 0xc0, 0xc6, 0x38, 0x00,
+ 0x30, 0x0c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x6c,
+ 0x7c, 0x0c, 0x76, 0x00, 0x30, 0x0c, 0xff, 0x7e, 0x00, 0xfe, 0x00, 0x30,
+ 0x00, 0x18, 0x00, 0x6c, 0x06, 0x18, 0xdc, 0x00, 0x30, 0x0c, 0x3c, 0x18,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xfe, 0x86, 0x30, 0xcc, 0x00,
+ 0x30, 0x0c, 0x66, 0x18, 0x18, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x6c,
+ 0xc6, 0x66, 0xcc, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00, 0x18, 0x80,
+ 0x00, 0x18, 0x00, 0x6c, 0x7c, 0xc6, 0x76, 0x00, 0x0c, 0x30, 0x00, 0x00,
+ 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7c, 0x18, 0x7c, 0x7c, 0x0c, 0xfe, 0x38, 0xfe, 0x7c, 0x7c, 0x00, 0x00,
+ 0x06, 0x00, 0x60, 0x7c, 0xc6, 0x38, 0xc6, 0xc6, 0x1c, 0xc0, 0x60, 0xc6,
+ 0xc6, 0xc6, 0x18, 0x18, 0x0c, 0x00, 0x30, 0xc6, 0xce, 0x78, 0x06, 0x06,
+ 0x3c, 0xc0, 0xc0, 0x06, 0xc6, 0xc6, 0x18, 0x18, 0x18, 0x00, 0x18, 0xc6,
+ 0xde, 0x18, 0x0c, 0x06, 0x6c, 0xc0, 0xc0, 0x0c, 0xc6, 0xc6, 0x00, 0x00,
+ 0x30, 0x7e, 0x0c, 0x0c, 0xf6, 0x18, 0x18, 0x3c, 0xcc, 0xfc, 0xfc, 0x18,
+ 0x7c, 0x7e, 0x00, 0x00, 0x60, 0x00, 0x06, 0x18, 0xe6, 0x18, 0x30, 0x06,
+ 0xfe, 0x06, 0xc6, 0x30, 0xc6, 0x06, 0x00, 0x00, 0x30, 0x00, 0x0c, 0x18,
+ 0xc6, 0x18, 0x60, 0x06, 0x0c, 0x06, 0xc6, 0x30, 0xc6, 0x06, 0x18, 0x18,
+ 0x18, 0x7e, 0x18, 0x00, 0xc6, 0x18, 0xc6, 0xc6, 0x0c, 0xc6, 0xc6, 0x30,
+ 0xc6, 0x0c, 0x18, 0x18, 0x0c, 0x00, 0x30, 0x18, 0x7c, 0x7e, 0xfe, 0x7c,
+ 0x1e, 0x7c, 0x7c, 0x30, 0x7c, 0x78, 0x00, 0x30, 0x06, 0x00, 0x60, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0xfc, 0x3c,
+ 0xf8, 0xfe, 0xfe, 0x3c, 0xc6, 0x3c, 0x1e, 0xe6, 0xf0, 0xc6, 0xc6, 0x38,
+ 0xc6, 0x38, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0xc6, 0x18, 0x0c, 0x66,
+ 0x60, 0xee, 0xe6, 0x6c, 0xc6, 0x6c, 0x66, 0xc2, 0x66, 0x62, 0x62, 0xc2,
+ 0xc6, 0x18, 0x0c, 0x6c, 0x60, 0xfe, 0xf6, 0xc6, 0xde, 0xc6, 0x66, 0xc0,
+ 0x66, 0x68, 0x68, 0xc0, 0xc6, 0x18, 0x0c, 0x6c, 0x60, 0xfe, 0xfe, 0xc6,
+ 0xde, 0xc6, 0x7c, 0xc0, 0x66, 0x78, 0x78, 0xc0, 0xfe, 0x18, 0x0c, 0x78,
+ 0x60, 0xd6, 0xde, 0xc6, 0xde, 0xfe, 0x66, 0xc0, 0x66, 0x68, 0x68, 0xde,
+ 0xc6, 0x18, 0x0c, 0x6c, 0x60, 0xc6, 0xce, 0xc6, 0xdc, 0xc6, 0x66, 0xc2,
+ 0x66, 0x62, 0x60, 0xc6, 0xc6, 0x18, 0xcc, 0x6c, 0x62, 0xc6, 0xc6, 0xc6,
+ 0xc0, 0xc6, 0x66, 0x66, 0x6c, 0x66, 0x60, 0x66, 0xc6, 0x18, 0xcc, 0x66,
+ 0x66, 0xc6, 0xc6, 0x6c, 0x7c, 0xc6, 0xfc, 0x3c, 0xf8, 0xfe, 0xf0, 0x3a,
+ 0xc6, 0x3c, 0x78, 0xe6, 0xfe, 0xc6, 0xc6, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x00, 0xfc, 0x7c, 0xfc, 0x7c, 0x7e, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0x66, 0xfe, 0x3c, 0x80, 0x3c, 0x6c, 0x00, 0x66, 0xc6, 0x66, 0xc6,
+ 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0x66, 0xc6, 0x30, 0xc0, 0x0c, 0xc6, 0x00,
+ 0x66, 0xc6, 0x66, 0xc6, 0x5a, 0xc6, 0xc6, 0xc6, 0x6c, 0x66, 0x8c, 0x30,
+ 0xe0, 0x0c, 0x00, 0x00, 0x66, 0xc6, 0x66, 0x60, 0x18, 0xc6, 0xc6, 0xc6,
+ 0x38, 0x66, 0x18, 0x30, 0x70, 0x0c, 0x00, 0x00, 0x7c, 0xc6, 0x7c, 0x38,
+ 0x18, 0xc6, 0xc6, 0xd6, 0x38, 0x3c, 0x30, 0x30, 0x38, 0x0c, 0x00, 0x00,
+ 0x60, 0xd6, 0x6c, 0x0c, 0x18, 0xc6, 0xc6, 0xd6, 0x38, 0x18, 0x60, 0x30,
+ 0x1c, 0x0c, 0x00, 0x00, 0x60, 0xde, 0x66, 0xc6, 0x18, 0xc6, 0x6c, 0xfe,
+ 0x6c, 0x18, 0xc2, 0x30, 0x0e, 0x0c, 0x00, 0x00, 0x60, 0x7c, 0x66, 0xc6,
+ 0x18, 0xc6, 0x38, 0x7c, 0xc6, 0x18, 0xc6, 0x30, 0x06, 0x0c, 0x00, 0x00,
+ 0xf0, 0x0c, 0xe6, 0x7c, 0x3c, 0x7c, 0x10, 0x6c, 0xc6, 0x3c, 0xfe, 0x3c,
+ 0x02, 0x3c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0xe0, 0x00, 0x1c, 0x00, 0x38, 0x00, 0xe0, 0x18, 0x06, 0xe0,
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x0c, 0x00, 0x6c, 0x00,
+ 0x60, 0x18, 0x06, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x0c, 0x00, 0x64, 0x00, 0x60, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x78, 0x78, 0x7c, 0x3c, 0x7c, 0x60, 0x76, 0x6c, 0x38, 0x0e, 0x66,
+ 0x18, 0xec, 0xdc, 0x7c, 0x00, 0x0c, 0x6c, 0xc6, 0x6c, 0xc6, 0xf0, 0xcc,
+ 0x76, 0x18, 0x06, 0x6c, 0x18, 0xfe, 0x66, 0xc6, 0x00, 0x7c, 0x66, 0xc0,
+ 0xcc, 0xfe, 0x60, 0xcc, 0x66, 0x18, 0x06, 0x78, 0x18, 0xd6, 0x66, 0xc6,
+ 0x00, 0xcc, 0x66, 0xc0, 0xcc, 0xc0, 0x60, 0xcc, 0x66, 0x18, 0x06, 0x6c,
+ 0x18, 0xd6, 0x66, 0xc6, 0x00, 0xcc, 0x66, 0xc6, 0xcc, 0xc6, 0x60, 0x7c,
+ 0x66, 0x18, 0x06, 0x66, 0x18, 0xd6, 0x66, 0xc6, 0x00, 0x76, 0x7c, 0x7c,
+ 0x76, 0x7c, 0xf0, 0x0c, 0xe6, 0x3c, 0x66, 0xe6, 0x3c, 0xc6, 0x66, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x66, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+ 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x70, 0x76, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x18, 0x18, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x10, 0xdc, 0x76, 0xdc, 0x7c,
+ 0xfc, 0xcc, 0x66, 0xc6, 0xc6, 0xc6, 0xfe, 0x18, 0x18, 0x18, 0x00, 0x38,
+ 0x66, 0xcc, 0x76, 0xc6, 0x30, 0xcc, 0x66, 0xc6, 0x6c, 0xc6, 0xcc, 0x70,
+ 0x00, 0x0e, 0x00, 0x6c, 0x66, 0xcc, 0x66, 0x70, 0x30, 0xcc, 0x66, 0xd6,
+ 0x38, 0xc6, 0x18, 0x18, 0x18, 0x18, 0x00, 0xc6, 0x66, 0xcc, 0x60, 0x1c,
+ 0x30, 0xcc, 0x66, 0xd6, 0x38, 0xc6, 0x30, 0x18, 0x18, 0x18, 0x00, 0xc6,
+ 0x7c, 0x7c, 0x60, 0xc6, 0x36, 0xcc, 0x3c, 0xfe, 0x6c, 0x7e, 0x66, 0x18,
+ 0x18, 0x18, 0x00, 0xfe, 0x60, 0x0c, 0xf0, 0x7c, 0x1c, 0x76, 0x18, 0x6c,
+ 0xc6, 0x06, 0xfe, 0x0e, 0x18, 0x70, 0x00, 0x00, 0x60, 0x0c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+ 0x00, 0x00, 0x0c, 0x10, 0x00, 0x60, 0x38, 0x00, 0x10, 0x00, 0x60, 0x00,
+ 0x18, 0x60, 0xc6, 0x6c, 0x3c, 0xcc, 0x18, 0x38, 0xcc, 0x30, 0x6c, 0x00,
+ 0x38, 0xcc, 0x30, 0x66, 0x3c, 0x30, 0xc6, 0x38, 0x66, 0xcc, 0x30, 0x6c,
+ 0xcc, 0x18, 0x38, 0x00, 0x6c, 0xcc, 0x18, 0x66, 0x66, 0x18, 0x10, 0x00,
+ 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x38, 0xc0, 0xcc, 0x7c, 0x78, 0x78, 0x78, 0x78, 0x66,
+ 0x7c, 0x7c, 0x7c, 0x38, 0x38, 0x38, 0x6c, 0x6c, 0xc0, 0xcc, 0xc6, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x60, 0xc6, 0xc6, 0xc6, 0x18, 0x18, 0x18, 0xc6, 0xc6,
+ 0xc2, 0xcc, 0xfe, 0x7c, 0x7c, 0x7c, 0x7c, 0x66, 0xfe, 0xfe, 0xfe, 0x18,
+ 0x18, 0x18, 0xc6, 0xc6, 0x66, 0xcc, 0xc0, 0xcc, 0xcc, 0xcc, 0xcc, 0x3c,
+ 0xc0, 0xc0, 0xc0, 0x18, 0x18, 0x18, 0xfe, 0xfe, 0x3c, 0xcc, 0xc6, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x0c, 0xc6, 0xc6, 0xc6, 0x18, 0x18, 0x18, 0xc6, 0xc6,
+ 0x0c, 0x76, 0x7c, 0x76, 0x76, 0x76, 0x76, 0x06, 0x7c, 0x7c, 0x7c, 0x3c,
+ 0x3c, 0x3c, 0xc6, 0xc6, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x00, 0x60, 0x30, 0x60, 0x00, 0xc6, 0xc6, 0x18, 0x38, 0x00, 0xf8, 0x0e,
+ 0x60, 0x00, 0x3e, 0x38, 0xc6, 0x30, 0x78, 0x30, 0xc6, 0xc6, 0xc6, 0x18,
+ 0x6c, 0x66, 0xcc, 0x1b, 0x00, 0x00, 0x6c, 0x6c, 0xc6, 0x18, 0xcc, 0x18,
+ 0xc6, 0x38, 0x00, 0x3c, 0x64, 0x66, 0xcc, 0x18, 0xfe, 0xcc, 0xcc, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0x66, 0x60, 0x3c, 0xf8, 0x18,
+ 0x66, 0x76, 0xcc, 0x7c, 0x7c, 0x7c, 0xcc, 0xcc, 0xc6, 0xc6, 0xc6, 0x60,
+ 0xf0, 0x18, 0xc4, 0x18, 0x60, 0x36, 0xfe, 0xc6, 0xc6, 0xc6, 0xcc, 0xcc,
+ 0xc6, 0xc6, 0xc6, 0x60, 0x60, 0x7e, 0xcc, 0x7e, 0x7c, 0x7e, 0xcc, 0xc6,
+ 0xc6, 0xc6, 0xcc, 0xcc, 0xc6, 0xc6, 0xc6, 0x66, 0x60, 0x18, 0xde, 0x18,
+ 0x60, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xcc, 0xc6, 0xc6, 0xc6, 0x3c,
+ 0x60, 0x7e, 0xcc, 0x18, 0x66, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0xcc,
+ 0x7e, 0x6c, 0xc6, 0x18, 0xe6, 0x18, 0xcc, 0x18, 0xfe, 0x6e, 0xce, 0x7c,
+ 0x7c, 0x7c, 0x76, 0x76, 0x06, 0x38, 0x7c, 0x18, 0xfc, 0x18, 0xc6, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x18, 0x18, 0x00, 0xdc, 0x3c, 0x38,
+ 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x30, 0x18, 0x30, 0x30,
+ 0x76, 0x00, 0x6c, 0x6c, 0x30, 0x00, 0x00, 0xc0, 0xc0, 0x18, 0x00, 0x00,
+ 0x60, 0x30, 0x60, 0x60, 0xdc, 0xc6, 0x6c, 0x6c, 0x30, 0x00, 0x00, 0xc6,
+ 0xc6, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x3e, 0x38,
+ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x36, 0xd8, 0x78, 0x38, 0x7c, 0xcc,
+ 0xdc, 0xf6, 0x00, 0x00, 0x30, 0x00, 0x00, 0xd8, 0xd8, 0x18, 0x6c, 0x6c,
+ 0x0c, 0x18, 0xc6, 0xcc, 0x66, 0xfe, 0x7e, 0x7c, 0x30, 0xfe, 0xfe, 0x30,
+ 0x30, 0x18, 0xd8, 0x36, 0x7c, 0x18, 0xc6, 0xcc, 0x66, 0xde, 0x00, 0x00,
+ 0x60, 0xc0, 0x06, 0x60, 0x66, 0x3c, 0x6c, 0x6c, 0xcc, 0x18, 0xc6, 0xcc,
+ 0x66, 0xce, 0x00, 0x00, 0xc6, 0xc0, 0x06, 0xdc, 0xce, 0x3c, 0x36, 0xd8,
+ 0xcc, 0x18, 0xc6, 0xcc, 0x66, 0xc6, 0x00, 0x00, 0xc6, 0xc0, 0x06, 0x86,
+ 0x9e, 0x3c, 0x00, 0x00, 0x76, 0x3c, 0x7c, 0x76, 0x66, 0xc6, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x0c, 0x3e, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x55, 0xdd, 0x18,
+ 0x18, 0x18, 0x36, 0x00, 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x18, 0x00,
+ 0x44, 0xaa, 0x77, 0x18, 0x18, 0x18, 0x36, 0x00, 0x00, 0x36, 0x36, 0x00,
+ 0x36, 0x36, 0x18, 0x00, 0x11, 0x55, 0xdd, 0x18, 0x18, 0x18, 0x36, 0x00,
+ 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x18, 0x00, 0x44, 0xaa, 0x77, 0x18,
+ 0x18, 0x18, 0x36, 0x00, 0x00, 0x36, 0x36, 0x00, 0x36, 0x36, 0x18, 0x00,
+ 0x11, 0x55, 0xdd, 0x18, 0x18, 0x18, 0x36, 0x00, 0x00, 0x36, 0x36, 0x00,
+ 0x36, 0x36, 0x18, 0x00, 0x44, 0xaa, 0x77, 0x18, 0x18, 0xf8, 0x36, 0x00,
+ 0xf8, 0xf6, 0x36, 0xfe, 0xf6, 0x36, 0xf8, 0x00, 0x11, 0x55, 0xdd, 0x18,
+ 0x18, 0x18, 0x36, 0x00, 0x18, 0x06, 0x36, 0x06, 0x06, 0x36, 0x18, 0x00,
+ 0x44, 0xaa, 0x77, 0x18, 0xf8, 0xf8, 0xf6, 0xfe, 0xf8, 0xf6, 0x36, 0xf6,
+ 0xfe, 0xfe, 0xf8, 0xf8, 0x11, 0x55, 0xdd, 0x18, 0x18, 0x18, 0x36, 0x36,
+ 0x18, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x18, 0x44, 0xaa, 0x77, 0x18,
+ 0x18, 0x18, 0x36, 0x36, 0x18, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x18,
+ 0x11, 0x55, 0xdd, 0x18, 0x18, 0x18, 0x36, 0x36, 0x18, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x18, 0x44, 0xaa, 0x77, 0x18, 0x18, 0x18, 0x36, 0x36,
+ 0x18, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x18, 0x11, 0x55, 0xdd, 0x18,
+ 0x18, 0x18, 0x36, 0x36, 0x18, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x18,
+ 0x44, 0xaa, 0x77, 0x18, 0x18, 0x18, 0x36, 0x36, 0x18, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x18, 0x36,
+ 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x18, 0x18, 0x18, 0x00, 0x18,
+ 0x00, 0x18, 0x18, 0x36, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x18,
+ 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x18, 0x36, 0x36, 0x00, 0x36, 0x00,
+ 0x36, 0x00, 0x36, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x18, 0x36,
+ 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x18, 0x18, 0x18, 0x00, 0x18,
+ 0x00, 0x18, 0x18, 0x36, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x18,
+ 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x1f, 0x36, 0x37, 0x3f, 0xf7, 0xff,
+ 0x37, 0xff, 0xf7, 0xff, 0x18, 0x18, 0x00, 0x18, 0x00, 0x18, 0x18, 0x36,
+ 0x30, 0x30, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x1f,
+ 0xff, 0xff, 0x1f, 0x37, 0x3f, 0x37, 0xff, 0xf7, 0x37, 0xff, 0xf7, 0xff,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x36, 0x00, 0x36, 0x00, 0x36,
+ 0x36, 0x00, 0x36, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x36,
+ 0x00, 0x36, 0x00, 0x36, 0x36, 0x00, 0x36, 0x00, 0x00, 0x00, 0x18, 0x18,
+ 0x00, 0x18, 0x18, 0x36, 0x00, 0x36, 0x00, 0x36, 0x36, 0x00, 0x36, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x36, 0x00, 0x36, 0x00, 0x36,
+ 0x36, 0x00, 0x36, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x36,
+ 0x00, 0x36, 0x00, 0x36, 0x36, 0x00, 0x36, 0x00, 0x00, 0x00, 0x18, 0x18,
+ 0x00, 0x18, 0x18, 0x36, 0x00, 0x36, 0x00, 0x36, 0x36, 0x00, 0x36, 0x00,
+ 0x36, 0x00, 0x00, 0x36, 0x18, 0x00, 0x00, 0x36, 0x18, 0x18, 0x00, 0xff,
+ 0x00, 0xf0, 0x0f, 0xff, 0x36, 0x00, 0x00, 0x36, 0x18, 0x00, 0x00, 0x36,
+ 0x18, 0x18, 0x00, 0xff, 0x00, 0xf0, 0x0f, 0xff, 0x36, 0x00, 0x00, 0x36,
+ 0x18, 0x00, 0x00, 0x36, 0x18, 0x18, 0x00, 0xff, 0x00, 0xf0, 0x0f, 0xff,
+ 0x36, 0x00, 0x00, 0x36, 0x18, 0x00, 0x00, 0x36, 0x18, 0x18, 0x00, 0xff,
+ 0x00, 0xf0, 0x0f, 0xff, 0x36, 0x00, 0x00, 0x36, 0x18, 0x00, 0x00, 0x36,
+ 0x18, 0x18, 0x00, 0xff, 0x00, 0xf0, 0x0f, 0xff, 0x36, 0xff, 0x00, 0x36,
+ 0x1f, 0x1f, 0x00, 0x36, 0xff, 0x18, 0x00, 0xff, 0x00, 0xf0, 0x0f, 0xff,
+ 0x36, 0x00, 0x00, 0x36, 0x18, 0x18, 0x00, 0x36, 0x18, 0x18, 0x00, 0xff,
+ 0x00, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x1f, 0x3f, 0xff,
+ 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x18, 0x36, 0x00,
+ 0x00, 0x18, 0x36, 0x36, 0x18, 0x00, 0x18, 0xff, 0xff, 0xf0, 0x0f, 0x00,
+ 0x00, 0x18, 0x36, 0x00, 0x00, 0x18, 0x36, 0x36, 0x18, 0x00, 0x18, 0xff,
+ 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x18, 0x36, 0x00, 0x00, 0x18, 0x36, 0x36,
+ 0x18, 0x00, 0x18, 0xff, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x18, 0x36, 0x00,
+ 0x00, 0x18, 0x36, 0x36, 0x18, 0x00, 0x18, 0xff, 0xff, 0xf0, 0x0f, 0x00,
+ 0x00, 0x18, 0x36, 0x00, 0x00, 0x18, 0x36, 0x36, 0x18, 0x00, 0x18, 0xff,
+ 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x18, 0x36, 0x00, 0x00, 0x18, 0x36, 0x36,
+ 0x18, 0x00, 0x18, 0xff, 0xff, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00,
+ 0x7e, 0x38, 0x38, 0x1e, 0x00, 0x03, 0x1c, 0x00, 0x00, 0x00, 0xc6, 0x00,
+ 0xc6, 0x00, 0x00, 0x00, 0x18, 0x6c, 0x6c, 0x30, 0x00, 0x06, 0x30, 0x7c,
+ 0x00, 0x7c, 0xc6, 0xfe, 0x60, 0x00, 0x66, 0x76, 0x3c, 0xc6, 0xc6, 0x18,
+ 0x00, 0x7e, 0x60, 0xc6, 0x76, 0xc6, 0xc0, 0x6c, 0x30, 0x7e, 0x66, 0xdc,
+ 0x66, 0xc6, 0xc6, 0x0c, 0x7e, 0xdb, 0x60, 0xc6, 0xdc, 0xfc, 0xc0, 0x6c,
+ 0x18, 0xd8, 0x66, 0x18, 0x66, 0xfe, 0xc6, 0x3e, 0xdb, 0xdb, 0x7c, 0xc6,
+ 0xd8, 0xc6, 0xc0, 0x6c, 0x30, 0xd8, 0x66, 0x18, 0x66, 0xc6, 0x6c, 0x66,
+ 0xdb, 0xf3, 0x60, 0xc6, 0xd8, 0xc6, 0xc0, 0x6c, 0x60, 0xd8, 0x7c, 0x18,
+ 0x3c, 0xc6, 0x6c, 0x66, 0x7e, 0x7e, 0x60, 0xc6, 0xdc, 0xfc, 0xc0, 0x6c,
+ 0xc6, 0xd8, 0x60, 0x18, 0x18, 0x6c, 0x6c, 0x66, 0x00, 0x60, 0x30, 0xc6,
+ 0x76, 0xc0, 0xc0, 0x6c, 0xfe, 0x70, 0x60, 0x18, 0x7e, 0x38, 0xee, 0x3c,
+ 0x00, 0xc0, 0x1c, 0xc6, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0f, 0xd8, 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x0c, 0x0e, 0x18, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x0c,
+ 0x6c, 0xd8, 0x00, 0x00, 0xfe, 0x18, 0x18, 0x18, 0x1b, 0x18, 0x18, 0x00,
+ 0x6c, 0x00, 0x00, 0x0c, 0x6c, 0x30, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x30,
+ 0x1b, 0x18, 0x18, 0x76, 0x38, 0x00, 0x00, 0x0c, 0x6c, 0x60, 0x7c, 0x00,
+ 0x00, 0x7e, 0x06, 0x60, 0x18, 0x18, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x0c,
+ 0x6c, 0xc8, 0x7c, 0x00, 0xfe, 0x18, 0x0c, 0x30, 0x18, 0x18, 0x7e, 0x00,
+ 0x00, 0x18, 0x00, 0x0c, 0x6c, 0xf8, 0x7c, 0x00, 0x00, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x00, 0x76, 0x00, 0x18, 0x18, 0xec, 0x00, 0x00, 0x7c, 0x00,
+ 0x00, 0x00, 0x30, 0x0c, 0x18, 0xd8, 0x18, 0xdc, 0x00, 0x00, 0x00, 0x6c,
+ 0x00, 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x18, 0xd8, 0x18, 0x00,
+ 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0xff, 0x7e, 0x7e,
+ 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+unsigned int vga8x14_dat_len = 3588;
+
+#else // EMBED_HERE
+
+extern unsigned char vga8x14_dat[];
+extern unsigned int vga8x14_dat_len;
+
+#endif // EMBED_HERE
+
+
+#pragma GCC diagnostic pop
+
+
+#endif // VGA8X14_DAT_H
diff --git a/client/src/firstrun.c b/client/src/firstrun.c
new file mode 100644
index 0000000..d931b06
--- /dev/null
+++ b/client/src/firstrun.c
@@ -0,0 +1,138 @@
+/*
+ * 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 .
+ *
+ */
+
+
+#include "config.h"
+#include "log.h"
+#include "memory.h"
+#include "timer.h"
+#include "task.h"
+#include "network.h"
+#include "settings.h"
+
+#include "firstrun.h"
+
+
+static uint8_t _firstRunRunning = 1;
+
+
+static void firstRunFail(void);
+static void taskFirstRun(void *data);
+static void taskFirstRunHelper(void *data);
+
+
+static void firstRunFail(void) {
+ netShutdown();
+ taskShutdown();
+ timerShutdown();
+ configShutdown();
+ osShutdown();
+ logClose();
+ memoryShutdown();
+ exit(1);
+}
+
+
+void firstRunCheckSetup(void) {
+ // ***TODO*** Check for needed files here.
+ mkdir("cache", 0777);
+
+ taskCreate(taskFirstRunHelper, NULL);
+ taskCreate(taskFirstRun, NULL);
+ taskRun();
+}
+
+
+static void taskFirstRun(void *data) {
+ int8_t comPort = -1;
+ int8_t r = 0;
+
+ (void)data;
+
+ logWrite("First Run Setup\n");
+ logWrite("===============\n\n");
+
+ // 0 1 2 3 4 5 6 7 8
+ // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
+ logWrite("Welcome to the KangaWorld Client! Before you can connect to KangaWorld, Setup\n");
+ logWrite("needs to detect a compatible softmodem and download several files.\n\n");
+ logWrite("One moment while we check for a compatible softmodem...\n\n");
+
+ comPort = settingsScanComPorts();
+
+ if (comPort < 0) {
+ logWrite("Unable to detect a compatible softmodem! For assistance, visit:\n");
+ logWrite("https://Kanga.World\n");
+ firstRunFail();
+ }
+
+ logWrite("Compatible softmodem found on COM%d:! Connecting to KangaWorld...\n\n", comPort + 1);
+
+ logWrite("Initializing modem...\n");
+ r = netConnectStep1();
+ if (r == NETWORK_CONNECT_OPEN_FAILED) {
+ logWrite("Unable to open COM port! Please check settings.\n");
+ _firstRunRunning = 0;
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_MODEM) {
+ logWrite("Modem does not support ENET! Please check settings.\n");
+ _firstRunRunning = 0;
+ return;
+ }
+
+ logWrite("Dialing modem...\n");
+ r = netConnectStep2();
+ if (r == NETWORK_CONNECT_NO_CARRIER) {
+ logWrite("Unable to connect to server! Please check settings or try later.\n");
+ _firstRunRunning = 0;
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_ENCRYPTION) {
+ logWrite("Unable to negotiate encryption settings!\n");
+ _firstRunRunning = 0;
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_SETTINGS) {
+ logWrite("Unable to fetch client settings!\n");
+ _firstRunRunning = 0;
+ return;
+ }
+
+ logWrite("Connected! Pre-caching needed files...\n");
+
+
+ logWrite("Disconnecting...\n");
+ netDisconnect();
+
+ _firstRunRunning = 0;
+
+ return;
+}
+
+
+static void taskFirstRunHelper(void *data) {
+
+ (void)data;
+
+ while (_firstRunRunning) {
+ timerUpdate();
+ taskYield();
+ }
+}
diff --git a/client/src/firstrun.h b/client/src/firstrun.h
new file mode 100644
index 0000000..dd7f45b
--- /dev/null
+++ b/client/src/firstrun.h
@@ -0,0 +1,31 @@
+/*
+ * 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 FIRSTRUN_H
+#define FIRSTRUN_H
+
+
+#include "os.h"
+
+
+void firstRunCheckSetup(void);
+
+
+#endif // FIRSTRUN_H
diff --git a/client/src/gui/font.c b/client/src/gui/font.c
index e7ca463..4b48d09 100644
--- a/client/src/gui/font.c
+++ b/client/src/gui/font.c
@@ -22,45 +22,67 @@
#include "surface.h"
+FontT *fontFromRAMLoad(uint8_t *pointer) {
+ FontT *font = NULL;
+ uint32_t size = 0;
+
+ font = (FontT *)malloc(sizeof(FontT));
+ if (!font) {
+ return NULL;
+ }
+
+ font->width = pointer[0]; // Width of character in pixels
+ font->height = pointer[1]; // Height of character in pixels
+ font->span = pointer[2]; // Width of atlas in characters
+ font->count = pointer[3]; // Number of characters in atlas - 1
+
+ font->widthPixels = font->width * font->span; // Width of atlas in pixels
+ font->heightPixels = font->height * ((font->count + 1) / font->span); // Height of atlas in pixels
+ size = font->widthPixels * font->heightPixels / 8; // Bits required to store atlas
+
+ font->bits = (uint8_t *)malloc(size);
+ if (!font->bits) {
+ DEL(font);
+ return NULL;
+ }
+
+ memcpy(font->bits, &pointer[4], size);
+
+ return font;
+}
+
+
uint16_t fontHeightGet(FontT *font) {
return font->height;
}
FontT *fontLoad(char *filename) {
- FILE *in = NULL;
- uint16_t size = 0;
- FontT *font = NULL;
+ FILE *in = NULL;
+ size_t size = 0;
+ uint8_t *buffer = NULL;
+ FontT *font = NULL;
in = fopen(filename, "rb");
if (!in) return NULL;
- font = (FontT *)malloc(sizeof(FontT));
- if (!font) {
+ fseek(in, 0, SEEK_END);
+ size = ftell(in);
+ fseek(in, 0, SEEK_SET);
+
+ buffer = (uint8_t *)malloc(size);
+ if (!buffer) {
fclose(in);
return NULL;
}
- font->width = fgetc(in);
- font->height = fgetc(in);
- font->span = fgetc(in);
- font->count = fgetc(in);
-
- font->widthPixels = font->width * font->span;
- font->heightPixels = font->height * (font->count / font->span);
-
- size = font->widthPixels * font->heightPixels;
- font->bits = (uint8_t *)malloc(size);
- if (!font->bits) {
- free(font);
- fclose(in);
- return NULL;
- }
-
- fread(font->bits, size, 1, in);
-
+ fread(buffer, size, 1, in);
fclose(in);
+ font = fontFromRAMLoad(buffer);
+
+ DEL(buffer);
+
return font;
}
diff --git a/client/src/gui/font.h b/client/src/gui/font.h
index 34f6975..28518cd 100644
--- a/client/src/gui/font.h
+++ b/client/src/gui/font.h
@@ -37,6 +37,7 @@ typedef struct FontS {
} FontT;
+FontT *fontFromRAMLoad(uint8_t *pointer);
uint16_t fontHeightGet(FontT *font);
FontT *fontLoad(char *filename);
void fontRender(FontT *font, char *string, ColorT foreground, ColorT background, uint16_t x, uint16_t y);
diff --git a/client/src/gui/gui.c b/client/src/gui/gui.c
index 00220e0..369df14 100644
--- a/client/src/gui/gui.c
+++ b/client/src/gui/gui.c
@@ -22,6 +22,7 @@
#include "gui.h"
+#include "embedded/vga8x14.h"
#include "widget.h"
#include "desktop.h"
#include "window.h"
@@ -29,9 +30,6 @@
int16_t _guiMetric[METRIC_COUNT];
ColorT _guiColor[COLOR_COUNT];
-FontT *_guiFont8 = NULL;
-FontT *_guiFont14 = NULL;
-FontT *_guiFont16 = NULL;
FontT *_guiFont = NULL;
WidgetT *_guiDragWidget = NULL;
uint16_t _guiDragOffsetX = 0;
@@ -43,7 +41,7 @@ static DesktopT *_guiDesktop = NULL;
static WidgetT *_guiLastWidgetLeft = NULL;
static uint8_t _guiLastWidgetLeftEvent = MOUSE_EVENT_NONE;
static WidgetT *_guiFocused = NULL;
-static uint8_t _guiHasStopped = 0;
+static uint8_t _guiHasStopped = 0; // This starts as 0 even if the GUI hasn't been started.
static WidgetT ***_guiDeleteList = NULL;
@@ -521,10 +519,7 @@ WidgetT *guiRootGet(void) {
void guiShutdown(void) {
// Unload fonts.
- fontUnload(&_guiFont16);
- fontUnload(&_guiFont14);
- fontUnload(&_guiFont8);
- _guiFont = NULL;
+ fontUnload(&_guiFont);
// Delete all widgets in GUI tree.
guiDelete((WidgetT **)&_guiDesktop);
@@ -631,12 +626,8 @@ DesktopT *guiStartup(void) {
_guiColor[COLOR_LISTBOX_ARROWS_ACTIVE] = vbeColorMake(168, 168, 168);
_guiColor[COLOR_LISTBOX_ARROWS_INACTIVE] = vbeColorMake( 80, 84, 80);
- // Load all font sizes.
- _guiFont8 = fontLoad("data/vga8x8.dat");
- _guiFont14 = fontLoad("data/vga8x14.dat");
- _guiFont16 = fontLoad("data/vga8x16.dat");
-
- _guiFont = _guiFont14; // Font to use for widgets.
+ // Load font.
+ _guiFont = fontFromRAMLoad(vga8x14_dat);
// Create desktop and return it. Remember it for later.
_guiDesktop = desktopNew();
diff --git a/client/src/gui/gui.h b/client/src/gui/gui.h
index 2b98b9f..948d0bd 100644
--- a/client/src/gui/gui.h
+++ b/client/src/gui/gui.h
@@ -182,9 +182,6 @@ typedef struct WindowS WindowT;
extern int16_t _guiMetric[METRIC_COUNT];
extern ColorT _guiColor[COLOR_COUNT];
extern FontT *_guiFont;
-extern FontT *_guiFont8;
-extern FontT *_guiFont14;
-extern FontT *_guiFont16;
extern WidgetT *_guiDragWidget;
extern uint16_t _guiDragOffsetX;
extern uint16_t _guiDragOffsetY;
diff --git a/client/src/linux/linux.c b/client/src/linux/linux.c
index 7e16a22..359a92f 100644
--- a/client/src/linux/linux.c
+++ b/client/src/linux/linux.c
@@ -77,12 +77,13 @@ static uint32_t _pixelFormat = SDL_PIXELFORMAT_RGBA8888;
static uint8_t _takeScreenshot = 0;
-static void comAddToBuffer(char *data, uint16_t len);
-static void comBufferShow(void);
-static void comModem(uint8_t c);
-static void processEvent(void);
-static void processNetworkEvent(void);
-static void vbeScreenshot(void);
+static void comAddToBuffer(char *data, uint16_t len);
+static void comBufferShow(void);
+static void comModem(uint8_t c);
+static void processEvent(void);
+static void processNetworkEvent(void);
+static uint32_t timerCallback(uint32_t interval, void *param);
+static void vbeScreenshot(void);
long biostime(int cmd, long newtime) {
@@ -379,6 +380,28 @@ void keyStartup(void) {
}
+void linuxOsShutdown(void) {
+ // Stop timer.
+ SDL_RemoveTimer(_timerID);
+
+ // Stop network.
+ enet_deinitialize();
+
+ SDL_Quit();
+}
+
+
+void linuxOsStartup(void) {
+ SDL_Init(SDL_INIT_EVERYTHING);
+
+ // And networking/serial startup.
+ enet_initialize();
+
+ // We do timer startup here, too.
+ _timerID = SDL_AddTimer(TIMER_INTERVAL, timerCallback, NULL);
+}
+
+
void mouseShutdown(void) {
// Eh, don't care.
}
@@ -463,8 +486,6 @@ static void processEvent(void) {
break;
}
}
-
- processNetworkEvent();
}
@@ -472,7 +493,7 @@ static void processNetworkEvent(void) {
ENetEvent event = { 0 };
if (_host) {
- while (enet_host_service(_host, &event, 1) > 0) {
+ while (enet_host_service(_host, &event, 0) > 0) {
switch (event.type) {
case ENET_EVENT_TYPE_CONNECT:
_connected = 1;
@@ -497,9 +518,11 @@ static void processNetworkEvent(void) {
}
-uint32_t timerCallback(uint32_t interval, void *param) {
+static uint32_t timerCallback(uint32_t interval, void *param) {
(void)param;
+ processNetworkEvent();
+
_timerTicks++;
if (_timerTicks > TICKS_PER_DAY) {
_timerTicks = 0;
@@ -550,15 +573,8 @@ void vbePresent(void) {
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
SDL_RenderPresent(_renderer);
- if (_host) {
- // Throttle this to some sane frame rate by checking for network events.
- for (temp=0; temp<32; temp++) {
- processNetworkEvent();
- }
- } else {
- // No network activity. Just sleep.
- SDL_Delay(32);
- }
+ // Throttle this to some sane frame rate.
+ SDL_Delay(32);
if (_takeScreenshot) {
_takeScreenshot = 0;
@@ -620,14 +636,6 @@ int16_t vbeShutdown(void) {
_window = NULL;
}
- // Stop network.
- enet_deinitialize();
-
- // Stop timer.
- SDL_RemoveTimer(_timerID);
-
- SDL_Quit();
-
return 0;
}
@@ -638,8 +646,6 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
_windowScale = 3;
- SDL_Init(SDL_INIT_EVERYTHING);
-
_window = SDL_CreateWindow("GUI Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, xRes, yRes, SDL_WINDOW_ALLOW_HIGHDPI);
_surface = SDL_GetWindowSurface(_window);
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
@@ -651,12 +657,6 @@ uint8_t vbeStartup(uint16_t xRes, uint16_t yRes, uint8_t bpp) {
_width = xRes;
_height = yRes;
- // We do timer startup here, too.
- _timerID = SDL_AddTimer(TIMER_INTERVAL, timerCallback, NULL);
-
- // And networking/serial startup.
- enet_initialize();
-
return 0;
}
diff --git a/client/src/login.c b/client/src/login.c
index 530e937..8328a95 100644
--- a/client/src/login.c
+++ b/client/src/login.c
@@ -97,26 +97,7 @@ static void setButtons(uint8_t enabled) {
static void taskDisconnect(void *nextTask) {
- PacketEncodeDataT encoded = { 0 };
- int16_t timeout = 2;
-
- // Tell server we're disconnecting.
- encoded.packetType = PACKET_TYPE_CLIENT_SHUTDOWN;
- encoded.control = PACKET_CONTROL_DAT;
- encoded.channel = 0;
- encoded.encrypt = 0;
- packetEncode(__packetThreadData, &encoded, NULL, 0);
- packetSend(__packetThreadData, &encoded);
-
- // Snooze a bit for the packet to send.
- while (timeout > 0) {
- taskYield();
- if (__timerQuarterSecondTick) timeout--;
- }
-
- // Shut down packet processing & COM port.
- netShutdown();
- comClose(__configData.serialCom - 1);
+ netDisconnect();
if (nextTask) taskCreate(taskWelcome, nextTask);
}
diff --git a/client/src/main.c b/client/src/main.c
index 3b742d7..e34b682 100644
--- a/client/src/main.c
+++ b/client/src/main.c
@@ -48,6 +48,8 @@
#include "config.h"
#include "runtime.h"
#include "comport.h"
+#include "network.h"
+#include "firstrun.h"
#include "welcome.h"
#include "signup.h"
@@ -92,10 +94,6 @@ static void taskGuiEventLoop(void *data) {
int main(int argc, char *argv[]) {
- FILE *cache = NULL;
- char *line = NULL;
- char *p = NULL;
-
#ifndef __linux__
// On DOS, display the contets of the log now that we're back in text mode.
char *logName = NULL;
@@ -104,6 +102,7 @@ int main(int argc, char *argv[]) {
memoryStartup(argv[0]);
logOpenByHandle(memoryLogHandleGet());
+ osStartup();
configStartup(argv[0]);
// 0 1 2 3 4 5 6 7 8
@@ -121,6 +120,12 @@ int main(int argc, char *argv[]) {
}
}
+ timerStartup();
+ taskStartup();
+
+ // Perform "first run" setup tasks.
+ firstRunCheckSetup();
+
// Do we have the video mode they asked for?
if (vbeStartup(__configData.videoWidth, __configData.videoHeight, __configData.videoDepth)) {
configShutdown();
@@ -131,54 +136,8 @@ int main(int argc, char *argv[]) {
surfaceStartup();
mouseStartup();
- timerStartup();
guiStartup();
- taskStartup();
-
- __packetThreadData = packetThreadDataCreate(NULL);
- packetSenderRegister(comPacketSender);
-
- __runtimeData.integers = NULL;
- __runtimeData.strings = NULL;
- __runtimeData.protocolVersion = 0;
-
- sh_new_strdup(__runtimeData.integers);
- sh_new_strdup(__runtimeData.strings);
-
- // ***TODO*** Default initial tables
-
- mkdir("cache", 0777);
- line = (char *)malloc(4096);
- if (line) {
- // Load string cache.
- cache = fopen("cache/string.dat", "rt");
- if (cache) {
- while (fscanf(cache, "%s\n", line) != EOF) {
- p = strstr(line, "=");
- if (p) {
- *p = 0;
- p++;
- shput(__runtimeData.strings, line, strdup(p));
- }
- }
- fclose(cache);
- }
- // Load integer cache.
- cache = fopen("cache/integer.dat", "rt");
- if (cache) {
- while (fscanf(cache, "%s\n", line) != EOF) {
- p = strstr(line, "=");
- if (p) {
- *p = 0;
- p++;
- shput(__runtimeData.integers, line, atol(p));
- }
- }
- fclose(cache);
- }
- free(line);
- line = NULL;
- }
+ // Do not call netStartup() here. It will be started when needed.
// taskCreate(taskSignUp, NULL);
taskCreate(taskWelcome, NULL);
@@ -186,44 +145,15 @@ int main(int argc, char *argv[]) {
taskRun();
- // Save & free integer table.
- cache = fopen("cache/integer.dat", "wt");
- if (cache) {
- if (__runtimeData.integers) {
- while (shlen(__runtimeData.integers) > 0) {
- //logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
- fprintf(cache, "%s=%d\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
- shdel(__runtimeData.integers, __runtimeData.integers[0].key);
- }
- shfree(__runtimeData.integers);
- }
- fclose(cache);
- }
-
- // Save & free string table.
- cache = fopen("cache/string.dat", "wt");
- if (cache) {
- if (__runtimeData.strings) {
- while (shlen(__runtimeData.strings) > 0) {
- //logWrite("[%s]=[%s]\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
- fprintf(cache, "%s=%s\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
- DEL(__runtimeData.strings[0].value);
- shdel(__runtimeData.strings, __runtimeData.strings[0].key);
- }
- shfree(__runtimeData.strings);
- }
- fclose(cache);
- }
-
- packetThreadDataDestroy(&__packetThreadData);
-
- taskShutdown();
+ netShutdown();
guiShutdown();
- timerShutdown();
mouseShutdown();
surfaceShutdown();
vbeShutdown();
+ taskShutdown();
+ timerShutdown();
configShutdown();
+ osShutdown();
logClose();
memoryShutdown();
diff --git a/client/src/network.c b/client/src/network.c
index 2df811f..db6d4fd 100644
--- a/client/src/network.c
+++ b/client/src/network.c
@@ -23,6 +23,7 @@
#include "comport.h"
#include "config.h"
#include "timer.h"
+#include "runtime.h"
#include "network.h"
@@ -35,6 +36,157 @@ typedef struct NetworkPacketS {
static NetworkPacketT *_packets = NULL;
static uint8_t _netRunning = 0;
+static uint8_t _netStarted = 0;
+
+
+int8_t netConnectStep1(void) {
+ int32_t r = 0;
+ char buffer[1024] = { 0 };
+
+ // Open COM port.
+ r = comOpen(__configData.serialCom - 1, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
+ if (r != SER_SUCCESS) return NETWORK_CONNECT_OPEN_FAILED;
+ // Send a CR to clear anything in the modem.
+ snprintf(buffer, 1023, "%c", 13);
+ comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
+ // Wait roughly a second for anything.
+ comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "weExpectNothing");
+ // Send actual init
+ snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
+ comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
+ // Wait roughly a second for "OK".
+ r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "OK");
+ if (r <= 0) {
+ comClose(__configData.serialCom - 1);
+ return NETWORK_CONNECT_BAD_MODEM;
+ }
+ // Flush COM port.
+ timerQuarterSecondsWait(4);
+ comReceiveBufferFlush(__configData.serialCom - 1);
+
+ return NETWORK_CONNECT_SUCCESS;
+}
+
+
+int8_t netConnectStep2(void) {
+ int32_t r = 0;
+ char buffer[1024] = { 0 };
+ PacketDecodeDataT *decoded = NULL;
+ PacketEncodeDataT encoded = { 0 };
+ uint8_t waiting = 1;
+ int16_t timeout = 0;
+
+ snprintf(buffer, 1023, "ATDT%s:%d%c", __configData.serverHost, __configData.serverPort, 13);
+ comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
+ // Wait 7 seconds for welcome banner.
+ r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4 * 7, "KPMPGSMKII\r");
+ if (r <= 0) {
+ comClose(__configData.serialCom - 1);
+ return NETWORK_CONNECT_NO_CARRIER;
+ }
+
+ // Start packet handler and negotiate encryption.
+ netStartup();
+ packetEncryptionSetup(__packetThreadData);
+ timeout = 5;
+ do {
+ if (packetEncryptionReady()) break;
+ taskYield();
+ if (__timerSecondTick) timeout--;
+ } while (!guiHasStopped() && timeout >= 0);
+ if (timeout < 0) {
+ comClose(__configData.serialCom - 1);
+ return NETWORK_CONNECT_BAD_ENCRYPTION;
+ }
+
+ // ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
+
+ // Wait for version and table packets to arrive.
+ timeout = 10;
+ do {
+ decoded = netGetPacket(0);
+ if (decoded) {
+ switch (decoded->packetType) {
+ case PACKET_TYPE_NUMBER:
+ // Store in number table.
+ shput(__runtimeData.integers, &decoded->data[4], (int32_t)decoded->data[0]);
+ // Reset timeout.
+ timeout = 10;
+ break;
+
+ case PACKET_TYPE_PROCEED:
+ waiting = 0;
+ break;
+
+ case PACKET_TYPE_STRING:
+ // Store in string table.
+ //logWrite("Storing [%s]=[%s]\n", decoded->data, &decoded->data[strlen(decoded->data) + 1]);
+ shput(__runtimeData.strings, decoded->data, strdup(&decoded->data[strlen(decoded->data) + 1]));
+ // Reset timeout.
+ timeout = 10;
+ break;
+
+ case PACKET_TYPE_VERSION:
+ packetContentUnpack(decoded->data, "i", &__runtimeData.protocolVersion);
+ // Do we need to update?
+ if (PACKET_PROTOCOL_VERSION == __runtimeData.protocolVersion) {
+ // Nope, we're good.
+ encoded.packetType = PACKET_TYPE_VERSION_OKAY;
+ } else {
+ // Version mismatch - upgrade time!
+ encoded.packetType = PACKET_TYPE_VERSION_BAD;
+ //***TODO***
+ }
+ encoded.control = PACKET_CONTROL_DAT;
+ encoded.channel = 0;
+ encoded.encrypt = 0;
+ packetEncode(__packetThreadData, &encoded, NULL, 0);
+ // Send GOOD or BAD.
+ packetSend(__packetThreadData, &encoded);
+ // Reset timeout.
+ timeout = 10;
+ break;
+
+ default:
+ logWrite("Unexpected packet received: %d\n", decoded->packetType);
+ break;
+ }
+ packetDecodeDataDestroy(&decoded);
+ }
+ taskYield();
+ if (__timerSecondTick) timeout--;
+ } while (!guiHasStopped() && timeout >= 0 && waiting);
+ if (timeout < 0) {
+ comClose(__configData.serialCom - 1);
+ return NETWORK_CONNECT_BAD_SETTINGS;
+ }
+
+ return NETWORK_CONNECT_SUCCESS;
+}
+
+
+void netDisconnect(void) {
+ PacketEncodeDataT encoded = { 0 };
+ int16_t timeout = 2;
+
+ // Tell server we're disconnecting.
+ encoded.packetType = PACKET_TYPE_CLIENT_SHUTDOWN;
+ encoded.control = PACKET_CONTROL_DAT;
+ encoded.channel = 0;
+ encoded.encrypt = 0;
+ packetEncode(__packetThreadData, &encoded, NULL, 0);
+ packetSend(__packetThreadData, &encoded);
+
+ // Snooze a bit for the packet to send.
+ while (timeout > 0) {
+ taskYield();
+ if (__timerQuarterSecondTick) timeout--;
+ }
+
+ // Shut down packet processing & COM port.
+ netShutdown();
+ comClose(__configData.serialCom - 1);
+}
uint8_t netGetChannelFree(void) {
@@ -67,11 +219,98 @@ PacketDecodeDataT *netGetPacket(uint8_t channel) {
void netShutdown(void) {
+ FILE *cache = NULL;
+
+ if (_netStarted) {
+ _netStarted = 0;
+
+ // Save & free integer table.
+ cache = fopen("cache/integer.dat", "wt");
+ if (cache) {
+ if (__runtimeData.integers) {
+ while (shlen(__runtimeData.integers) > 0) {
+ //logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
+ fprintf(cache, "%s=%d\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
+ shdel(__runtimeData.integers, __runtimeData.integers[0].key);
+ }
+ shfree(__runtimeData.integers);
+ }
+ fclose(cache);
+ }
+
+ // Save & free string table.
+ cache = fopen("cache/string.dat", "wt");
+ if (cache) {
+ if (__runtimeData.strings) {
+ while (shlen(__runtimeData.strings) > 0) {
+ //logWrite("[%s]=[%s]\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
+ fprintf(cache, "%s=%s\n", __runtimeData.strings[0].key, __runtimeData.strings[0].value);
+ DEL(__runtimeData.strings[0].value);
+ shdel(__runtimeData.strings, __runtimeData.strings[0].key);
+ }
+ shfree(__runtimeData.strings);
+ }
+ fclose(cache);
+ }
+
+ packetThreadDataDestroy(&__packetThreadData);
+ }
+
_netRunning = 0;
}
void netStartup(void) {
+ FILE *cache = NULL;
+ char *line = NULL;
+ char *p = NULL;
+
+ _netStarted = 1;
+
+ __packetThreadData = packetThreadDataCreate(NULL);
+ packetSenderRegister(comPacketSender);
+
+ __runtimeData.integers = NULL;
+ __runtimeData.strings = NULL;
+ __runtimeData.protocolVersion = 0;
+
+ sh_new_strdup(__runtimeData.integers);
+ sh_new_strdup(__runtimeData.strings);
+
+ // ***TODO*** Default initial tables
+
+ line = (char *)malloc(4096);
+ if (line) {
+ // Load string cache.
+ cache = fopen("cache/string.dat", "rt");
+ if (cache) {
+ while (fscanf(cache, "%s\n", line) != EOF) {
+ p = strstr(line, "=");
+ if (p) {
+ *p = 0;
+ p++;
+ shput(__runtimeData.strings, line, strdup(p));
+ }
+ }
+ fclose(cache);
+ }
+ // Load integer cache.
+ cache = fopen("cache/integer.dat", "rt");
+ if (cache) {
+ while (fscanf(cache, "%s\n", line) != EOF) {
+ p = strstr(line, "=");
+ if (p) {
+ *p = 0;
+ p++;
+ shput(__runtimeData.integers, line, atol(p));
+ }
+ }
+ fclose(cache);
+ }
+ free(line);
+ line = NULL;
+ }
+
taskCreate(taskNetwork, NULL);
}
diff --git a/client/src/network.h b/client/src/network.h
index 333632d..fccc4c5 100644
--- a/client/src/network.h
+++ b/client/src/network.h
@@ -25,6 +25,17 @@
#include "os.h"
+#define NETWORK_CONNECT_SUCCESS 0
+#define NETWORK_CONNECT_OPEN_FAILED 1
+#define NETWORK_CONNECT_BAD_MODEM 2
+#define NETWORK_CONNECT_NO_CARRIER 3
+#define NETWORK_CONNECT_BAD_ENCRYPTION 4
+#define NETWORK_CONNECT_BAD_SETTINGS 5
+
+
+int8_t netConnectStep1(void);
+int8_t netConnectStep2(void);
+void netDisconnect(void);
uint8_t netGetChannelFree(void);
PacketDecodeDataT *netGetPacket(uint8_t channel);
void netShutdown(void);
diff --git a/client/src/settings.c b/client/src/settings.c
index 398495d..d9ced81 100644
--- a/client/src/settings.c
+++ b/client/src/settings.c
@@ -95,30 +95,12 @@ static void btnOkayClick(WidgetT *widget) {
}
-void taskSettings(void *data) {
-
- int32_t rc;
- uint32_t len;
- char buffer[1024];
- uint8_t selected = 1;
-
- _done = (widgetCallback)data;
-
- TagItemT uiDetecting[] = {
- T_START,
- T_WINDOW, O(_winDetecting),
- T_TITLE, P("Detecting Modems"),
- T_WIDTH, 200, T_HEIGHT, 100,
- T_LABEL, O(_lblOneMoment),
- T_X, 25, T_Y, 25,
- T_TITLE, P("One Moment Please!"),
- T_LABEL, T_DONE,
- T_WINDOW, T_DONE,
- T_END
- };
-
- tagListRun(uiDetecting);
- taskYield(); // Cause dialog to paint.
+int8_t settingsScanComPorts(void) {
+ char buffer[1024] = { 0 };
+ uint8_t selected = 1;
+ int32_t rc = 0;
+ uint32_t len = 0;
+ int8_t lastFound = -1;
// Scan the COM ports for a compatable modem.
for (int x=0; x<4; x++) {
@@ -134,7 +116,8 @@ void taskSettings(void *data) {
_port[x].status = PORT_GOOD_MODEM;
_port[x].selected = selected;
_port[x].enabled = 1;
- selected = 0;
+ selected = 0;
+ lastFound = x;
} else {
if (strstr(buffer, "ERROR")) {
snprintf(_port[x].title, TITLE_LEN - 1, "COM%d - Incompatable Modem", x + 1);
@@ -157,6 +140,35 @@ void taskSettings(void *data) {
}
}
+ return lastFound;
+}
+
+
+void taskSettings(void *data) {
+
+ int32_t rc;
+ uint32_t len;
+
+ _done = (widgetCallback)data;
+
+ TagItemT uiDetecting[] = {
+ T_START,
+ T_WINDOW, O(_winDetecting),
+ T_TITLE, P("Detecting Modems"),
+ T_WIDTH, 200, T_HEIGHT, 100,
+ T_LABEL, O(_lblOneMoment),
+ T_X, 25, T_Y, 25,
+ T_TITLE, P("One Moment Please!"),
+ T_LABEL, T_DONE,
+ T_WINDOW, T_DONE,
+ T_END
+ };
+
+ tagListRun(uiDetecting);
+ taskYield(); // Cause dialog to paint.
+
+ settingsScanComPorts();
+
guiDelete(D(_winDetecting));
TagItemT uiSettings[] = {
diff --git a/client/src/settings.h b/client/src/settings.h
index 0c61e57..a63c3fe 100644
--- a/client/src/settings.h
+++ b/client/src/settings.h
@@ -25,7 +25,8 @@
#include "os.h"
-void taskSettings(void *data);
+int8_t settingsScanComPorts(void);
+void taskSettings(void *data);
#endif // SETTINGS_H
diff --git a/client/src/system/os.c b/client/src/system/os.c
index 1c32230..a653605 100644
--- a/client/src/system/os.c
+++ b/client/src/system/os.c
@@ -21,3 +21,15 @@
#include "os.h"
+void osShutdown(void) {
+#ifdef __linux__
+ linuxOsShutdown();
+#endif
+}
+
+
+void osStartup(void) {
+#ifdef __linux__
+ linuxOsStartup();
+#endif
+}
diff --git a/client/src/system/os.h b/client/src/system/os.h
index d659b03..81cb419 100644
--- a/client/src/system/os.h
+++ b/client/src/system/os.h
@@ -44,6 +44,10 @@
// Linux DOS replacements.
long biostime(int cmd, long newtime);
+// Linux support functions.
+void linuxOsShutdown(void);
+void linuxOsStartup(void);
+
#else
#define BITS32
@@ -74,6 +78,9 @@ long biostime(int cmd, long newtime);
#define NEW(t,v) (v)=(t*)malloc(sizeof(t))
#define DEL(v) {free(v); v=NULL;}
+#define SUCCESS 1
+#define FAIL 0
+
// Some helper defines.
#define DIVISIBLE_BY_EIGHT(x) ((((x) >> 3) << 3) == (x))
#define HIGH_BYTE(b) ((uint8_t)(((b) & 0xFF00) >> 8))
@@ -86,4 +93,8 @@ typedef struct PacketThreadDataS PacketThreadDataT;
extern PacketThreadDataT *__packetThreadData; // Declared in main.c
+void osShutdown(void);
+void osStartup(void);
+
+
#endif // OS_H
diff --git a/client/src/welcome.c b/client/src/welcome.c
index c50bcb8..6aa0a98 100644
--- a/client/src/welcome.c
+++ b/client/src/welcome.c
@@ -28,7 +28,6 @@
#include "comport.h"
#include "timer.h"
#include "network.h"
-#include "runtime.h"
#include "window.h"
#include "picture.h"
@@ -78,156 +77,6 @@ static void btnMsgBoxQuit(MsgBoxButtonT button) {
}
-static void taskConnectClick(void *data) {
- int32_t r = 0;
- char buffer[1024] = { 0 };
- PacketDecodeDataT *decoded = NULL;
- PacketEncodeDataT encoded = { 0 };
- int16_t timeout = 0;
- uint8_t waiting = 1;
-
- (void)data;
-
- // Ghost all buttons.
- widgetEnableSet(W(_btnConnect), 0);
- widgetEnableSet(W(_btnSettings), 0);
- widgetEnableSet(W(_btnQuit), 0);
-
- // Hide welcome banner, show init.
- widgetVisibleSet(W(_picLogo), 0);
- widgetVisibleSet(W(_picInit), 1);
- taskYield();
-
- // Open COM port.
- r = comOpen(__configData.serialCom - 1, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
- if (r != SER_SUCCESS) {
- msgBoxOne("COM Problem", MSGBOX_ICON_ERROR, "Unable to open COM port!\nPlease check settings.", "Okay", btnMsgBox);
- return;
- }
- // Send a CR to clear anything in the modem.
- snprintf(buffer, 1023, "%c", 13);
- comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
- // Wait roughly a second for anything.
- comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "weExpectNothing");
- // Send actual init
- snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
- comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
- // Wait roughly a second for "OK".
- r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4, "OK");
- if (r <= 0) {
- comClose(__configData.serialCom - 1);
- msgBoxOne("Modem Problem", MSGBOX_ICON_ERROR, "Modem does not support ENET!\nPlease check settings.", "Okay", btnMsgBox);
- return;
- }
- // Flush COM port.
- timerQuarterSecondsWait(4);
- comReceiveBufferFlush(__configData.serialCom - 1);
-
- // Show dialing, dial service.
- widgetVisibleSet(W(_picDialing), 1);
- taskYield();
- snprintf(buffer, 1023, "ATDT%s:%d%c", __configData.serverHost, __configData.serverPort, 13);
- comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
- // Wait 7 seconds for welcome banner.
- r = comWaitWithTimeout(__configData.serialCom - 1, buffer, 1023, 4 * 7, "KPMPGSMKII\r");
- if (r <= 0) {
- comClose(__configData.serialCom - 1);
- msgBoxOne("No Connection", MSGBOX_ICON_INFORMATION, "Unable to connect to server!\nPlease check settings or try later.", "Okay", btnMsgBox);
- return;
- }
-
- // Start packet handler and negotiate encryption.
- netStartup();
- packetEncryptionSetup(__packetThreadData);
- timeout = 5;
- do {
- if (packetEncryptionReady()) break;
- taskYield();
- if (__timerSecondTick) timeout--;
- } while (!guiHasStopped() && timeout >= 0);
- if (timeout < 0) {
- comClose(__configData.serialCom - 1);
- msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to negotiate encryption settings!", "Okay", btnMsgBox);
- return;
- }
-
- // ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
-
- // Wait for version and table packets to arrive.
- timeout = 10;
- do {
- decoded = netGetPacket(0);
- if (decoded) {
- switch (decoded->packetType) {
- case PACKET_TYPE_NUMBER:
- // Store in number table.
- shput(__runtimeData.integers, &decoded->data[4], (int32_t)decoded->data[0]);
- // Reset timeout.
- timeout = 10;
- break;
-
- case PACKET_TYPE_PROCEED:
- waiting = 0;
- break;
-
- case PACKET_TYPE_STRING:
- // Store in string table.
- //logWrite("Storing [%s]=[%s]\n", decoded->data, &decoded->data[strlen(decoded->data) + 1]);
- shput(__runtimeData.strings, decoded->data, strdup(&decoded->data[strlen(decoded->data) + 1]));
- // Reset timeout.
- timeout = 10;
- break;
-
- case PACKET_TYPE_VERSION:
- packetContentUnpack(decoded->data, "i", &__runtimeData.protocolVersion);
- // Do we need to update?
- if (PACKET_PROTOCOL_VERSION == __runtimeData.protocolVersion) {
- // Nope, we're good.
- encoded.packetType = PACKET_TYPE_VERSION_OKAY;
- } else {
- // Version mismatch - upgrade time!
- encoded.packetType = PACKET_TYPE_VERSION_BAD;
- //***TODO***
- }
- encoded.control = PACKET_CONTROL_DAT;
- encoded.channel = 0;
- encoded.encrypt = 0;
- packetEncode(__packetThreadData, &encoded, NULL, 0);
- // Send GOOD or BAD.
- packetSend(__packetThreadData, &encoded);
- // Reset timeout.
- timeout = 10;
- break;
-
- default:
- logWrite("Unexpected packet received: %d\n", decoded->packetType);
- break;
- }
- packetDecodeDataDestroy(&decoded);
- }
- taskYield();
- if (__timerSecondTick) timeout--;
- } while (!guiHasStopped() && timeout >= 0 && waiting);
- if (timeout < 0) {
- comClose(__configData.serialCom - 1);
- msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to fetch client settings!", "Okay", btnMsgBox);
- return;
- }
-
- // Connected! Show icon.
- widgetVisibleSet(W(_picConnect), 1);
- timeout = 6; // Roughly 1.5 seconds.
- while (timeout > 0 && !guiHasStopped()) {
- taskYield();
- if (__timerQuarterSecondTick) timeout--;
- }
-
- // Switch to Login window.
- guiDelete(D(_winWelcome));
- taskCreate(taskLogin, NULL);
-}
-
-
static void btnQuitClick(WidgetT *widget) {
(void)widget;
setButtons(0);
@@ -312,3 +161,61 @@ void taskWelcome(void *data) {
tagListRun(uiWelcome);
}
+
+
+static void taskConnectClick(void *data) {
+ int32_t r = 0;
+ int16_t timeout = 0;
+
+ (void)data;
+
+ // Ghost all buttons.
+ widgetEnableSet(W(_btnConnect), 0);
+ widgetEnableSet(W(_btnSettings), 0);
+ widgetEnableSet(W(_btnQuit), 0);
+
+ // Hide welcome banner, show init.
+ widgetVisibleSet(W(_picLogo), 0);
+ widgetVisibleSet(W(_picInit), 1);
+ taskYield();
+
+ r = netConnectStep1();
+ if (r == NETWORK_CONNECT_OPEN_FAILED) {
+ msgBoxOne("COM Problem", MSGBOX_ICON_ERROR, "Unable to open COM port!\nPlease check settings.", "Okay", btnMsgBox);
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_MODEM) {
+ msgBoxOne("Modem Problem", MSGBOX_ICON_ERROR, "Modem does not support ENET!\nPlease check settings.", "Okay", btnMsgBox);
+ return;
+ }
+
+ // Show dialing, dial service.
+ widgetVisibleSet(W(_picDialing), 1);
+ taskYield();
+
+ r = netConnectStep2();
+ if (r == NETWORK_CONNECT_NO_CARRIER) {
+ msgBoxOne("No Connection", MSGBOX_ICON_INFORMATION, "Unable to connect to server!\nPlease check settings or try later.", "Okay", btnMsgBox);
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_ENCRYPTION) {
+ msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to negotiate encryption settings!", "Okay", btnMsgBox);
+ return;
+ }
+ if (r == NETWORK_CONNECT_BAD_SETTINGS) {
+ msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to fetch client settings!", "Okay", btnMsgBox);
+ return;
+ }
+
+ // Connected! Show icon.
+ widgetVisibleSet(W(_picConnect), 1);
+ timeout = 6; // Roughly 1.5 seconds.
+ while (timeout > 0 && !guiHasStopped()) {
+ taskYield();
+ if (__timerQuarterSecondTick) timeout--;
+ }
+
+ // Switch to Login window.
+ guiDelete(D(_winWelcome));
+ taskCreate(taskLogin, NULL);
+}
diff --git a/client/src/welcome.h b/client/src/welcome.h
index ba98f3e..bc64762 100644
--- a/client/src/welcome.h
+++ b/client/src/welcome.h
@@ -25,7 +25,7 @@
#include "os.h"
-void taskWelcome(void *data);
+void taskWelcome(void *data);
#endif // WELCOME_H
diff --git a/font/data/vga8x14.png b/font/assets/vga8x14.png
similarity index 100%
rename from font/data/vga8x14.png
rename to font/assets/vga8x14.png
diff --git a/font/data/vga8x16.png b/font/assets/vga8x16.png
similarity index 100%
rename from font/data/vga8x16.png
rename to font/assets/vga8x16.png
diff --git a/font/data/vga8x8.png b/font/assets/vga8x8.png
similarity index 100%
rename from font/data/vga8x8.png
rename to font/assets/vga8x8.png
diff --git a/font/data/vga8x14.dat b/font/data/vga8x14.dat
new file mode 100644
index 0000000..432c721
--- /dev/null
+++ b/font/data/vga8x14.dat
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f547ef7ca4aa8fd9050cf370473ed2ee4b0db030613008fd7ed6a7dc08e9f3c7
+size 3588
diff --git a/font/data/vga8x16.dat b/font/data/vga8x16.dat
new file mode 100644
index 0000000..bd9288e
--- /dev/null
+++ b/font/data/vga8x16.dat
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ffaf5a93c5e4315b7ed5059ed8cf1322824e9f4ee3a3d93d878e068f74ea6329
+size 4100
diff --git a/font/data/vga8x8.dat b/font/data/vga8x8.dat
new file mode 100644
index 0000000..e41fe84
--- /dev/null
+++ b/font/data/vga8x8.dat
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:014d7209c4f671963ab147b478213def901f657eff3a6c5eafd65298903d6138
+size 2052
diff --git a/font/src/main.c b/font/src/main.c
index 2672065..9dabeb9 100644
--- a/font/src/main.c
+++ b/font/src/main.c
@@ -53,8 +53,8 @@ void makeFont(char *source, char *target, int pixelsW, int pixelsH, int charsW,
}
// Provide some metadata for enhancement later.
- fputc(pixelsW, out); // Width of characters
- fputc(pixelsH, out); // Height of characters
+ fputc(pixelsW, out); // Width of characters in pixels
+ fputc(pixelsH, out); // Height of characters in pixels
fputc(charsW, out); // Number of characters per row
fputc(charCount, out); // Number of characters - 1
@@ -82,9 +82,9 @@ int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
- makeFont("/home/scott/code/kpmpgsmkii/font/data/vga8x8.png", "/home/scott/code/kpmpgsmkii/bin/data/vga8x8.dat", 8, 8, 16, 255);
- makeFont("/home/scott/code/kpmpgsmkii/font/data/vga8x14.png", "/home/scott/code/kpmpgsmkii/bin/data/vga8x14.dat", 8, 14, 16, 255);
- makeFont("/home/scott/code/kpmpgsmkii/font/data/vga8x16.png", "/home/scott/code/kpmpgsmkii/bin/data/vga8x16.dat", 8, 16, 16, 255);
+ makeFont("/home/scott/code/kpmpgsmkii/font/assets/vga8x8.png", "/home/scott/code/kpmpgsmkii/font/data/vga8x8.dat", 8, 8, 16, 255);
+ makeFont("/home/scott/code/kpmpgsmkii/font/assets/vga8x14.png", "/home/scott/code/kpmpgsmkii/font/data/vga8x14.dat", 8, 14, 16, 255);
+ makeFont("/home/scott/code/kpmpgsmkii/font/assets/vga8x16.png", "/home/scott/code/kpmpgsmkii/font/data/vga8x16.dat", 8, 16, 16, 255);
return 0;
}
diff --git a/kpmpgsmkii.pro b/kpmpgsmkii.pro
index 00ff9fd..dd61259 100644
--- a/kpmpgsmkii.pro
+++ b/kpmpgsmkii.pro
@@ -16,11 +16,23 @@
# along with this program. If not, see .
#
+
TEMPLATE = subdirs
CONFIG *= ORDERED
SUBDIRS = \
client \
server
-# font \
+# font
# primes
+
+OTHER_FILES = \
+ .gitattributes \
+ .gitignore \
+ buildPrerequisites.sh \
+ LICENSE \
+ Makefile.djgpp \
+ build.sh \
+ get-sql.sh \
+ test.conf \
+ test.sh
diff --git a/server/src/rest.c b/server/src/rest.c
index fef82a3..0f6aac9 100644
--- a/server/src/rest.c
+++ b/server/src/rest.c
@@ -221,14 +221,15 @@ json_object *restRequest(char *command, char *format, ...) {
//logWrite("Request: %s\n", json_object_to_json_string_ext(request, JSON_C_TO_STRING_PRETTY));
response = restUrlPost(request);
json_object_put(request);
- logWrite("Response: %s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
+ //logWrite("Response: %s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
if (response) {
string = (char *)json_object_get_string(json_object_object_get(response, "result"));
result = (string[0] == 't' || string[0] == 'T') ? 1 : 0;
- if (result) {
+ if (!result) {
logWrite("restRequest: %s\n", json_object_get_string(json_object_object_get(response, "reason")));
json_object_put(response);
+ response = NULL;
}
} else {
logWrite("restRequest: No response.\n");