Maelstrom: Work in progress on a multiplayer lobby dialog.

https://github.com/libsdl-org/Maelstrom/commit/09f5027a52964769a4090d35309ad62eab17ae2b

From 09f5027a52964769a4090d35309ad62eab17ae2b Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 5 Nov 2011 16:37:02 -0400
Subject: [PATCH] Work in progress on a multiplayer lobby dialog.

---
 Images/joystick.bmp  | Bin 0 -> 9270 bytes
 Images/keyboard.bmp  | Bin 0 -> 9270 bytes
 Images/network.bmp   | Bin 0 -> 9270 bytes
 MaelstromLobby.cpp   |  62 ++++++++++++
 MaelstromUI.cpp      |   3 +
 Maelstrom_Globals.h  |   2 +-
 Makefile.am          |  11 ++-
 Makefile.in          |  57 ++++++-----
 UI/lobby.xml         |  49 ++++++++++
 UI/main.xml          | 218 +++++++++++++++++++++++++++++++++++++++++++
 controls.cpp         |   3 +-
 controls.h           |   6 +-
 init.cpp             |   1 -
 logic.h              |   5 -
 main.cpp             |  31 +++---
 netlogic/Makefile.am |   3 +
 netlogic/Makefile.in |  10 +-
 netlogic/game.cpp    |   4 +
 netlogic/globals.h   |   1 +
 netlogic/lobby.cpp   | 183 ++++++++++++++++++++++++++++++++++++
 netlogic/lobby.h     |  68 ++++++++++++++
 netlogic/logic.cpp   |  68 +-------------
 netlogic/netplay.cpp |  51 ++++++----
 netlogic/netplay.h   |  11 ++-
 netlogic/packet.h    |  74 +++++++++++++++
 netlogic/protocol.h  | 126 ++++++++++++++++++++++++-
 utils/array.h        |   3 +
 27 files changed, 902 insertions(+), 148 deletions(-)
 create mode 100644 Images/joystick.bmp
 create mode 100644 Images/keyboard.bmp
 create mode 100644 Images/network.bmp
 create mode 100644 MaelstromLobby.cpp
 create mode 100644 UI/lobby.xml
 create mode 100644 UI/main.xml
 create mode 100644 netlogic/lobby.cpp
 create mode 100644 netlogic/lobby.h
 create mode 100644 netlogic/packet.h

diff --git a/Images/joystick.bmp b/Images/joystick.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..07799ef5d5e33490f9aee837e5b6fee8d4f29e45
GIT binary patch
literal 9270
zcmeHMSyz--7PX)IvHw6n^g}=PQ+`0NWF;%z89TFyiDH}qK?Oww2Sh{&YH$b&LQrN3
zM3A9?0-2$Jq9|$vnZyE7=BcQvZ}&c*R6??h(MY0M%d^(CiYlS*zGv@!&bjsPw_f?j
zIyGM5zyIX=*UI|Ky1(-ogYW<CuMgM57uK!A%XoPLzw-%ry<SXCPQqrhp}oCbT^5T4
z4<0;#y!WDp+wDf5-HwcJzeUWJEr|T+BOHA1Jsf!deT49N*tTuBl9YtLzP=X@$Nc;}
zic?b&^WlexdgBem{_g{%1_dGi*fC^BMk0}W4}a$!?0xGk1b_7vbUGab?~4$V<V9*|
zC{DiqIxcP8gicKXCapHiI(ji9k3AO5b2;nkk$?O+!kH6);w&jCdF~kIXJ(KY7KU%Q
z_tKLmF~R*V4GzN1<rx@&r@tR=@@0{)&vkWUuET)Nj7%INr-C+YKzDcdb4!6}vGU?Y
zoPPCHRG&G6#XEPP+`S8BWCW1s!^2R9hM*9OEHAMvntCwT-id~!%Lsk@ZNwZt442FG
zTrdn8jW|!P7lwqubMGE7HU^B20!}B~-21{nKbDvS6~hlW2H>)EW4=|7%e!~OpLw`R
z9!*bA|KS*lBO-8_dVJ8+1B{PDA%=PG+uYuU#;PjR6x={#sTNj)0aLect2i)3JR^22
zb{SwKkHVOPAYwSYcdv@$kMh`AYBuS$*H9Z11BG6%@aGAhcTJTRxrgJCu^|*$pYK;!
z_ScbUEGWY`b)XEBPj`E%4GU(QTF{o9g42GR5z2E2qOQaI{gI!S$5f8}t{!VGFGmXZ
zKf$`hVuc0rMq65foRH(tY(IkQfzc=mK8f<UWK_f?A$M~G47x_l4)Xk+{VE2R*@%Va
z7A({^!IXX#mjVKD;N5o-#1*`06VmC&{i6Th!Dky;ql#FgJX2F3dC^VI6kNOv%?|FJ
z`!4i9jvJxzs62la<tHzpWM3T0qAp^%x0m}Lq)x~u=D|B;#d3Ei78{zdpt}Y8wJfCV
z*^7f8e1Jf~v2i0VBql=Y_gd<_n!Zsl+?ktGS9xhMazmnc-j|_0pN@i^$B@4z5(T@W
za3drRH}=G$n0PFPF1SYMM`O&x3I@@GGH8L@)Pbd2by%#_VJIsXSqH+fUvQ9D0bhK9
zgj1)`)y3am1HaNyyB+KWu&@ASb{6^BnaJ6C5E|~gIN}U)z6?X2-yvwW9Z~mRObjLa
zzk#8p6$|1;_lD?KKVpDjxMQWp&G4Ao;i|m_S6L<Q=M|#($T38G_L+)ftJHVa^SZja
zXY#BDo_*Wdv%uma6!s3eSsBRQ!abAcxf{cgv*7^pHifJEuQ+`L+Jq}8k2(*7z6~zc
z2#h&_6%4{9kV}FA!~kMY228}!hUFR^TqR|g$jL|L@faNY@=MiocYN{*BKGfxR;&F@
zeW5uk3pM<GWob!Wr6tA43XFhe%V89f|D`eC;rbrxARroLCzDhSR3}}dPV`V#yjCFw
z<sNI?syqmn1cT&388kuZH^SS~3b(Eb%Z0_5&DNkHHV)D3Q+CpKB_I3QXB8F}J{68h
z`niVQy+q$6Az?H3AnQyba{a<kv^N&o#P4zAKs*X}9mn<EG1T%Y)bgzE(@&K9_f-sF
zy-?_r${6eQ7&Re!a6Zg~k4q2?14iO7Krs_XO(oo#>sZdthcV$S61HuJKYQD+MJLkV
zrldSkf2*)}D5wAQUcU}3FT+h9Rcb4c6&;Vf9g!%ce-=`^a{kv3oI-hSKCIN9)Cx>Y
zfQJPThtxg6fic$YQQ{cwXZ`*umjnZd0k?^vuLDX?Gdwj~xbrk{rDwr<IuRHB0}wz?
zZDBrkZQiW*hKt<O<Kj+31B&?n=j9BEVToSU*ietmOP7%ocNY0^iO|qfON)wdoBpTJ
zXBGObTJMNKYMw6_QoGe$NdGZPPB~fYe#RxipsZkkgFG}h!CO-S553Bhnt`FS7m%?h
z1Uo+d7=FZ(lb!vmUe!SjYqxI2lGFjIGhB1r=WT}rwjL9l(udNYRG;M|*suC<NZnIb
za7ZqEx{y9f8D$^nq^?)_(hpoB21p(RgS{1sr3p%11-v=A@TR20dMW|I>p#b4dRBFH
z_2W{Y@}@O57G<n6W1XGwiZ=@m=0kJ=>RUV(^eA<$V33*z!TfVR38z#(NiRr`TEXD+
zrPW*#43Y;B18mLAM+21FGALKl(S70+{F#G20RgJ69|uCT&{tfHBI-!TK5UHrnnDc1
zDTNqRj}o7iT0tDXTqvt@v6@pq%>_N`F<e@*w`0NH0k6FcinSTAG(u^ug7;D?GK2QQ
zkNg&oeUcCj-!3gh2|c=$oEl&c>XEZw$%P_%lAi?!wSrZA^5sI+_bOdH^r#WF*H|95
zu`mD8TkrPhQD(b?ZymF!usgA2XD*0A5ezk@xR;QK-JgDn*y!kA)xm0ff@83@7UjEk
z;RgFKJN3IHJn`|#heJ5E3db*T%1b`=o4b*c+Kt%wE)2;$+Gj*3XSZ|XUL2)`?Hcf6
zz($X-wLHW?F1fE=L&Dcv5W;=PeaO>>mmIpQ*F($sCXb$A<lhq<DyLR3`1mBb@bO7<
z;p3C|>}an8nxfnIV*3*Q^YIe41@>UfYCyBegzqO6#8WbRogO&MCU_m>k!V`Dq$_1j
z4aROiKa9vs_zW@0Ijoj<5m~G=E$k<!r3aFH5QpeO)i!e>z0}V=%3(4hHESF}N8Rw-
z?ZK{nPK?>RVQ8+$&B0M5J7-bl7{G{;dtT*BFw~(m^Z<f*-|?*b7wDq%Df(#|Jt2d-
zsy%T6<5nxYtNG;P6tyilBp3HM7gg$da3p>KA%_=HSMR`dzZr{zW?1zN=x%MmprHvf
zy++KDSKhwPhrVQKMhSb^eLR1eht?`eZr;RAjRtzoCmHlC?V&>$70;4hY9$vwkMiYW
zz-mETb2B>HT4<$Rn7_jrjy<2$IQNhRR-+yX4RP349gNDZB6xaPA8f6-78H!5!NH^_
z^SVZHhj$Y@ckaZwbLWuCe&sZ0#w_NzfRFv`i`}AyRURdr5^Z4WJ|>17Xsf!3l2c*0
z_5C@_4fn!n=|nU2THaTLOj8O1t9D?@(Sv1E6XN)HlgZb$n&IxUcaDmRLI^e8($b>N
zhjMr4;_9PkY3LPs+qc8QI|-N6W*?u3!817ylc62;$+4(B8I0_0|An!tge6Un4*Gxn
zunu{atGL*97EW^)hO3Ja${tnU%KEkj;pDwaG`)D=zI`y!J02At)`~%XUJ>zK<^9%3
z2YDd55R4P!Xm4$TKI05-or^?q*jMP_{->yg=B8U{bkss?E`h$Y8MD0x<V7Dr4DV><
ze4aH#KgZ}lhsbq1?|7dis^jBP5Euv#KVQW#I|Wl`8`>**FOzl}twovW?dgJ-^TQ19
zGtBx%SoBSpv>R}@MTeuTU2W_!pEc&_i;3jm!Gi~X@!TKv84oxsq;Q5evp2yKy>@OI
z%aixmhquGf)&#qeb0+5oj6a-3)j5v6_cHZ-DJTFr7cM+i-F?&^<h3gH5uv=_)$z{x
zY486Hxw%Ms^Gys1hZoqp&QcRIoE@flUpC1;^#Nzm`@E|p2AShr>@o6>L?DeCn-$GJ
zW6bbxoS@Ig#l^8yJ${~e)JJ(e9<(GU<2&9{wxwOc;y8QKdG@U{EV|R2dnP$AOgQ0v
zFoJ>lY9#O64vpN!{)W$b)aQ4yrw$JfS99>F_n+i7se3l|km>8!Bkj{qP<!SZ*eY&f
zsHGmgoWokuQji(E8!4=d-SppOsq1SLMeN-odEX)5xjbtua%QlRixtdg20b>7b7Cg_
zMaw$kAirEPYpijkr>CpFBlog@#<<3wQ+)Hc^sg@h-eP*6@JDLbpD_&V%MSCdRK7?3
bGlqPxa`oy}^vHJ{FXQD2ygY&DdIJ9kNX|Tl

literal 0
HcmV?d00001

diff --git a/Images/keyboard.bmp b/Images/keyboard.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..edaeb77008fac7f4ebcf1242036ef90f1378a831
GIT binary patch
literal 9270
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
F{2SNiWl;bC

literal 0
HcmV?d00001

diff --git a/Images/network.bmp b/Images/network.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..f64701be6337ace18010817371faca1aaf596046
GIT binary patch
literal 9270
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
NhB?*b<o|1({|8)(Wy1gf

literal 0
HcmV?d00001

diff --git a/MaelstromLobby.cpp b/MaelstromLobby.cpp
new file mode 100644
index 00000000..5636f0b4
--- /dev/null
+++ b/MaelstromLobby.cpp
@@ -0,0 +1,62 @@
+/*
+    Maelstrom: Open Source version of the classic game by Ambrosia Software
+    Copyright (C) 1997-2011  Sam Lantinga
+
+    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 2 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, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include "SDL_net.h"
+
+#include "netlogic/protocol.h"
+
+#define MAX_PACKET_SIZE	1024
+
+void ProcessPacket(UDPpacket *packet)
+{
+	printf("Received packet from %s\n", SDLNet_ResolveIP(&packet->address));
+}
+
+int main(int argc, char *argv[])
+{
+	UDPsocket sock;
+	UDPpacket *packet;
+
+	sock = SDLNet_UDP_Open(LOBBY_PORT);
+	if (!sock) {
+		fprintf(stderr, "Couldn't create socket on port %d: %s\n",
+			LOBBY_PORT, SDL_GetError());
+		exit(1);
+	}
+
+	packet = SDLNet_AllocPacket(MAX_PACKET_SIZE);
+	if (!packet) {
+		fprintf(stderr, "Couldn't allocate packet of size %d: %s\n",
+			MAX_PACKET_SIZE, SDL_GetError());
+		SDLNet_UDP_Close(sock);
+		exit(1);
+	}
+
+	for ( ; ; ) {
+		while (SDLNet_UDP_Recv(sock, packet)) {
+			ProcessPacket(packet);
+		}
+
+		SDL_Delay(100);
+	}
+	SDLNet_UDP_Close(sock);
+}
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index 00b7401c..45121e4b 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -27,6 +27,7 @@
 #include "controls.h"
 #include "netlogic/about.h"
 #include "netlogic/game.h"
+#include "netlogic/lobby.h"
 #include "MacDialog.h"
 #include "screenlib/UIElementButton.h"
 #include "screenlib/UIElementCheckbox.h"
@@ -172,6 +173,8 @@ MaelstromUI::CreatePanelDelegate(UIPanel *panel, const char *delegate)
 		return new MainPanelDelegate(panel);
 	} else if (strcasecmp(delegate, "AboutPanel") == 0) {
 		return new AboutPanelDelegate(panel);
+	} else if (strcasecmp(delegate, "LobbyDialog") == 0) {
+		return new LobbyDialogDelegate(panel);
 	} else if (strcasecmp(delegate, "GamePanel") == 0) {
 		return new GamePanelDelegate(panel);
 	} else if (strcasecmp(delegate, "ControlsDialog") == 0) {
diff --git a/Maelstrom_Globals.h b/Maelstrom_Globals.h
index 8998c64c..cb643cb4 100644
--- a/Maelstrom_Globals.h
+++ b/Maelstrom_Globals.h
@@ -27,7 +27,6 @@
 
 #include "screenlib/SDL_FrameBuf.h"
 #include "screenlib/UIManager.h"
-#include "screenlib/UIPanel.h"
 
 #include "maclib/Mac_FontServ.h"
 #include "maclib/Mac_Sound.h"
@@ -128,6 +127,7 @@ extern int	gNumSprites;
 #define PANEL_BONUS	"bonus"
 #define PANEL_GAMEOVER	"gameover"
 #define PANEL_ABOUT	"about_story"
+#define DIALOG_LOBBY	"lobby"
 #define DIALOG_CONTROLS	"controls"
 #define DIALOG_ZAP	"zap"
 #define DIALOG_DAWN	"dawn"
diff --git a/Makefile.am b/Makefile.am
index 7eb05b8c..fd7153db 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,7 @@
 
 
 bin_PROGRAMS = Maelstrom
+noinst_PROGRAMS = MaelstromLobby
 
 Maelstrom_SOURCES =		\
 	Maelstrom.h		\
@@ -28,16 +29,18 @@ Maelstrom_SOURCES =		\
 	scores.cpp		\
 	scores.h
 
-LOGIC = netlogic
-
 Maelstrom_LDADD = 			\
-	$(LOGIC)/liblogic.a		\
+	netlogic/liblogic.a		\
 	screenlib/libSDLscreen.a	\
 	maclib/libSDLmac.a		\
 	utils/libutils.a		\
 	@MATHLIB@ @INETLIB@ @ICONOBJ@
 
-SUBDIRS = $(LOGIC) screenlib maclib utils
+MaelstromLobby_SOURCES = MaelstromLobby.cpp
+
+MaelstromLobby_LDADD = @INETLIB@
+
+SUBDIRS = netlogic screenlib maclib utils
 
 EXTRA_DIST =			\
 	autogen.sh		\
diff --git a/Makefile.in b/Makefile.in
index 6efbba37..0ae832ce 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -34,6 +34,7 @@ build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
 bin_PROGRAMS = Maelstrom$(EXEEXT)
+noinst_PROGRAMS = MaelstromLobby$(EXEEXT)
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Maelstrom.spec.in \
 	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
@@ -50,14 +51,17 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_CLEAN_FILES = Maelstrom.spec
 am__installdirs = "$(DESTDIR)$(bindir)"
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(bin_PROGRAMS)
+PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
 am_Maelstrom_OBJECTS = MaelstromUI.$(OBJEXT) MacDialog.$(OBJEXT) \
 	controls.$(OBJEXT) fastrand.$(OBJEXT) init.$(OBJEXT) \
 	load.$(OBJEXT) main.$(OBJEXT) myerror.$(OBJEXT) rect.$(OBJEXT) \
 	scores.$(OBJEXT)
 Maelstrom_OBJECTS = $(am_Maelstrom_OBJECTS)
-Maelstrom_DEPENDENCIES = $(LOGIC)/liblogic.a screenlib/libSDLscreen.a \
+Maelstrom_DEPENDENCIES = netlogic/liblogic.a screenlib/libSDLscreen.a \
 	maclib/libSDLmac.a utils/libutils.a
+am_MaelstromLobby_OBJECTS = MaelstromLobby.$(OBJEXT)
+MaelstromLobby_OBJECTS = $(am_MaelstromLobby_OBJECTS)
+MaelstromLobby_DEPENDENCIES =
 DEFAULT_INCLUDES = -I.@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -70,8 +74,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(Maelstrom_SOURCES)
-DIST_SOURCES = $(Maelstrom_SOURCES)
+SOURCES = $(Maelstrom_SOURCES) $(MaelstromLobby_SOURCES)
+DIST_SOURCES = $(Maelstrom_SOURCES) $(MaelstromLobby_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
 	html-recursive info-recursive install-data-recursive \
 	install-dvi-recursive install-exec-recursive \
@@ -225,15 +229,16 @@ Maelstrom_SOURCES = \
 	scores.cpp		\
 	scores.h
 
-LOGIC = netlogic
 Maelstrom_LDADD = \
-	$(LOGIC)/liblogic.a		\
+	netlogic/liblogic.a		\
 	screenlib/libSDLscreen.a	\
 	maclib/libSDLmac.a		\
 	utils/libutils.a		\
 	@MATHLIB@ @INETLIB@ @ICONOBJ@
 
-SUBDIRS = $(LOGIC) screenlib maclib utils
+MaelstromLobby_SOURCES = MaelstromLobby.cpp
+MaelstromLobby_LDADD = @INETLIB@
+SUBDIRS = netlogic screenlib maclib utils
 EXTRA_DIST = \
 	autogen.sh		\
 	VisualC.zip		\
@@ -316,9 +321,15 @@ uninstall-binPROGRAMS:
 
 clean-binPROGRAMS:
 	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
 Maelstrom$(EXEEXT): $(Maelstrom_OBJECTS) $(Maelstrom_DEPENDENCIES) 
 	@rm -f Maelstrom$(EXEEXT)
 	$(CXXLINK) $(Maelstrom_OBJECTS) $(Maelstrom_LDADD) $(LIBS)
+MaelstromLobby$(EXEEXT): $(MaelstromLobby_OBJECTS) $(MaelstromLobby_DEPENDENCIES) 
+	@rm -f MaelstromLobby$(EXEEXT)
+	$(CXXLINK) $(MaelstromLobby_OBJECTS) $(MaelstromLobby_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -327,6 +338,7 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MacDialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MaelstromLobby.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MaelstromUI.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controls.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastrand.Po@am__quote@
@@ -658,7 +670,8 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-recursive
 
-clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \
+	mostlyclean-am
 
 distclean: distclean-recursive
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -723,20 +736,20 @@ uninstall-am: uninstall-binPROGRAMS
 
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
 	all all-am am--refresh check check-am clean clean-binPROGRAMS \
-	clean-generic ctags ctags-recursive dist dist-all dist-bzip2 \
-	dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
-	distclean-compile distclean-generic distclean-tags \
-	distcleancheck distdir distuninstallcheck dvi dvi-am html \
-	html-am info info-am install install-am install-binPROGRAMS \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-exec-hook install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
-	ps ps-am tags tags-recursive uninstall uninstall-am \
-	uninstall-binPROGRAMS
+	clean-generic clean-noinstPROGRAMS ctags ctags-recursive dist \
+	dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \
+	distcheck distclean distclean-compile distclean-generic \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-exec-hook \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am uninstall-binPROGRAMS
 
 
 install-exec-hook:
diff --git a/UI/lobby.xml b/UI/lobby.xml
new file mode 100644
index 00000000..56b29c1e
--- /dev/null
+++ b/UI/lobby.xml
@@ -0,0 +1,49 @@
+<Dialog delegate="LobbyDialog">
+	<Size w="378" h="266"/>
+	<Elements>
+		<Icon name="image" id="103">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="14" y="14"/>
+		</Icon>
+		<DialogLabel name="line1" text="Multiplayer Setup">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="image" x="14"/>
+		</DialogLabel>
+
+		<DialogRadioGroup name="hostOrJoin" bindValue="Network.HostOrJoin">
+			<Elements>
+				<DialogRadioButton name="hostgame" text="Host a game" checked="true" id="1">
+					<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="70" y="36"/>
+				</DialogRadioButton>
+				<DialogRadioButton name="joingame" text="Join a game" id="2">
+					<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="hostgame" x="4"/>
+				</DialogRadioButton>
+			</Elements>
+		</DialogRadioGroup>
+
+		<DialogCheckbox name="globalGame" bindValue="Network.GlobalGame" text="Global">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="290" y="41"/>
+		</DialogCheckbox>
+
+		<Area name="hostpanel">
+			<Elements>
+				<DialogCheckbox name="player1" text="Player 1" checked="true">
+					<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="14" y ="86"/>
+				</DialogCheckbox>
+				<Image file="Images/keyboard.bmp">
+					<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="player1" x="8"/>
+				</Image>
+			</Elements>
+		</Area>
+		<Area name="joinpanel">
+			<Elements>
+			</Elements>
+		</Area>
+
+		<DialogButton name="doitButton" text="Do it!" default="true" id="1">
+			<Anchor anchorFrom="BOTTOMRIGHT" anchorTo="BOTTOMRIGHT" x="-10" y="-11"/>
+		</DialogButton>
+		<DialogButton text="Cancel">
+			<Size w="73"/>
+			<Anchor anchorFrom="RIGHT" anchorTo="LEFT" anchor="doitButton" x="-14"/>
+		</DialogButton>
+	</Elements>
+</Dialog>
diff --git a/UI/main.xml b/UI/main.xml
new file mode 100644
index 00000000..bfa0cfa9
--- /dev/null
+++ b/UI/main.xml
@@ -0,0 +1,218 @@
+<Panel template="FramedPanel" delegate="MainPanel">
+	<Elements>
+		<Title name="image" id="129">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="CENTER" x="-251" y="-187"/>
+		</Title>
+
+		<!-- Catch-all button to bonk when a key is pressed -->
+		<Button template="HotkeyOnly" hotkey="any" clickSound="108"/>
+
+		<!-- dividers -->
+		<Line name="vertical_divider">
+			<Color r="0x9C" g="0x9C" b="0xFF"/>
+			<Size w="1" h="384"/>
+			<Anchor anchorFrom="CENTER" anchorTo="CENTER" x="42"/>
+		</Line>
+		<Line name="hdivider_left">
+			<Color r="0x9C" g="0x9C" b="0xFF"/>
+			<Size w="298" h="1"/>
+			<Anchor anchorFrom="RIGHT" anchorTo="TOPLEFT" anchor="vertical_divider" y="153"/>
+		</Line>
+		<Line name="hdivider_right">
+			<Color r="0x9C" g="0x9C" b="0xFF"/>
+			<Size w="214" h="1"/>
+			<Anchor anchorFrom="LEFT" anchorTo="TOPRIGHT" anchor="vertical_divider" y="263"/>
+		</Line>
+
+		<!-- high scores -->
+		<Label name="name_header" template="LargeYellowUnderline" text="Name">
+			<Anchor anchorFrom="BOTTOMLEFT" anchorTo="BOTTOMLEFT" anchor="hdivider_left" x="5" y="23"/>
+		</Label>
+		<Label name="score_header" template="LargeYellowUnderline" text="Score">
+			<Anchor anchorFrom="BOTTOMLEFT" anchorTo="BOTTOMLEFT" anchor="hdivider_left" x="185" y="23"/>
+		</Label>
+		<Label name="wave_header" template="LargeYellowUnderline" text="Wave">
+			<Anchor anchorFrom="BOTTOMLEFT" anchorTo="BOTTOMLEFT" anchor="hdivider_left" x="245" y="23"/>
+		</Label>
+
+		<Label name="name_0" template="Medium">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="name_header" y="24"/>
+		</Label>
+		<Label name="score_0" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="score_header" y="24"/>
+		</Label>
+		<Label name="wave_0" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="wave_header" x="-10" y="24"/>
+		</Label>
+		<Label name="name_1" template="Medium">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="name_0" y="18"/>
+		</Label>
+		<Label name="score_1" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="score_0" y="18"/>
+		</Label>
+		<Label name="wave_1" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="wave_0" y="18"/>
+		</Label>
+		<Label name="name_2" template="Medium">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="name_1" y="18"/>
+		</Label>
+		<Label name="score_2" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="score_1" y="18"/>
+		</Label>
+		<Label name="wave_2" template="Medium">
+			<Anchor anchorFrom="TOPRIGHT" anchorTo="TOPRIGHT" anchor="wave_1" y="18"/>
+		</Label>
+		<Label name="name_3" template="Medium">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" anchor="name_2" y="18"/>
+		</Label>
+		<Label name="score_3" template="Medium">
+			<Anchor ancho

(Patch may be truncated, please check the link at the top of this post.)