Completed conversion from task-based code to event-based. Needs testing but now runs on DOS!
This commit is contained in:
parent
ecf6d1f842
commit
114dd36513
64 changed files with 1928 additions and 1216 deletions
|
@ -33,10 +33,13 @@ BINDIR = bin
|
||||||
|
|
||||||
# CFLAGS, LDFLAGS, CPPFLAGS, PREFIX can be overriden on CLI
|
# CFLAGS, LDFLAGS, CPPFLAGS, PREFIX can be overriden on CLI
|
||||||
CFLAGS := $(DEBUG)
|
CFLAGS := $(DEBUG)
|
||||||
|
#CFLAGS += -DALLEGRONOTAVAIL -DALLEGRONOTPROGS -DDZCOMM_SRC
|
||||||
CFLAGS += -I$(SRCDIR)/client/src -I$(SRCDIR)/client/src/system -I$(SRCDIR)/client/src/dos -I$(SRCDIR)/client/src/gui -I$(SRCDIR)/client/src/thirdparty
|
CFLAGS += -I$(SRCDIR)/client/src -I$(SRCDIR)/client/src/system -I$(SRCDIR)/client/src/dos -I$(SRCDIR)/client/src/gui -I$(SRCDIR)/client/src/thirdparty
|
||||||
CFLAGS += -I$(SRCDIR)/shared -I$(SRCDIR)/shared/thirdparty
|
CFLAGS += -I$(SRCDIR)/shared -I$(SRCDIR)/shared/thirdparty
|
||||||
|
#CFLAGS += -I$(SRCDIR)/client/src/thirdparty/dzcomm -I$(SRCDIR)/client/src/thirdparty/dzcomm/include
|
||||||
CPPFLAGS :=
|
CPPFLAGS :=
|
||||||
LDFLAGS :=
|
LDFLAGS :=
|
||||||
|
#LDFLAGS += -L$(SRCDIR)/client/src/thirdparty/dzcomm -ldzcom
|
||||||
PREFIX := /usr/local
|
PREFIX := /usr/local
|
||||||
TARGET_ARCH :=
|
TARGET_ARCH :=
|
||||||
|
|
||||||
|
@ -61,6 +64,7 @@ DEP := $(OBJ:.o=.d)
|
||||||
BIN := $(BINDIR)/$(TARGET)
|
BIN := $(BINDIR)/$(TARGET)
|
||||||
-include $(DEP)
|
-include $(DEP)
|
||||||
|
|
||||||
|
#obj/client/src/thirdparty/dzcomm/src/dos/djirqs.o
|
||||||
|
|
||||||
#$(info [${SRC}])
|
#$(info [${SRC}])
|
||||||
#$(info [${OBJ}])
|
#$(info [${OBJ}])
|
||||||
|
|
1
build.sh
1
build.sh
|
@ -27,6 +27,7 @@ mkdir -p \
|
||||||
obj/client/src/system \
|
obj/client/src/system \
|
||||||
obj/client/src/dos \
|
obj/client/src/dos \
|
||||||
obj/client/src/gui \
|
obj/client/src/gui \
|
||||||
|
obj/client/src/embedded \
|
||||||
obj/client/src/thirdparty/serial \
|
obj/client/src/thirdparty/serial \
|
||||||
obj/shared/thirdparty/memwatch \
|
obj/shared/thirdparty/memwatch \
|
||||||
obj/shared/thirdparty/blowfish-api \
|
obj/shared/thirdparty/blowfish-api \
|
||||||
|
|
|
@ -79,8 +79,10 @@ function outputLicense() {
|
||||||
|
|
||||||
|
|
||||||
pushd font/data
|
pushd font/data
|
||||||
|
|
||||||
createEmbeddedBinary vga8x14 dat ../../client/src/embedded
|
createEmbeddedBinary vga8x14 dat ../../client/src/embedded
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd client/data
|
||||||
|
createEmbeddedBinary mouse png ../../client/src/embedded
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,9 @@ QMAKE_CFLAGS += -O0
|
||||||
|
|
||||||
DEFINES *= CLIENT
|
DEFINES *= CLIENT
|
||||||
|
|
||||||
|
UNUSED_CRAP = \
|
||||||
|
src/thirdparty/dzcomm/include/dzcomm.h
|
||||||
|
|
||||||
DOS_HEADERS = \
|
DOS_HEADERS = \
|
||||||
src/thirdparty/serial/serial.h
|
src/thirdparty/serial/serial.h
|
||||||
|
|
||||||
|
@ -68,9 +71,10 @@ HEADERS = \
|
||||||
$$SHARED/packets.h \
|
$$SHARED/packets.h \
|
||||||
src/config.h \
|
src/config.h \
|
||||||
$$SHARED/util.h \
|
$$SHARED/util.h \
|
||||||
src/embedded/vga8x14.h \
|
src/embedded/embedded.h \
|
||||||
src/firstrun.h \
|
|
||||||
src/gui/msgbox.h \
|
src/gui/msgbox.h \
|
||||||
|
src/gui/timer.h \
|
||||||
|
src/hangup.h \
|
||||||
src/login.h \
|
src/login.h \
|
||||||
src/menu.h \
|
src/menu.h \
|
||||||
src/network.h \
|
src/network.h \
|
||||||
|
@ -84,13 +88,13 @@ HEADERS = \
|
||||||
src/system/surface.h \
|
src/system/surface.h \
|
||||||
src/system/taglist.h \
|
src/system/taglist.h \
|
||||||
src/system/keyboard.h \
|
src/system/keyboard.h \
|
||||||
src/system/task.h \
|
|
||||||
src/system/timer.h \
|
|
||||||
$$SHARED/array.h \
|
$$SHARED/array.h \
|
||||||
$$SHARED/log.h \
|
$$SHARED/log.h \
|
||||||
src/system/mouse.h \
|
src/system/mouse.h \
|
||||||
src/system/vesa.h \
|
src/system/vesa.h \
|
||||||
src/system/os.h \
|
src/system/os.h \
|
||||||
|
src/embedded/vga8x14.h \
|
||||||
|
src/embedded/mouse.h \
|
||||||
src/gui/listbox.h \
|
src/gui/listbox.h \
|
||||||
src/gui/terminal.h \
|
src/gui/terminal.h \
|
||||||
src/gui/updown.h \
|
src/gui/updown.h \
|
||||||
|
@ -117,16 +121,11 @@ SOURCES = \
|
||||||
$$SHARED/packet.c \
|
$$SHARED/packet.c \
|
||||||
$$SHARED/thirdparty/tiny-AES-c/aes.c \
|
$$SHARED/thirdparty/tiny-AES-c/aes.c \
|
||||||
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
|
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
|
||||||
src/config.c \
|
|
||||||
$$SHARED/memory.c \
|
$$SHARED/memory.c \
|
||||||
src/embedded/embedded.c \
|
src/embedded/embedded.c \
|
||||||
src/firstrun.c \
|
|
||||||
src/gui/msgbox.c \
|
src/gui/msgbox.c \
|
||||||
src/login.c \
|
src/gui/timer.c \
|
||||||
src/menu.c \
|
src/hangup.c \
|
||||||
src/network.c \
|
|
||||||
src/settings.c \
|
|
||||||
src/signup.c \
|
|
||||||
src/system/comport.c \
|
src/system/comport.c \
|
||||||
src/system/os.c \
|
src/system/os.c \
|
||||||
src/system/surface.c \
|
src/system/surface.c \
|
||||||
|
@ -134,8 +133,6 @@ SOURCES = \
|
||||||
$$SHARED/util.c \
|
$$SHARED/util.c \
|
||||||
$$SHARED/array.c \
|
$$SHARED/array.c \
|
||||||
$$SHARED/log.c \
|
$$SHARED/log.c \
|
||||||
src/system/timer.c \
|
|
||||||
src/system/task.c \
|
|
||||||
src/gui/listbox.c \
|
src/gui/listbox.c \
|
||||||
src/gui/terminal.c \
|
src/gui/terminal.c \
|
||||||
src/gui/updown.c \
|
src/gui/updown.c \
|
||||||
|
@ -152,8 +149,14 @@ SOURCES = \
|
||||||
src/gui/button.c \
|
src/gui/button.c \
|
||||||
src/gui/checkbox.c \
|
src/gui/checkbox.c \
|
||||||
src/gui/label.c \
|
src/gui/label.c \
|
||||||
|
src/config.c \
|
||||||
src/main.c \
|
src/main.c \
|
||||||
src/welcome.c
|
src/welcome.c \
|
||||||
|
src/login.c \
|
||||||
|
src/menu.c \
|
||||||
|
src/signup.c \
|
||||||
|
src/network.c \
|
||||||
|
src/settings.c
|
||||||
|
|
||||||
LIBS = \
|
LIBS = \
|
||||||
-lSDL2 \
|
-lSDL2 \
|
||||||
|
|
|
@ -19,4 +19,4 @@
|
||||||
|
|
||||||
|
|
||||||
#define EMBED_HERE
|
#define EMBED_HERE
|
||||||
#include "vga8x14.h"
|
#include "embedded/embedded.h"
|
||||||
|
|
|
@ -18,23 +18,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef TASK_H
|
#ifndef EMBEDDED_H
|
||||||
#define TASK_H
|
#define EMBEDDED_H
|
||||||
|
|
||||||
|
|
||||||
#include "os.h"
|
#include "mouse.h"
|
||||||
#include "widget.h"
|
#include "vga8x14.h"
|
||||||
|
|
||||||
|
|
||||||
typedef void (*taskFunction)(void *data);
|
#endif // EMBEDDED_H
|
||||||
|
|
||||||
|
|
||||||
uint8_t taskCreate(void (*function)(void *), void *data);
|
|
||||||
void taskProxy(WidgetT *widget);
|
|
||||||
void taskRun(void);
|
|
||||||
void taskShutdown(void);
|
|
||||||
void taskStartup(void);
|
|
||||||
void taskYield(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // TASK_H
|
|
457
client/src/embedded/mouse.h
Normal file
457
client/src/embedded/mouse.h
Normal file
|
@ -0,0 +1,457 @@
|
||||||
|
/*
|
||||||
|
* Kangaroo Punch MultiPlayer Game Server Mark II
|
||||||
|
* Copyright (C) 2020-2021 Scott Duensing
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MOUSE_PNG_H
|
||||||
|
#define MOUSE_PNG_H
|
||||||
|
|
||||||
|
|
||||||
|
// ===== THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT =====
|
||||||
|
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
|
|
||||||
|
#ifdef EMBED_HERE
|
||||||
|
|
||||||
|
unsigned char mouse_png[] = {
|
||||||
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||||
|
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18,
|
||||||
|
0x08, 0x06, 0x00, 0x00, 0x00, 0xf3, 0xa0, 0x7d, 0x0c, 0x00, 0x00, 0x10,
|
||||||
|
0x66, 0x7a, 0x54, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f,
|
||||||
|
0x66, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65, 0x78,
|
||||||
|
0x69, 0x66, 0x00, 0x00, 0x78, 0xda, 0xc5, 0x9a, 0x5b, 0x76, 0x1b, 0x39,
|
||||||
|
0x12, 0x44, 0xff, 0xb1, 0x8a, 0x59, 0x02, 0xde, 0x8f, 0xe5, 0xe0, 0x91,
|
||||||
|
0x38, 0xa7, 0x77, 0x30, 0xcb, 0x9f, 0x9b, 0xa8, 0x22, 0x2d, 0xca, 0x94,
|
||||||
|
0x65, 0xbb, 0x3f, 0xc6, 0x6c, 0x89, 0xa5, 0x62, 0x15, 0x0a, 0xc8, 0x8c,
|
||||||
|
0x8c, 0xc8, 0x00, 0xdb, 0xc8, 0x7f, 0xff, 0xd9, 0xe6, 0x3f, 0xfc, 0x4b,
|
||||||
|
0xd6, 0x66, 0x13, 0x53, 0xa9, 0xb9, 0xe5, 0x6c, 0xf9, 0x17, 0x5b, 0x6c,
|
||||||
|
0xbe, 0x73, 0x50, 0xed, 0xf5, 0xaf, 0x9f, 0xdf, 0xce, 0xc6, 0xf3, 0xfb,
|
||||||
|
0xfe, 0xc3, 0x3e, 0x0e, 0x5e, 0xce, 0x1b, 0xf7, 0xb8, 0xc9, 0x73, 0x2a,
|
||||||
|
0xf0, 0x1e, 0xae, 0x3f, 0x6b, 0xbe, 0xcf, 0x0b, 0xe7, 0x3d, 0xd7, 0xfb,
|
||||||
|
0xfb, 0xfc, 0xbc, 0xc7, 0xe9, 0x9c, 0x4f, 0x1f, 0x06, 0x6a, 0x72, 0x7f,
|
||||||
|
0x30, 0x5e, 0x3f, 0xe8, 0xf7, 0x40, 0xbe, 0xde, 0x0f, 0x78, 0x4c, 0xe5,
|
||||||
|
0x7e, 0x50, 0x70, 0xd7, 0x03, 0xec, 0xba, 0x07, 0xea, 0xf7, 0x40, 0xc1,
|
||||||
|
0xdf, 0x4f, 0x8e, 0xd7, 0xdf, 0xe3, 0x7e, 0x72, 0x6e, 0xb5, 0x7c, 0x5c,
|
||||||
|
0xc2, 0x7a, 0x2c, 0xad, 0xde, 0x67, 0xea, 0xf5, 0x63, 0xf4, 0x57, 0x0c,
|
||||||
|
0xc5, 0xe7, 0x94, 0x5d, 0x89, 0xfc, 0x8e, 0xde, 0x96, 0x92, 0x1b, 0xc7,
|
||||||
|
0xd5, 0xdb, 0x58, 0x88, 0xdb, 0xd2, 0x89, 0xee, 0xe9, 0x9b, 0xde, 0x97,
|
||||||
|
0xc6, 0x35, 0xce, 0xe7, 0xbf, 0xcd, 0xe3, 0x52, 0xcf, 0x9c, 0xbc, 0x04,
|
||||||
|
0x17, 0xec, 0xf9, 0x5d, 0xaf, 0x59, 0x06, 0xfd, 0x71, 0xa1, 0xeb, 0xf9,
|
||||||
|
0xf3, 0x9b, 0x50, 0xe9, 0xa7, 0x1c, 0x87, 0x73, 0x26, 0x84, 0x72, 0xe2,
|
||||||
|
0x6b, 0x0d, 0x29, 0x63, 0x0a, 0xcc, 0xbc, 0xdd, 0xb1, 0x15, 0xfb, 0x8c,
|
||||||
|
0xe6, 0x4b, 0x6c, 0x9e, 0xe9, 0x7a, 0xff, 0xcf, 0xfc, 0xce, 0xb2, 0x6e,
|
||||||
|
0x38, 0xbc, 0xa4, 0xbb, 0xf7, 0x57, 0x18, 0x98, 0x0f, 0x4f, 0x72, 0xef,
|
||||||
|
0x60, 0x90, 0xe5, 0x3e, 0x1f, 0x3e, 0x65, 0x2f, 0x3f, 0xdf, 0xcf, 0x79,
|
||||||
|
0xf3, 0xf9, 0x03, 0x97, 0xde, 0xa7, 0xfb, 0xe4, 0xf4, 0xc3, 0x8c, 0x4a,
|
||||||
|
0x7c, 0x3e, 0xd8, 0xbf, 0xcc, 0xc8, 0xc5, 0x07, 0xe4, 0x9e, 0xe9, 0x7d,
|
||||||
|
0xfe, 0xec, 0xbd, 0xea, 0xde, 0x72, 0xad, 0xae, 0xc7, 0xcc, 0x92, 0xf3,
|
||||||
|
0xbd, 0xa8, 0xc7, 0x4a, 0x9c, 0x39, 0xa9, 0xdc, 0x6b, 0x28, 0x08, 0xce,
|
||||||
|
0x6d, 0x99, 0x57, 0xe1, 0x27, 0x71, 0x5c, 0xce, 0xab, 0xf1, 0xaa, 0x94,
|
||||||
|
0xcb, 0x04, 0x63, 0xcb, 0x4e, 0x3b, 0x78, 0x4d, 0xd7, 0x9c, 0x27, 0x95,
|
||||||
|
0x9b, 0x09, 0x2c, 0xd7, 0xdd, 0x36, 0x4e, 0xce, 0xc1, 0x74, 0x93, 0x39,
|
||||||
|
0x46, 0x2f, 0xbe, 0xf0, 0xee, 0xfd, 0x24, 0xeb, 0x7a, 0xae, 0x92, 0x8b,
|
||||||
|
0xe6, 0x67, 0xd0, 0xa4, 0x47, 0x7d, 0xb9, 0xed, 0x4b, 0x68, 0x61, 0x01,
|
||||||
|
0x01, 0x1f, 0x26, 0x50, 0x09, 0x9c, 0xf5, 0x7b, 0x9b, 0x7b, 0x2e, 0xee,
|
||||||
|
0x3c, 0xb7, 0x9d, 0xe7, 0x4d, 0xea, 0x6f, 0xd9, 0xe5, 0xb8, 0xd4, 0x3b,
|
||||||
|
0x06, 0x73, 0xdc, 0xf2, 0xed, 0xcb, 0xfc, 0xce, 0x45, 0xbf, 0x7a, 0xed,
|
||||||
|
0xad, 0xb5, 0xe4, 0x9c, 0x79, 0xd4, 0x0c, 0xb8, 0x60, 0x5e, 0x5e, 0x03,
|
||||||
|
0xce, 0x34, 0x34, 0x73, 0xfa, 0x9b, 0xcb, 0xc8, 0x88, 0xdb, 0x77, 0x50,
|
||||||
|
0xd3, 0x09, 0xf0, 0xe3, 0xf5, 0x0a, 0xc8, 0x3b, 0xb1, 0x81, 0x14, 0xa6,
|
||||||
|
0x13, 0xe6, 0xca, 0x02, 0xbb, 0x1d, 0xd7, 0x10, 0x23, 0xb9, 0x1f, 0xd8,
|
||||||
|
0x0a, 0x27, 0xd1, 0x81, 0xeb, 0x12, 0xef, 0x57, 0x71, 0xbb, 0xb2, 0xae,
|
||||||
|
0xfb, 0x75, 0xa0, 0xc8, 0xb3, 0x13, 0x93, 0xa1, 0x92, 0xa2, 0xb3, 0xd9,
|
||||||
|
0x85, 0xe4, 0xb2, 0xb3, 0xc5, 0xfb, 0xe2, 0x1c, 0x81, 0xac, 0x24, 0xa8,
|
||||||
|
0x3b, 0x5b, 0x7d, 0x88, 0x7e, 0x90, 0x01, 0x97, 0x92, 0x5f, 0x4c, 0xd2,
|
||||||
|
0xc7, 0x10, 0x32, 0xb9, 0xa1, 0x08, 0x78, 0xb4, 0xe1, 0x9e, 0xe2, 0xce,
|
||||||
|
0xb5, 0x3e, 0xf9, 0xeb, 0x3c, 0x2c, 0x49, 0x26, 0x52, 0xc8, 0xa1, 0x90,
|
||||||
|
0x9b, 0x16, 0x3a, 0xc9, 0x8a, 0x31, 0x81, 0x9f, 0x12, 0x2b, 0x18, 0xea,
|
||||||
|
0x29, 0xa4, 0x98, 0x52, 0xca, 0xa9, 0xa4, 0x9a, 0x5a, 0xea, 0x39, 0xe4,
|
||||||
|
0x68, 0xa8, 0xb0, 0x9c, 0x4b, 0x56, 0xba, 0xed, 0x25, 0x94, 0x58, 0x52,
|
||||||
|
0xc9, 0xa5, 0x94, 0x5a, 0x5a, 0xe9, 0x35, 0xd4, 0x58, 0x53, 0xcd, 0xb5,
|
||||||
|
0xd4, 0x5a, 0x5b, 0xed, 0xcd, 0xb7, 0x00, 0x1b, 0xa7, 0x46, 0x39, 0xb6,
|
||||||
|
0xda, 0x5a, 0xeb, 0x9d, 0x67, 0x76, 0x46, 0xee, 0xd9, 0x74, 0xae, 0xef,
|
||||||
|
0x9c, 0x19, 0x7e, 0x84, 0x11, 0x47, 0x1a, 0x79, 0x94, 0x51, 0x47, 0x1b,
|
||||||
|
0x7d, 0x02, 0x9f, 0x19, 0x67, 0x9a, 0x79, 0x96, 0x59, 0x67, 0x9b, 0x7d,
|
||||||
|
0xf9, 0x15, 0x16, 0x75, 0xbc, 0xf2, 0x2a, 0xab, 0xae, 0xb6, 0xba, 0x38,
|
||||||
|
0x01, 0x4a, 0x12, 0x25, 0x19, 0xc9, 0x52, 0xa4, 0x4a, 0x93, 0xbe, 0xc1,
|
||||||
|
0xda, 0x0e, 0x3b, 0xee, 0xb4, 0xf3, 0x2e, 0xbb, 0xee, 0xb6, 0xfb, 0x33,
|
||||||
|
0x6b, 0xee, 0x2e, 0xdb, 0xcf, 0xaf, 0x3f, 0xc8, 0x9a, 0xbb, 0xb3, 0xe6,
|
||||||
|
0x4f, 0xa6, 0xf4, 0xba, 0xf2, 0xcc, 0x1a, 0x67, 0x4b, 0xb9, 0xde, 0xcd,
|
||||||
|
0xc1, 0x0b, 0x83, 0x68, 0xce, 0xc8, 0x98, 0x8f, 0x8e, 0x8c, 0x17, 0xcd,
|
||||||
|
0x00, 0x80, 0xf6, 0x9a, 0x33, 0x5b, 0x5d, 0x8c, 0x5e, 0x33, 0xa7, 0x39,
|
||||||
|
0xb3, 0xcd, 0x53, 0x15, 0xc9, 0x33, 0xc9, 0xa4, 0xb9, 0x59, 0xce, 0x76,
|
||||||
|
0x97, 0x7d, 0x34, 0x21, 0x8a, 0xf3, 0x69, 0xbb, 0x67, 0xee, 0x7e, 0x64,
|
||||||
|
0xee, 0x8f, 0xf2, 0x66, 0x72, 0xfc, 0x65, 0xde, 0xfc, 0xef, 0x66, 0xce,
|
||||||
|
0x68, 0xea, 0xfe, 0x65, 0xe6, 0x4e, 0xde, 0x8c, 0xa4, 0x0f, 0x79, 0x7b,
|
||||||
|
0x93, 0xb5, 0xa5, 0xdc, 0x3c, 0x4f, 0xc6, 0xae, 0x2a, 0xd4, 0x98, 0xda,
|
||||||
|
0x40, 0xf5, 0xf1, 0xb9, 0xf0, 0xd8, 0xb8, 0xf5, 0xb8, 0x9a, 0x5d, 0xf2,
|
||||||
|
0xde, 0x65, 0xec, 0x6e, 0xfb, 0x5c, 0xbd, 0x89, 0x1b, 0xbd, 0x10, 0xe0,
|
||||||
|
0xde, 0x6b, 0x02, 0xfa, 0x73, 0x87, 0x24, 0x33, 0xc7, 0x54, 0x57, 0x4f,
|
||||||
|
0xd5, 0xcf, 0xd4, 0xfb, 0xd2, 0x09, 0x13, 0xef, 0x3e, 0x1c, 0xc1, 0x5c,
|
||||||
|
0x84, 0x75, 0x11, 0xae, 0x68, 0x58, 0x48, 0x2f, 0x4d, 0x92, 0xef, 0x4a,
|
||||||
|
0x80, 0x76, 0x34, 0xf1, 0x7d, 0xad, 0x22, 0x6d, 0x71, 0x5f, 0x5e, 0xe7,
|
||||||
|
0x67, 0xe7, 0x15, 0x4b, 0x0e, 0xb5, 0x27, 0x52, 0x52, 0x72, 0x76, 0x31,
|
||||||
|
0xf1, 0x5f, 0x49, 0xcd, 0x5f, 0x47, 0x4a, 0xd4, 0xe6, 0x71, 0xf0, 0x67,
|
||||||
|
0xef, 0xd9, 0xe9, 0xbb, 0x4b, 0xbb, 0x16, 0x27, 0x0d, 0xc2, 0xec, 0x66,
|
||||||
|
0xce, 0x01, 0xa1, 0xa7, 0x56, 0xe1, 0xfe, 0x2e, 0x3c, 0x75, 0x14, 0xe2,
|
||||||
|
0x02, 0x1a, 0x76, 0x49, 0xba, 0x7a, 0xef, 0xb6, 0x84, 0xd4, 0x06, 0x33,
|
||||||
|
0x18, 0x8e, 0x49, 0x6e, 0xe6, 0x54, 0x7d, 0xd7, 0x05, 0xd7, 0x91, 0xf2,
|
||||||
|
0x86, 0x02, 0x5a, 0xf2, 0x75, 0x9a, 0xb6, 0x56, 0x1b, 0xe3, 0x9a, 0xab,
|
||||||
|
0x0c, 0x0f, 0x4e, 0xcf, 0xb3, 0xe2, 0x9f, 0xbe, 0x9b, 0xe7, 0x09, 0x57,
|
||||||
|
0x53, 0x22, 0x65, 0x5b, 0xa6, 0x84, 0xbd, 0x7d, 0x24, 0xcc, 0xc8, 0xcb,
|
||||||
|
0x20, 0x07, 0x4d, 0x67, 0x06, 0x5a, 0x7c, 0xdf, 0xad, 0xfa, 0x21, 0xe7,
|
||||||
|
0xef, 0xd5, 0x66, 0xd9, 0x12, 0x9b, 0x64, 0x24, 0x84, 0xbf, 0x0d, 0xab,
|
||||||
|
0x6d, 0xdc, 0x18, 0x15, 0xa9, 0xd7, 0x8a, 0x6b, 0x91, 0xe5, 0xd6, 0x59,
|
||||||
|
0x16, 0xa3, 0x31, 0x34, 0x47, 0x3a, 0x5e, 0xd9, 0x9b, 0xb1, 0xd2, 0x3d,
|
||||||
|
0x9a, 0x94, 0xed, 0x7c, 0xa9, 0x69, 0xc4, 0xbc, 0x49, 0x40, 0x33, 0xdc,
|
||||||
|
0x53, 0xf3, 0x68, 0xb9, 0xec, 0x3c, 0x46, 0xaa, 0x92, 0x28, 0x31, 0xd2,
|
||||||
|
0x08, 0x17, 0x88, 0x9b, 0x5a, 0xad, 0x13, 0x76, 0x2c, 0x34, 0x22, 0x7b,
|
||||||
|
0xca, 0x68, 0x0c, 0x06, 0x2c, 0xd2, 0xb6, 0x00, 0x4e, 0x6a, 0x12, 0x7d,
|
||||||
|
0xc8, 0x6c, 0x6b, 0xd4, 0x6d, 0x08, 0x65, 0x63, 0x5d, 0xdb, 0xdb, 0x94,
|
||||||
|
0x47, 0x62, 0xd6, 0xb3, 0x74, 0x5f, 0x58, 0x1d, 0xf7, 0xf9, 0xdc, 0x53,
|
||||||
|
0x1c, 0x54, 0x41, 0x88, 0x00, 0x8b, 0x21, 0xdc, 0x52, 0xe5, 0x2c, 0x5c,
|
||||||
|
0x67, 0x25, 0xf3, 0x91, 0x87, 0x22, 0xa6, 0x42, 0x2b, 0x2e, 0x88, 0xcd,
|
||||||
|
0x65, 0xf0, 0x59, 0x4a, 0xdc, 0x7d, 0xa4, 0x55, 0xa7, 0x00, 0xa8, 0xb9,
|
||||||
|
0x52, 0xa3, 0xd6, 0x59, 0xad, 0xa3, 0x68, 0x6a, 0xcb, 0x64, 0xb5, 0x8f,
|
||||||
|
0x41, 0x5d, 0xae, 0xb9, 0xe1, 0x87, 0xd2, 0xc7, 0x8e, 0x7d, 0x0e, 0x28,
|
||||||
|
0x2c, 0x6e, 0x07, 0xc8, 0xd6, 0x30, 0xc9, 0x47, 0xca, 0x87, 0x21, 0x98,
|
||||||
|
0x65, 0x9e, 0xe2, 0x1b, 0x85, 0x95, 0x56, 0xab, 0x17, 0x4e, 0x56, 0x8f,
|
||||||
|
0xf5, 0xff, 0x9f, 0xb5, 0x26, 0xf3, 0x01, 0xe0, 0x32, 0xa7, 0x5e, 0xc5,
|
||||||
|
0xd0, 0x42, 0xbf, 0xa0, 0xc3, 0xd9, 0x06, 0xa1, 0xe8, 0x11, 0xa3, 0x64,
|
||||||
|
0x7d, 0x07, 0xad, 0x94, 0xfd, 0x16, 0xe3, 0xdb, 0xb6, 0x6b, 0x49, 0xa9,
|
||||||
|
0xb1, 0xcc, 0x08, 0x0d, 0x75, 0x32, 0x3f, 0x1b, 0xbd, 0x7b, 0x21, 0xf8,
|
||||||
|
0x23, 0x14, 0xba, 0xdb, 0x19, 0x39, 0x39, 0x2b, 0xb8, 0xb7, 0xb1, 0x6a,
|
||||||
|
0x06, 0xad, 0xac, 0xb4, 0x4b, 0x58, 0x30, 0x8b, 0xdb, 0x6e, 0xe8, 0xcc,
|
||||||
|
0xba, 0xd1, 0xac, 0xeb, 0xc8, 0xf9, 0xa4, 0x72, 0x77, 0x0d, 0x1e, 0xcf,
|
||||||
|
0xb3, 0x8b, 0x12, 0xf7, 0xd3, 0x79, 0x35, 0x05, 0x91, 0x05, 0x55, 0x2d,
|
||||||
|
0xe6, 0xbd, 0x73, 0x8d, 0x69, 0x53, 0xd4, 0x7b, 0x32, 0xb1, 0xba, 0x72,
|
||||||
|
0x5e, 0x4e, 0xab, 0xc5, 0x0e, 0x13, 0xd6, 0x4c, 0x62, 0x7b, 0xa3, 0x92,
|
||||||
|
0xba, 0x87, 0x22, 0x68, 0x80, 0x24, 0xc5, 0x1e, 0x60, 0xf5, 0x9c, 0x41,
|
||||||
|
0xe6, 0x29, 0x4d, 0xe2, 0x34, 0xbf, 0x29, 0x64, 0xf3, 0xb6, 0xb2, 0xcb,
|
||||||
|
0x0a, 0x07, 0xcf, 0x81, 0x46, 0x6d, 0xb6, 0x30, 0x57, 0x04, 0x7f, 0xd3,
|
||||||
|
0x53, 0x8a, 0xc0, 0x10, 0x36, 0x1d, 0x92, 0x6d, 0xdf, 0x9d, 0x60, 0xe5,
|
||||||
|
0x72, 0x42, 0xdd, 0xbc, 0x01, 0xc4, 0x4c, 0x72, 0x55, 0x5a, 0x5a, 0xe8,
|
||||||
|
0x10, 0x76, 0xa0, 0x76, 0x1d, 0xa0, 0xcc, 0x65, 0x7c, 0x4e, 0xb4, 0x93,
|
||||||
|
0x6b, 0x78, 0x42, 0x79, 0x0d, 0x1f, 0xf6, 0x19, 0xfe, 0xca, 0x1a, 0x4f,
|
||||||
|
0x68, 0xf9, 0x7a, 0xc2, 0x68, 0x00, 0x15, 0x8e, 0x64, 0xdd, 0x03, 0x2c,
|
||||||
|
0x75, 0x74, 0x20, 0xbb, 0x2e, 0xc0, 0x1d, 0x62, 0x5e, 0x99, 0x0a, 0x00,
|
||||||
|
0xc6, 0xe4, 0x7b, 0x4c, 0x94, 0x41, 0xbb, 0x44, 0x18, 0x32, 0x3a, 0xa9,
|
||||||
|
0xe0, 0x20, 0x74, 0x38, 0xfb, 0x24, 0xd1, 0x91, 0x26, 0x78, 0xfe, 0xa4,
|
||||||
|
0xd8, 0x95, 0x13, 0x7e, 0x5f, 0xb2, 0x4e, 0x81, 0xf2, 0x53, 0x1c, 0x54,
|
||||||
|
0x97, 0xfa, 0xa2, 0x22, 0xa9, 0xc1, 0xda, 0x20, 0x74, 0xee, 0x9d, 0xad,
|
||||||
|
0x43, 0x45, 0x92, 0x73, 0x5d, 0x08, 0x24, 0xeb, 0x75, 0xa8, 0x15, 0xa2,
|
||||||
|
0x96, 0x78, 0x6a, 0x0c, 0x8d, 0xcf, 0x14, 0xfb, 0x94, 0xee, 0x48, 0x28,
|
||||||
|
0x1b, 0x48, 0x57, 0xe5, 0x58, 0x2b, 0x48, 0x5f, 0xf0, 0x2d, 0x5c, 0x6d,
|
||||||
|
0x4b, 0x20, 0x10, 0x79, 0x12, 0x06, 0x7e, 0x8b, 0x78, 0xb4, 0x29, 0x1b,
|
||||||
|
0xcf, 0xac, 0xa9, 0x2b, 0x50, 0x61, 0x41, 0x56, 0xdf, 0xcb, 0x6b, 0x29,
|
||||||
|
0x12, 0xed, 0x59, 0x92, 0x53, 0xb2, 0x6e, 0x21, 0x0e, 0xa4, 0x87, 0xb0,
|
||||||
|
0x50, 0x77, 0x95, 0xd2, 0xfc, 0x48, 0xdb, 0xf9, 0x49, 0xdb, 0xe6, 0x57,
|
||||||
|
0xb4, 0x7c, 0x92, 0x77, 0x52, 0xa7, 0x64, 0xf1, 0xab, 0xe4, 0x69, 0x89,
|
||||||
|
0x68, 0xfe, 0x9a, 0x7f, 0x49, 0x1e, 0x95, 0xf4, 0xcb, 0xf4, 0x3d, 0xd3,
|
||||||
|
0xb8, 0x03, 0xa5, 0x32, 0x03, 0x8f, 0xaa, 0x66, 0x2a, 0x43, 0xf9, 0xa4,
|
||||||
|
0x95, 0x77, 0x58, 0xb1, 0x9d, 0x40, 0xd7, 0x95, 0x0a, 0x47, 0xac, 0x64,
|
||||||
|
0x86, 0x82, 0x5a, 0x39, 0x4a, 0xc1, 0x51, 0x49, 0x95, 0x25, 0xd2, 0x67,
|
||||||
|
0xf8, 0xb4, 0x52, 0x97, 0xb9, 0x64, 0xa3, 0x97, 0x9e, 0x93, 0xde, 0x9b,
|
||||||
|
0x51, 0xa9, 0x03, 0xab, 0x49, 0x0c, 0x83, 0xb5, 0x4c, 0x74, 0x16, 0x8b,
|
||||||
|
0x84, 0x9a, 0xe9, 0x3c, 0x07, 0x79, 0x57, 0x5b, 0x70, 0x06, 0x17, 0x16,
|
||||||
|
0xa7, 0x0e, 0x64, 0x86, 0xd4, 0x7f, 0xd6, 0x1e, 0xf3, 0x77, 0xe2, 0xf3,
|
||||||
|
0xb3, 0xf6, 0x98, 0x6f, 0x68, 0xeb, 0xb7, 0x59, 0xca, 0xbc, 0xa7, 0xa9,
|
||||||
|
0x5f, 0xb2, 0xd4, 0xdb, 0x77, 0xa3, 0xb0, 0x55, 0x0f, 0x75, 0x14, 0xe8,
|
||||||
|
0xd6, 0x1f, 0xe8, 0xe4, 0xd6, 0x9f, 0xf3, 0xcc, 0xaf, 0x14, 0xe8, 0x45,
|
||||||
|
0x80, 0xcc, 0xef, 0x28, 0x10, 0x59, 0x7c, 0xd5, 0xa0, 0x4b, 0x81, 0x0e,
|
||||||
|
0x3f, 0x3e, 0x24, 0xc8, 0x5c, 0x1a, 0x04, 0xe0, 0xfe, 0x4e, 0x85, 0x9e,
|
||||||
|
0x22, 0x64, 0xfe, 0xa5, 0x0a, 0x3d, 0x45, 0xc8, 0xe8, 0x6c, 0x7e, 0x4f,
|
||||||
|
0x87, 0x1e, 0x09, 0x64, 0x41, 0xf3, 0x62, 0xa6, 0x47, 0x12, 0x55, 0xd2,
|
||||||
|
0xcd, 0xc9, 0xe3, 0xab, 0xd6, 0xbc, 0xa6, 0xf0, 0x4e, 0x20, 0xde, 0xe7,
|
||||||
|
0x97, 0x29, 0x34, 0x5f, 0xe5, 0xf4, 0x56, 0x22, 0xfb, 0xd4, 0xa2, 0x87,
|
||||||
|
0x12, 0x5d, 0x3a, 0xf4, 0x50, 0xa1, 0xa7, 0x08, 0x99, 0xbf, 0x52, 0x21,
|
||||||
|
0xd8, 0x95, 0x62, 0x98, 0x64, 0x87, 0x10, 0x45, 0x1d, 0x2e, 0x1b, 0x6e,
|
||||||
|
0x6a, 0x99, 0xbc, 0xef, 0x95, 0xb2, 0x28, 0xb5, 0x6d, 0x8f, 0x69, 0x82,
|
||||||
|
0x9c, 0x74, 0x53, 0x8a, 0x43, 0x6f, 0x29, 0x46, 0xcc, 0x31, 0x0e, 0x17,
|
||||||
|
0x63, 0x56, 0xb9, 0xbb, 0xda, 0x30, 0x07, 0x6c, 0x99, 0xe9, 0x4e, 0x21,
|
||||||
|
0xc1, 0x89, 0xe5, 0x48, 0xc5, 0x99, 0x99, 0xd2, 0x8c, 0x03, 0xfa, 0x5c,
|
||||||
|
0x64, 0x93, 0x18, 0x45, 0x02, 0x14, 0x5d, 0x1c, 0x08, 0x14, 0x68, 0x83,
|
||||||
|
0x35, 0xe9, 0x5a, 0x17, 0x9c, 0x4b, 0xaa, 0x71, 0x84, 0x30, 0x3d, 0xfe,
|
||||||
|
0x60, 0xe2, 0xc2, 0x75, 0xea, 0x20, 0x8f, 0xb9, 0x4c, 0xdd, 0x92, 0x49,
|
||||||
|
0x06, 0x4b, 0x8b, 0x66, 0x61, 0x16, 0xa9, 0xcb, 0x11, 0x3a, 0xd5, 0x4c,
|
||||||
|
0x66, 0x9b, 0x96, 0x21, 0x4b, 0x01, 0xca, 0x7d, 0x43, 0x12, 0x73, 0xca,
|
||||||
|
0x76, 0x98, 0x85, 0xc4, 0xdc, 0x56, 0x50, 0x34, 0x2b, 0x25, 0x8c, 0x05,
|
||||||
|
0x9a, 0x4a, 0x94, 0x80, 0x1e, 0x36, 0xda, 0x63, 0xb2, 0x51, 0xa4, 0xcc,
|
||||||
|
0x53, 0xfd, 0x61, 0x25, 0xd0, 0xbb, 0xbb, 0xa3, 0x6d, 0xcf, 0x76, 0x82,
|
||||||
|
0x78, 0x7c, 0xaa, 0x74, 0x0f, 0x7e, 0x00, 0xe6, 0xb1, 0x18, 0x68, 0x2d,
|
||||||
|
0x59, 0x8c, 0x10, 0x62, 0x6a, 0xd8, 0x99, 0xda, 0x7d, 0xa5, 0xd3, 0x8e,
|
||||||
|
0xe6, 0xdf, 0xc9, 0xe2, 0x0f, 0x62, 0x35, 0xdf, 0xca, 0xe2, 0x77, 0xef,
|
||||||
|
0xb7, 0x6c, 0x9a, 0xf7, 0xba, 0xf9, 0xe7, 0xb2, 0x69, 0xde, 0xeb, 0xe6,
|
||||||
|
0x3e, 0x4f, 0x71, 0xb9, 0x4c, 0x6f, 0x31, 0xe6, 0x19, 0x2c, 0x83, 0xbb,
|
||||||
|
0xe2, 0x79, 0xd4, 0x8e, 0x7e, 0x7b, 0x51, 0x91, 0x8b, 0x9b, 0x7a, 0x44,
|
||||||
|
0x4e, 0xf7, 0x48, 0x53, 0x4c, 0xc9, 0x98, 0x29, 0xc4, 0x2e, 0x8a, 0x1d,
|
||||||
|
0x62, 0x05, 0xbb, 0xb8, 0x32, 0x48, 0x91, 0x44, 0x08, 0x49, 0x23, 0x4a,
|
||||||
|
0xbb, 0x63, 0x44, 0xe8, 0x76, 0x03, 0x63, 0x2b, 0x82, 0x8a, 0x10, 0x62,
|
||||||
|
0x46, 0x4e, 0xa1, 0x15, 0x7c, 0x1a, 0xc6, 0xa9, 0x43, 0x47, 0x1e, 0x1c,
|
||||||
|
0x31, 0xaf, 0x4c, 0x09, 0xa1, 0xb0, 0x58, 0x1f, 0xd8, 0x5a, 0xfc, 0xc2,
|
||||||
|
0x02, 0x0a, 0x45, 0xa7, 0x18, 0x77, 0x6d, 0x25, 0x3c, 0x24, 0x56, 0x0e,
|
||||||
|
0x6c, 0xd6, 0xde, 0x03, 0x9e, 0xd0, 0x21, 0xc5, 0x81, 0xa8, 0xe6, 0x59,
|
||||||
|
0x17, 0x26, 0x08, 0x4e, 0xdf, 0xa9, 0x40, 0xb5, 0xa9, 0xc1, 0x43, 0xd8,
|
||||||
|
0xb5, 0xd0, 0xeb, 0x1e, 0xb9, 0xc7, 0xd6, 0xd5, 0x48, 0x8d, 0x2d, 0x4a,
|
||||||
|
0xc0, 0x29, 0x54, 0x2c, 0xe0, 0x08, 0x56, 0xb3, 0xec, 0xe1, 0xfb, 0xc6,
|
||||||
|
0xe1, 0xbb, 0xd2, 0x36, 0xaf, 0xb5, 0x1d, 0xec, 0xf7, 0x20, 0xd8, 0xf0,
|
||||||
|
0xe2, 0x0a, 0x01, 0x1b, 0x76, 0x30, 0xa4, 0x9b, 0xa7, 0xbc, 0x9b, 0xc7,
|
||||||
|
0xc1, 0xfd, 0x3e, 0x9c, 0x6c, 0x92, 0xa3, 0x06, 0x70, 0x05, 0xa2, 0x1a,
|
||||||
|
0x61, 0x38, 0x3a, 0x10, 0x9b, 0x5b, 0xc2, 0xc4, 0x26, 0x72, 0x8d, 0x64,
|
||||||
|
0x86, 0x25, 0xb3, 0xe0, 0x10, 0x25, 0x5a, 0xaf, 0x98, 0x15, 0x5c, 0xb3,
|
||||||
|
0x81, 0x9d, 0xb7, 0x6e, 0x39, 0x2e, 0x1d, 0xa5, 0x5d, 0xb6, 0x32, 0xca,
|
||||||
|
0x56, 0x0e, 0xd1, 0x79, 0x62, 0x20, 0xaf, 0x2e, 0xb6, 0x06, 0xa7, 0x07,
|
||||||
|
0x1a, 0xa6, 0x2d, 0x8e, 0xd1, 0xb9, 0x6f, 0x2f, 0xbb, 0x8a, 0x2e, 0x4c,
|
||||||
|
0xec, 0xa4, 0x3d, 0x3e, 0xb8, 0xf1, 0x9d, 0x54, 0x61, 0x47, 0xff, 0x7a,
|
||||||
|
0x30, 0xa3, 0xa3, 0x7d, 0x1a, 0x4c, 0x49, 0xd9, 0x4b, 0x1b, 0x54, 0x67,
|
||||||
|
0x10, 0x58, 0x17, 0x82, 0x1d, 0x83, 0x1a, 0xa3, 0xcf, 0x1a, 0x6b, 0xf8,
|
||||||
|
0xd6, 0x97, 0xd0, 0x37, 0xe9, 0x86, 0x05, 0x39, 0xb5, 0x58, 0x7a, 0x60,
|
||||||
|
0xd8, 0x0c, 0xce, 0x97, 0x1a, 0xed, 0xa7, 0x37, 0x69, 0x6b, 0x57, 0xc5,
|
||||||
|
0x37, 0xfc, 0xb1, 0xec, 0xbe, 0xd8, 0xfc, 0x6a, 0xd4, 0xa9, 0xfd, 0x78,
|
||||||
|
0x98, 0xac, 0xc8, 0xf5, 0x37, 0xb7, 0xa0, 0xdf, 0xa4, 0xc3, 0xd1, 0x34,
|
||||||
|
0x9c, 0x12, 0x81, 0x8f, 0x54, 0x22, 0x9f, 0xed, 0xc9, 0xdf, 0x76, 0x27,
|
||||||
|
0xe6, 0x73, 0x7b, 0xf2, 0xa9, 0x3b, 0x39, 0x32, 0xf8, 0xcd, 0x5c, 0xe9,
|
||||||
|
0x5f, 0x66, 0x61, 0x46, 0x7b, 0xd0, 0x95, 0xdd, 0xcc, 0x7b, 0x11, 0x6f,
|
||||||
|
0x29, 0x36, 0xad, 0x85, 0xbe, 0x90, 0x57, 0x3a, 0x4e, 0xa2, 0x11, 0x6b,
|
||||||
|
0x5d, 0xb5, 0x7a, 0xfa, 0x2a, 0x48, 0xea, 0x23, 0xe9, 0x56, 0x41, 0x36,
|
||||||
|
0x5b, 0x26, 0x46, 0x00, 0xc5, 0xea, 0x16, 0x0d, 0xc0, 0x80, 0x79, 0x3d,
|
||||||
|
0xca, 0x54, 0x0a, 0xab, 0xed, 0xda, 0xc5, 0xa1, 0xb0, 0x09, 0x6a, 0x26,
|
||||||
|
0xe2, 0xdf, 0xf3, 0xa6, 0x79, 0x4f, 0x9c, 0x5f, 0xf1, 0x66, 0x69, 0x47,
|
||||||
|
0x3e, 0x76, 0x3a, 0x42, 0x09, 0xd5, 0xc3, 0x63, 0xc4, 0x8e, 0x2a, 0x35,
|
||||||
|
0xa7, 0x53, 0x90, 0x1d, 0xe9, 0xa8, 0xa0, 0xfe, 0x99, 0xc3, 0x1f, 0xb5,
|
||||||
|
0xa0, 0x3f, 0x3a, 0x50, 0xf3, 0xa6, 0x05, 0xa5, 0x35, 0xe9, 0xf1, 0x2d,
|
||||||
|
0x55, 0xa6, 0xcb, 0xa3, 0xb1, 0x32, 0xaa, 0xb9, 0xcf, 0xad, 0xde, 0xcc,
|
||||||
|
0x0d, 0x08, 0x61, 0x33, 0x23, 0x64, 0x72, 0x35, 0x2f, 0x1d, 0xb2, 0x71,
|
||||||
|
0x1e, 0x2a, 0xdb, 0xbe, 0x79, 0x16, 0xe9, 0xaa, 0x44, 0x1f, 0xb3, 0xee,
|
||||||
|
0x3b, 0x2e, 0x5d, 0x25, 0xc2, 0xea, 0x14, 0xb7, 0x40, 0x53, 0xfc, 0x01,
|
||||||
|
0x30, 0x3e, 0x2a, 0x5c, 0xcc, 0x4d, 0x4f, 0xb8, 0x8d, 0x7e, 0x9f, 0x90,
|
||||||
|
0x45, 0xa9, 0x6c, 0x6c, 0x22, 0xcc, 0x7b, 0xc8, 0xd7, 0xa2, 0xd0, 0x34,
|
||||||
|
0x1e, 0x25, 0x6b, 0x5d, 0x85, 0xa2, 0x3c, 0xc3, 0x15, 0x42, 0x63, 0xb4,
|
||||||
|
0xd0, 0x6a, 0x97, 0x01, 0x84, 0xaa, 0x74, 0x9f, 0xda, 0xd0, 0x64, 0xd3,
|
||||||
|
0x57, 0x0f, 0x65, 0x75, 0xd2, 0x45, 0x93, 0x22, 0x39, 0x8e, 0x9d, 0x7b,
|
||||||
|
0x6b, 0xa8, 0xce, 0x22, 0x75, 0x81, 0x60, 0xaa, 0x0b, 0xd4, 0xef, 0x6b,
|
||||||
|
0x4e, 0x3f, 0xa0, 0x1d, 0x3f, 0x72, 0xce, 0x01, 0xe8, 0x04, 0xe6, 0x78,
|
||||||
|
0x39, 0x80, 0x50, 0x43, 0x9e, 0x86, 0xfe, 0x2b, 0x86, 0xa5, 0x71, 0x86,
|
||||||
|
0x25, 0x68, 0xb1, 0x00, 0x0d, 0x04, 0xcb, 0xc8, 0xf0, 0x94, 0xaf, 0x70,
|
||||||
|
0xbb, 0x6d, 0x54, 0x6a, 0xf6, 0xa1, 0xc3, 0x7b, 0xb3, 0x8f, 0x09, 0x56,
|
||||||
|
0xb5, 0x21, 0x1c, 0x89, 0x5b, 0x74, 0xef, 0x49, 0xb3, 0x3a, 0xcf, 0xd2,
|
||||||
|
0x52, 0xa0, 0x63, 0xaa, 0x72, 0x0a, 0x42, 0xc8, 0xaf, 0x74, 0xf4, 0x03,
|
||||||
|
0xfe, 0x62, 0x4a, 0x93, 0xb5, 0x85, 0x19, 0x84, 0x16, 0x04, 0xef, 0xd9,
|
||||||
|
0x6a, 0x59, 0xd9, 0x7b, 0xa8, 0x5b, 0x9d, 0xd2, 0xce, 0x61, 0x9c, 0xcc,
|
||||||
|
0x35, 0x80, 0xd5, 0x9b, 0xe9, 0xe1, 0x1a, 0x98, 0x58, 0xe9, 0xc0, 0x3a,
|
||||||
|
0xea, 0xee, 0x1a, 0xea, 0x4d, 0xaf, 0x52, 0xd6, 0xe5, 0x74, 0x9b, 0xa3,
|
||||||
|
0x4c, 0x27, 0xba, 0xd3, 0x3e, 0x4c, 0xe5, 0xc3, 0x1d, 0xcc, 0xc3, 0x30,
|
||||||
|
0x91, 0x7b, 0x1a, 0x00, 0x27, 0xc5, 0xa0, 0xed, 0x0d, 0x6d, 0xe7, 0xb8,
|
||||||
|
0x42, 0xec, 0x49, 0x50, 0xaa, 0x28, 0x43, 0x88, 0x48, 0xc1, 0x3d, 0xf1,
|
||||||
|
0xe7, 0xf5, 0xc3, 0xad, 0x53, 0xd2, 0x13, 0xf5, 0x32, 0x8b, 0x89, 0x72,
|
||||||
|
0x9a, 0x68, 0x8c, 0x4d, 0x55, 0xef, 0xcb, 0xf4, 0x49, 0x8c, 0xa4, 0x51,
|
||||||
|
0xf7, 0x34, 0xb3, 0xca, 0xd2, 0xcb, 0x2d, 0xe7, 0x8e, 0x6b, 0x5d, 0xd7,
|
||||||
|
0xaa, 0xa0, 0xb9, 0x85, 0x39, 0x7e, 0x8d, 0xc3, 0x33, 0x0c, 0x7f, 0x8a,
|
||||||
|
0x6f, 0xf3, 0x95, 0xc5, 0x42, 0xee, 0xc6, 0xc7, 0x56, 0xf1, 0xd1, 0xe8,
|
||||||
|
0xd5, 0x45, 0xd2, 0xc7, 0x49, 0x7a, 0x15, 0x4a, 0x8b, 0x85, 0x0c, 0xaa,
|
||||||
|
0x93, 0x26, 0x62, 0x68, 0x7b, 0xdc, 0xc6, 0x42, 0x64, 0x71, 0xfb, 0x4f,
|
||||||
|
0x4e, 0x0a, 0x9e, 0x5a, 0xd5, 0xc4, 0x77, 0xf9, 0x82, 0xee, 0x9f, 0x04,
|
||||||
|
0x3d, 0x04, 0x6f, 0x60, 0xea, 0x58, 0xf4, 0x5e, 0x24, 0x8a, 0xf2, 0x41,
|
||||||
|
0xad, 0xf3, 0x86, 0x00, 0x9a, 0xf8, 0x31, 0x55, 0x0b, 0x91, 0xd2, 0x16,
|
||||||
|
0x60, 0x86, 0xda, 0x94, 0x12, 0xb9, 0x17, 0x17, 0xdd, 0x8a, 0x57, 0x65,
|
||||||
|
0xf7, 0x78, 0x5c, 0x6c, 0xac, 0x8b, 0x72, 0x7a, 0x26, 0xfc, 0x1a, 0xed,
|
||||||
|
0x2a, 0x2e, 0x0a, 0x0e, 0xda, 0x14, 0x9a, 0xf8, 0x29, 0x95, 0x2a, 0x21,
|
||||||
|
0x71, 0x40, 0x5e, 0x5a, 0xe9, 0xf4, 0x1f, 0x18, 0x01, 0xa2, 0xcc, 0xe2,
|
||||||
|
0x7a, 0x82, 0x8e, 0xd3, 0x42, 0xfa, 0x3b, 0xde, 0x00, 0x8c, 0x8a, 0xcd,
|
||||||
|
0x6a, 0x98, 0xdb, 0x1c, 0xd5, 0xc8, 0x82, 0xe3, 0x90, 0xbd, 0x28, 0xc8,
|
||||||
|
0x04, 0x56, 0x81, 0xde, 0xbf, 0x51, 0x40, 0xc0, 0xb9, 0xe7, 0x45, 0x17,
|
||||||
|
0xef, 0x93, 0x55, 0x0b, 0x0c, 0xfd, 0x21, 0x54, 0x44, 0xf2, 0xb4, 0xf3,
|
||||||
|
0xfe, 0x67, 0x23, 0x64, 0xbe, 0x70, 0x42, 0x20, 0x1b, 0x9c, 0x20, 0xa2,
|
||||||
|
0x9c, 0x81, 0x2e, 0x5c, 0x56, 0x4f, 0x19, 0x51, 0x5f, 0x21, 0xc2, 0xbd,
|
||||||
|
0x30, 0x2d, 0xd1, 0x15, 0xd1, 0x20, 0x39, 0x44, 0xb8, 0xfa, 0x6d, 0x2e,
|
||||||
|
0x43, 0xa8, 0x1b, 0x43, 0x08, 0x13, 0x1d, 0x2b, 0x9e, 0x91, 0x16, 0xa0,
|
||||||
|
0xab, 0xf6, 0x00, 0xfe, 0x7b, 0xd7, 0xc8, 0xa5, 0x90, 0xce, 0xe6, 0xc2,
|
||||||
|
0x74, 0x25, 0x2e, 0xdd, 0x7c, 0x5f, 0xfa, 0xc5, 0x62, 0xd5, 0xf2, 0xdb,
|
||||||
|
0x95, 0x7e, 0xa3, 0x74, 0xc3, 0x2d, 0x3c, 0xca, 0x37, 0x35, 0x35, 0x15,
|
||||||
|
0xeb, 0x43, 0x14, 0x97, 0xfa, 0xcb, 0xc5, 0xe0, 0x3c, 0x36, 0xcb, 0xd2,
|
||||||
|
0x56, 0x11, 0x51, 0xd9, 0x94, 0xf8, 0xb2, 0x97, 0xfd, 0xcc, 0xdd, 0x5f,
|
||||||
|
0xed, 0xc9, 0xa9, 0xdf, 0xf3, 0x6e, 0x1e, 0x07, 0x8f, 0x6e, 0xe5, 0x1b,
|
||||||
|
0x37, 0xf9, 0x68, 0x57, 0x7e, 0x82, 0xaa, 0xf9, 0xa2, 0x5f, 0xd9, 0xa1,
|
||||||
|
0x1c, 0xec, 0x79, 0x1a, 0x35, 0xfa, 0xbf, 0x40, 0xb3, 0xa4, 0x7d, 0xc9,
|
||||||
|
0xb2, 0xb2, 0xc3, 0x2b, 0xe3, 0xa8, 0x43, 0xc8, 0x09, 0xa5, 0x2d, 0xde,
|
||||||
|
0xa1, 0x57, 0x20, 0x43, 0xb4, 0x37, 0xa0, 0xfb, 0xb2, 0xf5, 0xf2, 0x8c,
|
||||||
|
0x54, 0x17, 0x45, 0xaf, 0xa2, 0xa8, 0xdf, 0x45, 0x91, 0xb8, 0x72, 0x79,
|
||||||
|
0x46, 0xb5, 0xec, 0xd4, 0xd8, 0xbd, 0xe7, 0x62, 0xed, 0xb5, 0xeb, 0x72,
|
||||||
|
0xfc, 0x5a, 0x78, 0x70, 0xc9, 0x4d, 0x52, 0xca, 0x51, 0x09, 0xe7, 0xe5,
|
||||||
|
0xa7, 0x36, 0x8b, 0x10, 0xb7, 0xee, 0xc2, 0x24, 0x24, 0x4f, 0x22, 0x44,
|
||||||
|
0xa7, 0xdf, 0xe5, 0x3d, 0x2c, 0x64, 0x8b, 0xe9, 0xf2, 0x90, 0xd9, 0x90,
|
||||||
|
0xe3, 0xb2, 0x92, 0x67, 0x20, 0xaf, 0x4d, 0x24, 0xe8, 0xc3, 0x10, 0x2d,
|
||||||
|
0x2d, 0xbe, 0x59, 0x46, 0x3f, 0xea, 0xb5, 0xb4, 0x30, 0x72, 0x5e, 0xba,
|
||||||
|
0xe3, 0xe2, 0x7c, 0xc4, 0x53, 0x26, 0x32, 0x9c, 0xf1, 0x49, 0x99, 0x35,
|
||||||
|
0x5c, 0xc4, 0x30, 0xcd, 0xc5, 0x0b, 0xe0, 0x70, 0x15, 0xbb, 0x33, 0x1d,
|
||||||
|
0x1b, 0x1d, 0x57, 0x49, 0xbd, 0xc5, 0xee, 0xe9, 0x2e, 0x75, 0xd7, 0x4d,
|
||||||
|
0xbb, 0x49, 0x8c, 0xa5, 0xee, 0xcd, 0x57, 0xfa, 0xdf, 0xc9, 0xa3, 0x81,
|
||||||
|
0xb6, 0xea, 0x04, 0x25, 0xc8, 0x3a, 0xa6, 0x76, 0x25, 0xc8, 0x91, 0xb6,
|
||||||
|
0x4e, 0x3c, 0xe6, 0x22, 0x32, 0xc0, 0x5d, 0xd6, 0x65, 0xf8, 0x46, 0x49,
|
||||||
|
0x88, 0xaf, 0xea, 0x84, 0x26, 0x21, 0xd2, 0xdd, 0x0e, 0xb8, 0x0d, 0x94,
|
||||||
|
0x46, 0x35, 0xa4, 0x42, 0x4f, 0x82, 0x88, 0xd1, 0x56, 0xaf, 0x35, 0x72,
|
||||||
|
0x2e, 0xc9, 0xe8, 0x17, 0x96, 0x4f, 0xa1, 0x40, 0xa4, 0xa5, 0x30, 0xb9,
|
||||||
|
0xfa, 0xdc, 0x8e, 0xb1, 0x8f, 0xbd, 0xe0, 0x4f, 0x3e, 0x7c, 0x28, 0xe0,
|
||||||
|
0xf1, 0x91, 0x78, 0x2f, 0xac, 0x32, 0x37, 0x99, 0x8d, 0x5f, 0xd3, 0x1d,
|
||||||
|
0x91, 0x7d, 0x9a, 0x59, 0xbd, 0xcc, 0x67, 0x57, 0x61, 0x1b, 0x80, 0x74,
|
||||||
|
0x9a, 0x54, 0xca, 0x0b, 0x37, 0xfa, 0x19, 0x7f, 0x1f, 0xe1, 0x07, 0x90,
|
||||||
|
0x84, 0x86, 0x1d, 0x8d, 0xb2, 0xba, 0x4b, 0x0d, 0x9a, 0x1c, 0xea, 0xb7,
|
||||||
|
0x80, 0xd5, 0xa0, 0x3d, 0x58, 0xfa, 0x18, 0x7c, 0xf8, 0xdc, 0x34, 0x09,
|
||||||
|
0xa8, 0x18, 0xd1, 0xc3, 0x75, 0x70, 0x86, 0xfe, 0x86, 0xe8, 0xd3, 0x89,
|
||||||
|
0x10, 0x6c, 0x81, 0x6d, 0x84, 0xda, 0x77, 0x63, 0x98, 0x4a, 0x1a, 0x03,
|
||||||
|
0x25, 0x95, 0x2c, 0x0c, 0x01, 0xeb, 0x45, 0x60, 0x75, 0x36, 0x62, 0x60,
|
||||||
|
0x3b, 0x69, 0xba, 0x0d, 0xa4, 0x73, 0x87, 0xac, 0xfa, 0x85, 0xae, 0xe6,
|
||||||
|
0xf4, 0x9b, 0xdf, 0x7e, 0xc4, 0x3a, 0xf3, 0x50, 0x84, 0x1f, 0x39, 0xf5,
|
||||||
|
0xc3, 0x14, 0xe5, 0xd0, 0x05, 0xad, 0x61, 0xe6, 0xa9, 0x05, 0xdd, 0xe9,
|
||||||
|
0xcb, 0x5e, 0xbd, 0x34, 0x2c, 0x83, 0xe8, 0x6e, 0x4a, 0x81, 0x96, 0xee,
|
||||||
|
0x94, 0x2e, 0xf3, 0xda, 0xc8, 0xd4, 0xc1, 0x99, 0x34, 0x40, 0x06, 0x36,
|
||||||
|
0x89, 0xe7, 0xd0, 0xef, 0xbc, 0x96, 0x61, 0x85, 0x18, 0x22, 0x4a, 0x9e,
|
||||||
|
0x12, 0xdf, 0x04, 0xda, 0xe5, 0x58, 0x6a, 0x9c, 0xa0, 0x10, 0x28, 0x52,
|
||||||
|
0xe5, 0x61, 0x97, 0x2e, 0xba, 0xc7, 0x5a, 0x90, 0x1a, 0x38, 0x95, 0xd4,
|
||||||
|
0xc5, 0xce, 0xcf, 0xbc, 0xda, 0x7c, 0x9c, 0x51, 0x68, 0x5a, 0x53, 0xe6,
|
||||||
|
0xf4, 0xfc, 0xd3, 0x6b, 0x7f, 0xa0, 0x05, 0x60, 0x9b, 0xba, 0x37, 0x4f,
|
||||||
|
0xaf, 0x06, 0x7c, 0x96, 0x7a, 0x3a, 0x00, 0x15, 0x15, 0x35, 0x4a, 0x52,
|
||||||
|
0xd4, 0x1f, 0x4e, 0xcc, 0xc3, 0x9f, 0x4b, 0x1a, 0x8e, 0x7f, 0x94, 0x98,
|
||||||
|
0x8f, 0x35, 0xd0, 0x0d, 0x84, 0xa7, 0x3b, 0xd8, 0x6d, 0x0f, 0x28, 0x59,
|
||||||
|
0xd0, 0x2c, 0x85, 0x53, 0x80, 0xb1, 0x23, 0xbc, 0xd2, 0x66, 0x9d, 0xf4,
|
||||||
|
0x8c, 0xba, 0x65, 0xf0, 0xd8, 0x86, 0xd0, 0xed, 0x93, 0xcc, 0xea, 0x86,
|
||||||
|
0xd0, 0xce, 0x5a, 0x96, 0x31, 0x2a, 0xbe, 0xbf, 0x2c, 0xbf, 0x81, 0x1e,
|
||||||
|
0xcd, 0x0c, 0x88, 0x8e, 0x5e, 0xf9, 0x13, 0x83, 0xce, 0x2c, 0x20, 0x31,
|
||||||
|
0x6f, 0x21, 0xbb, 0xe4, 0xb5, 0x1f, 0x8c, 0xd0, 0xf6, 0x50, 0x1b, 0xdc,
|
||||||
|
0xcf, 0xf7, 0x58, 0x2a, 0xd8, 0x3c, 0x95, 0xf9, 0xa3, 0xb9, 0xba, 0x11,
|
||||||
|
0x64, 0xfa, 0xa5, 0xe2, 0x99, 0x78, 0xe3, 0xa5, 0xe1, 0xb6, 0xaa, 0x91,
|
||||||
|
0xa5, 0x15, 0x83, 0xe0, 0x37, 0x5d, 0x35, 0xb9, 0x57, 0xf7, 0xa5, 0xdf,
|
||||||
|
0xf8, 0x53, 0xec, 0x9d, 0x36, 0x77, 0xfb, 0x5d, 0x10, 0x34, 0xf0, 0x32,
|
||||||
|
0x46, 0x0b, 0x54, 0x8d, 0x4a, 0x07, 0xda, 0x9f, 0xc8, 0x4d, 0xfa, 0xb8,
|
||||||
|
0x57, 0xfe, 0x6e, 0xab, 0x9c, 0x2b, 0xe9, 0xa8, 0xb9, 0xd6, 0x22, 0x3e,
|
||||||
|
0x09, 0xb4, 0xa0, 0x06, 0xb9, 0xe3, 0x27, 0x0a, 0x2d, 0x3c, 0x60, 0xae,
|
||||||
|
0xcd, 0x40, 0x04, 0xfa, 0x45, 0x60, 0xd3, 0x4d, 0x2a, 0x9a, 0xb3, 0xb6,
|
||||||
|
0xbd, 0x53, 0xbd, 0x2c, 0xc0, 0xaa, 0x4d, 0x48, 0x72, 0x52, 0xf7, 0x17,
|
||||||
|
0x73, 0x02, 0x27, 0x0b, 0x4c, 0xcf, 0xf0, 0x28, 0x49, 0x87, 0x2f, 0x7b,
|
||||||
|
0x92, 0xe8, 0xea, 0xe8, 0x60, 0xc0, 0xd0, 0xe7, 0xab, 0xd4, 0x2e, 0x49,
|
||||||
|
0x85, 0x5e, 0xb2, 0x08, 0xed, 0x2d, 0xe6, 0xb3, 0x83, 0xd3, 0x79, 0x3b,
|
||||||
|
0xbb, 0x4d, 0xc5, 0xbf, 0x9a, 0xbc, 0x2b, 0xcf, 0xfa, 0x25, 0xe2, 0x45,
|
||||||
|
0x75, 0xd4, 0x2d, 0xdd, 0x88, 0xa8, 0xf7, 0x60, 0xfe, 0x37, 0xaf, 0x5c,
|
||||||
|
0xb4, 0x02, 0xf1, 0x4c, 0x25, 0x1f, 0x59, 0xf1, 0x6c, 0x86, 0xc0, 0x87,
|
||||||
|
0x60, 0x11, 0x30, 0xc1, 0x15, 0xf4, 0xe8, 0x6e, 0xc2, 0x7b, 0x08, 0x7e,
|
||||||
|
0x72, 0x67, 0xca, 0x24, 0x99, 0x26, 0xc2, 0xc5, 0xaa, 0x2e, 0x3f, 0x65,
|
||||||
|
0xc5, 0x67, 0x23, 0x26, 0xc7, 0x48, 0xca, 0x44, 0x8b, 0xdf, 0x54, 0xe8,
|
||||||
|
0xbb, 0x26, 0x07, 0x12, 0x99, 0x00, 0x12, 0x58, 0x5b, 0xad, 0x37, 0x5a,
|
||||||
|
0x4f, 0x1e, 0xae, 0xd5, 0x2b, 0x89, 0xbc, 0xe6, 0x18, 0x6a, 0xd3, 0x92,
|
||||||
|
0xd4, 0x95, 0xeb, 0xa3, 0x29, 0x40, 0xcd, 0x68, 0xd6, 0x3e, 0x21, 0xd1,
|
||||||
|
0x71, 0x71, 0x65, 0x4a, 0x88, 0x24, 0xb2, 0xbc, 0x54, 0x45, 0xee, 0xdd,
|
||||||
|
0xb2, 0xa4, 0x65, 0x7b, 0xed, 0x96, 0x11, 0x7c, 0x18, 0x8f, 0x8a, 0xd3,
|
||||||
|
0xf6, 0x07, 0x57, 0xe0, 0xaa, 0x06, 0x59, 0x79, 0x13, 0x2c, 0x23, 0x11,
|
||||||
|
0xc1, 0xa7, 0xad, 0xfe, 0xaa, 0xed, 0xac, 0xbb, 0x43, 0x1e, 0xe9, 0x40,
|
||||||
|
0x4c, 0xcc, 0xad, 0x26, 0x6a, 0x80, 0xf0, 0x3d, 0xcf, 0xe6, 0x95, 0xdf,
|
||||||
|
0xfb, 0x29, 0x24, 0xba, 0xc5, 0x71, 0x35, 0x31, 0xb7, 0x98, 0x20, 0x25,
|
||||||
|
0x09, 0xa5, 0x42, 0xf7, 0xd2, 0xbe, 0xbf, 0x66, 0x31, 0x5f, 0x63, 0xe7,
|
||||||
|
0x57, 0x7d, 0xfe, 0xd5, 0xe6, 0x5f, 0xbd, 0xfb, 0xc5, 0xc8, 0xe6, 0xd9,
|
||||||
|
0xba, 0xf7, 0x45, 0x03, 0x97, 0xab, 0xca, 0x6d, 0xde, 0x3f, 0xf8, 0x98,
|
||||||
|
0xaa, 0xa9, 0xa2, 0x4e, 0x24, 0x1c, 0x46, 0x26, 0xe4, 0xfe, 0x99, 0x76,
|
||||||
|
0x6d, 0xdd, 0x48, 0x98, 0xee, 0x2f, 0x45, 0xd3, 0xf1, 0x7a, 0xd7, 0xd7,
|
||||||
|
0x83, 0xd0, 0xeb, 0x79, 0x96, 0x5a, 0x14, 0x92, 0x43, 0x88, 0x56, 0x18,
|
||||||
|
0x87, 0x39, 0x63, 0x9a, 0x03, 0x0d, 0xc3, 0xb5, 0xee, 0x07, 0xe9, 0xe2,
|
||||||
|
0xb0, 0xe6, 0x8c, 0x1f, 0xd0, 0x65, 0x5e, 0x60, 0xf6, 0xe5, 0x7b, 0xef,
|
||||||
|
0x2a, 0x59, 0x52, 0x28, 0xe5, 0x2d, 0x39, 0xa3, 0xeb, 0x03, 0x8f, 0x31,
|
||||||
|
0xd4, 0xdd, 0x07, 0xd7, 0xaa, 0xeb, 0xce, 0x28, 0x47, 0x74, 0xfd, 0xe6,
|
||||||
|
0x9c, 0x8a, 0x07, 0xdb, 0x54, 0x3e, 0xe9, 0xcf, 0x22, 0xfa, 0x9d, 0xbc,
|
||||||
|
0x78, 0x01, 0x62, 0x6e, 0x2f, 0x75, 0xc8, 0x34, 0xba, 0x47, 0xa0, 0x2f,
|
||||||
|
0x87, 0x30, 0xd6, 0x7d, 0x1a, 0xbb, 0xa3, 0x1f, 0xb8, 0xd3, 0xb0, 0x33,
|
||||||
|
0x6f, 0x70, 0x38, 0xa8, 0xbe, 0x4d, 0x24, 0xfd, 0xf9, 0xb8, 0x91, 0x90,
|
||||||
|
0xad, 0x5f, 0x65, 0xec, 0x39, 0x61, 0x00, 0xed, 0xb0, 0xc0, 0xc7, 0x61,
|
||||||
|
0xdd, 0xc3, 0xb9, 0x84, 0xe2, 0x4a, 0x4c, 0x92, 0x43, 0xc6, 0xe6, 0x67,
|
||||||
|
0x36, 0x56, 0x01, 0x52, 0x1f, 0x31, 0x4a, 0x4b, 0x17, 0x7e, 0xf5, 0x7f,
|
||||||
|
0x8d, 0x68, 0x9d, 0x00, 0x65, 0x27, 0x0b, 0x85, 0x9f, 0x0a, 0xef, 0x8c,
|
||||||
|
0x75, 0x86, 0xac, 0x48, 0xab, 0x40, 0x7d, 0xd9, 0x00, 0x67, 0xe2, 0xad,
|
||||||
|
0x8d, 0x21, 0xcd, 0xac, 0x2b, 0x96, 0x06, 0x92, 0x1f, 0xa6, 0x9d, 0x90,
|
||||||
|
0x46, 0x20, 0x45, 0x52, 0x72, 0x8c, 0xba, 0x91, 0xc2, 0x0d, 0x57, 0xcc,
|
||||||
|
0x40, 0x7b, 0xfc, 0x1c, 0x45, 0x6a, 0x8d, 0x7b, 0xcc, 0xff, 0x00, 0x59,
|
||||||
|
0x81, 0x84, 0x20, 0x42, 0x67, 0xd2, 0x1b, 0x00, 0x00, 0x01, 0x86, 0x69,
|
||||||
|
0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69,
|
||||||
|
0x6c, 0x65, 0x00, 0x00, 0x78, 0x9c, 0x7d, 0x91, 0x3d, 0x48, 0xc3, 0x40,
|
||||||
|
0x1c, 0xc5, 0x5f, 0x53, 0xa5, 0x52, 0x2b, 0x0e, 0x16, 0x11, 0x11, 0xc9,
|
||||||
|
0x50, 0x9d, 0x2c, 0x88, 0x8a, 0x08, 0x2e, 0x5a, 0x85, 0x22, 0x54, 0x08,
|
||||||
|
0xb5, 0x42, 0xab, 0x0e, 0x26, 0x97, 0x7e, 0x08, 0x4d, 0x1a, 0x92, 0x14,
|
||||||
|
0x17, 0x47, 0xc1, 0xb5, 0xe0, 0xe0, 0xc7, 0x62, 0xd5, 0xc1, 0xc5, 0x59,
|
||||||
|
0x57, 0x07, 0x57, 0x41, 0x10, 0xfc, 0x00, 0x71, 0x73, 0x73, 0x52, 0x74,
|
||||||
|
0x91, 0x12, 0xff, 0x97, 0x14, 0x5a, 0xc4, 0x7a, 0x70, 0xdc, 0x8f, 0x77,
|
||||||
|
0xf7, 0x1e, 0x77, 0xef, 0x00, 0xa1, 0x5a, 0x64, 0x9a, 0xd5, 0x36, 0x0a,
|
||||||
|
0x68, 0xba, 0x6d, 0x26, 0xe3, 0x31, 0x31, 0x9d, 0x59, 0x11, 0x03, 0xaf,
|
||||||
|
0x08, 0xa2, 0x13, 0xbd, 0x98, 0xc6, 0xa0, 0xcc, 0x2c, 0x63, 0x56, 0x92,
|
||||||
|
0x12, 0x68, 0x39, 0xbe, 0xee, 0xe1, 0xe3, 0xeb, 0x5d, 0x94, 0x67, 0xb5,
|
||||||
|
0x3e, 0xf7, 0xe7, 0xe8, 0x52, 0xb3, 0x16, 0x03, 0x7c, 0x22, 0xf1, 0x0c,
|
||||||
|
0x33, 0x4c, 0x9b, 0x78, 0x9d, 0x78, 0x72, 0xd3, 0x36, 0x38, 0xef, 0x13,
|
||||||
|
0x87, 0x59, 0x41, 0x56, 0x89, 0xcf, 0x89, 0x47, 0x4c, 0xba, 0x20, 0xf1,
|
||||||
|
0x23, 0xd7, 0x15, 0x8f, 0xdf, 0x38, 0xe7, 0x5d, 0x16, 0x78, 0x66, 0xd8,
|
||||||
|
0x4c, 0x25, 0xe7, 0x88, 0xc3, 0xc4, 0x62, 0xbe, 0x89, 0x95, 0x26, 0x66,
|
||||||
|
0x05, 0x53, 0x23, 0x9e, 0x20, 0x8e, 0xa8, 0x9a, 0x4e, 0xf9, 0x42, 0xda,
|
||||||
|
0x63, 0x95, 0xf3, 0x16, 0x67, 0xad, 0x58, 0x66, 0xf5, 0x7b, 0xf2, 0x17,
|
||||||
|
0x86, 0xb2, 0xfa, 0xf2, 0x12, 0xd7, 0x69, 0x0e, 0x20, 0x8e, 0x05, 0x2c,
|
||||||
|
0x42, 0x82, 0x08, 0x05, 0x65, 0x6c, 0xa0, 0x08, 0x1b, 0x51, 0x5a, 0x75,
|
||||||
|
0x52, 0x2c, 0x24, 0x69, 0x3f, 0xd6, 0xc2, 0xdf, 0xef, 0xfa, 0x25, 0x72,
|
||||||
|
0x29, 0xe4, 0xda, 0x00, 0x23, 0xc7, 0x3c, 0x4a, 0xd0, 0x20, 0xbb, 0x7e,
|
||||||
|
0xf0, 0x3f, 0xf8, 0xdd, 0xad, 0x95, 0x1b, 0x1f, 0xf3, 0x92, 0x42, 0x31,
|
||||||
|
0xa0, 0xfd, 0xc5, 0x71, 0x3e, 0x86, 0x80, 0xc0, 0x2e, 0x50, 0xab, 0x38,
|
||||||
|
0xce, 0xf7, 0xb1, 0xe3, 0xd4, 0x4e, 0x00, 0xff, 0x33, 0x70, 0xa5, 0x37,
|
||||||
|
0xfc, 0xa5, 0x2a, 0x30, 0xf5, 0x49, 0x7a, 0xa5, 0xa1, 0x45, 0x8e, 0x80,
|
||||||
|
0xee, 0x6d, 0xe0, 0xe2, 0xba, 0xa1, 0x29, 0x7b, 0xc0, 0xe5, 0x0e, 0xd0,
|
||||||
|
0xf7, 0x64, 0xc8, 0xa6, 0xec, 0x4a, 0x7e, 0x9a, 0x42, 0x2e, 0x07, 0xbc,
|
||||||
|
0x9f, 0xd1, 0x37, 0x65, 0x80, 0x9e, 0x5b, 0x20, 0xb8, 0xea, 0xf5, 0x56,
|
||||||
|
0xdf, 0xc7, 0xe9, 0x03, 0x90, 0xa2, 0xae, 0x12, 0x37, 0xc0, 0xc1, 0x21,
|
||||||
|
0x30, 0x9c, 0xa7, 0xec, 0xb5, 0x16, 0xef, 0xee, 0x68, 0xee, 0xed, 0xdf,
|
||||||
|
0x33, 0xf5, 0xfe, 0x7e, 0x00, 0xb6, 0x7a, 0x72, 0xc2, 0xb7, 0x19, 0xd7,
|
||||||
|
0x5a, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0xf9, 0x43, 0xbb, 0x7f, 0x00, 0x00, 0x00, 0x09, 0x70,
|
||||||
|
0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, 0x23, 0x00, 0x00, 0x2e, 0x23, 0x01,
|
||||||
|
0x78, 0xa5, 0x3f, 0x76, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45,
|
||||||
|
0x07, 0xe5, 0x0a, 0x0b, 0x17, 0x1e, 0x25, 0x91, 0xc0, 0xe1, 0x5c, 0x00,
|
||||||
|
0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65,
|
||||||
|
0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77,
|
||||||
|
0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0x0e, 0x17,
|
||||||
|
0x00, 0x00, 0x00, 0x8f, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xa5, 0x92,
|
||||||
|
0x49, 0x0e, 0xc0, 0x20, 0x0c, 0x03, 0x1d, 0x8b, 0xff, 0x7f, 0xd9, 0x3d,
|
||||||
|
0x54, 0xdd, 0x21, 0x5b, 0x91, 0x10, 0x82, 0x90, 0x89, 0x21, 0x36, 0x00,
|
||||||
|
0x02, 0x84, 0xee, 0xe0, 0xbe, 0xd8, 0x5f, 0x40, 0x1f, 0x42, 0x00, 0x90,
|
||||||
|
0xd4, 0x86, 0x9c, 0x0a, 0xba, 0x10, 0xde, 0x37, 0x1d, 0x08, 0xdf, 0x07,
|
||||||
|
0x55, 0x08, 0x67, 0x87, 0x15, 0x08, 0x57, 0x81, 0x2c, 0x84, 0x5e, 0x30,
|
||||||
|
0x03, 0x61, 0x24, 0x31, 0x82, 0x30, 0xf3, 0x51, 0x1e, 0x84, 0xd9, 0x76,
|
||||||
|
0xad, 0x20, 0xac, 0x98, 0x66, 0x06, 0x61, 0xd5, 0xba, 0x6f, 0xc8, 0xf0,
|
||||||
|
0x2e, 0x9b, 0x45, 0x3e, 0xb0, 0xb9, 0x82, 0x23, 0xf1, 0xaa, 0xa6, 0xe5,
|
||||||
|
0x64, 0xbd, 0xaa, 0xd3, 0x85, 0x3d, 0x59, 0x93, 0x37, 0x27, 0x8c, 0xf4,
|
||||||
|
0x4c, 0x56, 0x5a, 0x09, 0x57, 0x95, 0xb3, 0x2a, 0x78, 0x7d, 0x52, 0xa7,
|
||||||
|
0x0b, 0x80, 0x01, 0x92, 0x1b, 0x7e, 0x6a, 0xf9, 0xdc, 0x18, 0x81, 0x6d,
|
||||||
|
0x42, 0x05, 0x1b, 0x88, 0xd3, 0x3f, 0x1e, 0x42, 0x28, 0x07, 0xad, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
||||||
|
};
|
||||||
|
unsigned int mouse_png_len = 4907;
|
||||||
|
|
||||||
|
#else // EMBED_HERE
|
||||||
|
|
||||||
|
extern unsigned char mouse_png[];
|
||||||
|
extern unsigned int mouse_png_len;
|
||||||
|
|
||||||
|
#endif // EMBED_HERE
|
||||||
|
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MOUSE_PNG_H
|
|
@ -1,138 +0,0 @@
|
||||||
/*
|
|
||||||
* Kangaroo Punch MultiPlayer Game Server Mark II
|
|
||||||
* Copyright (C) 2020-2021 Scott Duensing
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -77,7 +77,7 @@ static void buttonMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_
|
||||||
|
|
||||||
// Fire callback on mouse up.
|
// Fire callback on mouse up.
|
||||||
if (event == MOUSE_EVENT_LEFT_UP) {
|
if (event == MOUSE_EVENT_LEFT_UP) {
|
||||||
if (b->clicked) b->clicked(widget);
|
if (b->clicked) guiPendingEventAdd(widget, b->clicked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ static void checkboxMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint1
|
||||||
// Toggle value.
|
// Toggle value.
|
||||||
checkboxValueSet(c, !checkboxValueGet(c));
|
checkboxValueSet(c, !checkboxValueGet(c));
|
||||||
// Fire callback on mouse up.
|
// Fire callback on mouse up.
|
||||||
if (c->clicked) c->clicked(widget);
|
if (c->clicked) guiPendingEventAdd(widget, c->clicked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,16 @@
|
||||||
|
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "embedded/vga8x14.h"
|
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
#include "desktop.h"
|
#include "desktop.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "embedded/embedded.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PendingEventsS {
|
||||||
|
WidgetT *widget;
|
||||||
|
widgetCallback callback;
|
||||||
|
} PendingEventsT;
|
||||||
|
|
||||||
|
|
||||||
int16_t _guiMetric[METRIC_COUNT];
|
int16_t _guiMetric[METRIC_COUNT];
|
||||||
|
@ -37,13 +43,23 @@ uint16_t _guiDragOffsetY = 0;
|
||||||
WindowT *_guiActiveWindow = NULL;
|
WindowT *_guiActiveWindow = NULL;
|
||||||
|
|
||||||
|
|
||||||
static DesktopT *_guiDesktop = NULL;
|
static DesktopT *_guiDesktop = NULL;
|
||||||
static WidgetT *_guiLastWidgetLeft = NULL;
|
static WidgetT *_guiLastWidgetLeft = NULL;
|
||||||
static uint8_t _guiLastWidgetLeftEvent = MOUSE_EVENT_NONE;
|
static uint8_t _guiLastWidgetLeftEvent = MOUSE_EVENT_NONE;
|
||||||
static WidgetT *_guiFocused = NULL;
|
static WidgetT *_guiFocused = NULL;
|
||||||
static uint8_t _guiHasStopped = 0; // This starts as 0 even if the GUI hasn't been started.
|
static uint8_t _guiHasStopped = 0; // This starts as 0 even if the GUI hasn't been started.
|
||||||
static WidgetT ***_guiDeleteList = NULL;
|
static WidgetT ***_guiDeleteList = NULL;
|
||||||
|
static uint32_t _guiTimerValue = 0;
|
||||||
|
static uint32_t _guiTimerLast = 0;
|
||||||
|
static uint32_t _guiTimerHalfSecond = 0;
|
||||||
|
static uint32_t _guiTimerSecond = 0;
|
||||||
|
static uint32_t _guiTimerQuarterSecondTick = 0;
|
||||||
|
static uint32_t _guiTimerHalfSecondTick = 0;
|
||||||
|
static uint32_t _guiTimerSecondTick = 0;
|
||||||
|
static uint32_t _guiTimerQuarterSecondOn = 0;
|
||||||
|
static uint32_t _guiTimerHalfSecondOn = 0;
|
||||||
|
static uint32_t _guiTimerSecondOn = 0;
|
||||||
|
static PendingEventsT **_guiPendingEvents = NULL;
|
||||||
|
|
||||||
// Widget Magic Debug Info. Don't forget to change MagicE!
|
// Widget Magic Debug Info. Don't forget to change MagicE!
|
||||||
static char *_magicDebugNames[MAGIC_COUNT] = {
|
static char *_magicDebugNames[MAGIC_COUNT] = {
|
||||||
|
@ -191,6 +207,10 @@ void guiDelete(WidgetT **widget) {
|
||||||
// Since deleting happens in widget events, it's not safe to do it
|
// Since deleting happens in widget events, it's not safe to do it
|
||||||
// immediately. Instead, we make a list of what to delete and
|
// immediately. Instead, we make a list of what to delete and
|
||||||
// then process it before painting.
|
// then process it before painting.
|
||||||
|
|
||||||
|
// This may be redundant now since there is a pending event list
|
||||||
|
// that is also handled in the paint event.
|
||||||
|
|
||||||
arrput(_guiDeleteList, widget);
|
arrput(_guiDeleteList, widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +269,6 @@ static void guiDeleteListItem(WidgetT **widget) {
|
||||||
if (plen == 1) {
|
if (plen == 1) {
|
||||||
// Erase the list.
|
// Erase the list.
|
||||||
arrfree(w->parent->children);
|
arrfree(w->parent->children);
|
||||||
w->parent->children = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,7 +278,6 @@ static void guiDeleteListItem(WidgetT **widget) {
|
||||||
if (w == _guiFocused) _guiFocused = NULL;
|
if (w == _guiFocused) _guiFocused = NULL;
|
||||||
|
|
||||||
// Delete us.
|
// Delete us.
|
||||||
//logWrite("Deleting %s %p\n", _magicDebugNames[w->magic], w);
|
|
||||||
if (w->delMethod != NULL) w->delMethod(&w);
|
if (w->delMethod != NULL) w->delMethod(&w);
|
||||||
arrfree(w->children);
|
arrfree(w->children);
|
||||||
if (w->surface != NULL) {
|
if (w->surface != NULL) {
|
||||||
|
@ -455,6 +473,14 @@ void guiMouseProcess(MouseT *mouse) {
|
||||||
|
|
||||||
void guiPaint(WidgetT *widget) {
|
void guiPaint(WidgetT *widget) {
|
||||||
|
|
||||||
|
// Process any pending events.
|
||||||
|
while (arrlen(_guiPendingEvents)) {
|
||||||
|
_guiPendingEvents[0]->callback(_guiPendingEvents[0]->widget);
|
||||||
|
DEL(_guiPendingEvents[0]);
|
||||||
|
arrdel(_guiPendingEvents, 0);
|
||||||
|
}
|
||||||
|
arrfree(_guiPendingEvents);
|
||||||
|
|
||||||
// Process any pending widget deletions.
|
// Process any pending widget deletions.
|
||||||
guiDeleteList();
|
guiDeleteList();
|
||||||
|
|
||||||
|
@ -512,6 +538,16 @@ void guiParentAndChildrenDirtySet(WidgetT *widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void guiPendingEventAdd(WidgetT *widget, void *callback) {
|
||||||
|
PendingEventsT *p = NULL;
|
||||||
|
|
||||||
|
NEW(PendingEventsT, p);
|
||||||
|
p->callback = callback;
|
||||||
|
p->widget = widget;
|
||||||
|
arrput(_guiPendingEvents, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WidgetT *guiRootGet(void) {
|
WidgetT *guiRootGet(void) {
|
||||||
return (WidgetT *)_guiDesktop;
|
return (WidgetT *)_guiDesktop;
|
||||||
}
|
}
|
||||||
|
@ -648,6 +684,86 @@ void guiStop(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t guiTimerGet(void) {
|
||||||
|
return _guiTimerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerHalfSecondOn(void) {
|
||||||
|
return _guiTimerHalfSecondOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerHalfSecondTick(void) {
|
||||||
|
return _guiTimerHalfSecondTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void guiTimerProcess(uint32_t rawClock) {
|
||||||
|
uint32_t delta;
|
||||||
|
|
||||||
|
_guiTimerValue = rawClock;
|
||||||
|
|
||||||
|
// Reset ticks.
|
||||||
|
_guiTimerQuarterSecondTick = 0;
|
||||||
|
_guiTimerHalfSecondTick = 0;
|
||||||
|
_guiTimerSecondTick = 0;
|
||||||
|
|
||||||
|
// Ensure we haven't rolled past midnight between calls.
|
||||||
|
if (_guiTimerValue >= _guiTimerLast) {
|
||||||
|
delta = _guiTimerValue - _guiTimerLast;
|
||||||
|
} else {
|
||||||
|
// Compensate for midnight rollover.
|
||||||
|
delta = (_guiTimerValue + TICKS_PER_DAY) - _guiTimerLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything ticks off the quarter second.
|
||||||
|
if (delta > TICKS_PER_SECOND * 0.25) {
|
||||||
|
_guiTimerLast = _guiTimerValue;
|
||||||
|
|
||||||
|
// Quarter Second timer.
|
||||||
|
_guiTimerQuarterSecondOn = !_guiTimerQuarterSecondOn;
|
||||||
|
_guiTimerQuarterSecondTick = 1;
|
||||||
|
|
||||||
|
// Half Second timer.
|
||||||
|
if (--_guiTimerHalfSecond == 0) {
|
||||||
|
_guiTimerHalfSecond = 2;
|
||||||
|
_guiTimerHalfSecondOn = !_guiTimerHalfSecondOn;
|
||||||
|
_guiTimerHalfSecondTick = 1;
|
||||||
|
|
||||||
|
// Second timer
|
||||||
|
if (--_guiTimerSecond == 0) {
|
||||||
|
_guiTimerSecond = 2;
|
||||||
|
_guiTimerSecondOn = !_guiTimerSecondOn;
|
||||||
|
_guiTimerSecondTick = 1;
|
||||||
|
} // Second.
|
||||||
|
|
||||||
|
} // Half Second.
|
||||||
|
|
||||||
|
} // Quarter Second.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerQuarterSecondOn(void) {
|
||||||
|
return _guiTimerQuarterSecondOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerQuarterSecondTick(void) {
|
||||||
|
return _guiTimerQuarterSecondTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerSecondOn(void) {
|
||||||
|
return _guiTimerSecondOn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t guiTimerSecondTick(void) {
|
||||||
|
return _guiTimerSecondTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *guiUserDataGet(WidgetT *widget) {
|
void *guiUserDataGet(WidgetT *widget) {
|
||||||
return widget->userData;
|
return widget->userData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum MagicE {
|
||||||
MAGIC_UPDOWN,
|
MAGIC_UPDOWN,
|
||||||
MAGIC_LISTBOX,
|
MAGIC_LISTBOX,
|
||||||
MAGIC_TERMINAL,
|
MAGIC_TERMINAL,
|
||||||
|
MAGIC_TIMER,
|
||||||
//MAGIC_DROPDOWN,
|
//MAGIC_DROPDOWN,
|
||||||
MAGIC_COUNT
|
MAGIC_COUNT
|
||||||
};
|
};
|
||||||
|
@ -201,10 +202,19 @@ void guiMousePositionOnWidgetGet(WidgetT *widget, MouseT *mouse, uint16_t *
|
||||||
void guiMouseProcess(MouseT *mouse);
|
void guiMouseProcess(MouseT *mouse);
|
||||||
void guiPaint(WidgetT *widget);
|
void guiPaint(WidgetT *widget);
|
||||||
void guiParentAndChildrenDirtySet(WidgetT *widget);
|
void guiParentAndChildrenDirtySet(WidgetT *widget);
|
||||||
|
void guiPendingEventAdd(WidgetT *widget, void *callback);
|
||||||
WidgetT *guiRootGet(void);
|
WidgetT *guiRootGet(void);
|
||||||
void guiShutdown(void);
|
void guiShutdown(void);
|
||||||
DesktopT *guiStartup(void);
|
DesktopT *guiStartup(void);
|
||||||
void guiStop(void);
|
void guiStop(void);
|
||||||
|
uint32_t guiTimerGet(void);
|
||||||
|
uint8_t guiTimerHalfSecondOn(void);
|
||||||
|
uint8_t guiTimerHalfSecondTick(void);
|
||||||
|
void guiTimerProcess(uint32_t rawClock);
|
||||||
|
uint8_t guiTimerQuarterSecondOn(void);
|
||||||
|
uint8_t guiTimerQuarterSecondTick(void);
|
||||||
|
uint8_t guiTimerSecondOn(void);
|
||||||
|
uint8_t guiTimerSecondTick(void);
|
||||||
void *guiUserDataGet(WidgetT *widget);
|
void *guiUserDataGet(WidgetT *widget);
|
||||||
void guiUserDataSet(WidgetT *widget, void *userData);
|
void guiUserDataSet(WidgetT *widget, void *userData);
|
||||||
void guiWidgetAndChildrenDirtySet(WidgetT *widget);
|
void guiWidgetAndChildrenDirtySet(WidgetT *widget);
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include "vesa.h"
|
#include "vesa.h"
|
||||||
|
|
||||||
|
|
||||||
|
static ImageT *imageNativeImageGet(unsigned char *raw, uint16_t x, uint16_t y);
|
||||||
|
|
||||||
|
|
||||||
ImageT *imageAllocate(uint16_t w, uint16_t h) {
|
ImageT *imageAllocate(uint16_t w, uint16_t h) {
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
uint16_t y;
|
uint16_t y;
|
||||||
|
@ -78,6 +81,20 @@ ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImageT *imageFromRAMLoad(uint8_t *buffer, size_t len) {
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint16_t n;
|
||||||
|
unsigned char *raw;
|
||||||
|
|
||||||
|
// Load image from RAM.
|
||||||
|
raw = stbi_load_from_memory((const unsigned char *)buffer, len, (int *)&x, (int *)&y, (int *)&n, 3);
|
||||||
|
if (!raw) return NULL;
|
||||||
|
|
||||||
|
return imageNativeImageGet(raw, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint16_t imageHeightGet(ImageT *image) {
|
uint16_t imageHeightGet(ImageT *image) {
|
||||||
return image->height;
|
return image->height;
|
||||||
}
|
}
|
||||||
|
@ -104,14 +121,20 @@ ImageT *imageLoad(char *filename) {
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
uint16_t y;
|
uint16_t y;
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
uint32_t b;
|
|
||||||
unsigned char *raw;
|
unsigned char *raw;
|
||||||
ImageT *image;
|
|
||||||
|
|
||||||
// Load image from disk
|
// Load image from disk
|
||||||
raw = stbi_load(filename, (int *)&x, (int *)&y, (int *)&n, 3);
|
raw = stbi_load(filename, (int *)&x, (int *)&y, (int *)&n, 3);
|
||||||
if (!raw) return NULL;
|
if (!raw) return NULL;
|
||||||
|
|
||||||
|
return imageNativeImageGet(raw, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ImageT *imageNativeImageGet(unsigned char *raw, uint16_t x, uint16_t y) {
|
||||||
|
uint32_t b;
|
||||||
|
ImageT *image;
|
||||||
|
|
||||||
// Create native image.
|
// Create native image.
|
||||||
image = imageAllocate(x, y);
|
image = imageAllocate(x, y);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ typedef struct ImageS {
|
||||||
|
|
||||||
ImageT *imageAllocate(uint16_t w, uint16_t h);
|
ImageT *imageAllocate(uint16_t w, uint16_t h);
|
||||||
ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color);
|
ImageT *imageCreate(uint16_t w, uint16_t h, ColorT color);
|
||||||
|
ImageT *imageFromRAMLoad(uint8_t *buffer, size_t len);
|
||||||
uint16_t imageHeightGet(ImageT *image);
|
uint16_t imageHeightGet(ImageT *image);
|
||||||
uint8_t imageInfoGet(char *filename, uint16_t *width, uint16_t *height);
|
uint8_t imageInfoGet(char *filename, uint16_t *width, uint16_t *height);
|
||||||
ImageT *imageLoad(char *filename);
|
ImageT *imageLoad(char *filename);
|
||||||
|
|
|
@ -95,7 +95,7 @@ static void labelMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t
|
||||||
|
|
||||||
// Fire callback on mouse up.
|
// Fire callback on mouse up.
|
||||||
if (event == MOUSE_EVENT_LEFT_UP) {
|
if (event == MOUSE_EVENT_LEFT_UP) {
|
||||||
if (l->clicked) l->clicked(widget);
|
if (l->clicked) guiPendingEventAdd(widget, l->clicked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ static void pictureMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16
|
||||||
|
|
||||||
// Fire callback on mouse up.
|
// Fire callback on mouse up.
|
||||||
if (event == MOUSE_EVENT_LEFT_UP) {
|
if (event == MOUSE_EVENT_LEFT_UP) {
|
||||||
if (p->clicked) p->clicked(widget);
|
if (p->clicked) guiPendingEventAdd(widget, p->clicked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ static void radioMouseEvent(WidgetT *widget, MouseT *mouse, uint16_t x, uint16_t
|
||||||
// Select us.
|
// Select us.
|
||||||
radioSelectedSet(r);
|
radioSelectedSet(r);
|
||||||
// Fire callback on mouse up.
|
// Fire callback on mouse up.
|
||||||
if (r->clicked) r->clicked(widget);
|
if (r->clicked) guiPendingEventAdd(widget, r->clicked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,7 @@ static void textboxPaint(WidgetT *widget, uint8_t enabled, RectT pos) {
|
||||||
free(draw);
|
free(draw);
|
||||||
|
|
||||||
// Draw cursor.
|
// Draw cursor.
|
||||||
if (guiFocusGet() == widget && __timerQuarterSecondOn) {
|
if (guiFocusGet() == widget && guiTimerQuarterSecondOn()) {
|
||||||
caretPos = textX + fontWidthGet(_guiFont) * t->caret;
|
caretPos = textX + fontWidthGet(_guiFont) * t->caret;
|
||||||
fontRender(_guiFont, cursor, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_TEXTBOX_BACKGROUND], caretPos, textY);
|
fontRender(_guiFont, cursor, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_TEXTBOX_BACKGROUND], caretPos, textY);
|
||||||
}
|
}
|
||||||
|
|
109
client/src/gui/timer.c
Normal file
109
client/src/gui/timer.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Kangaroo Punch MultiPlayer Game Server Mark II
|
||||||
|
* Copyright (C) 2020-2021 Scott Duensing
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void timerPaint(WidgetT *widget, uint8_t enabled, RectT pos);
|
||||||
|
|
||||||
|
|
||||||
|
WidgetT *timerInit(WidgetT *widget, widgetCallback timeout, uint16_t quarterSeconds) {
|
||||||
|
TimerT *t = (TimerT *)widget;
|
||||||
|
|
||||||
|
t->running = 1;
|
||||||
|
t->counter = 0;
|
||||||
|
t->quarterSeconds = quarterSeconds;
|
||||||
|
t->timeout = timeout;
|
||||||
|
t->base.paintMethod = timerPaint;
|
||||||
|
|
||||||
|
// We use the paint event to handle timer processing.
|
||||||
|
GUI_SET_FLAG(widget, WIDGET_FLAG_ALWAYS_PAINT);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TimerT *timerNew(widgetCallback timeout, uint16_t quarterSeconds) {
|
||||||
|
TimerT *timer = (TimerT *)malloc(sizeof(TimerT));
|
||||||
|
WidgetT *widget = NULL;
|
||||||
|
|
||||||
|
if (!timer) return NULL;
|
||||||
|
|
||||||
|
widget = widgetInit(W(timer), MAGIC_TIMER, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
if (!widget) {
|
||||||
|
free(timer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = (TimerT *)timerInit((WidgetT *)timer, timeout, quarterSeconds);
|
||||||
|
if (!timer) {
|
||||||
|
free(timer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void timerPaint(WidgetT *widget, uint8_t enabled, RectT pos) {
|
||||||
|
TimerT *t = (TimerT *)widget;
|
||||||
|
|
||||||
|
(void)enabled;
|
||||||
|
(void)pos;
|
||||||
|
|
||||||
|
// Do we care?
|
||||||
|
if (t->running) {
|
||||||
|
// Everything ticks off the quarter second.
|
||||||
|
if (guiTimerQuarterSecondTick()) t->counter++;
|
||||||
|
// We don't check for timeout inside the tick condition so that timers of 0 fire immediately.
|
||||||
|
if (t->counter >= t->quarterSeconds) {
|
||||||
|
// Timeout! Call user.
|
||||||
|
guiPendingEventAdd(widget, t->timeout);
|
||||||
|
t->counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timerQuarterSecondsSet(TimerT *timer, uint16_t quarterSeconds) {
|
||||||
|
timer->quarterSeconds = quarterSeconds;
|
||||||
|
timer->counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timerReset(TimerT *timer) {
|
||||||
|
timer->counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timerStart(TimerT *timer) {
|
||||||
|
timer->counter = 0;
|
||||||
|
timer->running = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timerStop(TimerT *timer) {
|
||||||
|
timer->running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void timerTimeoutSet(TimerT *timer, widgetCallback timeout) {
|
||||||
|
timer->timeout = timeout;
|
||||||
|
}
|
|
@ -22,22 +22,26 @@
|
||||||
#define TIMER_H
|
#define TIMER_H
|
||||||
|
|
||||||
|
|
||||||
#include "os.h"
|
#include "gui.h"
|
||||||
|
#include "widget.h"
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t __timerQuarterSecondTick;
|
typedef struct TimerS {
|
||||||
extern uint8_t __timerHalfSecondTick;
|
WidgetT base; // Must be first in every widget
|
||||||
extern uint8_t __timerSecondTick;
|
widgetCallback timeout;
|
||||||
|
uint16_t quarterSeconds;
|
||||||
extern uint8_t __timerQuarterSecondOn;
|
uint16_t counter;
|
||||||
extern uint8_t __timerHalfSecondOn;
|
uint8_t running;
|
||||||
extern uint8_t __timerSecondOn;
|
} TimerT;
|
||||||
|
|
||||||
|
|
||||||
void timerShutdown(void);
|
WidgetT *timerInit(WidgetT *widget, widgetCallback timeout, uint16_t quarterSeconds);
|
||||||
void timerStartup(void);
|
TimerT *timerNew(widgetCallback timeout, uint16_t quarterSeconds);
|
||||||
void timerUpdate(void);
|
void timerQuarterSecondsSet(TimerT *timer, uint16_t quarterSeconds);
|
||||||
void timerQuarterSecondsWait(uint8_t quarterSeconds);
|
void timerReset(TimerT *timer);
|
||||||
|
void timerStart(TimerT *timer);
|
||||||
|
void timerStop(TimerT *timer);
|
||||||
|
void timerTimeoutSet(TimerT *timer, widgetCallback timeout);
|
||||||
|
|
||||||
|
|
||||||
#endif // TIMER_H
|
#endif // TIMER_H
|
|
@ -310,7 +310,7 @@ static void updownPaint(WidgetT *widget, uint8_t enabled, RectT pos) {
|
||||||
fontRender(_guiFont, draw, _guiColor[COLOR_UPDOWN_TEXT], _guiColor[COLOR_UPDOWN_BACKGROUND], textX, textY);
|
fontRender(_guiFont, draw, _guiColor[COLOR_UPDOWN_TEXT], _guiColor[COLOR_UPDOWN_BACKGROUND], textX, textY);
|
||||||
|
|
||||||
// Draw cursor.
|
// Draw cursor.
|
||||||
if (guiFocusGet() == widget && __timerQuarterSecondOn) {
|
if (guiFocusGet() == widget && guiTimerQuarterSecondOn()) {
|
||||||
textX += (strlen(draw) - 1) * fontWidthGet(_guiFont);
|
textX += (strlen(draw) - 1) * fontWidthGet(_guiFont);
|
||||||
fontRender(_guiFont, cursor, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_TEXTBOX_BACKGROUND], textX, textY);
|
fontRender(_guiFont, cursor, _guiColor[COLOR_TEXTBOX_TEXT], _guiColor[COLOR_TEXTBOX_BACKGROUND], textX, textY);
|
||||||
}
|
}
|
||||||
|
|
107
client/src/hangup.c
Normal file
107
client/src/hangup.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Kangaroo Punch MultiPlayer Game Server Mark II
|
||||||
|
* Copyright (C) 2020-2021 Scott Duensing
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
#include "label.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#include "taglist.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "network.h"
|
||||||
|
#include "comport.h"
|
||||||
|
|
||||||
|
#include "hangup.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum HangupStateE {
|
||||||
|
S_START_HANGUP = 0,
|
||||||
|
S_WAITING
|
||||||
|
} HangupStateT;
|
||||||
|
|
||||||
|
|
||||||
|
static widgetCallback _done = NULL;
|
||||||
|
static WindowT *_winHangup = NULL;
|
||||||
|
static LabelT *_lblHangup = NULL;
|
||||||
|
static TimerT *_timProgress = NULL;
|
||||||
|
static HangupStateT _state = S_START_HANGUP;
|
||||||
|
|
||||||
|
|
||||||
|
static void timHangupProgress(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
void hangupShow(void *nextFunction) {
|
||||||
|
|
||||||
|
_done = (widgetCallback)nextFunction;
|
||||||
|
|
||||||
|
TagItemT uiDetecting[] = {
|
||||||
|
T_START,
|
||||||
|
T_WINDOW, O(_winHangup),
|
||||||
|
T_TITLE, P("Goodbye"),
|
||||||
|
T_WIDTH, 200, T_HEIGHT, 100,
|
||||||
|
T_LABEL, O(_lblHangup),
|
||||||
|
T_X, 41, T_Y, 25,
|
||||||
|
T_TITLE, P("Disconnecting!"),
|
||||||
|
T_LABEL, T_DONE,
|
||||||
|
T_TIMER, O(_timProgress),
|
||||||
|
T_EVENT, P(timHangupProgress),
|
||||||
|
T_VALUE, 0,
|
||||||
|
T_TIMER, T_DONE,
|
||||||
|
T_WINDOW, T_DONE,
|
||||||
|
T_END
|
||||||
|
};
|
||||||
|
|
||||||
|
// We can use a module-global variable instead of widget user data
|
||||||
|
// because there will never be more than one disconnect dialog on
|
||||||
|
// the screen at a time.
|
||||||
|
_state = S_START_HANGUP;
|
||||||
|
|
||||||
|
tagListRun(uiDetecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void timHangupProgress(WidgetT *widget) {
|
||||||
|
PacketEncodeDataT encoded = { 0 };
|
||||||
|
TimerT *t = (TimerT *)widget;
|
||||||
|
|
||||||
|
switch (_state) {
|
||||||
|
case S_START_HANGUP:
|
||||||
|
// 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.
|
||||||
|
_state = S_WAITING;
|
||||||
|
timerQuarterSecondsSet(t, 3 * 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAITING:
|
||||||
|
// Shut down packet processing & COM port.
|
||||||
|
netShutdown();
|
||||||
|
comClose(__configData.serialCom - 1);
|
||||||
|
timerStop(t);
|
||||||
|
// On to the next dialog.
|
||||||
|
guiDelete(D(_winHangup));
|
||||||
|
_done(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef FIRSTRUN_H
|
#ifndef HANGUP_H
|
||||||
#define FIRSTRUN_H
|
#define HANGUP_H
|
||||||
|
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
void firstRunCheckSetup(void);
|
void hangupShow(void *nextFunction);
|
||||||
|
|
||||||
|
|
||||||
#endif // FIRSTRUN_H
|
#endif // HANGUP_H
|
|
@ -32,9 +32,6 @@
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
|
|
||||||
|
|
||||||
#define SECONDS_IN_DAY 86400
|
|
||||||
#define TICKS_PER_SECOND 18.2
|
|
||||||
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
|
|
||||||
#define TIMER_INTERVAL (1000 / TICKS_PER_SECOND)
|
#define TIMER_INTERVAL (1000 / TICKS_PER_SECOND)
|
||||||
|
|
||||||
#define COM_BUFFER_SIZE 2048
|
#define COM_BUFFER_SIZE 2048
|
||||||
|
@ -61,7 +58,7 @@ static uint8_t _ASCIIKeep = 0;
|
||||||
static uint8_t _scanCodeKeep = 0;
|
static uint8_t _scanCodeKeep = 0;
|
||||||
static uint8_t _keyPressed = 0;
|
static uint8_t _keyPressed = 0;
|
||||||
static uint8_t _debounce = 0;
|
static uint8_t _debounce = 0;
|
||||||
static long _timerTicks = 0;
|
static uint32_t _timerTicks = 0;
|
||||||
static SDL_TimerID _timerID = { 0 };
|
static SDL_TimerID _timerID = { 0 };
|
||||||
static ENetHost *_host = NULL;
|
static ENetHost *_host = NULL;
|
||||||
static ENetPeer *_peer = NULL;
|
static ENetPeer *_peer = NULL;
|
||||||
|
@ -86,10 +83,7 @@ static uint32_t timerCallback(uint32_t interval, void *param);
|
||||||
static void vbeScreenshot(void);
|
static void vbeScreenshot(void);
|
||||||
|
|
||||||
|
|
||||||
long biostime(int cmd, long newtime) {
|
uint32_t rawclock(void) {
|
||||||
(void)cmd;
|
|
||||||
(void)newtime;
|
|
||||||
|
|
||||||
return _timerTicks;
|
return _timerTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,61 +21,82 @@
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "msgbox.h"
|
#include "msgbox.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#include "login.h"
|
#include "login.h"
|
||||||
#include "signup.h"
|
#include "signup.h"
|
||||||
#include "welcome.h"
|
#include "welcome.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "hangup.h"
|
||||||
|
|
||||||
|
|
||||||
static WindowT *_winLogin = NULL;
|
typedef enum LoginStateE {
|
||||||
static TextboxT *_txtUser = NULL;
|
S_START_LOGIN = 0,
|
||||||
static TextboxT *_txtPass = NULL;
|
S_WAIT_LOGIN
|
||||||
static ButtonT *_btnCancel = NULL;
|
} LoginStateT;
|
||||||
static ButtonT *_btnSignUp = NULL;
|
|
||||||
static ButtonT *_btnLogin = NULL;
|
|
||||||
|
static WindowT *_winLogin = NULL;
|
||||||
|
static TextboxT *_txtUser = NULL;
|
||||||
|
static TextboxT *_txtPass = NULL;
|
||||||
|
static ButtonT *_btnCancel = NULL;
|
||||||
|
static ButtonT *_btnSignUp = NULL;
|
||||||
|
static ButtonT *_btnLogin = NULL;
|
||||||
|
static TimerT *_timProgress = NULL;
|
||||||
|
static LoginStateT _state = S_START_LOGIN;
|
||||||
|
static uint8_t _channel = 0;
|
||||||
|
|
||||||
|
|
||||||
static void btnCancelClick(WidgetT *widget);
|
static void btnCancelClick(WidgetT *widget);
|
||||||
|
static void btnLoginClick(WidgetT *widget);
|
||||||
static void btnSignUpClick(WidgetT *widget);
|
static void btnSignUpClick(WidgetT *widget);
|
||||||
static void btnMsgBoxCancel(MsgBoxButtonT button);
|
static void btnMsgBoxCancel(MsgBoxButtonT button);
|
||||||
static void btnMsgBoxContinue(MsgBoxButtonT button);
|
static void btnMsgBoxContinue(MsgBoxButtonT button);
|
||||||
|
static void packetHandler(PacketDecodeDataT *packet);
|
||||||
static void setButtons(uint8_t enabled);
|
static void setButtons(uint8_t enabled);
|
||||||
static void taskDisconnect(void *data);
|
static void timLoginProgress(WidgetT *widget);
|
||||||
static void taskLoginClick(void *data);
|
|
||||||
|
|
||||||
|
|
||||||
static void btnCancelClick(WidgetT *widget) {
|
static void btnCancelClick(WidgetT *widget) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
// ***TODO*** This should disable the entire dialog instead of just the buttons. Need to finish the Enable GUI code first.
|
|
||||||
|
|
||||||
setButtons(0);
|
setButtons(0);
|
||||||
msgBoxTwo("Cancel?", MSGBOX_ICON_QUESTION, "Cancel login?\n \nThis will disconnect you from the server.", "Okay", btnMsgBoxCancel, "Cancel", btnMsgBoxCancel);
|
msgBoxTwo("Cancel?", MSGBOX_ICON_QUESTION, "Cancel login?\n \nThis will disconnect you from the server.", "Okay", btnMsgBoxCancel, "Cancel", btnMsgBoxCancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void btnLoginClick(WidgetT *widget) {
|
||||||
|
(void)widget;
|
||||||
|
|
||||||
|
setButtons(0);
|
||||||
|
|
||||||
|
_state = S_START_LOGIN;
|
||||||
|
timerQuarterSecondsSet(_timProgress, 0);
|
||||||
|
timerStart(_timProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void btnSignUpClick(WidgetT *widget) {
|
static void btnSignUpClick(WidgetT *widget) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
|
netChannelRelease(_channel);
|
||||||
guiDelete(D(_winLogin));
|
guiDelete(D(_winLogin));
|
||||||
taskCreate(taskSignUp, NULL);
|
signupShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void btnMsgBoxCancel(MsgBoxButtonT button) {
|
static void btnMsgBoxCancel(MsgBoxButtonT button) {
|
||||||
|
|
||||||
if (button == MSGBOX_BUTTON_ONE) {
|
if (button == MSGBOX_BUTTON_ONE) {
|
||||||
|
netChannelRelease(_channel);
|
||||||
guiDelete(D(_winLogin));
|
guiDelete(D(_winLogin));
|
||||||
taskCreate(taskDisconnect, taskWelcome);
|
hangupShow(welcomeShow);
|
||||||
} else {
|
} else {
|
||||||
setButtons(1);
|
setButtons(1);
|
||||||
}
|
}
|
||||||
|
@ -89,24 +110,9 @@ static void btnMsgBoxContinue(MsgBoxButtonT button) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setButtons(uint8_t enabled) {
|
void loginShow() {
|
||||||
widgetEnableSet(W(_btnCancel), enabled);
|
|
||||||
widgetEnableSet(W(_btnSignUp), enabled);
|
|
||||||
widgetEnableSet(W(_btnLogin), enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// ***TODO*** We used to have a FORGOT PASSWORD link here, too.
|
||||||
static void taskDisconnect(void *nextTask) {
|
|
||||||
netDisconnect();
|
|
||||||
if (nextTask) taskCreate(taskWelcome, nextTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskLogin(void *data) {
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
// ***TODO*** We used to have a FORGOT PASSWORD button here, too.
|
|
||||||
|
|
||||||
TagItemT uiLogin[] = {
|
TagItemT uiLogin[] = {
|
||||||
T_START,
|
T_START,
|
||||||
|
@ -142,70 +148,88 @@ void taskLogin(void *data) {
|
||||||
T_BUTTON, O(_btnLogin),
|
T_BUTTON, O(_btnLogin),
|
||||||
T_TITLE, P("Login"),
|
T_TITLE, P("Login"),
|
||||||
T_X, 199, T_Y, 85,
|
T_X, 199, T_Y, 85,
|
||||||
T_CLICK, P(taskProxy),
|
T_CLICK, P(btnLoginClick),
|
||||||
T_USER_DATA, P(taskLoginClick),
|
|
||||||
T_BUTTON, T_DONE,
|
T_BUTTON, T_DONE,
|
||||||
|
T_TIMER, O(_timProgress),
|
||||||
|
T_EVENT, P(timLoginProgress),
|
||||||
|
T_VALUE, 0,
|
||||||
|
T_ENABLED, 0,
|
||||||
|
T_TIMER, T_DONE,
|
||||||
|
|
||||||
T_WINDOW, T_DONE,
|
T_WINDOW, T_DONE,
|
||||||
T_END
|
T_END
|
||||||
};
|
};
|
||||||
|
|
||||||
tagListRun(uiLogin);
|
tagListRun(uiLogin);
|
||||||
|
_channel = netChannelGet(packetHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void taskLoginClick(void *data) {
|
static void packetHandler(PacketDecodeDataT *packet) {
|
||||||
char *packetData = NULL;
|
char *packetData;
|
||||||
int8_t success = 0;
|
int8_t success;
|
||||||
uint16_t length = 0;
|
|
||||||
int16_t timeout = 10;
|
|
||||||
PacketEncodeDataT encoded = { 0 };
|
|
||||||
PacketDecodeDataT *decoded = NULL;
|
|
||||||
|
|
||||||
(void)data;
|
switch (packet->packetType) {
|
||||||
|
case PACKET_TYPE_LOGIN_RESULT:
|
||||||
|
packetContentUnpack(packet->data, "is", &success, &packetData);
|
||||||
|
logWrite("Login: %d %s\n", success, packetData);
|
||||||
|
if (success) {
|
||||||
|
netChannelRelease(_channel);
|
||||||
|
guiDelete(D(_winLogin));
|
||||||
|
menuShow();
|
||||||
|
} else {
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
||||||
|
}
|
||||||
|
DEL(packetData);
|
||||||
|
timerStop(_timProgress);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
timerStop(_timProgress);
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetDecodeDataDestroy(&packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void setButtons(uint8_t enabled) {
|
||||||
// ***TODO*** This should disable the entire dialog instead of just the buttons. Need to finish the Enable GUI code first.
|
// ***TODO*** This should disable the entire dialog instead of just the buttons. Need to finish the Enable GUI code first.
|
||||||
|
|
||||||
setButtons(0);
|
widgetEnableSet(W(_btnCancel), enabled);
|
||||||
|
widgetEnableSet(W(_btnSignUp), enabled);
|
||||||
packetData = packetContentPack(&length, "ss", textboxValueGet(_txtUser), textboxValueGet(_txtPass));
|
widgetEnableSet(W(_btnLogin), enabled);
|
||||||
|
|
||||||
// Send login request.
|
|
||||||
encoded.packetType = PACKET_TYPE_LOGIN;
|
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
|
||||||
encoded.channel = 0;
|
|
||||||
encoded.encrypt = 1;
|
|
||||||
packetEncode(__packetThreadData, &encoded, packetData, length);
|
|
||||||
packetSend(__packetThreadData, &encoded);
|
|
||||||
|
|
||||||
DEL(packetData);
|
|
||||||
|
|
||||||
// Wait for response.
|
|
||||||
do {
|
|
||||||
decoded = netGetPacket(0);
|
|
||||||
if (decoded) {
|
|
||||||
switch (decoded->packetType) {
|
|
||||||
case PACKET_TYPE_LOGIN_RESULT:
|
|
||||||
packetContentUnpack(decoded->data, "is", &success, &packetData);
|
|
||||||
logWrite("Login: %d %s\n", success, packetData);
|
|
||||||
if (success) {
|
|
||||||
guiDelete(D(_winLogin));
|
|
||||||
taskCreate(taskMenu, NULL);
|
|
||||||
} else {
|
|
||||||
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
|
||||||
}
|
|
||||||
DEL(packetData);
|
|
||||||
timeout = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
|
|
||||||
timeout = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
packetDecodeDataDestroy(&decoded);
|
|
||||||
}
|
|
||||||
taskYield();
|
|
||||||
if (__timerQuarterSecondTick) timeout--;
|
|
||||||
} while (!guiHasStopped() && timeout > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void timLoginProgress(WidgetT *widget) {
|
||||||
|
char *packetData;
|
||||||
|
uint16_t length;
|
||||||
|
PacketEncodeDataT encoded;
|
||||||
|
TimerT *t = (TimerT *)widget;
|
||||||
|
|
||||||
|
switch (_state) {
|
||||||
|
case S_START_LOGIN:
|
||||||
|
setButtons(0);
|
||||||
|
packetData = packetContentPack(&length, "ss", textboxValueGet(_txtUser), textboxValueGet(_txtPass));
|
||||||
|
// Send login request.
|
||||||
|
encoded.packetType = PACKET_TYPE_LOGIN;
|
||||||
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
|
encoded.channel = _channel;
|
||||||
|
encoded.encrypt = 1;
|
||||||
|
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||||
|
packetSend(__packetThreadData, &encoded);
|
||||||
|
DEL(packetData);
|
||||||
|
// Wait for response.
|
||||||
|
timerQuarterSecondsSet(t, 10 * 4);
|
||||||
|
_state = S_WAIT_LOGIN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_LOGIN:
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "No response received.", "Okay", btnMsgBoxContinue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
void taskLogin(void *data);
|
void loginShow(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // LOGIN_H
|
#endif // LOGIN_H
|
||||||
|
|
|
@ -40,71 +40,125 @@
|
||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "task.h"
|
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "firstrun.h"
|
#include "timer.h"
|
||||||
|
#include "embedded/embedded.h"
|
||||||
|
|
||||||
#include "welcome.h"
|
#include "welcome.h"
|
||||||
#include "signup.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
|
||||||
PacketThreadDataT *__packetThreadData = NULL; // Exported in os.h
|
PacketThreadDataT *__packetThreadData = NULL; // Exported in os.h
|
||||||
RuntimeDataT __runtimeData; // Exported in runtime.h
|
RuntimeDataT __runtimeData; // Exported in runtime.h
|
||||||
|
|
||||||
|
static MouseT *_mouse = NULL;
|
||||||
|
static ImageT *_pointer = NULL;
|
||||||
|
static ColorT _alpha = 0;
|
||||||
|
|
||||||
static void taskGuiEventLoop(void *data);
|
#ifndef __linux__
|
||||||
|
char *_logName = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void taskGuiEventLoop(void *data) {
|
static void checkSettings(void);
|
||||||
MouseT *mouse = NULL;
|
static void eventLoop(void);
|
||||||
ImageT *pointer = NULL;
|
static uint8_t hasValidSettings(void);
|
||||||
ColorT alpha = { 0 };
|
static void shutdown(void);
|
||||||
|
static uint8_t startup(int argc, char *argv[]);
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
pointer = imageLoad("data/mouse.png");
|
static void checkSettings(void) {
|
||||||
alpha = imagePixelGet(pointer, 5, 0);
|
// Do we have a valid COM port?
|
||||||
|
if (!hasValidSettings()) {
|
||||||
|
logWrite("No compatible modem found. Cannot continue.\n");
|
||||||
|
guiStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
welcomeShow();
|
||||||
|
eventLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void eventLoop(void) {
|
||||||
|
// Main Event Loop.
|
||||||
do {
|
do {
|
||||||
timerUpdate();
|
netProcess();
|
||||||
mouse = mouseRead();
|
guiTimerProcess(rawclock());
|
||||||
|
_mouse = mouseRead();
|
||||||
if (keyHit()) {
|
if (keyHit()) {
|
||||||
guiKeyboardProcess(keyASCIIGet(), keyExtendedGet(), keyScanCodeGet(), keyShiftGet(), keyControlGet(), keyAltGet());
|
guiKeyboardProcess(keyASCIIGet(), keyExtendedGet(), keyScanCodeGet(), keyShiftGet(), keyControlGet(), keyAltGet());
|
||||||
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", keyASCIIGet(), keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
|
//logWrite("Key '%d' Extended '%d' Scancode '%d' Shift '%d' Control '%d' Alt '%d'\n", keyASCIIGet(), keyExtended(), keyScanCode(), keyShift(), keyControl(), keyAlt());
|
||||||
if (keyASCIIGet() == 27) guiStop();
|
if (keyASCIIGet() == 27) guiStop();
|
||||||
}
|
}
|
||||||
guiMouseProcess(mouse);
|
guiMouseProcess(_mouse);
|
||||||
guiComposite();
|
guiComposite();
|
||||||
imageRenderWithAlpha(pointer, mouse->x, mouse->y, alpha);
|
imageRenderWithAlpha(_pointer, _mouse->x, _mouse->y, _alpha);
|
||||||
vbeVBlankWait();
|
vbeVBlankWait();
|
||||||
vbePresent();
|
vbePresent();
|
||||||
taskYield();
|
|
||||||
} while (!guiHasStopped());
|
} while (!guiHasStopped());
|
||||||
|
|
||||||
imageUnload(&pointer);
|
shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t hasValidSettings(void) {
|
||||||
|
return (__configData.serialCom > 0 && __configData.serialCom < 5);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
|
static void shutdown(void) {
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
// On DOS, display the contets of the log now that we're back in text mode.
|
// On DOS, display the contets of the log now that we're back in text mode.
|
||||||
char *logName = NULL;
|
|
||||||
FILE *in = NULL;
|
FILE *in = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
imageUnload(&_pointer);
|
||||||
|
|
||||||
|
netShutdown();
|
||||||
|
guiShutdown();
|
||||||
|
mouseShutdown();
|
||||||
|
surfaceShutdown();
|
||||||
|
vbeShutdown();
|
||||||
|
configShutdown();
|
||||||
|
osShutdown();
|
||||||
|
logClose();
|
||||||
|
memoryShutdown();
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
//***TODO*** Why the frack does this not work?!
|
||||||
|
textmode(C80);
|
||||||
|
// On DOS, display the contets of the log now that we're back in text mode.
|
||||||
|
in = fopen(_logName, "r");
|
||||||
|
if (in) {
|
||||||
|
while (!feof(in)) {
|
||||||
|
putc(fgetc(in), stdout);
|
||||||
|
}
|
||||||
|
fclose(in);
|
||||||
|
free(in);
|
||||||
|
}
|
||||||
|
free(_logName);
|
||||||
|
_Exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t startup(int argc, char *argv[]) {
|
||||||
memoryStartup(argv[0]);
|
memoryStartup(argv[0]);
|
||||||
logOpenByHandle(memoryLogHandleGet());
|
logOpenByHandle(memoryLogHandleGet());
|
||||||
osStartup();
|
osStartup();
|
||||||
configStartup(argv[0]);
|
configStartup(argv[0]);
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
_logName = utilAppNameWithNewExtensionGet(argv[0], "log");
|
||||||
|
#endif
|
||||||
|
|
||||||
// 0 1 2 3 4 5 6 7 8
|
// 0 1 2 3 4 5 6 7 8
|
||||||
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
logWrite("%s", "Kangaroo Punch MultiPlayer DOS Game Client Mark II\n");
|
logWrite("%s", "Kangaroo Punch MultiPlayer DOS Game Client Mark II\n");
|
||||||
|
@ -116,16 +170,10 @@ int main(int argc, char *argv[]) {
|
||||||
configShutdown();
|
configShutdown();
|
||||||
logClose();
|
logClose();
|
||||||
memoryShutdown();
|
memoryShutdown();
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timerStartup();
|
|
||||||
taskStartup();
|
|
||||||
|
|
||||||
// Perform "first run" setup tasks.
|
|
||||||
firstRunCheckSetup();
|
|
||||||
|
|
||||||
// Do we have the video mode they asked for?
|
// Do we have the video mode they asked for?
|
||||||
if (vbeStartup(__configData.videoWidth, __configData.videoHeight, __configData.videoDepth)) {
|
if (vbeStartup(__configData.videoWidth, __configData.videoHeight, __configData.videoDepth)) {
|
||||||
configShutdown();
|
configShutdown();
|
||||||
|
@ -137,42 +185,29 @@ int main(int argc, char *argv[]) {
|
||||||
surfaceStartup();
|
surfaceStartup();
|
||||||
mouseStartup();
|
mouseStartup();
|
||||||
guiStartup();
|
guiStartup();
|
||||||
// Do not call netStartup() here. It will be started when needed.
|
netStartup();
|
||||||
|
|
||||||
// taskCreate(taskSignUp, NULL);
|
_pointer = imageFromRAMLoad(mouse_png, mouse_png_len);
|
||||||
taskCreate(taskWelcome, NULL);
|
_alpha = imagePixelGet(_pointer, 5, 0);
|
||||||
taskCreate(taskGuiEventLoop, NULL);
|
|
||||||
|
return 0;
|
||||||
taskRun();
|
}
|
||||||
|
|
||||||
netShutdown();
|
|
||||||
guiShutdown();
|
int main(int argc, char *argv[]) {
|
||||||
mouseShutdown();
|
|
||||||
surfaceShutdown();
|
if (startup(argc, argv)) return 1;
|
||||||
vbeShutdown();
|
|
||||||
taskShutdown();
|
// Perform "first run" setup tasks or start the client?
|
||||||
timerShutdown();
|
if (hasValidSettings()) {
|
||||||
configShutdown();
|
// We have what we need, start the client.
|
||||||
osShutdown();
|
welcomeShow();
|
||||||
logClose();
|
} else {
|
||||||
memoryShutdown();
|
// Run the setup.
|
||||||
|
settingsShow(checkSettings);
|
||||||
#ifndef __linux__
|
}
|
||||||
//***TODO*** Why the frack does this not work?!
|
|
||||||
textmode(C80);
|
eventLoop();
|
||||||
// On DOS, display the contets of the log now that we're back in text mode.
|
|
||||||
logName = utilAppNameWithNewExtensionGet(argv[0], "log");
|
|
||||||
in = fopen(logName, "r");
|
|
||||||
if (in) {
|
|
||||||
while (!feof(in)) {
|
|
||||||
putc(fgetc(in), stdout);
|
|
||||||
}
|
|
||||||
fclose(in);
|
|
||||||
free(in);
|
|
||||||
}
|
|
||||||
free(logName);
|
|
||||||
_Exit(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
|
||||||
void taskMenu(void *data) {
|
void menuShow(void) {
|
||||||
(void)data;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
void taskMenu(void *data);
|
void menuShow(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // MENU_H
|
#endif // MENU_H
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "task.h"
|
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
@ -28,174 +27,30 @@
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct NetworkPacketS {
|
typedef struct NetworkChannelsS {
|
||||||
uint8_t key;
|
uint8_t key;
|
||||||
PacketDecodeDataT **value;
|
netPacketHandler value;
|
||||||
} NetworkPacketT;
|
} NetworkChannelsT;
|
||||||
|
|
||||||
|
|
||||||
static NetworkPacketT *_packets = NULL;
|
static netPacketHandler *_systemHandlers = NULL;
|
||||||
static uint8_t _netRunning = 0;
|
static NetworkChannelsT *_channels = NULL;
|
||||||
static uint8_t _netStarted = 0;
|
static uint8_t _netRunning = 0;
|
||||||
|
static uint8_t _netStarted = 0;
|
||||||
|
|
||||||
|
|
||||||
int8_t netConnectStep1(void) {
|
uint8_t netChannelGet(netPacketHandler handler) {
|
||||||
int32_t r = 0;
|
uint8_t channel = 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) {
|
|
||||||
uint8_t channel = 0; // We reserve 0 for system stuff. Returning 0 means no channel was found.
|
|
||||||
uint16_t x = 0;
|
uint16_t x = 0;
|
||||||
|
|
||||||
for (x=1; x<255; x++) {
|
// We reserve 0 for system stuff.
|
||||||
if (hmgeti(_packets, x) < 0) {
|
// Returning 0 means no channel was found.
|
||||||
|
|
||||||
|
// Find first unused channel.
|
||||||
|
for (x=1; x<255; x++) {
|
||||||
|
if (hmgeti(_channels, x) < 0) {
|
||||||
channel = x;
|
channel = x;
|
||||||
|
hmput(_channels, x, handler);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,23 +59,121 @@ uint8_t netGetChannelFree(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PacketDecodeDataT *netGetPacket(uint8_t channel) {
|
void netChannelRelease(uint8_t channel) {
|
||||||
int32_t r = 0;
|
hmdel(_channels, channel);
|
||||||
PacketDecodeDataT *packet = NULL;
|
}
|
||||||
|
|
||||||
r = hmgeti(_packets, channel);
|
|
||||||
if (r < 0) return NULL;
|
|
||||||
if (arrlen(_packets[r].value) == 0) return NULL;
|
|
||||||
packet = _packets[r].value[0];
|
|
||||||
arrdel(_packets[r].value, 0);
|
|
||||||
|
|
||||||
return packet;
|
void netChannelSystemGet(netPacketHandler handler) {
|
||||||
|
arrput(_systemHandlers, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void netChannelSystemRelease(netPacketHandler handler) {
|
||||||
|
uint16_t x;
|
||||||
|
|
||||||
|
for (x=0; x<arrlen(_systemHandlers); /* no increment */) {
|
||||||
|
if (_systemHandlers[x] == handler) {
|
||||||
|
arrdel(_systemHandlers, x);
|
||||||
|
} else {
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void netPacketHandlerStart(void) {
|
||||||
|
_netRunning = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void netPacketHandlerStop(void) {
|
||||||
|
if (_netRunning) {
|
||||||
|
_netRunning = 0;
|
||||||
|
|
||||||
|
// Return all channels.
|
||||||
|
while (hmlen(_channels)) hmdel(_channels, _channels[0].key);
|
||||||
|
hmfree(_channels);
|
||||||
|
|
||||||
|
// Return all system channels.
|
||||||
|
while (arrlen(_systemHandlers)) arrdel(_systemHandlers, 0);
|
||||||
|
arrfree(_systemHandlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void netProcess(void) {
|
||||||
|
int32_t r;
|
||||||
|
char buffer[1024];
|
||||||
|
PacketDecodeDataT *packet;
|
||||||
|
PacketDecodeDataT decoded;
|
||||||
|
PacketEncodeDataT encoded;
|
||||||
|
|
||||||
|
// ***TODO*** Detect disconnection. Maybe have callbacks registered that can notify tasks?
|
||||||
|
|
||||||
|
if (_netRunning) {
|
||||||
|
|
||||||
|
// Read pending bytes.
|
||||||
|
r = comRead(__configData.serialCom - 1, buffer, 1024);
|
||||||
|
// New data or not, process anything in the queue.
|
||||||
|
if (packetDecode(__packetThreadData, &decoded, buffer, r)) {
|
||||||
|
switch (decoded.packetType) {
|
||||||
|
case PACKET_TYPE_PING:
|
||||||
|
// Reply with PONG
|
||||||
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
|
encoded.packetType = PACKET_TYPE_PONG;
|
||||||
|
encoded.channel = 0;
|
||||||
|
encoded.encrypt = 0;
|
||||||
|
packetEncode(__packetThreadData, &encoded, NULL, 0);
|
||||||
|
packetSend(__packetThreadData, &encoded);
|
||||||
|
packetDecodeDataStaticDestroy(&decoded);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Is this the system channel?
|
||||||
|
if (decoded.channel == 0) {
|
||||||
|
// Send it to all registered handlers.
|
||||||
|
for (r=0; r<arrlen(_systemHandlers); r++) {
|
||||||
|
// Copy the packet out.
|
||||||
|
NEW(PacketDecodeDataT, packet);
|
||||||
|
packet->channel = decoded.channel;
|
||||||
|
packet->length = decoded.length;
|
||||||
|
packet->packetType = decoded.packetType;
|
||||||
|
packet->data = (char *)malloc(decoded.length);
|
||||||
|
memcpy(packet->data, decoded.data, decoded.length);
|
||||||
|
// Send it to the subscriber.
|
||||||
|
_systemHandlers[r](packet);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Does someone want this channel?
|
||||||
|
r = hmgeti(_channels, decoded.channel);
|
||||||
|
if (r >= 0) {
|
||||||
|
// Copy the packet out.
|
||||||
|
NEW(PacketDecodeDataT, packet);
|
||||||
|
packet->channel = decoded.channel;
|
||||||
|
packet->length = decoded.length;
|
||||||
|
packet->packetType = decoded.packetType;
|
||||||
|
packet->data = (char *)malloc(decoded.length);
|
||||||
|
memcpy(packet->data, decoded.data, decoded.length);
|
||||||
|
// Send it to the subscriber.
|
||||||
|
_channels[r].value(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Destroy our copy.
|
||||||
|
packetDecodeDataStaticDestroy(&decoded);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _netRunning
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void netShutdown(void) {
|
void netShutdown(void) {
|
||||||
FILE *cache = NULL;
|
FILE *cache = NULL;
|
||||||
|
|
||||||
|
netPacketHandlerStop();
|
||||||
|
|
||||||
if (_netStarted) {
|
if (_netStarted) {
|
||||||
_netStarted = 0;
|
_netStarted = 0;
|
||||||
|
|
||||||
|
@ -230,7 +183,7 @@ void netShutdown(void) {
|
||||||
if (__runtimeData.integers) {
|
if (__runtimeData.integers) {
|
||||||
while (shlen(__runtimeData.integers) > 0) {
|
while (shlen(__runtimeData.integers) > 0) {
|
||||||
//logWrite("[%s]=[%d]\n", __runtimeData.integers[0].key, __runtimeData.integers[0].value);
|
//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);
|
fprintf(cache, "%s=%ld\n", __runtimeData.integers[0].key, (long)__runtimeData.integers[0].value);
|
||||||
shdel(__runtimeData.integers, __runtimeData.integers[0].key);
|
shdel(__runtimeData.integers, __runtimeData.integers[0].key);
|
||||||
}
|
}
|
||||||
shfree(__runtimeData.integers);
|
shfree(__runtimeData.integers);
|
||||||
|
@ -255,8 +208,6 @@ void netShutdown(void) {
|
||||||
|
|
||||||
packetThreadDataDestroy(&__packetThreadData);
|
packetThreadDataDestroy(&__packetThreadData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_netRunning = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,131 +215,59 @@ void netStartup(void) {
|
||||||
FILE *cache = NULL;
|
FILE *cache = NULL;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
char *temp = NULL;
|
||||||
|
|
||||||
_netStarted = 1;
|
if (!_netStarted) {
|
||||||
|
_netStarted = 1;
|
||||||
|
|
||||||
__packetThreadData = packetThreadDataCreate(NULL);
|
__packetThreadData = packetThreadDataCreate(NULL);
|
||||||
packetSenderRegister(comPacketSender);
|
packetSenderRegister(comPacketSender);
|
||||||
|
|
||||||
__runtimeData.integers = NULL;
|
__runtimeData.integers = NULL;
|
||||||
__runtimeData.strings = NULL;
|
__runtimeData.strings = NULL;
|
||||||
__runtimeData.protocolVersion = 0;
|
__runtimeData.protocolVersion = 0;
|
||||||
|
|
||||||
sh_new_strdup(__runtimeData.integers);
|
sh_new_strdup(__runtimeData.integers);
|
||||||
sh_new_strdup(__runtimeData.strings);
|
sh_new_strdup(__runtimeData.strings);
|
||||||
|
|
||||||
// ***TODO*** Default initial tables
|
// ***TODO*** Default initial tables
|
||||||
|
|
||||||
line = (char *)malloc(4096);
|
line = (char *)malloc(4096);
|
||||||
if (line) {
|
if (line) {
|
||||||
// Load string cache.
|
// Load string cache.
|
||||||
cache = fopen("cache/string.dat", "rt");
|
cache = fopen("cache/string.dat", "rt");
|
||||||
if (cache) {
|
if (cache) {
|
||||||
while (fscanf(cache, "%s\n", line) != EOF) {
|
while (fscanf(cache, "%s\n", line) != EOF) {
|
||||||
p = strstr(line, "=");
|
p = strstr(line, "=");
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = 0;
|
*p = 0;
|
||||||
p++;
|
p++;
|
||||||
shput(__runtimeData.strings, line, strdup(p));
|
// Do we have this string already?
|
||||||
|
temp = shget(__runtimeData.strings, line);
|
||||||
|
if (temp) {
|
||||||
|
DEL(temp);
|
||||||
|
shdel(__runtimeData.strings, line);
|
||||||
|
}
|
||||||
|
shput(__runtimeData.strings, line, strdup(p));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
fclose(cache);
|
||||||
}
|
}
|
||||||
fclose(cache);
|
// Load integer cache.
|
||||||
}
|
cache = fopen("cache/integer.dat", "rt");
|
||||||
// Load integer cache.
|
if (cache) {
|
||||||
cache = fopen("cache/integer.dat", "rt");
|
while (fscanf(cache, "%s\n", line) != EOF) {
|
||||||
if (cache) {
|
p = strstr(line, "=");
|
||||||
while (fscanf(cache, "%s\n", line) != EOF) {
|
if (p) {
|
||||||
p = strstr(line, "=");
|
*p = 0;
|
||||||
if (p) {
|
p++;
|
||||||
*p = 0;
|
shput(__runtimeData.integers, line, atol(p));
|
||||||
p++;
|
}
|
||||||
shput(__runtimeData.integers, line, atol(p));
|
|
||||||
}
|
}
|
||||||
|
fclose(cache);
|
||||||
}
|
}
|
||||||
fclose(cache);
|
free(line);
|
||||||
|
line = NULL;
|
||||||
}
|
}
|
||||||
free(line);
|
|
||||||
line = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taskCreate(taskNetwork, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskNetwork(void *data) {
|
|
||||||
int32_t r = 0;
|
|
||||||
char buffer[1024] = { 0 };
|
|
||||||
PacketDecodeDataT *packet = NULL;
|
|
||||||
PacketDecodeDataT decoded = { 0 };
|
|
||||||
PacketEncodeDataT encoded = { 0 };
|
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
_netRunning = 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
// ***TODO*** Detect disconnection. Maybe have callbacks registered that can notify tasks?
|
|
||||||
|
|
||||||
// Read pending bytes.
|
|
||||||
r = comRead(__configData.serialCom - 1, buffer, 1024);
|
|
||||||
// New data or not, process anything in the queue.
|
|
||||||
if (packetDecode(__packetThreadData, &decoded, buffer, r)) {
|
|
||||||
|
|
||||||
// Is this something we care about?
|
|
||||||
switch (decoded.packetType) {
|
|
||||||
case PACKET_TYPE_PING:
|
|
||||||
// Reply with PONG
|
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
|
||||||
encoded.packetType = PACKET_TYPE_PONG;
|
|
||||||
encoded.channel = 0;
|
|
||||||
encoded.encrypt = 0;
|
|
||||||
packetEncode(__packetThreadData, &encoded, NULL, 0);
|
|
||||||
packetSend(__packetThreadData, &encoded);
|
|
||||||
packetDecodeDataStaticDestroy(&decoded);
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Silences a warning.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the packet out.
|
|
||||||
NEW(PacketDecodeDataT, packet);
|
|
||||||
packet->channel = decoded.channel;
|
|
||||||
packet->length = decoded.length;
|
|
||||||
packet->packetType = decoded.packetType;
|
|
||||||
packet->data = (char *)malloc(decoded.length);
|
|
||||||
memcpy(packet->data, decoded.data, decoded.length);
|
|
||||||
|
|
||||||
// Is there a list of packets for this channel already?
|
|
||||||
r = hmgeti(_packets, packet->channel);
|
|
||||||
if (r < 0) {
|
|
||||||
// No. Create dynamic array for this channel.
|
|
||||||
hmput(_packets, packet->channel, NULL);
|
|
||||||
r = hmgeti(_packets, packet->channel);
|
|
||||||
}
|
|
||||||
// Add new packet to existing list.
|
|
||||||
arrput(_packets[r].value, packet);
|
|
||||||
|
|
||||||
packetDecodeDataStaticDestroy(&decoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yield to UI.
|
|
||||||
taskYield();
|
|
||||||
|
|
||||||
} while (!guiHasStopped() && _netRunning);
|
|
||||||
|
|
||||||
// Free any unclaimed packets.
|
|
||||||
while (hmlenu(_packets) > 0) {
|
|
||||||
// Free any packets for this channel.
|
|
||||||
while (arrlenu(_packets[0].value) > 0) {
|
|
||||||
packetDecodeDataDestroy(&_packets[0].value[0]);
|
|
||||||
arrdel(_packets[0].value, 0);
|
|
||||||
}
|
|
||||||
arrfree(_packets[0].value);
|
|
||||||
hmdel(_packets, _packets[0].key);
|
|
||||||
}
|
|
||||||
hmfree(_packets);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,23 +25,18 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
#define NETWORK_CONNECT_SUCCESS 0
|
typedef void (*netPacketHandler)(PacketDecodeDataT *packet);
|
||||||
#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);
|
uint8_t netChannelGet(netPacketHandler handler);
|
||||||
int8_t netConnectStep2(void);
|
void netChannelRelease(uint8_t channel);
|
||||||
void netDisconnect(void);
|
void netChannelSystemGet(netPacketHandler handler);
|
||||||
uint8_t netGetChannelFree(void);
|
void netChannelSystemRelease(netPacketHandler handler);
|
||||||
PacketDecodeDataT *netGetPacket(uint8_t channel);
|
void netPacketHandlerStart(void);
|
||||||
void netShutdown(void);
|
void netPacketHandlerStop(void);
|
||||||
void netStartup(void);
|
void netProcess(void);
|
||||||
|
void netShutdown(void);
|
||||||
void taskNetwork(void *data);
|
void netStartup(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // NETWORK_H
|
#endif // NETWORK_H
|
||||||
|
|
|
@ -22,9 +22,7 @@
|
||||||
#include "welcome.h"
|
#include "welcome.h"
|
||||||
|
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
#include "task.h"
|
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
@ -34,6 +32,7 @@
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
#include "updown.h"
|
#include "updown.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
|
||||||
#define GROUP_COM 1
|
#define GROUP_COM 1
|
||||||
|
@ -46,6 +45,14 @@
|
||||||
#define TITLE_LEN 80
|
#define TITLE_LEN 80
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum SettingsStateE {
|
||||||
|
S_START_SCAN = 0,
|
||||||
|
S_OPEN_COM,
|
||||||
|
S_WAIT_FOR_INIT,
|
||||||
|
S_SCAN_COMPLETE
|
||||||
|
} SettingsStateT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct PortS {
|
typedef struct PortS {
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
char title[TITLE_LEN];
|
char title[TITLE_LEN];
|
||||||
|
@ -55,19 +62,23 @@ typedef struct PortS {
|
||||||
} PortT;
|
} PortT;
|
||||||
|
|
||||||
|
|
||||||
static WindowT *_winDetecting;
|
static WindowT *_winDetecting = NULL;
|
||||||
static LabelT *_lblOneMoment;
|
static LabelT *_lblOneMoment = NULL;
|
||||||
static WindowT *_winSettings;
|
static WindowT *_winSettings = NULL;
|
||||||
static FrameT *_frmComPorts;
|
static FrameT *_frmComPorts = NULL;
|
||||||
static FrameT *_frmServer;
|
static FrameT *_frmServer = NULL;
|
||||||
static ButtonT *_btnOkay;
|
static ButtonT *_btnOkay = NULL;
|
||||||
static TextboxT *_txtServer;
|
static TextboxT *_txtServer = NULL;
|
||||||
static UpdownT *_updPort;
|
static TimerT *_timProgress = NULL;
|
||||||
static PortT _port[4];
|
static UpdownT *_updPort = NULL;
|
||||||
static widgetCallback _done;
|
static PortT _port[4] = { 0 };
|
||||||
|
static widgetCallback _done = NULL;
|
||||||
|
static SettingsStateT _state = S_START_SCAN;
|
||||||
|
|
||||||
|
|
||||||
static void btnOkayClick(WidgetT *widget);
|
static void btnOkayClick(WidgetT *widget);
|
||||||
|
static void settingsComShow(void);
|
||||||
|
static void timSettingsProgress(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
static void btnOkayClick(WidgetT *widget) {
|
static void btnOkayClick(WidgetT *widget) {
|
||||||
|
@ -95,61 +106,9 @@ static void btnOkayClick(WidgetT *widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int8_t settingsScanComPorts(void) {
|
void settingsShow(void *callback) {
|
||||||
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.
|
_done = (widgetCallback)callback;
|
||||||
for (int x=0; x<4; x++) {
|
|
||||||
rc = comOpen(x, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
|
||||||
if (rc == SER_SUCCESS) {
|
|
||||||
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
|
|
||||||
comWrite(x, buffer, strlen(buffer));
|
|
||||||
timerQuarterSecondsWait(4);
|
|
||||||
len = comRead(x, buffer, 1023);
|
|
||||||
buffer[len] = 0;
|
|
||||||
if (strstr(buffer, "OK")) {
|
|
||||||
snprintf(_port[x].title, TITLE_LEN - 1, "COM%d - SoftModem Found!", x + 1);
|
|
||||||
_port[x].status = PORT_GOOD_MODEM;
|
|
||||||
_port[x].selected = selected;
|
|
||||||
_port[x].enabled = 1;
|
|
||||||
selected = 0;
|
|
||||||
lastFound = x;
|
|
||||||
} else {
|
|
||||||
if (strstr(buffer, "ERROR")) {
|
|
||||||
snprintf(_port[x].title, TITLE_LEN - 1, "COM%d - Incompatable Modem", x + 1);
|
|
||||||
_port[x].status = PORT_BAD_MODEM;
|
|
||||||
_port[x].selected = 0;
|
|
||||||
_port[x].enabled = 0;
|
|
||||||
} else {
|
|
||||||
snprintf(_port[x].title, TITLE_LEN - 1, "COM%d - No Modem", x + 1);
|
|
||||||
_port[x].status = PORT_NO_MODEM;
|
|
||||||
_port[x].selected = 0;
|
|
||||||
_port[x].enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
comClose(x);
|
|
||||||
} else {
|
|
||||||
snprintf(_port[x].title, TITLE_LEN - 1, "COM%d - Not Present", x + 1);
|
|
||||||
_port[x].status = PORT_NONE;
|
|
||||||
_port[x].selected = 0;
|
|
||||||
_port[x].enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastFound;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskSettings(void *data) {
|
|
||||||
|
|
||||||
int32_t rc;
|
|
||||||
uint32_t len;
|
|
||||||
|
|
||||||
_done = (widgetCallback)data;
|
|
||||||
|
|
||||||
TagItemT uiDetecting[] = {
|
TagItemT uiDetecting[] = {
|
||||||
T_START,
|
T_START,
|
||||||
|
@ -160,14 +119,27 @@ void taskSettings(void *data) {
|
||||||
T_X, 25, T_Y, 25,
|
T_X, 25, T_Y, 25,
|
||||||
T_TITLE, P("One Moment Please!"),
|
T_TITLE, P("One Moment Please!"),
|
||||||
T_LABEL, T_DONE,
|
T_LABEL, T_DONE,
|
||||||
|
T_TIMER, O(_timProgress),
|
||||||
|
T_EVENT, P(timSettingsProgress),
|
||||||
|
T_VALUE, 0,
|
||||||
|
T_TIMER, T_DONE,
|
||||||
T_WINDOW, T_DONE,
|
T_WINDOW, T_DONE,
|
||||||
T_END
|
T_END
|
||||||
};
|
};
|
||||||
|
|
||||||
tagListRun(uiDetecting);
|
// We can use a module-global variable instead of widget user data
|
||||||
taskYield(); // Cause dialog to paint.
|
// because there will never be more than one settings dialog on
|
||||||
|
// the screen at a time.
|
||||||
|
_state = S_START_SCAN;
|
||||||
|
|
||||||
settingsScanComPorts();
|
tagListRun(uiDetecting);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void settingsComShow(void) {
|
||||||
|
|
||||||
|
int32_t y;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
guiDelete(D(_winDetecting));
|
guiDelete(D(_winDetecting));
|
||||||
|
|
||||||
|
@ -222,12 +194,88 @@ void taskSettings(void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add COM discovery to GUI.
|
// Add COM discovery to GUI.
|
||||||
rc = 0;
|
y = 0;
|
||||||
for (len=0; len<4; len++) {
|
for (len=0; len<4; len++) {
|
||||||
_port[len].rdoCOM = radioNew(5, rc, _port[len].title, GROUP_COM);
|
_port[len].rdoCOM = radioNew(5, y, _port[len].title, GROUP_COM);
|
||||||
if (_port[len].selected) radioSelectedSet(_port[len].rdoCOM);
|
if (_port[len].selected) radioSelectedSet(_port[len].rdoCOM);
|
||||||
widgetEnableSet(W(_port[len].rdoCOM), _port[len].enabled);
|
widgetEnableSet(W(_port[len].rdoCOM), _port[len].enabled);
|
||||||
guiAttach(W(_frmComPorts), W(_port[len].rdoCOM));
|
guiAttach(W(_frmComPorts), W(_port[len].rdoCOM));
|
||||||
rc += 20;
|
y += 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void timSettingsProgress(WidgetT *widget) {
|
||||||
|
char buffer[1024];
|
||||||
|
int32_t rc;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
|
static uint8_t selected;
|
||||||
|
static int32_t com;
|
||||||
|
|
||||||
|
switch (_state) {
|
||||||
|
case S_START_SCAN:
|
||||||
|
com = 0;
|
||||||
|
selected = 1;
|
||||||
|
_state = S_OPEN_COM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_OPEN_COM:
|
||||||
|
rc = comOpen(com, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
||||||
|
if (rc == SER_SUCCESS) {
|
||||||
|
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
|
||||||
|
comWrite(com, buffer, strlen(buffer));
|
||||||
|
timerQuarterSecondsSet((TimerT *)widget, 4);
|
||||||
|
_state = S_WAIT_FOR_INIT;
|
||||||
|
} else {
|
||||||
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Not Present", com + 1);
|
||||||
|
_port[com].status = PORT_NONE;
|
||||||
|
_port[com].selected = 0;
|
||||||
|
_port[com].enabled = 0;
|
||||||
|
com++;
|
||||||
|
if (com < 4) {
|
||||||
|
_state = S_OPEN_COM;
|
||||||
|
} else {
|
||||||
|
_state = S_SCAN_COMPLETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_FOR_INIT:
|
||||||
|
len = comRead(com, buffer, 1023);
|
||||||
|
buffer[len] = 0;
|
||||||
|
if (strstr(buffer, "OK")) {
|
||||||
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Modem Found!", com + 1);
|
||||||
|
_port[com].status = PORT_GOOD_MODEM;
|
||||||
|
_port[com].selected = selected;
|
||||||
|
_port[com].enabled = 1;
|
||||||
|
selected = 0;
|
||||||
|
} else {
|
||||||
|
if (strstr(buffer, "ERROR")) {
|
||||||
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - Incompatable Modem", com + 1);
|
||||||
|
_port[com].status = PORT_BAD_MODEM;
|
||||||
|
_port[com].selected = 0;
|
||||||
|
_port[com].enabled = 0;
|
||||||
|
} else {
|
||||||
|
snprintf(_port[com].title, TITLE_LEN - 1, "COM%d - No Modem", com + 1);
|
||||||
|
_port[com].status = PORT_NO_MODEM;
|
||||||
|
_port[com].selected = 0;
|
||||||
|
_port[com].enabled = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
comClose(com);
|
||||||
|
com++;
|
||||||
|
if (com < 4) {
|
||||||
|
_state = S_OPEN_COM;
|
||||||
|
} else {
|
||||||
|
_state = S_SCAN_COMPLETE;
|
||||||
|
}
|
||||||
|
timerQuarterSecondsSet((TimerT *)widget, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_SCAN_COMPLETE:
|
||||||
|
timerStop(_timProgress);
|
||||||
|
settingsComShow();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
int8_t settingsScanComPorts(void);
|
void settingsShow(void *callback);
|
||||||
void taskSettings(void *data);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|
|
@ -22,34 +22,44 @@
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "msgbox.h"
|
#include "msgbox.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
#include "signup.h"
|
#include "signup.h"
|
||||||
#include "login.h"
|
#include "login.h"
|
||||||
|
|
||||||
|
|
||||||
static WindowT *_winSignUp = NULL;
|
typedef enum SignUpStateE {
|
||||||
static LabelT *_lblRequired = NULL;
|
S_START_SIGNUP = 0,
|
||||||
static TextboxT *_txtEmail = NULL;
|
S_SIGNUP_WAIT
|
||||||
static TextboxT *_txtFirst = NULL;
|
} SignUpStateT;
|
||||||
static TextboxT *_txtLast = NULL;
|
|
||||||
static TextboxT *_txtUser = NULL;
|
|
||||||
static TextboxT *_txtPass1 = NULL;
|
static WindowT *_winSignUp = NULL;
|
||||||
static TextboxT *_txtPass2 = NULL;
|
static LabelT *_lblRequired = NULL;
|
||||||
static ButtonT *_btnCancel = NULL;
|
static TextboxT *_txtEmail = NULL;
|
||||||
static ButtonT *_btnSignUp = NULL;
|
static TextboxT *_txtFirst = NULL;
|
||||||
|
static TextboxT *_txtLast = NULL;
|
||||||
|
static TextboxT *_txtUser = NULL;
|
||||||
|
static TextboxT *_txtPass1 = NULL;
|
||||||
|
static TextboxT *_txtPass2 = NULL;
|
||||||
|
static ButtonT *_btnCancel = NULL;
|
||||||
|
static ButtonT *_btnSignUp = NULL;
|
||||||
|
static TimerT *_timProgress = NULL;
|
||||||
|
static SignUpStateT _state = S_START_SIGNUP;
|
||||||
|
static uint8_t _channel = 0;
|
||||||
|
|
||||||
|
|
||||||
static void btnCancelClick(WidgetT *widget);
|
static void btnCancelClick(WidgetT *widget);
|
||||||
static void btnMsgBoxContinue(MsgBoxButtonT button);
|
static void btnMsgBoxContinue(MsgBoxButtonT button);
|
||||||
static void btnMsgBoxFinish(MsgBoxButtonT button);
|
static void btnMsgBoxFinish(MsgBoxButtonT button);
|
||||||
|
static void btnSignUpClick(WidgetT *widget);
|
||||||
|
static void packetHandler(PacketDecodeDataT *packet);
|
||||||
static void setButtons(uint8_t enabled);
|
static void setButtons(uint8_t enabled);
|
||||||
static void taskSignUpClick(void *data);
|
static void timSignUpProgress(WidgetT *widget);
|
||||||
static uint8_t validateEmail(char *email);
|
static uint8_t validateEmail(char *email);
|
||||||
static uint8_t validateEmailLetter(char c);
|
static uint8_t validateEmailLetter(char c);
|
||||||
static uint8_t validateName(char *username);
|
static uint8_t validateName(char *username);
|
||||||
|
@ -61,7 +71,8 @@ static void btnCancelClick(WidgetT *widget) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
guiDelete(D(_winSignUp));
|
guiDelete(D(_winSignUp));
|
||||||
taskCreate(taskLogin, NULL);
|
netChannelRelease(_channel);
|
||||||
|
loginShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +87,73 @@ static void btnMsgBoxFinish(MsgBoxButtonT button) {
|
||||||
(void)button;
|
(void)button;
|
||||||
|
|
||||||
guiDelete(D(_winSignUp));
|
guiDelete(D(_winSignUp));
|
||||||
taskCreate(taskLogin, NULL);
|
netChannelRelease(_channel);
|
||||||
|
loginShow();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void btnSignUpClick(WidgetT *widget) {
|
||||||
|
(void)widget;
|
||||||
|
|
||||||
|
setButtons(0);
|
||||||
|
|
||||||
|
// Validate it. ***TODO*** These messages could be a lot better.
|
||||||
|
if (!validateEmail(textboxValueGet(_txtEmail))) {
|
||||||
|
msgBoxOne("Invalid E-Mail", MSGBOX_ICON_ERROR, "Please enter a valid E-mail address.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validateName(textboxValueGet(_txtFirst))) {
|
||||||
|
msgBoxOne("Invalid First Name", MSGBOX_ICON_ERROR, "Please enter a valid first name.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validateName(textboxValueGet(_txtLast))) {
|
||||||
|
msgBoxOne("Invalid Last Name", MSGBOX_ICON_ERROR, "Please enter a valid last name.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strcmp(textboxValueGet(_txtPass1), textboxValueGet(_txtPass2)) != 0) {
|
||||||
|
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Passwords must match.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validatePassword(textboxValueGet(_txtPass1))) {
|
||||||
|
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Please enter a valid password.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validateUser(textboxValueGet(_txtUser))) {
|
||||||
|
msgBoxOne("Invalid User Name", MSGBOX_ICON_ERROR, "Please enter a valid user name.", "Okay", btnMsgBoxContinue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = S_START_SIGNUP;
|
||||||
|
timerQuarterSecondsSet(_timProgress, 0);
|
||||||
|
timerStart(_timProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void packetHandler(PacketDecodeDataT *packet) {
|
||||||
|
uint16_t length;
|
||||||
|
char *packetData;
|
||||||
|
|
||||||
|
// Reset timeout.
|
||||||
|
timerReset(_timProgress);
|
||||||
|
|
||||||
|
switch (packet->packetType) {
|
||||||
|
case PACKET_TYPE_SIGNUP_RESULT:
|
||||||
|
packetContentUnpack(packet->data, "is", &length, &packetData);
|
||||||
|
if (length) {
|
||||||
|
msgBoxOne("Success!", MSGBOX_ICON_INFORMATION, packetData, "Okay", btnMsgBoxFinish);
|
||||||
|
} else {
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
||||||
|
}
|
||||||
|
DEL(packetData);
|
||||||
|
timerStop(_timProgress);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logWrite("Unexpected packet received: %d\n", packet->packetType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetDecodeDataDestroy(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,9 +163,7 @@ static void setButtons(uint8_t enabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void taskSignUp(void *data) {
|
void signupShow(void) {
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
TagItemT uiSignUp[] = {
|
TagItemT uiSignUp[] = {
|
||||||
T_START,
|
T_START,
|
||||||
|
@ -160,101 +235,56 @@ void taskSignUp(void *data) {
|
||||||
T_BUTTON, O(_btnSignUp),
|
T_BUTTON, O(_btnSignUp),
|
||||||
T_TITLE, P("Sign Up"),
|
T_TITLE, P("Sign Up"),
|
||||||
T_X, 291, T_Y, 270,
|
T_X, 291, T_Y, 270,
|
||||||
T_CLICK, P(taskProxy),
|
T_CLICK, P(btnSignUpClick),
|
||||||
T_USER_DATA, P(taskSignUpClick),
|
|
||||||
T_BUTTON, T_DONE,
|
T_BUTTON, T_DONE,
|
||||||
|
T_TIMER, O(_timProgress),
|
||||||
|
T_EVENT, P(timSignUpProgress),
|
||||||
|
T_VALUE, 0,
|
||||||
|
T_ENABLED, 0,
|
||||||
|
T_TIMER, T_DONE,
|
||||||
|
|
||||||
T_WINDOW, T_DONE,
|
T_WINDOW, T_DONE,
|
||||||
T_END
|
T_END
|
||||||
};
|
};
|
||||||
|
|
||||||
tagListRun(uiSignUp);
|
tagListRun(uiSignUp);
|
||||||
|
_channel = netChannelGet(packetHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void taskSignUpClick(void *data) {
|
static void timSignUpProgress(WidgetT *widget) {
|
||||||
PacketEncodeDataT encoded = { 0 };
|
PacketEncodeDataT encoded;
|
||||||
PacketDecodeDataT *decoded = NULL;
|
uint16_t length;
|
||||||
int16_t timeout = 10;
|
char *packetData;
|
||||||
uint16_t length = 0;
|
TimerT *t = (TimerT *)widget;
|
||||||
char *packetData = NULL;
|
|
||||||
|
|
||||||
(void)data;
|
switch (_state) {
|
||||||
|
case S_START_SIGNUP:
|
||||||
|
packetData = packetContentPack(&length, "sssss",
|
||||||
|
textboxValueGet(_txtEmail),
|
||||||
|
textboxValueGet(_txtFirst),
|
||||||
|
textboxValueGet(_txtLast),
|
||||||
|
textboxValueGet(_txtPass1),
|
||||||
|
textboxValueGet(_txtUser)
|
||||||
|
);
|
||||||
|
|
||||||
// ***TODO*** This should disable the entire dialog instead of just the buttons. Need to finish the Enable GUI code first.
|
// Send signup request.
|
||||||
|
encoded.packetType = PACKET_TYPE_SIGNUP;
|
||||||
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
|
encoded.channel = _channel;
|
||||||
|
encoded.encrypt = 1;
|
||||||
|
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||||
|
packetSend(__packetThreadData, &encoded);
|
||||||
|
DEL(packetData);
|
||||||
|
// Wait for response.
|
||||||
|
timerQuarterSecondsSet(_timProgress, 10 * 4);
|
||||||
|
break;
|
||||||
|
|
||||||
setButtons(0);
|
case S_SIGNUP_WAIT:
|
||||||
|
timerStop(t);
|
||||||
// Validate it. ***TODO*** These messages could be a lot better.
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "No response received.", "Okay", btnMsgBoxContinue);
|
||||||
if (!validateEmail(textboxValueGet(_txtEmail))) {
|
break;
|
||||||
msgBoxOne("Invalid E-Mail", MSGBOX_ICON_ERROR, "Please enter a valid E-mail address.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!validateName(textboxValueGet(_txtFirst))) {
|
|
||||||
msgBoxOne("Invalid First Name", MSGBOX_ICON_ERROR, "Please enter a valid first name.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!validateName(textboxValueGet(_txtLast))) {
|
|
||||||
msgBoxOne("Invalid Last Name", MSGBOX_ICON_ERROR, "Please enter a valid last name.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (strcmp(textboxValueGet(_txtPass1), textboxValueGet(_txtPass2)) != 0) {
|
|
||||||
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Passwords must match.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!validatePassword(textboxValueGet(_txtPass1))) {
|
|
||||||
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Please enter a valid password.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!validateUser(textboxValueGet(_txtUser))) {
|
|
||||||
msgBoxOne("Invalid User Name", MSGBOX_ICON_ERROR, "Please enter a valid user name.", "Okay", btnMsgBoxContinue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
packetData = packetContentPack(&length, "sssss",
|
|
||||||
textboxValueGet(_txtEmail),
|
|
||||||
textboxValueGet(_txtFirst),
|
|
||||||
textboxValueGet(_txtLast),
|
|
||||||
textboxValueGet(_txtPass1),
|
|
||||||
textboxValueGet(_txtUser)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Send signup request.
|
|
||||||
encoded.packetType = PACKET_TYPE_SIGNUP;
|
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
|
||||||
encoded.channel = 0;
|
|
||||||
encoded.encrypt = 1;
|
|
||||||
packetEncode(__packetThreadData, &encoded, packetData, length);
|
|
||||||
packetSend(__packetThreadData, &encoded);
|
|
||||||
|
|
||||||
DEL(packetData);
|
|
||||||
|
|
||||||
// Wait for response.
|
|
||||||
do {
|
|
||||||
decoded = netGetPacket(0);
|
|
||||||
if (decoded) {
|
|
||||||
switch (decoded->packetType) {
|
|
||||||
case PACKET_TYPE_SIGNUP_RESULT:
|
|
||||||
packetContentUnpack(decoded->data, "is", &length, &packetData);
|
|
||||||
if (length) {
|
|
||||||
msgBoxOne("Success!", MSGBOX_ICON_INFORMATION, packetData, "Okay", btnMsgBoxFinish);
|
|
||||||
} else {
|
|
||||||
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
|
||||||
}
|
|
||||||
DEL(packetData);
|
|
||||||
timeout = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
|
|
||||||
timeout = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
packetDecodeDataDestroy(&decoded);
|
|
||||||
}
|
|
||||||
taskYield();
|
|
||||||
if (__timerQuarterSecondTick) timeout--;
|
|
||||||
} while (!guiHasStopped() && timeout > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
void taskSignUp(void *data);
|
void signupShow(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // SIGNUP_H
|
#endif // SIGNUP_H
|
||||||
|
|
|
@ -17,10 +17,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "task.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,44 +41,65 @@ int comReceiveBufferFlush(int com) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int comWaitWithTimeout(int com, char *buffer, int len, int quarterSeconds, char *expecting) {
|
/*
|
||||||
int r;
|
TASKBEGIN(comWaitWithTimeout)
|
||||||
int quarterTicks = 0;
|
int32_t r;
|
||||||
int count = 0;
|
uint32_t quarterTicks;
|
||||||
int bufferIndex = 0;
|
int32_t count;
|
||||||
char data[2];
|
int32_t bufferIndex;
|
||||||
|
char incoming[2];
|
||||||
|
ComWaitWithTimeoutT *args;
|
||||||
|
|
||||||
// Returns number of bytes read into buffer.
|
taskCode({
|
||||||
// Value is positive if "expect" was found.
|
// Returns number of bytes read into buffer.
|
||||||
// Value is negative if not found.
|
// Value is positive if "expect" was found.
|
||||||
|
// Value is negative if not found.
|
||||||
|
|
||||||
while (quarterTicks <= quarterSeconds) {
|
logWrite("Entering comWaitWithTimeout\n");
|
||||||
r = comRead(com, data, 1);
|
|
||||||
if (r == 1) {
|
self->args = (ComWaitWithTimeoutT *)data;
|
||||||
buffer[bufferIndex++] = data[0];
|
|
||||||
buffer[bufferIndex] = 0;
|
while (self->quarterTicks <= self->args->quarterSeconds) {
|
||||||
if (data[0] == expecting[count]) {
|
|
||||||
count++;
|
// logWrite("Calling comRead\n");
|
||||||
if (count == (int)strlen(expecting)) {
|
self->r = comRead(self->args->com, self->incoming, 1);
|
||||||
// Found our expect.
|
// logWrite("Back from comRead with %d\n", self->r);
|
||||||
|
|
||||||
|
if (self->r == 1) {
|
||||||
|
self->args->buffer[self->bufferIndex++] = self->incoming[0];
|
||||||
|
self->args->buffer[self->bufferIndex] = 0;
|
||||||
|
if (self->incoming[0] == self->args->expecting[self->count]) {
|
||||||
|
self->count++;
|
||||||
|
if (self->count == (int)strlen(self->args->expecting)) {
|
||||||
|
// Found our expect.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self->count = 0;
|
||||||
|
}
|
||||||
|
if (self->bufferIndex == self->args->len - 1) {
|
||||||
|
// Out of buffer.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
count = 0;
|
|
||||||
}
|
}
|
||||||
if (bufferIndex == len - 1) {
|
|
||||||
// Out of buffer.
|
// logWrite("Yielding from comWaitWithTimeout\n");
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
taskYield();
|
taskYield();
|
||||||
if (__timerQuarterSecondTick) quarterTicks++;
|
// logWrite("Back in comWaitWithTimeout\n");
|
||||||
|
|
||||||
|
if (__timerQuarterSecondTick) {
|
||||||
|
self->quarterTicks++;
|
||||||
|
logWrite("Tick\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (count == (int)strlen(expecting)) {
|
logWrite("Exiting comWaitWithTimeout\n");
|
||||||
return bufferIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -bufferIndex;
|
if (self->count == (int)strlen(self->args->expecting)) {
|
||||||
}
|
self->args->result = self->bufferIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->args->result = -self->bufferIndex;
|
||||||
|
});
|
||||||
|
TASKEND
|
||||||
|
*/
|
||||||
|
|
|
@ -26,6 +26,16 @@
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ComWaitWithTimeoutS {
|
||||||
|
int32_t result;
|
||||||
|
uint8_t com;
|
||||||
|
char *buffer;
|
||||||
|
int32_t len;
|
||||||
|
uint32_t quarterSeconds;
|
||||||
|
char *expecting;
|
||||||
|
} ComWaitWithTimeoutT;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
#define SER_SUCCESS 0
|
#define SER_SUCCESS 0
|
||||||
|
@ -35,7 +45,6 @@
|
||||||
|
|
||||||
#define SER_HANDSHAKING_RTSCTS 2
|
#define SER_HANDSHAKING_RTSCTS 2
|
||||||
|
|
||||||
|
|
||||||
int comClose(int com);
|
int comClose(int com);
|
||||||
int comOpen(int com, long bps, int dataBits, char parity, int stopBits, int handshaking);
|
int comOpen(int com, long bps, int dataBits, char parity, int stopBits, int handshaking);
|
||||||
int comRead(int com, char *data, int len);
|
int comRead(int com, char *data, int len);
|
||||||
|
@ -55,7 +64,6 @@ int comWrite(int com, const char *data, int len);
|
||||||
|
|
||||||
void comPacketSender(char *data, uint32_t length, void *userData);
|
void comPacketSender(char *data, uint32_t length, void *userData);
|
||||||
int comReceiveBufferFlush(int com);
|
int comReceiveBufferFlush(int com);
|
||||||
int comWaitWithTimeout(int com, char *buffer, int len, int quarterSeconds, char *expecting);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // COMPORT_H
|
#endif // COMPORT_H
|
||||||
|
|
|
@ -21,6 +21,16 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t osFileExists(char *filename) {
|
||||||
|
FILE *f = fopen(filename, "rb");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void osShutdown(void) {
|
void osShutdown(void) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
linuxOsShutdown();
|
linuxOsShutdown();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
// Common platform includes.
|
// Common platform includes.
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -37,12 +38,17 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define SECONDS_IN_DAY 86400
|
||||||
|
#define TICKS_PER_SECOND 18.2
|
||||||
|
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
#define BITS64
|
#define BITS64
|
||||||
|
|
||||||
// Linux DOS replacements.
|
// Linux DOS replacements.
|
||||||
long biostime(int cmd, long newtime);
|
uint32_t rawclock(void);
|
||||||
|
|
||||||
// Linux support functions.
|
// Linux support functions.
|
||||||
void linuxOsShutdown(void);
|
void linuxOsShutdown(void);
|
||||||
|
@ -75,8 +81,8 @@ void linuxOsStartup(void);
|
||||||
|
|
||||||
|
|
||||||
// Allocation helpers.
|
// Allocation helpers.
|
||||||
#define NEW(t,v) (v)=(t*)malloc(sizeof(t))
|
#define NEW(t,v) (v)=(t*)calloc(1, sizeof(t))
|
||||||
#define DEL(v) {free(v); v=NULL;}
|
#define DEL(v) { if (v) { free(v); v = NULL; } }
|
||||||
|
|
||||||
#define SUCCESS 1
|
#define SUCCESS 1
|
||||||
#define FAIL 0
|
#define FAIL 0
|
||||||
|
@ -93,8 +99,9 @@ typedef struct PacketThreadDataS PacketThreadDataT;
|
||||||
extern PacketThreadDataT *__packetThreadData; // Declared in main.c
|
extern PacketThreadDataT *__packetThreadData; // Declared in main.c
|
||||||
|
|
||||||
|
|
||||||
void osShutdown(void);
|
uint8_t osFileExists(char *filename);
|
||||||
void osStartup(void);
|
void osShutdown(void);
|
||||||
|
void osStartup(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // OS_H
|
#endif // OS_H
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "textbox.h"
|
#include "textbox.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "updown.h"
|
#include "updown.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
|
@ -166,6 +167,7 @@ static void tagListWidgetAttributeHandle(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_CLICK:
|
case T_CLICK:
|
||||||
|
case T_EVENT:
|
||||||
click = (widgetCallback)v;
|
click = (widgetCallback)v;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -331,6 +333,13 @@ static void tagListWidgetAttributeHandle(void) {
|
||||||
textboxPasswordCharacterSet((TextboxT *)widget, mask);
|
textboxPasswordCharacterSet((TextboxT *)widget, mask);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_TIMER:
|
||||||
|
if (hasValue && click) {
|
||||||
|
widget = W(timerNew(click, (uint32_t)valueInt));
|
||||||
|
if (!enabled) timerStop((TimerT *)widget);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case T_UPDOWN:
|
case T_UPDOWN:
|
||||||
widget = W(updownNew(pos.x, pos.y, minimum, maximum, step, title));
|
widget = W(updownNew(pos.x, pos.y, minimum, maximum, step, title));
|
||||||
if (hasValue) updownValueSet((UpdownT *)widget, valueInt);
|
if (hasValue) updownValueSet((UpdownT *)widget, valueInt);
|
||||||
|
|
|
@ -54,6 +54,7 @@ enum TagItemsE {
|
||||||
T_RADIOBUTTON,
|
T_RADIOBUTTON,
|
||||||
T_TERMINAL,
|
T_TERMINAL,
|
||||||
T_TEXTBOX,
|
T_TEXTBOX,
|
||||||
|
T_TIMER,
|
||||||
T_UPDOWN,
|
T_UPDOWN,
|
||||||
T_WINDOW,
|
T_WINDOW,
|
||||||
|
|
||||||
|
@ -65,6 +66,7 @@ enum TagItemsE {
|
||||||
T_COLOR_BACKGROUND,
|
T_COLOR_BACKGROUND,
|
||||||
T_COLOR_FOREGROUND,
|
T_COLOR_FOREGROUND,
|
||||||
T_ENABLED,
|
T_ENABLED,
|
||||||
|
T_EVENT,
|
||||||
T_FILENAME,
|
T_FILENAME,
|
||||||
T_GROUP,
|
T_GROUP,
|
||||||
T_HEIGHT,
|
T_HEIGHT,
|
||||||
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
* Kangaroo Punch MultiPlayer Game Server Mark II
|
|
||||||
* Copyright (C) 2020-2021 Scott Duensing
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define MINICORO_IMPL
|
|
||||||
#define MCO_USE_ASM
|
|
||||||
//#define MCO_DEFAULT_STACK_SIZE 114688 // Default is 57344
|
|
||||||
#include "thirdparty/minicoro/minicoro.h"
|
|
||||||
|
|
||||||
#include "task.h"
|
|
||||||
#include "array.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct TaskS {
|
|
||||||
mco_coro *coroutine;
|
|
||||||
void (*function)(void *);
|
|
||||||
void *data;
|
|
||||||
} TaskT;
|
|
||||||
|
|
||||||
|
|
||||||
static TaskT **_taskList = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static void taskHandle(mco_coro* coroutine);
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t taskCreate(void (*function)(void *), void *data) {
|
|
||||||
mco_desc desc = mco_desc_init(taskHandle, 0);
|
|
||||||
mco_result res = 0;
|
|
||||||
TaskT *task = (TaskT *)malloc(sizeof(TaskT));
|
|
||||||
|
|
||||||
if (task) {
|
|
||||||
task->function = function;
|
|
||||||
task->data = data;
|
|
||||||
desc.user_data = task;
|
|
||||||
res = mco_create(&task->coroutine, &desc);
|
|
||||||
if (res != MCO_SUCCESS) {
|
|
||||||
mco_destroy(task->coroutine);
|
|
||||||
free(task);
|
|
||||||
return 1; // Failed
|
|
||||||
}
|
|
||||||
arrput(_taskList, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; // Failed
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void taskHandle(mco_coro* coroutine) {
|
|
||||||
TaskT *task = (TaskT *)mco_get_user_data(coroutine);
|
|
||||||
task->function(task->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskProxy(WidgetT *widget) {
|
|
||||||
taskFunction task = (taskFunction)guiUserDataGet(widget);
|
|
||||||
taskCreate(task, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskRun(void) {
|
|
||||||
uint16_t taskIndex = 0;
|
|
||||||
|
|
||||||
// Run until there are no more tasks.
|
|
||||||
while (arrlen(_taskList) > 0) {
|
|
||||||
|
|
||||||
// Run each task in order.
|
|
||||||
taskIndex = 0;
|
|
||||||
while (taskIndex < arrlen(_taskList)) {
|
|
||||||
|
|
||||||
// Run task.
|
|
||||||
mco_resume(_taskList[taskIndex]->coroutine);
|
|
||||||
// Did it finish?
|
|
||||||
if (mco_status(_taskList[taskIndex]->coroutine) == MCO_DEAD) {
|
|
||||||
// Task ended. Remove it.
|
|
||||||
mco_destroy(_taskList[taskIndex]->coroutine);
|
|
||||||
free(_taskList[taskIndex]);
|
|
||||||
arrdel(_taskList, taskIndex);
|
|
||||||
} else {
|
|
||||||
// Next task.
|
|
||||||
taskIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // while each task
|
|
||||||
|
|
||||||
} // while tasks exist
|
|
||||||
|
|
||||||
arrfree(_taskList);
|
|
||||||
_taskList = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskShutdown(void) {
|
|
||||||
// Nada
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void taskStartup(void) {
|
|
||||||
// Nada
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void __attribute__ ((noinline)) taskYield(void) {
|
|
||||||
mco_yield(mco_running());
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
* Kangaroo Punch MultiPlayer Game Server Mark II
|
|
||||||
* Copyright (C) 2020-2021 Scott Duensing
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "timer.h"
|
|
||||||
#include "task.h"
|
|
||||||
#include "gui.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define SECONDS_IN_DAY 86400
|
|
||||||
#define TICKS_PER_SECOND 18.2
|
|
||||||
#define TICKS_PER_DAY (SECONDS_IN_DAY * TICKS_PER_SECOND)
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t __timerQuarterSecondTick = 0;
|
|
||||||
uint8_t __timerHalfSecondTick = 0;
|
|
||||||
uint8_t __timerSecondTick = 0;
|
|
||||||
|
|
||||||
uint8_t __timerQuarterSecondOn = 0;
|
|
||||||
uint8_t __timerHalfSecondOn = 0;
|
|
||||||
uint8_t __timerSecondOn = 0;
|
|
||||||
|
|
||||||
|
|
||||||
static long _timerLast = 0;
|
|
||||||
static uint8_t _timerHalfSecond = 2;
|
|
||||||
static uint8_t _timerSecond = 2;
|
|
||||||
|
|
||||||
|
|
||||||
void timerShutdown(void) {
|
|
||||||
// Nothing yet.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void timerStartup(void) {
|
|
||||||
_timerLast = biostime(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void timerUpdate(void) {
|
|
||||||
long now;
|
|
||||||
long delta;
|
|
||||||
|
|
||||||
now = biostime(0, 0);
|
|
||||||
|
|
||||||
// Reset ticks.
|
|
||||||
__timerQuarterSecondTick = 0;
|
|
||||||
__timerHalfSecondTick = 0;
|
|
||||||
__timerSecondTick = 0;
|
|
||||||
|
|
||||||
// Ensure we haven't rolled past midnight between calls.
|
|
||||||
if (now >= _timerLast) {
|
|
||||||
delta = now - _timerLast;
|
|
||||||
} else {
|
|
||||||
// Compensate for midnight rollover.
|
|
||||||
delta = (now + TICKS_PER_DAY) - _timerLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything ticks off the quarter second.
|
|
||||||
if (delta > TICKS_PER_SECOND * 0.25) {
|
|
||||||
_timerLast = now;
|
|
||||||
|
|
||||||
// Quarter Second timer.
|
|
||||||
__timerQuarterSecondOn = !__timerQuarterSecondOn;
|
|
||||||
__timerQuarterSecondTick = 1;
|
|
||||||
|
|
||||||
// Half Second timer.
|
|
||||||
if (--_timerHalfSecond == 0) {
|
|
||||||
_timerHalfSecond = 2;
|
|
||||||
__timerHalfSecondOn = !__timerHalfSecondOn;
|
|
||||||
__timerHalfSecondTick = 1;
|
|
||||||
|
|
||||||
// Second timer
|
|
||||||
if (--_timerSecond == 0) {
|
|
||||||
_timerSecond = 2;
|
|
||||||
__timerSecondOn = !__timerSecondOn;
|
|
||||||
__timerSecondTick = 1;
|
|
||||||
} // Second.
|
|
||||||
|
|
||||||
} // Half Second.
|
|
||||||
|
|
||||||
} // Quarter Second.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void timerQuarterSecondsWait(uint8_t quarterSeconds) {
|
|
||||||
uint8_t counter = 0;
|
|
||||||
|
|
||||||
while (counter <= quarterSeconds && !guiHasStopped()) {
|
|
||||||
if (__timerQuarterSecondTick) {
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
taskYield();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,35 +23,62 @@
|
||||||
#include "login.h"
|
#include "login.h"
|
||||||
|
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
#include "task.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "comport.h"
|
#include "comport.h"
|
||||||
#include "timer.h"
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "runtime.h"
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "picture.h"
|
#include "picture.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "msgbox.h"
|
#include "msgbox.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
|
||||||
static WindowT *_winWelcome = NULL;
|
typedef enum WelcomeStateE {
|
||||||
static PictureT *_picLogo = NULL;
|
S_START_CONNECT = 0,
|
||||||
static PictureT *_picInit = NULL;
|
S_START_INIT_MODEM,
|
||||||
static PictureT *_picDialing = NULL;
|
S_INIT_MODEM,
|
||||||
static PictureT *_picConnect = NULL;
|
S_INIT_RESULT,
|
||||||
static ButtonT *_btnQuit = NULL;
|
S_DIAL,
|
||||||
static ButtonT *_btnSettings = NULL;
|
S_WAIT_FOR_BANNER,
|
||||||
static ButtonT *_btnConnect = NULL;
|
S_WAIT_FOR_ENCRYPTION,
|
||||||
|
S_WAIT_FOR_DATA_TIMEOUT,
|
||||||
|
S_WAIT_FOR_ICON
|
||||||
|
} WelcomeStateT;
|
||||||
|
|
||||||
|
|
||||||
static void taskConnectClick(void *data);
|
static WindowT *_winWelcome = NULL;
|
||||||
|
static PictureT *_picLogo = NULL;
|
||||||
|
static PictureT *_picInit = NULL;
|
||||||
|
static PictureT *_picDialing = NULL;
|
||||||
|
static PictureT *_picConnect = NULL;
|
||||||
|
static ButtonT *_btnQuit = NULL;
|
||||||
|
static ButtonT *_btnSettings = NULL;
|
||||||
|
static ButtonT *_btnConnect = NULL;
|
||||||
|
static TimerT *_timProgress = NULL;
|
||||||
|
static WelcomeStateT _state = S_START_CONNECT;
|
||||||
|
static int16_t _timeoutCounter = 0;
|
||||||
|
|
||||||
|
|
||||||
|
static void btnConnectClick(WidgetT *widget);
|
||||||
static void btnMsgBox(MsgBoxButtonT button);
|
static void btnMsgBox(MsgBoxButtonT button);
|
||||||
static void btnMsgBoxQuit(MsgBoxButtonT button);
|
static void btnMsgBoxQuit(MsgBoxButtonT button);
|
||||||
static void btnQuitClick(WidgetT *widget);
|
static void btnQuitClick(WidgetT *widget);
|
||||||
static void btnSettingsClick(WidgetT *widget);
|
static void btnSettingsClick(WidgetT *widget);
|
||||||
|
static void packetHandler(PacketDecodeDataT *packet);
|
||||||
static void setButtons(uint8_t enabled);
|
static void setButtons(uint8_t enabled);
|
||||||
static void settingsFinished(WidgetT *widget);
|
static void settingsFinished(WidgetT *widget);
|
||||||
|
static void timWelcomeProgress(WidgetT *widget);
|
||||||
|
|
||||||
|
|
||||||
|
static void btnConnectClick(WidgetT *widget) {
|
||||||
|
(void)widget;
|
||||||
|
|
||||||
|
_state = S_START_CONNECT;
|
||||||
|
timerQuarterSecondsSet(_timProgress, 0);
|
||||||
|
timerStart(_timProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void btnMsgBox(MsgBoxButtonT button) {
|
static void btnMsgBox(MsgBoxButtonT button) {
|
||||||
|
@ -79,6 +106,7 @@ static void btnMsgBoxQuit(MsgBoxButtonT button) {
|
||||||
|
|
||||||
static void btnQuitClick(WidgetT *widget) {
|
static void btnQuitClick(WidgetT *widget) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
setButtons(0);
|
setButtons(0);
|
||||||
msgBoxTwo("Quit?", MSGBOX_ICON_QUESTION, "Exit to DOS?", "Okay", btnMsgBoxQuit, "Cancel", btnMsgBoxQuit);
|
msgBoxTwo("Quit?", MSGBOX_ICON_QUESTION, "Exit to DOS?", "Okay", btnMsgBoxQuit, "Cancel", btnMsgBoxQuit);
|
||||||
}
|
}
|
||||||
|
@ -86,8 +114,69 @@ static void btnQuitClick(WidgetT *widget) {
|
||||||
|
|
||||||
static void btnSettingsClick(WidgetT *widget) {
|
static void btnSettingsClick(WidgetT *widget) {
|
||||||
(void)widget;
|
(void)widget;
|
||||||
|
|
||||||
setButtons(0);
|
setButtons(0);
|
||||||
taskCreate(taskSettings, settingsFinished);
|
settingsShow(settingsFinished);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void packetHandler(PacketDecodeDataT *packet) {
|
||||||
|
PacketEncodeDataT encoded;
|
||||||
|
char *temp;
|
||||||
|
|
||||||
|
// Reset timeout.
|
||||||
|
timerReset(_timProgress);
|
||||||
|
|
||||||
|
switch (packet->packetType) {
|
||||||
|
case PACKET_TYPE_NUMBER:
|
||||||
|
// Store in number table.
|
||||||
|
shput(__runtimeData.integers, &packet->data[4], (int32_t)packet->data[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PACKET_TYPE_PROCEED:
|
||||||
|
// Connected! Show icon.
|
||||||
|
widgetVisibleSet(W(_picConnect), 1);
|
||||||
|
// Leave it up about 1.5 seconds.
|
||||||
|
timerQuarterSecondsSet(_timProgress, 6);
|
||||||
|
_state = S_WAIT_FOR_ICON;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PACKET_TYPE_STRING:
|
||||||
|
// Do we have this string already?
|
||||||
|
temp = shget(__runtimeData.strings, packet->data);
|
||||||
|
if (temp) {
|
||||||
|
DEL(temp);
|
||||||
|
shdel(__runtimeData.strings, packet->data);
|
||||||
|
}
|
||||||
|
// Store in string table.
|
||||||
|
shput(__runtimeData.strings, packet->data, strdup(&packet->data[strlen(packet->data) + 1]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PACKET_TYPE_VERSION:
|
||||||
|
packetContentUnpack(packet->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);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logWrite("Unexpected packet received: %d\n", packet->packetType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetDecodeDataDestroy(&packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,9 +193,7 @@ static void settingsFinished(WidgetT *widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void taskWelcome(void *data) {
|
void welcomeShow(void) {
|
||||||
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
// 450x128 logo
|
// 450x128 logo
|
||||||
|
|
||||||
|
@ -150,10 +237,14 @@ void taskWelcome(void *data) {
|
||||||
T_BUTTON, O(_btnConnect),
|
T_BUTTON, O(_btnConnect),
|
||||||
T_TITLE, P("Connect"),
|
T_TITLE, P("Connect"),
|
||||||
T_X, 379, T_Y, 157,
|
T_X, 379, T_Y, 157,
|
||||||
T_CLICK, P(taskProxy),
|
T_CLICK, P(btnConnectClick),
|
||||||
T_USER_DATA, P(taskConnectClick),
|
|
||||||
T_ENABLED, (__configData.serialCom > 0 && strlen(__configData.serverHost) > 2) ? T_TRUE : T_FALSE,
|
T_ENABLED, (__configData.serialCom > 0 && strlen(__configData.serverHost) > 2) ? T_TRUE : T_FALSE,
|
||||||
T_BUTTON, T_DONE,
|
T_BUTTON, T_DONE,
|
||||||
|
T_TIMER, O(_timProgress),
|
||||||
|
T_EVENT, P(timWelcomeProgress),
|
||||||
|
T_VALUE, 0,
|
||||||
|
T_ENABLED, 0,
|
||||||
|
T_TIMER, T_DONE,
|
||||||
|
|
||||||
T_WINDOW, T_DONE,
|
T_WINDOW, T_DONE,
|
||||||
T_END
|
T_END
|
||||||
|
@ -163,59 +254,128 @@ void taskWelcome(void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void taskConnectClick(void *data) {
|
static void timWelcomeProgress(WidgetT *widget) {
|
||||||
int32_t r = 0;
|
TimerT *t = (TimerT *)widget;
|
||||||
int16_t timeout = 0;
|
int32_t r = 0;
|
||||||
|
uint32_t len = 0;
|
||||||
|
static char buffer[1024] = { 0 };
|
||||||
|
static uint16_t offset = 0;
|
||||||
|
|
||||||
(void)data;
|
switch (_state) {
|
||||||
|
case S_START_CONNECT:
|
||||||
|
// 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);
|
||||||
|
_state = S_START_INIT_MODEM;
|
||||||
|
break;
|
||||||
|
|
||||||
// Ghost all buttons.
|
case S_START_INIT_MODEM:
|
||||||
widgetEnableSet(W(_btnConnect), 0);
|
// Open COM port.
|
||||||
widgetEnableSet(W(_btnSettings), 0);
|
r = comOpen(__configData.serialCom - 1, 57600L, 8, 'n', 1, SER_HANDSHAKING_RTSCTS);
|
||||||
widgetEnableSet(W(_btnQuit), 0);
|
if (r != SER_SUCCESS) {
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("COM Problem", MSGBOX_ICON_ERROR, "Unable to open COM port!\nPlease check settings.", "Okay", btnMsgBox);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Send a CR to clear anything in the modem.
|
||||||
|
snprintf(buffer, 1023, "%c", 13);
|
||||||
|
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
||||||
|
timerQuarterSecondsSet(t, 4);
|
||||||
|
_state = S_INIT_MODEM;
|
||||||
|
break;
|
||||||
|
|
||||||
// Hide welcome banner, show init.
|
case S_INIT_MODEM:
|
||||||
widgetVisibleSet(W(_picLogo), 0);
|
// Just read anything to clear the buffer.
|
||||||
widgetVisibleSet(W(_picInit), 1);
|
len = comRead(__configData.serialCom - 1, buffer, 1023);
|
||||||
taskYield();
|
// Send actual init
|
||||||
|
snprintf(buffer, 1023, "%s%c", "AT+SOCK1", 13);
|
||||||
|
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
||||||
|
_state = S_INIT_RESULT;
|
||||||
|
break;
|
||||||
|
|
||||||
r = netConnectStep1();
|
case S_INIT_RESULT:
|
||||||
if (r == NETWORK_CONNECT_OPEN_FAILED) {
|
len = comRead(__configData.serialCom - 1, buffer, 1023);
|
||||||
msgBoxOne("COM Problem", MSGBOX_ICON_ERROR, "Unable to open COM port!\nPlease check settings.", "Okay", btnMsgBox);
|
buffer[len] = 0;
|
||||||
return;
|
if (strstr(buffer, "OK") == NULL) {
|
||||||
|
comClose(__configData.serialCom - 1);
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("Modem Problem", MSGBOX_ICON_ERROR, "Modem does not support ENET!\nPlease check settings.", "Okay", btnMsgBox);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Show dialing, dial service.
|
||||||
|
widgetVisibleSet(W(_picDialing), 1);
|
||||||
|
timerQuarterSecondsSet(t, 0);
|
||||||
|
_state = S_DIAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_DIAL:
|
||||||
|
snprintf(buffer, 1023, "ATDT%s:%d%c", __configData.serverHost, __configData.serverPort, 13);
|
||||||
|
comWrite(__configData.serialCom - 1, buffer, strlen(buffer));
|
||||||
|
timerQuarterSecondsSet(t, 0); // Run as fast as we can so we don't miss any data.
|
||||||
|
offset = 0;
|
||||||
|
_timeoutCounter = 7 * 4; // Seven seconds.
|
||||||
|
_state = S_WAIT_FOR_BANNER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_FOR_BANNER:
|
||||||
|
// Process incoming bytes one at a time so we don't accidentally eat the first packet after the banner.
|
||||||
|
len = comRead(__configData.serialCom - 1, &buffer[offset], 1);
|
||||||
|
offset += len;
|
||||||
|
buffer[offset] = 0;
|
||||||
|
// ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
|
||||||
|
if (strstr(buffer, "KPMPGSMKII\rOKAY\r") != NULL) {
|
||||||
|
// Connect! Start packet handler and negotiate encryption.
|
||||||
|
netPacketHandlerStart();
|
||||||
|
packetEncryptionSetup(__packetThreadData);
|
||||||
|
// Watch system channel for packets.
|
||||||
|
netChannelSystemGet(packetHandler);
|
||||||
|
timerQuarterSecondsSet(t, 1);
|
||||||
|
_timeoutCounter = 5 * 4; // Five seconds.
|
||||||
|
_state = S_WAIT_FOR_ENCRYPTION;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Did we time out?
|
||||||
|
if (guiTimerQuarterSecondTick()) _timeoutCounter--;
|
||||||
|
if (_timeoutCounter == 0) {
|
||||||
|
comClose(__configData.serialCom - 1);
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("No Connection", MSGBOX_ICON_INFORMATION, "Unable to connect to server!\nPlease check settings or try later.", "Okay", btnMsgBox);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_FOR_ENCRYPTION:
|
||||||
|
if (packetEncryptionReady()) {
|
||||||
|
timerQuarterSecondsSet(t, 5 * 4);
|
||||||
|
_state = S_WAIT_FOR_DATA_TIMEOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Did we time out?
|
||||||
|
_timeoutCounter--;
|
||||||
|
if (_timeoutCounter == 0) {
|
||||||
|
netPacketHandlerStop();
|
||||||
|
comClose(__configData.serialCom - 1);
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to negotiate encryption settings!", "Okay", btnMsgBox);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_FOR_DATA_TIMEOUT:
|
||||||
|
netPacketHandlerStop();
|
||||||
|
comClose(__configData.serialCom - 1);
|
||||||
|
timerStop(t);
|
||||||
|
msgBoxOne("Negotiation Error", MSGBOX_ICON_INFORMATION, "Unable to fetch client settings!", "Okay", btnMsgBox);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_WAIT_FOR_ICON:
|
||||||
|
// Switch to Login window.
|
||||||
|
timerStop(t);
|
||||||
|
netChannelSystemRelease(packetHandler);
|
||||||
|
guiDelete(D(_winWelcome));
|
||||||
|
loginShow();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
|
||||||
void taskWelcome(void *data);
|
void welcomeShow(void);
|
||||||
|
|
||||||
|
|
||||||
#endif // WELCOME_H
|
#endif // WELCOME_H
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Title: Chat
|
Title: Discord
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
5
kanga.world/content/4_chat/2_matrix/redirect.txt
Normal file
5
kanga.world/content/4_chat/2_matrix/redirect.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Title: Matrix
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Redirect: https://matrix.to/#/#DosGame:matrix.kangaroopunch.com
|
1
kanga.world/content/4_chat/go-home.txt
Normal file
1
kanga.world/content/4_chat/go-home.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Title: Chat
|
|
@ -57,6 +57,7 @@ function kpApiUserLogin($username, $pass, &$response) {
|
||||||
// Find user by name instead of email.
|
// Find user by name instead of email.
|
||||||
$user = kirby()->users()->filterBy('name', $username)->first();
|
$user = kirby()->users()->filterBy('name', $username)->first();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
|
// ***TODO*** Must be activated!
|
||||||
// Attempt to sign them in.
|
// Attempt to sign them in.
|
||||||
kirby()->auth()->login($user->email(), $pass);
|
kirby()->auth()->login($user->email(), $pass);
|
||||||
// They don't need an actual Kirby session, so log them off.
|
// They don't need an actual Kirby session, so log them off.
|
||||||
|
|
|
@ -23,6 +23,11 @@ return [
|
||||||
|
|
||||||
switch (get('command')) {
|
switch (get('command')) {
|
||||||
|
|
||||||
|
case 'API_AVAILABLE':
|
||||||
|
$response['result'] = 'true';
|
||||||
|
$response['reason'] = 'API Available.';
|
||||||
|
break;
|
||||||
|
|
||||||
case 'API_TEST':
|
case 'API_TEST':
|
||||||
kpApiTest($response);
|
kpApiTest($response);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"><?= $item->title() ?></a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"><?= $item->title() ?></a>
|
||||||
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
<?php foreach($item->children()->listed()->flip() as $child): ?>
|
<?php foreach($item->children()->listed() as $child): ?>
|
||||||
<li><a class="dropdown-item" href="<?= $child->url() ?>"><?= $child->year() ?> - <?= $child->title() ?></a></li>
|
<li><a class="dropdown-item" href="<?= $child->url() ?>"><?= $child->title() ?></a></li>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
5
kanga.world/site/templates/go-home.php
Normal file
5
kanga.world/site/templates/go-home.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0; url=/" />
|
||||||
|
</head>
|
||||||
|
</html>
|
|
@ -37,17 +37,10 @@ typedef void (*clientApi)(ClientThreadT *client, PacketDecodeDataT *data);
|
||||||
|
|
||||||
|
|
||||||
// Also update enum in packets.h!
|
// Also update enum in packets.h!
|
||||||
clientApi clientApiMethod[PACKET_END_OF_SERVER_PACKETS - PACKET_END_OF_DUAL_PACKETS] = {
|
static clientApi _clientApiMethod[PACKET_TYPE_COUNT];
|
||||||
clientApiClientShutdown,
|
|
||||||
clientApiLogin,
|
|
||||||
clientApiPong,
|
|
||||||
clientApiSignup,
|
|
||||||
clientApiVersionBad,
|
|
||||||
clientApiVersionOkay
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t clientDequeuePacket(ClientThreadT *client);
|
static uint8_t clientDequeuePacket(ClientThreadT *client);
|
||||||
|
|
||||||
|
|
||||||
static uint8_t clientDequeuePacket(ClientThreadT *client) {
|
static uint8_t clientDequeuePacket(ClientThreadT *client) {
|
||||||
|
@ -68,8 +61,8 @@ static uint8_t clientDequeuePacket(ClientThreadT *client) {
|
||||||
|
|
||||||
// New data or not, process anything in the queue.
|
// New data or not, process anything in the queue.
|
||||||
if (packetDecode(client->packetThreadData, &decode, data, length)) {
|
if (packetDecode(client->packetThreadData, &decode, data, length)) {
|
||||||
if ((decode.packetType > PACKET_END_OF_DUAL_PACKETS) && (decode.packetType < PACKET_END_OF_SERVER_PACKETS)) {
|
if (_clientApiMethod[decode.packetType]) {
|
||||||
clientApiMethod[decode.packetType - (PACKET_END_OF_DUAL_PACKETS + 1)](client, &decode);
|
_clientApiMethod[decode.packetType](client, &decode);
|
||||||
} else {
|
} else {
|
||||||
consoleMessageQueue("%ld: Channel %d Unknown Packet %d\n", client->threadIndex, decode.channel, decode.packetType);
|
consoleMessageQueue("%ld: Channel %d Unknown Packet %d\n", client->threadIndex, decode.channel, decode.packetType);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +96,23 @@ void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clientShutdown(void) {
|
||||||
|
// Nothing yet.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void clientStartup(void) {
|
||||||
|
memset(_clientApiMethod, 0, sizeof(_clientApiMethod));
|
||||||
|
|
||||||
|
_clientApiMethod[PACKET_TYPE_CLIENT_SHUTDOWN] = clientApiClientShutdown;
|
||||||
|
_clientApiMethod[PACKET_TYPE_LOGIN] = clientApiLogin;
|
||||||
|
_clientApiMethod[PACKET_TYPE_PONG] = clientApiPong;
|
||||||
|
_clientApiMethod[PACKET_TYPE_SIGNUP] = clientApiSignup;
|
||||||
|
_clientApiMethod[PACKET_TYPE_VERSION_BAD] = clientApiVersionBad;
|
||||||
|
_clientApiMethod[PACKET_TYPE_VERSION_OKAY] = clientApiVersionOkay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *clientThread(void *data) {
|
void *clientThread(void *data) {
|
||||||
|
|
||||||
ENetPeer *peer = (ENetPeer *)data;
|
ENetPeer *peer = (ENetPeer *)data;
|
||||||
|
@ -134,6 +144,7 @@ void *clientThread(void *data) {
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
DEL(packetData);
|
DEL(packetData);
|
||||||
versionSent = 1;
|
versionSent = 1;
|
||||||
|
consoleMessageQueue("PACKET_TYPE_VERSION sent.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@ typedef struct ClientThreadS {
|
||||||
|
|
||||||
|
|
||||||
void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length);
|
void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length);
|
||||||
|
void clientShutdown(void);
|
||||||
|
void clientStartup(void);
|
||||||
void *clientThread(void *data);
|
void *clientThread(void *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ void clientApiLogin(ClientThreadT *client, PacketDecodeDataT *data) {
|
||||||
// Build packet.
|
// Build packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_LOGIN_RESULT;
|
encoded.packetType = PACKET_TYPE_LOGIN_RESULT;
|
||||||
encoded.channel = 0;
|
encoded.channel = data->channel;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
||||||
// Send it.
|
// Send it.
|
||||||
|
|
|
@ -59,7 +59,7 @@ void clientApiSignup(ClientThreadT *client, PacketDecodeDataT *data) {
|
||||||
// Build packet.
|
// Build packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_SIGNUP_RESULT;
|
encoded.packetType = PACKET_TYPE_SIGNUP_RESULT;
|
||||||
encoded.channel = 0;
|
encoded.channel = data->channel;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
||||||
// Send it.
|
// Send it.
|
||||||
|
|
|
@ -72,12 +72,13 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
|
||||||
// Build packet.
|
// Build packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_STRING;
|
encoded.packetType = PACKET_TYPE_STRING;
|
||||||
encoded.channel = 0;
|
encoded.channel = data->channel;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, buffer, length);
|
packetEncode(client->packetThreadData, &encoded, buffer, length);
|
||||||
// Send it.
|
// Send it.
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
DEL(buffer);
|
DEL(buffer);
|
||||||
|
consoleMessageQueue("PACKET_TYPE_STRING [%s] sent.\n", strings[i].key);
|
||||||
}
|
}
|
||||||
restHelperConfigStringMapRelease(strings);
|
restHelperConfigStringMapRelease(strings);
|
||||||
|
|
||||||
|
@ -111,22 +112,23 @@ void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) {
|
||||||
// Build packet.
|
// Build packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_NUMBER;
|
encoded.packetType = PACKET_TYPE_NUMBER;
|
||||||
encoded.channel = 0;
|
encoded.channel = data->channel;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, buffer, length);
|
packetEncode(client->packetThreadData, &encoded, buffer, length);
|
||||||
// Send it.
|
// Send it.
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
DEL(buffer);
|
DEL(buffer);
|
||||||
|
consoleMessageQueue("PACKET_TYPE_NUMBER [%s] sent.\n", integers[i].key);
|
||||||
}
|
}
|
||||||
restHelperConfigIntegerMapRelease(integers);
|
restHelperConfigIntegerMapRelease(integers);
|
||||||
|
|
||||||
// Build PROCEED packet.
|
// Build PROCEED packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_PROCEED;
|
encoded.packetType = PACKET_TYPE_PROCEED;
|
||||||
encoded.channel = 0;
|
encoded.channel = data->channel;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, NULL, 0);
|
packetEncode(client->packetThreadData, &encoded, NULL, 0);
|
||||||
// Send it.
|
// Send it.
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
|
consoleMessageQueue("PACKET_TYPE_PROCEED sent.\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,7 @@ int main(int argc, char *argv[]) {
|
||||||
settingsClientVersion = restHelperConfigIntegerGet(response, "clientVersion", 1);
|
settingsClientVersion = restHelperConfigIntegerGet(response, "clientVersion", 1);
|
||||||
restRelease(response);
|
restRelease(response);
|
||||||
|
|
||||||
|
clientStartup();
|
||||||
serverStartup(settingsPortNumber, settingsMaxClients);
|
serverStartup(settingsPortNumber, settingsMaxClients);
|
||||||
logWrite("Server online.\n");
|
logWrite("Server online.\n");
|
||||||
|
|
||||||
|
@ -121,6 +122,7 @@ int main(int argc, char *argv[]) {
|
||||||
// Wait for all running threads to shut down.
|
// Wait for all running threads to shut down.
|
||||||
logWrite("Shutting down.\n");
|
logWrite("Shutting down.\n");
|
||||||
serverShutdown();
|
serverShutdown();
|
||||||
|
clientShutdown();
|
||||||
|
|
||||||
// Shut down.
|
// Shut down.
|
||||||
restShutdown();
|
restShutdown();
|
||||||
|
|
|
@ -275,7 +275,8 @@ void restShutdown(void) {
|
||||||
|
|
||||||
|
|
||||||
uint8_t restStartup(char *url, char *user, char *password) {
|
uint8_t restStartup(char *url, char *user, char *password) {
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
|
json_object *response;
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
|
@ -299,6 +300,11 @@ uint8_t restStartup(char *url, char *user, char *password) {
|
||||||
_restUser = strdup(user);
|
_restUser = strdup(user);
|
||||||
_restPass = strdup(password);
|
_restPass = strdup(password);
|
||||||
|
|
||||||
|
// Is the remote server there?
|
||||||
|
response = restRequest("API_AVAILABLE", NULL);
|
||||||
|
if (!response) return FAIL;
|
||||||
|
restRelease(response);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,8 +134,9 @@ void *serverThread(void *data) {
|
||||||
// Tell the console.
|
// Tell the console.
|
||||||
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
enet_address_get_host_ip(&event.peer->address, buffer, 2047);
|
||||||
consoleMessageQueue("%ld: [%s] connected.\n", client->threadIndex, buffer);
|
consoleMessageQueue("%ld: [%s] connected.\n", client->threadIndex, buffer);
|
||||||
|
// ***TODO*** Should probably cleanly handle a full server here with some kind of SERVER_FULL packet.
|
||||||
// Send banner to client.
|
// Send banner to client.
|
||||||
packet = enet_packet_create("KPMPGSMKII\r", 11, ENET_PACKET_FLAG_RELIABLE);
|
packet = enet_packet_create("KPMPGSMKII\rOKAY\r", 16, ENET_PACKET_FLAG_RELIABLE);
|
||||||
enet_peer_send(event.peer, 0, packet);
|
enet_peer_send(event.peer, 0, packet);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -78,11 +78,11 @@ void logWrite(char *format, ...) {
|
||||||
vsnprintf(_logBuffer, _logBufferSize, format, args2);
|
vsnprintf(_logBuffer, _logBufferSize, format, args2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
//#ifdef __linux__
|
||||||
// Also output to stdout on Linux.
|
// Also output to stdout on Linux.
|
||||||
fprintf(stdout, "%s", _logBuffer);
|
fprintf(stdout, "%s", _logBuffer);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
if (_logCallback) _logCallback(_logBuffer);
|
if (_logCallback) _logCallback(_logBuffer);
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,6 @@ char *packetContentPack(uint16_t *length, char *format, ...) {
|
||||||
static char work[PACKET_MAX] = { 0 };
|
static char work[PACKET_MAX] = { 0 };
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
int8_t value8 = 0;
|
|
||||||
int32_t value32 = 0;
|
int32_t value32 = 0;
|
||||||
|
|
||||||
*length = 0;
|
*length = 0;
|
||||||
|
@ -123,7 +122,6 @@ char *packetContentPack(uint16_t *length, char *format, ...) {
|
||||||
void packetContentUnpack(char *buffer, char *format, ...) {
|
void packetContentUnpack(char *buffer, char *format, ...) {
|
||||||
va_list args = { 0 };
|
va_list args = { 0 };
|
||||||
char **string = NULL;
|
char **string = NULL;
|
||||||
int8_t *value8 = NULL;
|
|
||||||
int32_t *value32 = NULL;
|
int32_t *value32 = NULL;
|
||||||
uint16_t length = 0;
|
uint16_t length = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,22 +31,19 @@
|
||||||
// This enum is treated as BYTES in the code. Do not go over 255 entries.
|
// This enum is treated as BYTES in the code. Do not go over 255 entries.
|
||||||
// Also update array in client.c!
|
// Also update array in client.c!
|
||||||
typedef enum PacketTypeE {
|
typedef enum PacketTypeE {
|
||||||
// Packets that can received by both server and client:
|
// These packets have to be first and in this order! Do not change them!
|
||||||
PACKET_TYPE_NONE = 0, // No packet.
|
PACKET_TYPE_NONE = 0, // No packet.
|
||||||
PACKET_TYPE_DH_REQUEST,
|
PACKET_TYPE_DH_REQUEST,
|
||||||
PACKET_TYPE_DH_RESPONSE,
|
PACKET_TYPE_DH_RESPONSE,
|
||||||
|
PACKET_TYPE_VERSION,
|
||||||
PACKET_END_OF_DUAL_PACKETS,
|
PACKET_TYPE_VERSION_BAD,
|
||||||
|
PACKET_TYPE_VERSION_OKAY,
|
||||||
|
|
||||||
// Packets received by only the server:
|
// Packets received by only the server:
|
||||||
PACKET_TYPE_CLIENT_SHUTDOWN,
|
PACKET_TYPE_CLIENT_SHUTDOWN,
|
||||||
PACKET_TYPE_LOGIN,
|
PACKET_TYPE_LOGIN,
|
||||||
PACKET_TYPE_PONG,
|
PACKET_TYPE_PONG,
|
||||||
PACKET_TYPE_SIGNUP,
|
PACKET_TYPE_SIGNUP,
|
||||||
PACKET_TYPE_VERSION_BAD,
|
|
||||||
PACKET_TYPE_VERSION_OKAY,
|
|
||||||
|
|
||||||
PACKET_END_OF_SERVER_PACKETS,
|
|
||||||
|
|
||||||
// Packets received by only the client:
|
// Packets received by only the client:
|
||||||
PACKET_TYPE_LOGIN_RESULT,
|
PACKET_TYPE_LOGIN_RESULT,
|
||||||
|
@ -56,7 +53,6 @@ typedef enum PacketTypeE {
|
||||||
PACKET_TYPE_SERVER_SHUTDOWN,
|
PACKET_TYPE_SERVER_SHUTDOWN,
|
||||||
PACKET_TYPE_SIGNUP_RESULT,
|
PACKET_TYPE_SIGNUP_RESULT,
|
||||||
PACKET_TYPE_STRING,
|
PACKET_TYPE_STRING,
|
||||||
PACKET_TYPE_VERSION,
|
|
||||||
|
|
||||||
// How many packet types do we recognize?
|
// How many packet types do we recognize?
|
||||||
PACKET_TYPE_COUNT
|
PACKET_TYPE_COUNT
|
||||||
|
|
4
test.sh
4
test.sh
|
@ -1,2 +1,4 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
${HOME}/code/dosbox-custom/dosbox-staging/build/dosbox -noprimaryconf -nolocalconf -conf test.conf &
|
#${HOME}/code/dosbox-custom/dosbox-staging/build/dosbox -noprimaryconf -nolocalconf -conf test.conf &
|
||||||
|
#dosbox -noprimaryconf -nolocalconf -conf test.conf &
|
||||||
|
${HOME}/bin/dosbox-staging-linux-v0.78.1/dosbox -noprimaryconf -nolocalconf -conf test.conf &
|
||||||
|
|
Loading…
Add table
Reference in a new issue