mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Allow disconnecting to the main menu
This commit is contained in:
parent
b2410f77e5
commit
c71273cb60
4 changed files with 60 additions and 47 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
#include "djui.h"
|
#include "djui.h"
|
||||||
#include "pc/cheats.h"
|
#include "pc/cheats.h"
|
||||||
#include "src/pc/pc_main.h"
|
#include "src/pc/pc_main.h"
|
||||||
|
#include "src/pc/network/network.h"
|
||||||
|
|
||||||
bool gDjuiPanelPauseCreated = false;
|
bool gDjuiPanelPauseCreated = false;
|
||||||
|
|
||||||
|
|
@ -9,13 +10,13 @@ static void djui_panel_pause_resume(UNUSED struct DjuiBase* caller) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void djui_panel_pause_quit_yes(UNUSED struct DjuiBase* caller) {
|
static void djui_panel_pause_quit_yes(UNUSED struct DjuiBase* caller) {
|
||||||
game_exit();
|
network_shutdown(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void djui_panel_pause_quit(struct DjuiBase* caller) {
|
static void djui_panel_pause_quit(struct DjuiBase* caller) {
|
||||||
djui_panel_confirm_create(caller,
|
djui_panel_confirm_create(caller,
|
||||||
"\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T",
|
"\\#ff0800\\Q\\#1be700\\U\\#00b3ff\\I\\#ffef00\\T",
|
||||||
"Are you sure you want to quit?",
|
"Are you sure you want to disconnect?",
|
||||||
djui_panel_pause_quit_yes);
|
djui_panel_pause_quit_yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +48,7 @@ void djui_panel_pause_create(struct DjuiBase* caller) {
|
||||||
djui_base_set_size(&button2->base, 1.0f, 64);
|
djui_base_set_size(&button2->base, 1.0f, 64);
|
||||||
djui_interactable_hook_click(&button2->base, djui_panel_pause_resume);
|
djui_interactable_hook_click(&button2->base, djui_panel_pause_resume);
|
||||||
|
|
||||||
struct DjuiButton* button3 = djui_button_create(&body->base, "Quit");
|
struct DjuiButton* button3 = djui_button_create(&body->base, "Disconnect");
|
||||||
djui_base_set_size_type(&button3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
djui_base_set_size_type(&button3->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||||
djui_base_set_size(&button3->base, 1.0f, 64);
|
djui_base_set_size(&button3->base, 1.0f, 64);
|
||||||
djui_interactable_hook_click(&button3->base, djui_panel_pause_quit);
|
djui_interactable_hook_click(&button3->base, djui_panel_pause_quit);
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@ void djui_popup_update(void) {
|
||||||
struct DjuiPopupList* next = node->next;
|
struct DjuiPopupList* next = node->next;
|
||||||
djui_base_set_location(&node->popup->base, 4, y);
|
djui_base_set_location(&node->popup->base, 4, y);
|
||||||
y += node->popup->base.height.value + 4;
|
y += node->popup->base.height.value + 4;
|
||||||
if (gNetworkType != NT_NONE && gNetworkPlayerLocal != NULL) {
|
|
||||||
f32 elapsed = (clock_elapsed() - node->createTime);
|
f32 elapsed = (clock_elapsed() - node->createTime);
|
||||||
|
|
||||||
// fade out
|
// fade out
|
||||||
|
|
@ -89,10 +88,6 @@ void djui_popup_update(void) {
|
||||||
node = next;
|
node = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// prevent popups from fading out when we're not connected
|
|
||||||
node->createTime = clock_elapsed();
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterate
|
// iterate
|
||||||
last = node;
|
last = node;
|
||||||
|
|
|
||||||
|
|
@ -453,10 +453,13 @@ void network_shutdown(bool sendLeaving, bool exiting) {
|
||||||
extern s16 gChangeLevel;
|
extern s16 gChangeLevel;
|
||||||
gChangeLevel = LEVEL_CASTLE_GROUNDS;
|
gChangeLevel = LEVEL_CASTLE_GROUNDS;
|
||||||
|
|
||||||
// TODO: enable
|
extern s16 gMenuMode;
|
||||||
/*extern bool gDjuiInMainMenu;
|
gMenuMode = -1;
|
||||||
|
|
||||||
|
djui_panel_shutdown();
|
||||||
|
extern bool gDjuiInMainMenu;
|
||||||
if (!gDjuiInMainMenu) {
|
if (!gDjuiInMainMenu) {
|
||||||
gDjuiInMainMenu = true;
|
gDjuiInMainMenu = true;
|
||||||
djui_panel_main_create(NULL);
|
djui_panel_main_create(NULL);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
#include "pc/djui/djui.h"
|
#include "pc/djui/djui.h"
|
||||||
|
|
||||||
static SOCKET curSocket = INVALID_SOCKET;
|
static SOCKET sCurSocket = INVALID_SOCKET;
|
||||||
static struct sockaddr_in addr[MAX_PLAYERS] = { 0 };
|
static struct sockaddr_in sAddr[MAX_PLAYERS] = { 0 };
|
||||||
|
|
||||||
static int socket_bind(SOCKET socket, unsigned int port) {
|
static int socket_bind(SOCKET socket, unsigned int port) {
|
||||||
struct sockaddr_in rxAddr;
|
struct sockaddr_in rxAddr;
|
||||||
|
|
@ -40,7 +40,7 @@ static int socket_receive(SOCKET socket, struct sockaddr_in* rxAddr, u8* buffer,
|
||||||
int rc = recvfrom(socket, (char*)buffer, bufferLength, 0, (struct sockaddr*)rxAddr, &rxAddrSize);
|
int rc = recvfrom(socket, (char*)buffer, bufferLength, 0, (struct sockaddr*)rxAddr, &rxAddrSize);
|
||||||
|
|
||||||
for (int i = 1; i < MAX_PLAYERS; i++) {
|
for (int i = 1; i < MAX_PLAYERS; i++) {
|
||||||
if (memcmp(rxAddr, &addr[i], sizeof(struct sockaddr_in)) == 0) {
|
if (memcmp(rxAddr, &sAddr[i], sizeof(struct sockaddr_in)) == 0) {
|
||||||
*localIndex = i;
|
*localIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -65,21 +65,32 @@ static bool ns_socket_initialize(enum NetworkType networkType) {
|
||||||
if (port == 0) { port = DEFAULT_PORT; }
|
if (port == 0) { port = DEFAULT_PORT; }
|
||||||
|
|
||||||
// create a receiver socket to receive datagrams
|
// create a receiver socket to receive datagrams
|
||||||
curSocket = socket_initialize();
|
sCurSocket = socket_initialize();
|
||||||
if (curSocket == INVALID_SOCKET) { return false; }
|
if (sCurSocket == INVALID_SOCKET) { return false; }
|
||||||
|
|
||||||
// connect
|
// connect
|
||||||
if (networkType == NT_SERVER) {
|
if (networkType == NT_SERVER) {
|
||||||
|
int reuse = 1;
|
||||||
|
if (setsockopt(sCurSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0) {
|
||||||
|
LOG_ERROR("setsockopt(SO_REUSEADDR) failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SO_REUSEPORT
|
||||||
|
if (setsockopt(sCurSocket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0) {
|
||||||
|
LOG_ERROR("setsockopt(SO_REUSEPORT) failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// bind the socket to any address and the specified port.
|
// bind the socket to any address and the specified port.
|
||||||
int rc = socket_bind(curSocket, port);
|
int rc = socket_bind(sCurSocket, port);
|
||||||
if (rc != NO_ERROR) { return false; }
|
if (rc != NO_ERROR) { return false; }
|
||||||
LOG_INFO("bound to port %u", port);
|
LOG_INFO("bound to port %u", port);
|
||||||
} else {
|
} else {
|
||||||
// save the port to send to
|
// save the port to send to
|
||||||
addr[0].sin_family = AF_INET;
|
sAddr[0].sin_family = AF_INET;
|
||||||
addr[0].sin_port = htons(port);
|
sAddr[0].sin_port = htons(port);
|
||||||
domain_resolution();
|
domain_resolution();
|
||||||
addr[0].sin_addr.s_addr = inet_addr(configJoinIp);
|
sAddr[0].sin_addr.s_addr = inet_addr(configJoinIp);
|
||||||
LOG_INFO("connecting to %s %u", configJoinIp, port);
|
LOG_INFO("connecting to %s %u", configJoinIp, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,27 +120,27 @@ static s64 ns_socket_get_id(UNUSED u8 localId) {
|
||||||
static char* ns_socket_get_id_str(u8 localId) {
|
static char* ns_socket_get_id_str(u8 localId) {
|
||||||
if (localId == UNKNOWN_LOCAL_INDEX) { localId = 0; }
|
if (localId == UNKNOWN_LOCAL_INDEX) { localId = 0; }
|
||||||
static char id_str[INET_ADDRSTRLEN] = { 0 };
|
static char id_str[INET_ADDRSTRLEN] = { 0 };
|
||||||
snprintf(id_str, INET_ADDRSTRLEN, "%s", inet_ntoa(addr[localId].sin_addr));
|
snprintf(id_str, INET_ADDRSTRLEN, "%s", inet_ntoa(sAddr[localId].sin_addr));
|
||||||
return id_str;
|
return id_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ns_socket_save_id(u8 localId, UNUSED s64 networkId) {
|
static void ns_socket_save_id(u8 localId, UNUSED s64 networkId) {
|
||||||
SOFT_ASSERT(localId > 0);
|
SOFT_ASSERT(localId > 0);
|
||||||
SOFT_ASSERT(localId < MAX_PLAYERS);
|
SOFT_ASSERT(localId < MAX_PLAYERS);
|
||||||
addr[localId] = addr[0];
|
sAddr[localId] = sAddr[0];
|
||||||
LOG_INFO("saved addr for id %d", localId);
|
LOG_INFO("saved addr for id %d", localId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ns_socket_clear_id(u8 localId) {
|
static void ns_socket_clear_id(u8 localId) {
|
||||||
if (localId == 0) { return; }
|
if (localId == 0) { return; }
|
||||||
SOFT_ASSERT(localId < MAX_PLAYERS);
|
SOFT_ASSERT(localId < MAX_PLAYERS);
|
||||||
memset(&addr[localId], 0, sizeof(struct sockaddr_in));
|
memset(&sAddr[localId], 0, sizeof(struct sockaddr_in));
|
||||||
LOG_INFO("cleared addr for id %d", localId);
|
LOG_INFO("cleared addr for id %d", localId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* ns_socket_dup_addr(u8 localIndex) {
|
static void* ns_socket_dup_addr(u8 localIndex) {
|
||||||
void* address = malloc(sizeof(struct sockaddr_in));
|
void* address = malloc(sizeof(struct sockaddr_in));
|
||||||
memcpy(address, &addr[localIndex], sizeof(struct sockaddr_in));
|
memcpy(address, &sAddr[localIndex], sizeof(struct sockaddr_in));
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,10 +155,10 @@ static void ns_socket_update(void) {
|
||||||
u8 data[PACKET_LENGTH + 1];
|
u8 data[PACKET_LENGTH + 1];
|
||||||
u16 dataLength = 0;
|
u16 dataLength = 0;
|
||||||
u8 localIndex = UNKNOWN_LOCAL_INDEX;
|
u8 localIndex = UNKNOWN_LOCAL_INDEX;
|
||||||
int rc = socket_receive(curSocket, &addr[0], data, PACKET_LENGTH + 1, &dataLength, &localIndex);
|
int rc = socket_receive(sCurSocket, &sAddr[0], data, PACKET_LENGTH + 1, &dataLength, &localIndex);
|
||||||
SOFT_ASSERT(dataLength < PACKET_LENGTH);
|
SOFT_ASSERT(dataLength < PACKET_LENGTH);
|
||||||
if (rc != NO_ERROR) { break; }
|
if (rc != NO_ERROR) { break; }
|
||||||
network_receive(localIndex, &addr[0], data, dataLength);
|
network_receive(localIndex, &sAddr[0], data, dataLength);
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,10 +168,10 @@ static int ns_socket_send(u8 localIndex, void* address, u8* data, u16 dataLength
|
||||||
if (gNetworkType == NT_CLIENT && gNetworkPlayers[localIndex].type != NPT_SERVER) { return SOCKET_ERROR; }
|
if (gNetworkType == NT_CLIENT && gNetworkPlayers[localIndex].type != NPT_SERVER) { return SOCKET_ERROR; }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in* userAddr = &addr[localIndex];
|
struct sockaddr_in* userAddr = &sAddr[localIndex];
|
||||||
if (localIndex == 0 && address != NULL) { userAddr = (struct sockaddr_in*)address; }
|
if (localIndex == 0 && address != NULL) { userAddr = (struct sockaddr_in*)address; }
|
||||||
|
|
||||||
int rc = socket_send(curSocket, userAddr, data, dataLength);
|
int rc = socket_send(sCurSocket, userAddr, data, dataLength);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LOG_ERROR(" localIndex: %d, packetType: %d, dataLength: %d", localIndex, data[0], dataLength);
|
LOG_ERROR(" localIndex: %d, packetType: %d, dataLength: %d", localIndex, data[0], dataLength);
|
||||||
}
|
}
|
||||||
|
|
@ -168,8 +179,11 @@ static int ns_socket_send(u8 localIndex, void* address, u8* data, u16 dataLength
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ns_socket_shutdown(void) {
|
static void ns_socket_shutdown(void) {
|
||||||
socket_shutdown(curSocket);
|
socket_shutdown(sCurSocket);
|
||||||
curSocket = INVALID_SOCKET;
|
sCurSocket = INVALID_SOCKET;
|
||||||
|
for (u16 i = 0; i < MAX_PLAYERS; i++) {
|
||||||
|
memset(&sAddr[i], 0, sizeof(struct sockaddr_in));
|
||||||
|
}
|
||||||
LOG_INFO("shutdown");
|
LOG_INFO("shutdown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue