}
}
+enum GameAction { newAIGame, newLocalGame, endGame, close, connect, host, stop };
+
+
#ifdef HIGH_DPI
define stateWidth = 300;
define turnWidth = 150;
class Chess : Window
{
background = gray, hasMenuBar = true, hasStatusBar = true,
+ fullRender = true;
text = APPNAME,
-#ifndef __ANDROID__
+#if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__)
hasClose = true, hasMaximize = true, hasMinimize = true,
borderStyle = sizable,
#endif
anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
bool hosting, local, ai;
+#ifndef CHESS_NONET
Socket sockets[Player];
ChessService service { port = CHESS_PORT, chess = this };
+#endif
MenuItem * driverItems;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(newAIGame))
{
ai = true;
chessState.gameRunning = true;
gameMenu, "New Local Game\tCtrl+L", l, ctrlL;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(newLocalGame))
{
local = true;
chessState.gameRunning = true;
gameMenu, "End Game", e;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- EndGame();
+ EndGame(endGame);
return true;
}
};
MenuItem { gameMenu, "Exit\tAlt+F4", x, NotifySelect = MenuFileExit };
+#ifndef CHESS_NONET
// Network Menu
MenuItem connectItem
{
networkMenu, "Connect...", c;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(connect))
{
hosting = false;
service.Stop();
- ConnectDialog { master = this }.Modal();
+ ConnectDialog { master = this, isModal = true }.Create();
}
return true;
}
networkMenu, "Host", h;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(host))
{
if(service.Start())
{
networkMenu, "Stop Hosting", s;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(EndGame())
+ if(EndGame(stop))
{
hosting = false;
service.Stop();
return true;
}
};
+#endif
// View Menu
MenuItem fullScreenItem
helpMenu, "About...\tF1", a, f1;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- AboutChess { master = this }.Modal();
+ AboutChess { master = this, isModal = true }.Create();
return true;
}
};
- // --- Chess Utilities ---
- bool MakeMove(int x1, int y1, int x2, int y2, PieceType promotion)
+ int cx1, cy1, cx2, cy2;
+
+ bool DoMove(int x1, int y1, int x2, int y2, PieceType promotion)
{
bool valid = false;
-
PieceType type = chessState.board[y1][x1].type;
Player player = chessState.board[y1][x1].player;
- // Pawn Promotion
- if(type == Pawn && y2 == ((player == White) ? 7 : 0))
- {
- if(chessState.isLocalPlayer[chessState.turn] &&
- IsMoveValid(x1,y1,x2,y2, chessState, null, true))
- {
- chess2D.Update(null);
- chess3D.Update(null);
- promotion = (PieceType)Promotion { master = this }.Modal();
- }
- }
-
if(StateMakeMove(chessState, x1,y1,x2,y2, promotion, true, null))
{
valid = true;
y2 = (byte)y2,
promotion = promotion
};
+#ifndef CHESS_NONET
sockets[player^(Player)1].Send((byte *)&packet, sizeof(ChessPacket));
+#endif
}
if(player == Black)
return valid;
}
+ // --- Chess Utilities ---
+ bool MakeMove(int x1, int y1, int x2, int y2, PieceType promotion)
+ {
+ bool valid = false;
+
+ PieceType type = chessState.board[y1][x1].type;
+ Player player = chessState.board[y1][x1].player;
+
+ // Pawn Promotion
+ if(type == Pawn && y2 == ((player == White) ? 7 : 0))
+ {
+ valid = true;
+ if(chessState.isLocalPlayer[chessState.turn] &&
+ (valid = IsMoveValid(x1,y1,x2,y2, chessState, null, true)))
+ {
+ valid = false;
+ cx1 = x1, cy1 = y1, cx2 = x2, cy2 = y2;
+ chess2D.Update(null);
+ chess3D.Update(null);
+ promotion = (PieceType)Promotion
+ {
+ master = this;
+ isModal = true;
+
+ void Chess::NotifyDestroyed(Window promotionDlg, DialogResult r)
+ {
+ DoMove(cx1, cy1, cx2, cy2, (PieceType)r);
+ if(ai)
+ aiThread.Play();
+ }
+ }.Create();
+ }
+ }
+ else
+ valid = DoMove(x1, y1, x2, y2, promotion);
+ return valid;
+ }
+
void ProcessUserMove(int x1, int y1, int x2, int y2)
{
if(MakeMove(x1, y1, x2, y2, 0))
void EnableMenus()
{
+#ifndef CHESS_NONET
stopItem.disabled = !hosting;
disconnectItem.disabled = !sockets[SERVER_COLOR] && !sockets[CLIENT_COLOR];
- endGameItem.disabled = !chessState.gameRunning;
hostItem.disabled = hosting;
+#endif
+ endGameItem.disabled = !chessState.gameRunning;
}
void SetDriver()
return true;
}
- bool EndGame()
+ void DoEndGame(GameAction action)
{
- if(chessState.gameRunning &&
- (chessState.state == Normal || chessState.state == Check))
- {
- if(MessageBox { type = okCancel, contents = "Quit current game?",
- master = this, text = "ECERE Chess" }.Modal() == cancel)
- return false;
- }
+#ifndef CHESS_NONET
if(sockets[SERVER_COLOR])
sockets[SERVER_COLOR].Disconnect(0);
else if(sockets[CLIENT_COLOR])
sockets[CLIENT_COLOR].Disconnect(0);
- else if(local || ai)
+ else
+#endif
+ if(local || ai)
{
if(ai) aiThread.Abort();
local = ai = false;
turnField.text = "";
stateField.text = "";
+ switch(action)
+ {
+ case newAIGame: aiItem.NotifySelect(this, aiItem, 0); break;
+ case newLocalGame: localItem.NotifySelect(this, localItem, 0); break;
+ }
+ }
+
+ GameAction nextAction;
+
+ bool EndGame(GameAction action)
+ {
+ if(chessState.gameRunning &&
+ (chessState.state == Normal || chessState.state == Check))
+ {
+ nextAction = action;
+ MessageBox
+ {
+ type = okCancel, contents = "Quit current game?",
+ master = this, text = "ECERE Chess";
+ isModal = true;
+
+ void Chess::NotifyDestroyed(Window msgBox, DialogResult result)
+ {
+ if(result != cancel)
+ DoEndGame(nextAction);
+ }
+ }.Create();
+ return false;
+ }
return true;
}
bool OnClose(bool parentClosing)
{
- return EndGame();
+ return EndGame(close);
}
void OnDestroy()
{
+#ifndef CHESS_NONET
delete sockets[Black];
delete sockets[White];
+#endif
delete driverItems;
}
+#ifndef CHESS_NONET
void Connect(const char * address)
{
ChessSocket socket { chess = this };
chessState.isLocalPlayer[SERVER_COLOR] = false;
}
}
+#endif
}
// --- Chess Communications ---
+#ifndef CHESS_NONET
class ChessSocket : Socket
{
Chess chess;
}
}
}
+#endif