HoverRace Coding Standards
Source documentation
We're using Doxygen for inline source documentation.
A note on portability
One of the big goals for post-1.x development is portability to other platforms. To that end, new code should keep portability in mind:
- Use standard C++ idioms where possible:
- bool instead of BOOL
- STL containers and algorithms
- Limit use of MFC to interfaces with existing code
- Persistent configuration settings should be managed by the MR_Config class instead of directly in the Registry.
- Prefer portable libraries
One notable exception to the "portable library" rule is the UI. Since it's likely that the UI bits will need to be rewritten entirely for a future OpenGL renderer, we're sticking with standard (non-MFC) Win32 dialogs for now, with the aim of using winelib as a stopgap measure.
Whitespace and indentation
The main coding standard is 4-character tabs (not spaces).
Looking at existing code and imitating its formatting provides a good place to start. Here is an example, from NetInterface.cpp:
BOOL CALLBACK MR_NetworkInterface::WaitGameNameCallBack(HWND pWindow, UINT pMsgId, WPARAM pWParam, LPARAM pLParam)
{
BOOL lReturnValue = FALSE;
static SOCKET sNewSocket;
switch (pMsgId) {
// Catch environment modification events
case WM_INITDIALOG:
{
sNewSocket = socket(PF_INET, SOCK_STREAM, 0);
if(sNewSocket == INVALID_SOCKET) {
SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CANT_CREATE_SOCK));
}
else {
SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CONNECTING_SERV));
SOCKADDR_IN lAddr;
lAddr.sin_family = AF_INET;
lAddr.sin_addr.s_addr = GetAddrFromStr(mActiveInterface->mServerAddr);
lAddr.sin_port = htons(mActiveInterface->mServerPort);
WSAAsyncSelect(sNewSocket, pWindow, MRM_SERVER_CONNECT, FD_CONNECT);
// Disable Nangle algo
int lCode;
int lTrue = 1;
lCode = setsockopt(sNewSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &lTrue, sizeof(int));
ASSERT(lCode != SOCKET_ERROR);
// Reduce output queue to 512 bytes
int lQueueSize = 512;
lCode = setsockopt(sNewSocket, SOL_SOCKET, SO_SNDBUF, (char *) &lQueueSize, sizeof(int));
ASSERT(lCode != SOCKET_ERROR);
connect(sNewSocket, (struct sockaddr *) &lAddr, sizeof(lAddr));
}
}
break;
case MRM_SERVER_CONNECT:
{
MR_NetMessageBuffer lOutputBuffer;
if(WSAGETSELECTERROR(pLParam) == 0) {
SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_GET_GAMEINFO));
mActiveInterface->mClient[0].Connect(sNewSocket);
WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, FD_READ);
SOCKADDR_IN lAddr;
int lSize = sizeof(lAddr);
lAddr.sin_family = AF_INET;
getsockname(mActiveInterface->mClient[0].GetSocket(), (struct sockaddr *) &lAddr, &lSize);
lAddr.sin_family = AF_INET;
// lAddr.sin_addr.s_addr = INADDR_ANY;
lAddr.sin_port = 0;
if(bind(mActiveInterface->mRegistrySocket, (LPSOCKADDR) & lAddr, sizeof(lAddr)) != 0) {
MessageBox(pWindow, MR_LoadString(IDS_CANT_CREATE_SOCK), MR_LoadString(IDS_TCP_CLIENT), MB_ICONERROR | MB_OK | MB_APPLMODAL);
}
lSize = sizeof(lAddr);
lAddr.sin_family = AF_INET;
getsockname(mActiveInterface->mRegistrySocket, (struct sockaddr *) &lAddr, &lSize);
lOutputBuffer.mMessageType = MRNM_GET_GAME_NAME;
lOutputBuffer.mDataLen = 8;
*(int *) &(lOutputBuffer.mData[0]) = lAddr.sin_addr.s_addr;
*(int *) &(lOutputBuffer.mData[4]) = lAddr.sin_port;
mActiveInterface->mClient[0].Send(&lOutputBuffer, MR_NET_REQUIRED);
}
else {
SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CANT_CONNECT));
}
}
lReturnValue = TRUE;
break;
case MRM_CLIENT:
{
const MR_NetMessageBuffer *lBuffer = NULL;
switch (WSAGETSELECTEVENT(pLParam)) {
case FD_READ:
WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, 0);
lBuffer = mActiveInterface->mClient[0].Poll();
if((lBuffer != NULL) && (lBuffer->mMessageType == MRNM_GAME_NAME)) {
mActiveInterface->mGameName = CString((const char *) lBuffer->mData, lBuffer->mDataLen);
EndDialog(pWindow, IDOK);
}
else {
// Bad message, reenable reception
WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, FD_READ);
}
break;
}
}
lReturnValue = TRUE;
break;
case WM_COMMAND:
switch (LOWORD(pWParam)) {
case IDCANCEL:
lReturnValue = TRUE;
closesocket(sNewSocket);
mActiveInterface->mClient[0].Disconnect();
EndDialog(pWindow, IDCANCEL);
break;
}
}
return lReturnValue;
}
