mirror of https://github.com/OpenRCT2/OpenRCT2.git
basic player list
This commit is contained in:
parent
c0dc591152
commit
7ccb0eb655
|
@ -3834,3 +3834,4 @@ STR_5492 :Scenario options
|
|||
|
||||
STR_6000 :Send Message
|
||||
STR_6001 :Type the message you would like to send.
|
||||
STR_6002 :Player List
|
||||
|
|
|
@ -447,6 +447,7 @@ enum {
|
|||
WC_TITLE_EDITOR = 122,
|
||||
WC_TITLE_COMMAND_EDITOR = 123,
|
||||
WC_CHAT_HOST = 124,
|
||||
WC_PLAYER_LIST = 125,
|
||||
|
||||
// Only used for colour schemes
|
||||
WC_STAFF = 220,
|
||||
|
@ -612,6 +613,7 @@ void window_sign_open(rct_windownumber number);
|
|||
void window_sign_small_open(rct_windownumber number);
|
||||
void window_cheats_open();
|
||||
void window_chat_open();
|
||||
void window_player_list_open();
|
||||
|
||||
void window_research_open();
|
||||
void window_research_development_page_paint(rct_window *w, rct_drawpixelinfo *dpi, int baseWidgetIndex);
|
||||
|
|
|
@ -2030,6 +2030,8 @@ enum {
|
|||
STR_DEBUG_DROPDOWN_INVENTIONS_LIST = 5491,
|
||||
STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS = 5492,
|
||||
|
||||
STR_PLAYER_LIST = 6002,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef DISABLE_NETWORK
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include "network.h"
|
||||
extern "C" {
|
||||
|
@ -49,7 +50,7 @@ enum {
|
|||
NETWORK_COMMAND_CHAT,
|
||||
NETWORK_COMMAND_GAMECMD,
|
||||
NETWORK_COMMAND_TICK,
|
||||
NETWORK_COMMAND_PLAYER,
|
||||
NETWORK_COMMAND_PLAYERLIST,
|
||||
NETWORK_COMMAND_MAX
|
||||
};
|
||||
|
||||
|
@ -108,6 +109,7 @@ const char* NetworkPacket::ReadString()
|
|||
if (*strend != 0) {
|
||||
return 0;
|
||||
}
|
||||
read++;
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -118,9 +120,17 @@ void NetworkPacket::Clear()
|
|||
data->clear();
|
||||
}
|
||||
|
||||
NetworkPlayer::NetworkPlayer(const char* name)
|
||||
{
|
||||
strncpy((char*)NetworkPlayer::name, name, sizeof(NetworkPlayer::name));
|
||||
NetworkPlayer::name[sizeof(NetworkPlayer::name) - 1] = 0;
|
||||
ping = 0;
|
||||
}
|
||||
|
||||
NetworkConnection::NetworkConnection()
|
||||
{
|
||||
authstatus = NETWORK_AUTH_NONE;
|
||||
player = 0;
|
||||
}
|
||||
|
||||
int NetworkConnection::ReadPacket()
|
||||
|
@ -213,6 +223,7 @@ Network::Network()
|
|||
client_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Client_Handle_CHAT;
|
||||
client_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Client_Handle_GAMECMD;
|
||||
client_command_handlers[NETWORK_COMMAND_TICK] = &Network::Client_Handle_TICK;
|
||||
client_command_handlers[NETWORK_COMMAND_PLAYERLIST] = &Network::Client_Handle_PLAYERLIST;
|
||||
server_command_handlers.resize(NETWORK_COMMAND_MAX, 0);
|
||||
server_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Server_Handle_AUTH;
|
||||
server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT;
|
||||
|
@ -241,18 +252,21 @@ bool Network::Init()
|
|||
void Network::Close()
|
||||
{
|
||||
if (mode == NETWORK_MODE_CLIENT) {
|
||||
mode = NETWORK_MODE_NONE;
|
||||
closesocket(server_socket);
|
||||
} else
|
||||
if (mode == NETWORK_MODE_SERVER) {
|
||||
mode = NETWORK_MODE_NONE;
|
||||
closesocket(listening_socket);
|
||||
for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
closesocket((*it)->socket);
|
||||
}
|
||||
client_connection_list.clear();
|
||||
}
|
||||
|
||||
mode = NETWORK_MODE_NONE;
|
||||
|
||||
client_connection_list.clear();
|
||||
game_command_queue.clear();
|
||||
player_list.clear();
|
||||
|
||||
if (wsa_initialized) {
|
||||
WSACleanup();
|
||||
wsa_initialized = false;
|
||||
|
@ -261,6 +275,7 @@ void Network::Close()
|
|||
|
||||
bool Network::BeginClient(const char* host, unsigned short port)
|
||||
{
|
||||
Close();
|
||||
if (!Init())
|
||||
return false;
|
||||
|
||||
|
@ -298,6 +313,7 @@ bool Network::BeginClient(const char* host, unsigned short port)
|
|||
|
||||
bool Network::BeginServer(unsigned short port)
|
||||
{
|
||||
Close();
|
||||
if (!Init())
|
||||
return false;
|
||||
|
||||
|
@ -332,6 +348,10 @@ bool Network::BeginServer(unsigned short port)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<NetworkPlayer> player(new NetworkPlayer("Server Player")); // change to make_unique in c++14
|
||||
player->flags |= NETWORK_PLAYER_FLAG_ISSERVER;
|
||||
player_list.push_back(std::move(player));
|
||||
|
||||
printf("Ready for clients...\n");
|
||||
|
||||
mode = NETWORK_MODE_SERVER;
|
||||
|
@ -343,6 +363,17 @@ int Network::GetMode()
|
|||
return mode;
|
||||
}
|
||||
|
||||
int Network::GetAuthStatus()
|
||||
{
|
||||
if (GetMode() == NETWORK_MODE_CLIENT) {
|
||||
return server_connection.authstatus;
|
||||
} else
|
||||
if (GetMode() == NETWORK_MODE_SERVER) {
|
||||
return NETWORK_AUTH_OK;
|
||||
}
|
||||
return NETWORK_AUTH_NONE;
|
||||
}
|
||||
|
||||
uint32 Network::GetServerTick()
|
||||
{
|
||||
return server_tick;
|
||||
|
@ -362,7 +393,7 @@ void Network::Update()
|
|||
} else
|
||||
if (GetMode() == NETWORK_MODE_SERVER) {
|
||||
auto it = client_connection_list.begin();
|
||||
while(it != client_connection_list.end()) {
|
||||
while (it != client_connection_list.end()) {
|
||||
if (!ProcessConnection(*(*it))) {
|
||||
RemoveClient((*it));
|
||||
it = client_connection_list.begin();
|
||||
|
@ -416,7 +447,7 @@ void Network::Server_Send_MAP()
|
|||
std::unique_ptr<NetworkPacket> packet = NetworkPacket::AllocatePacket();
|
||||
*packet << (uint32)NETWORK_COMMAND_MAP << (uint32)size << (uint32)i;
|
||||
packet->Write(&buffer[i], datasize);
|
||||
for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(NetworkPacket::DuplicatePacket(*packet));
|
||||
}
|
||||
}
|
||||
|
@ -436,7 +467,7 @@ void Network::Server_Send_CHAT(const char* text)
|
|||
std::unique_ptr<NetworkPacket> packet = NetworkPacket::AllocatePacket();
|
||||
*packet << (uint32)NETWORK_COMMAND_CHAT;
|
||||
packet->Write((uint8*)text, strlen(text) + 1);
|
||||
for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(NetworkPacket::DuplicatePacket(*packet));
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +483,7 @@ void Network::Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx
|
|||
{
|
||||
std::unique_ptr<NetworkPacket> packet = NetworkPacket::AllocatePacket();
|
||||
*packet << (uint32)NETWORK_COMMAND_GAMECMD << (uint32)RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) << eax << (ebx | (1 << 31)) << ecx << edx << esi << edi << ebp;
|
||||
for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(NetworkPacket::DuplicatePacket(*packet));
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +492,20 @@ void Network::Server_Send_TICK()
|
|||
{
|
||||
std::unique_ptr<NetworkPacket> packet = NetworkPacket::AllocatePacket();
|
||||
*packet << (uint32)NETWORK_COMMAND_TICK << (uint32)RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32);
|
||||
for(auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(NetworkPacket::DuplicatePacket(*packet));
|
||||
}
|
||||
}
|
||||
|
||||
void Network::Server_Send_PLAYERLIST()
|
||||
{
|
||||
std::unique_ptr<NetworkPacket> packet = NetworkPacket::AllocatePacket();
|
||||
*packet << (uint32)NETWORK_COMMAND_PLAYERLIST << (uint32)player_list.size();
|
||||
for (unsigned int i = 0; i < player_list.size(); i++) {
|
||||
packet->WriteString((const char*)player_list[i]->name);
|
||||
*packet << player_list[i]->id << player_list[i]->flags;
|
||||
}
|
||||
for (auto it = client_connection_list.begin(); it != client_connection_list.end(); it++) {
|
||||
(*it)->QueuePacket(NetworkPacket::DuplicatePacket(*packet));
|
||||
}
|
||||
}
|
||||
|
@ -534,15 +578,18 @@ void Network::ProcessGameCommandQueue()
|
|||
void Network::AddClient(SOCKET socket)
|
||||
{
|
||||
printf("New client connection\n");
|
||||
auto networkconnection = std::unique_ptr<NetworkConnection>(new NetworkConnection); // change to make_unique in c++14
|
||||
networkconnection->socket = socket;
|
||||
client_connection_list.push_back(std::move(networkconnection));
|
||||
auto connection = std::unique_ptr<NetworkConnection>(new NetworkConnection); // change to make_unique in c++14
|
||||
connection->socket = socket;
|
||||
client_connection_list.push_back(std::move(connection));
|
||||
}
|
||||
|
||||
void Network::RemoveClient(std::unique_ptr<NetworkConnection>& networkconnection)
|
||||
void Network::RemoveClient(std::unique_ptr<NetworkConnection>& connection)
|
||||
{
|
||||
printf("Client removed\n");
|
||||
client_connection_list.remove(networkconnection);
|
||||
NetworkPlayer* connection_player = connection->player;
|
||||
player_list.erase(std::remove_if(player_list.begin(), player_list.end(), [connection_player](std::unique_ptr<NetworkPlayer>& player){ return player.get() == connection_player; }), player_list.end());
|
||||
client_connection_list.remove(connection);
|
||||
Server_Send_PLAYERLIST();
|
||||
}
|
||||
|
||||
void Network::PrintError()
|
||||
|
@ -561,22 +608,30 @@ int Network::Client_Handle_AUTH(NetworkConnection& connection, NetworkPacket& pa
|
|||
|
||||
int Network::Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
const char* gameversion = packet.ReadString();
|
||||
const char* name = packet.ReadString();
|
||||
const char* password = packet.ReadString();
|
||||
connection.authstatus = NETWORK_AUTH_OK;
|
||||
if (!gameversion || strcmp(gameversion, OPENRCT2_VERSION) != 0) {
|
||||
connection.authstatus = NETWORK_AUTH_BADVERSION;
|
||||
} else
|
||||
if (!name) {
|
||||
connection.authstatus = NETWORK_AUTH_BADNAME;
|
||||
} else
|
||||
if (!password || strcmp(password, Network::password) != 0) {
|
||||
connection.authstatus = NETWORK_AUTH_BADPASSWORD;
|
||||
if (connection.authstatus != NETWORK_AUTH_OK) {
|
||||
const char* gameversion = packet.ReadString();
|
||||
const char* name = packet.ReadString();
|
||||
const char* password = packet.ReadString();
|
||||
if (!gameversion || strcmp(gameversion, OPENRCT2_VERSION) != 0) {
|
||||
connection.authstatus = NETWORK_AUTH_BADVERSION;
|
||||
} else
|
||||
if (!name) {
|
||||
connection.authstatus = NETWORK_AUTH_BADNAME;
|
||||
} else
|
||||
if (!password || strcmp(password, Network::password) != 0) {
|
||||
connection.authstatus = NETWORK_AUTH_BADPASSWORD;
|
||||
} else {
|
||||
connection.authstatus = NETWORK_AUTH_OK;
|
||||
std::unique_ptr<NetworkPlayer> player(new NetworkPlayer(name)); // change to make_unique in c++14
|
||||
printf("New player: %s\n", player->name);
|
||||
connection.player = player.get();
|
||||
player_list.push_back(std::move(player));
|
||||
Server_Send_PLAYERLIST();
|
||||
}
|
||||
std::unique_ptr<NetworkPacket> responsepacket = NetworkPacket::AllocatePacket();
|
||||
*responsepacket << (uint32)NETWORK_COMMAND_AUTH << (uint32)connection.authstatus;
|
||||
connection.QueuePacket(std::move(responsepacket));
|
||||
}
|
||||
std::unique_ptr<NetworkPacket> responsepacket = NetworkPacket::AllocatePacket();
|
||||
*responsepacket << (uint32)NETWORK_COMMAND_AUTH << (uint32)connection.authstatus;
|
||||
connection.QueuePacket(std::move(responsepacket));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -598,6 +653,9 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
|
|||
SDL_RWops* rw = SDL_RWFromMem(&chunk_buffer[0], size);
|
||||
if (game_load_sv6(rw)) {
|
||||
game_load_init();
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) & 1)
|
||||
pause_toggle();
|
||||
game_command_queue.clear();
|
||||
}
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
|
@ -661,6 +719,23 @@ int Network::Client_Handle_TICK(NetworkConnection& connection, NetworkPacket& pa
|
|||
return 1;
|
||||
}
|
||||
|
||||
int Network::Client_Handle_PLAYERLIST(NetworkConnection& connection, NetworkPacket& packet)
|
||||
{
|
||||
player_list.clear();
|
||||
uint32 size;
|
||||
packet >> size;
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
const char* name = packet.ReadString();
|
||||
std::unique_ptr<NetworkPlayer> player(new NetworkPlayer(name)); // change to make_unique in c++14
|
||||
packet >> player->id >> player->flags;
|
||||
if (player->flags & NETWORK_PLAYER_FLAG_ISSERVER) {
|
||||
server_connection.player = player.get();
|
||||
}
|
||||
player_list.push_back(std::move(player));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int network_init()
|
||||
{
|
||||
return gNetwork.Init();
|
||||
|
@ -691,11 +766,26 @@ int network_get_mode()
|
|||
return gNetwork.GetMode();
|
||||
}
|
||||
|
||||
int network_get_authstatus()
|
||||
{
|
||||
return gNetwork.GetAuthStatus();
|
||||
}
|
||||
|
||||
uint32 network_get_server_tick()
|
||||
{
|
||||
return gNetwork.GetServerTick();
|
||||
}
|
||||
|
||||
int network_get_num_players()
|
||||
{
|
||||
return gNetwork.player_list.size();
|
||||
}
|
||||
|
||||
const char* network_get_player_name(unsigned int index)
|
||||
{
|
||||
return (const char*)gNetwork.player_list[index]->name;
|
||||
}
|
||||
|
||||
void network_send_map()
|
||||
{
|
||||
gNetwork.Server_Send_MAP();
|
||||
|
|
|
@ -40,6 +40,10 @@ enum {
|
|||
NETWORK_AUTH_BADPASSWORD
|
||||
};
|
||||
|
||||
enum {
|
||||
NETWORK_PLAYER_FLAG_ISSERVER = 1 << 0,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <list>
|
||||
|
@ -54,6 +58,8 @@ extern "C" {
|
|||
template <std::size_t size>
|
||||
struct ByteSwapT { };
|
||||
template <>
|
||||
struct ByteSwapT<1> { static uint8 SwapBE(uint8 value) { return value; } };
|
||||
template <>
|
||||
struct ByteSwapT<2> { static uint16 SwapBE(uint16 value) { return SDL_SwapBE16(value); } };
|
||||
template <>
|
||||
struct ByteSwapT<4> { static uint32 SwapBE(uint32 value) { return SDL_SwapBE32(value); } };
|
||||
|
@ -83,6 +89,16 @@ public:
|
|||
int read;
|
||||
};
|
||||
|
||||
class NetworkPlayer
|
||||
{
|
||||
public:
|
||||
NetworkPlayer(const char* name);
|
||||
uint8 id;
|
||||
uint8 name[32 + 1];
|
||||
uint16 ping;
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
class NetworkConnection
|
||||
{
|
||||
public:
|
||||
|
@ -94,19 +110,13 @@ public:
|
|||
SOCKET socket;
|
||||
NetworkPacket inboundpacket;
|
||||
int authstatus;
|
||||
NetworkPlayer* player;
|
||||
|
||||
private:
|
||||
int SendPacket(NetworkPacket& packet);
|
||||
std::list<std::unique_ptr<NetworkPacket>> outboundpackets;
|
||||
};
|
||||
|
||||
class NetworkPlayer
|
||||
{
|
||||
public:
|
||||
uint8 name[16 + 1];
|
||||
uint16 ping;
|
||||
};
|
||||
|
||||
class Network
|
||||
{
|
||||
public:
|
||||
|
@ -117,6 +127,7 @@ public:
|
|||
bool BeginClient(const char* host, unsigned short port);
|
||||
bool BeginServer(unsigned short port);
|
||||
int GetMode();
|
||||
int GetAuthStatus();
|
||||
uint32 GetServerTick();
|
||||
void Update();
|
||||
|
||||
|
@ -127,6 +138,9 @@ public:
|
|||
void Client_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
|
||||
void Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp);
|
||||
void Server_Send_TICK();
|
||||
void Server_Send_PLAYERLIST();
|
||||
|
||||
std::vector<std::unique_ptr<NetworkPlayer>> player_list;
|
||||
|
||||
private:
|
||||
bool ProcessConnection(NetworkConnection& connection);
|
||||
|
@ -169,6 +183,7 @@ private:
|
|||
int Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Client_Handle_TICK(NetworkConnection& connection, NetworkPacket& packet);
|
||||
int Client_Handle_PLAYERLIST(NetworkConnection& connection, NetworkPacket& packet);
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
@ -181,7 +196,10 @@ int network_begin_server(int port);
|
|||
|
||||
void network_update();
|
||||
int network_get_mode();
|
||||
int network_get_authstatus();
|
||||
uint32 network_get_server_tick();
|
||||
int network_get_num_players();
|
||||
const char* network_get_player_name(unsigned int index);
|
||||
|
||||
void network_send_map();
|
||||
void network_send_chat(const char* text);
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../network/network.h"
|
||||
|
||||
static void window_chat_host_emptysub() { }
|
||||
|
||||
static void window_chat_host_textinput(rct_window *w, int widgetIndex, char *text)
|
||||
{
|
||||
network_send_chat(text);
|
||||
|
@ -71,4 +71,213 @@ void window_chat_open()
|
|||
w->colours[2] = 0;
|
||||
w->number = 0;
|
||||
window_text_input_open(w, 0, 6000, 6001, STR_NONE, 0, 64);
|
||||
}
|
||||
|
||||
enum WINDOW_PLAYER_LIST_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
WIDX_TITLE,
|
||||
WIDX_CLOSE,
|
||||
WIDX_CONTENT_PANEL,
|
||||
WIDX_TAB1,
|
||||
WIDX_LIST,
|
||||
};
|
||||
|
||||
static rct_widget window_player_list_widgets[] = {
|
||||
{ WWT_FRAME, 0, 0, 319, 0, 269, 0x0FFFFFFFF, 65535 }, // panel / background
|
||||
{ WWT_CAPTION, 0, 1, 318, 1, 14, STR_PLAYER_LIST, STR_WINDOW_TITLE_TIP }, // title bar
|
||||
{ WWT_CLOSEBOX, 0, 307, 317, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button
|
||||
{ WWT_RESIZE, 1, 0, 319, 43, 269, 0x0FFFFFFFF, STR_NONE }, // content panel
|
||||
{ WWT_TAB, 1, 3, 33, 17, 43, 0x02000144E, STR_NONE }, // tab
|
||||
{ WWT_SCROLL, 1, 3, 316, 72, 266, 3, 65535 }, // list
|
||||
{ WIDGETS_END },
|
||||
};
|
||||
|
||||
static void window_player_list_mouseup(rct_window *w, int widgetIndex);
|
||||
static void window_player_list_resize(rct_window *w);
|
||||
static void window_player_list_mousedown(int widgetIndex, rct_window* w, rct_widget* widget);
|
||||
static void window_player_list_update(rct_window *w);
|
||||
static void window_player_list_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height);
|
||||
static void window_player_list_invalidate(rct_window *w);
|
||||
static void window_player_list_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
||||
static void window_player_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex);
|
||||
|
||||
static rct_window_event_list window_player_list_events = {
|
||||
NULL,
|
||||
window_player_list_mouseup,
|
||||
window_player_list_resize,
|
||||
window_player_list_mousedown,
|
||||
NULL,
|
||||
NULL,
|
||||
window_player_list_update,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
window_player_list_scrollgetsize,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
window_player_list_invalidate,
|
||||
window_player_list_paint,
|
||||
window_player_list_scrollpaint
|
||||
};
|
||||
|
||||
static void window_player_list_refresh_list(rct_window *w);
|
||||
|
||||
void window_player_list_open()
|
||||
{
|
||||
rct_window* window;
|
||||
|
||||
// Check if window is already open
|
||||
window = window_bring_to_front_by_class(WC_PLAYER_LIST);
|
||||
if (window != NULL)
|
||||
return;
|
||||
|
||||
window = window_create_auto_pos(320, 270, &window_player_list_events, WC_PLAYER_LIST, WF_10 | WF_RESIZABLE);
|
||||
|
||||
window->widgets = window_player_list_widgets;
|
||||
window->enabled_widgets = 1 << WIDX_CLOSE;
|
||||
window->no_list_items = 0;
|
||||
window->selected_list_item = -1;
|
||||
window->frame_no = 0;
|
||||
window->min_width = 320;
|
||||
window->min_height = 270;
|
||||
window->max_width = 500;
|
||||
window->max_height = 450;
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->page = 0;
|
||||
window->list_information_type = 0;
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
}
|
||||
|
||||
static void window_player_list_mouseup(rct_window *w, int widgetIndex)
|
||||
{
|
||||
switch (widgetIndex) {
|
||||
case WIDX_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_player_list_resize(rct_window *w)
|
||||
{
|
||||
if (w->width < w->min_width) {
|
||||
window_invalidate(w);
|
||||
w->width = w->min_width;
|
||||
}
|
||||
if (w->height < w->min_height) {
|
||||
window_invalidate(w);
|
||||
w->height = w->min_height;
|
||||
}
|
||||
|
||||
window_player_list_refresh_list(w);
|
||||
}
|
||||
|
||||
static void window_player_list_mousedown(int widgetIndex, rct_window* w, rct_widget* widget)
|
||||
{
|
||||
switch (widgetIndex) {
|
||||
case WIDX_TAB1:
|
||||
if (w->page != widgetIndex - WIDX_TAB1) {
|
||||
w->page = widgetIndex - WIDX_TAB1;
|
||||
w->no_list_items = 0;
|
||||
w->frame_no = 0;
|
||||
w->selected_list_item = -1;
|
||||
window_invalidate(w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_player_list_update(rct_window *w)
|
||||
{
|
||||
widget_invalidate(w, WIDX_TAB1 + w->page);
|
||||
}
|
||||
|
||||
static void window_player_list_scrollgetsize(rct_window *w, int scrollIndex, int *width, int *height)
|
||||
{
|
||||
int i;
|
||||
|
||||
uint16 playerCount = 0;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) != -1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) = -1;
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
*height = playerCount * 10;
|
||||
i = *height - window_player_list_widgets[WIDX_LIST].bottom + window_player_list_widgets[WIDX_LIST].top + 21;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
if (i < w->scrolls[0].v_top) {
|
||||
w->scrolls[0].v_top = i;
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
*width = 420;
|
||||
}
|
||||
|
||||
static void window_player_list_invalidate(rct_window *w)
|
||||
{
|
||||
for (int i = 0; i < 1; i++)
|
||||
w->pressed_widgets &= ~(1 << (WIDX_TAB1 + i));
|
||||
w->pressed_widgets |= 1LL << (WIDX_TAB1 + w->page);
|
||||
window_player_list_widgets[WIDX_BACKGROUND].right = w->width - 1;
|
||||
window_player_list_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
window_player_list_widgets[WIDX_CONTENT_PANEL].right = w->width - 1;
|
||||
window_player_list_widgets[WIDX_CONTENT_PANEL].bottom = w->height - 1;
|
||||
window_player_list_widgets[WIDX_TITLE].right = w->width - 2;
|
||||
window_player_list_widgets[WIDX_CLOSE].left = w->width - 2 - 0x0B;
|
||||
window_player_list_widgets[WIDX_CLOSE].right = w->width - 2 - 0x0B + 0x0A;
|
||||
window_player_list_widgets[WIDX_LIST].right = w->width - 4;
|
||||
window_player_list_widgets[WIDX_LIST].bottom = w->height - 0x0F;
|
||||
}
|
||||
|
||||
static void window_player_list_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
||||
{
|
||||
window_draw_widgets(w, dpi);
|
||||
}
|
||||
|
||||
static void window_player_list_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scrollIndex)
|
||||
{
|
||||
int y;
|
||||
|
||||
gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ((char*)0x0141FC48)[w->colours[1] * 8]);
|
||||
|
||||
y = 0;
|
||||
for (int i = 0; i < network_get_num_players(); i++) {
|
||||
if (y > dpi->y + dpi->height) {
|
||||
break;
|
||||
}
|
||||
|
||||
int format = 1191;
|
||||
|
||||
if (y + 11 >= dpi->y) {
|
||||
gfx_draw_string(dpi, (char*)network_get_player_name(i), 255, 0, y - 1);
|
||||
}
|
||||
y += 10;
|
||||
}
|
||||
}
|
||||
|
||||
static void window_player_list_refresh_list(rct_window *w)
|
||||
{
|
||||
window_invalidate(w);
|
||||
|
||||
w->no_list_items = 1;
|
||||
w->list_item_positions[0] = 0;
|
||||
|
||||
w->selected_list_item = -1;
|
||||
window_invalidate(w);
|
||||
}
|
|
@ -65,6 +65,7 @@ enum {
|
|||
WIDX_FINANCES,
|
||||
WIDX_RESEARCH,
|
||||
WIDX_NEWS,
|
||||
WIDX_NETWORK,
|
||||
|
||||
WIDX_SEPARATOR,
|
||||
};
|
||||
|
@ -105,6 +106,10 @@ typedef enum {
|
|||
DDIDX_SCENARIO_OPTIONS = 4
|
||||
} TOP_TOOLBAR_DEBUG_DDIDX;
|
||||
|
||||
typedef enum {
|
||||
DDIDX_PLAYER_LIST = 0
|
||||
} TOP_TOOLBAR_NETWORK_DDIDX;
|
||||
|
||||
enum {
|
||||
DDIDX_CHEATS,
|
||||
DDIDX_ENABLE_SANDBOX_MODE = 2,
|
||||
|
@ -129,6 +134,7 @@ static const int left_aligned_widgets_order[] = {
|
|||
WIDX_ROTATE,
|
||||
WIDX_VIEW_MENU,
|
||||
WIDX_MAP,
|
||||
WIDX_NETWORK,
|
||||
};
|
||||
|
||||
// from right to left
|
||||
|
@ -179,6 +185,7 @@ static rct_widget window_top_toolbar_widgets[] = {
|
|||
{ WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 3235 }, // Finances
|
||||
{ WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 2275 }, // Research
|
||||
{ WWT_TRNBTN, 3, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, STR_SHOW_RECENT_MESSAGES_TIP }, // News
|
||||
{ WWT_TRNBTN, 1, 0x001E, 0x003B, 0, 27, 0x20000000 | 0x15F9, 2276 }, // Network
|
||||
|
||||
{ WWT_EMPTY, 0, 0, 10-1, 0, 0, 0xFFFFFFFF, STR_NONE }, // Artificial widget separator
|
||||
{ WIDGETS_END },
|
||||
|
@ -234,6 +241,8 @@ void top_toolbar_init_rotate_menu(rct_window *window, rct_widget *widget);
|
|||
void top_toolbar_rotate_menu_dropdown(short dropdownIndex);
|
||||
void top_toolbar_init_debug_menu(rct_window *window, rct_widget *widget);
|
||||
void top_toolbar_debug_menu_dropdown(short dropdownIndex);
|
||||
void top_toolbar_init_network_menu(rct_window *window, rct_widget *widget);
|
||||
void top_toolbar_network_menu_dropdown(short dropdownIndex);
|
||||
|
||||
void toggle_footpath_window();
|
||||
void toggle_land_window(rct_window *topToolbar, int widgetIndex);
|
||||
|
@ -461,6 +470,9 @@ static void window_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widg
|
|||
case WIDX_DEBUG:
|
||||
top_toolbar_init_debug_menu(w, widget);
|
||||
break;
|
||||
case WIDX_NETWORK:
|
||||
top_toolbar_init_network_menu(w, widget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,6 +572,9 @@ static void window_top_toolbar_dropdown(rct_window *w, int widgetIndex, int drop
|
|||
case WIDX_DEBUG:
|
||||
top_toolbar_debug_menu_dropdown(dropdownIndex);
|
||||
break;
|
||||
case WIDX_NETWORK:
|
||||
top_toolbar_network_menu_dropdown(dropdownIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,6 +613,7 @@ static void window_top_toolbar_invalidate(rct_window *w)
|
|||
window_top_toolbar_widgets[WIDX_CHEATS].type = WWT_TRNBTN;
|
||||
window_top_toolbar_widgets[WIDX_DEBUG].type = gConfigGeneral.debugging_tools ? WWT_TRNBTN : WWT_EMPTY;
|
||||
window_top_toolbar_widgets[WIDX_NEWS].type = WWT_TRNBTN;
|
||||
window_top_toolbar_widgets[WIDX_NETWORK].type = WWT_TRNBTN;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) {
|
||||
window_top_toolbar_widgets[WIDX_PAUSE].type = WWT_EMPTY;
|
||||
|
@ -645,7 +661,7 @@ static void window_top_toolbar_invalidate(rct_window *w)
|
|||
}
|
||||
|
||||
enabledWidgets = 0;
|
||||
for (i = WIDX_PAUSE; i <= WIDX_NEWS; i++)
|
||||
for (i = WIDX_PAUSE; i <= WIDX_NETWORK; i++)
|
||||
if (window_top_toolbar_widgets[i].type != WWT_EMPTY)
|
||||
enabledWidgets |= (1 << i);
|
||||
w->enabled_widgets = enabledWidgets;
|
||||
|
@ -2862,6 +2878,21 @@ void top_toolbar_init_debug_menu(rct_window* w, rct_widget* widget) {
|
|||
RCT2_GLOBAL(0x9DEBA2, uint16) = 0;
|
||||
}
|
||||
|
||||
void top_toolbar_init_network_menu(rct_window* w, rct_widget* widget) {
|
||||
gDropdownItemsFormat[0] = STR_PLAYER_LIST;
|
||||
|
||||
window_dropdown_show_text(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1] | 0x80,
|
||||
0,
|
||||
1
|
||||
);
|
||||
|
||||
RCT2_GLOBAL(0x9DEBA2, uint16) = 0;
|
||||
}
|
||||
|
||||
void top_toolbar_debug_menu_dropdown(short dropdownIndex) {
|
||||
if (dropdownIndex == -1) dropdownIndex = RCT2_GLOBAL(0x9DEBA2, uint16);
|
||||
rct_window* w = window_get_main();
|
||||
|
@ -2887,6 +2918,18 @@ void top_toolbar_debug_menu_dropdown(short dropdownIndex) {
|
|||
}
|
||||
}
|
||||
|
||||
void top_toolbar_network_menu_dropdown(short dropdownIndex) {
|
||||
if (dropdownIndex == -1) dropdownIndex = RCT2_GLOBAL(0x9DEBA2, uint16);
|
||||
rct_window* w = window_get_main();
|
||||
if (w) {
|
||||
switch (dropdownIndex) {
|
||||
case DDIDX_PLAYER_LIST:
|
||||
window_player_list_open();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0066CDE4
|
||||
|
|
Loading…
Reference in New Issue