Improve doc comments for vendor:ggpo

This commit is contained in:
gingerBill
2024-08-14 13:55:25 +01:00
parent 8abe054665
commit df61096317
+260 -304
View File
@@ -1,3 +1,15 @@
/*
Created in 2009, the GGPO networking SDK pioneered the use of rollback networking in peer-to-peer games.
It's designed specifically to hide network latency in fast paced, twitch style games which require very
precise inputs and frame perfect execution.
Traditional techniques account for network transmission time by adding delay to a players input, resulting
in a sluggish, laggy game-feel. Rollback networking uses input prediction and speculative execution to
send player inputs to the game immediately, providing the illusion of a zero-latency network. Using rollback,
the same timings, reactions visual and audio queues, and muscle memory your players build up playing offline
translate directly online. The GGPO networking SDK is designed to make incorporating rollback networking
into new and existing games as easy as possible.
*/
package vendor_ggpo package vendor_ggpo
foreign import lib "GGPO.lib" foreign import lib "GGPO.lib"
@@ -19,31 +31,27 @@ PlayerType :: enum c.int {
SPECTATOR, SPECTATOR,
} }
/*
* The Player structure used to describe players in add_player
*
* size: Should be set to the size_of(Player)
*
* type: One of the PlayerType values describing how inputs should be handled
* Local players must have their inputs updated every frame via
* add_local_inputs. Remote players values will come over the
* network.
*
* player_num: The player number. Should be between 1 and the number of players
* In the game (e.g. in a 2 player game, either 1 or 2).
*
* If type == PLAYERTYPE_REMOTE:
*
* remote.ip_address: The ip address of the ggpo session which will host this
* player.
*
* remote.port: The port where udp packets should be sent to reach this player.
* All the local inputs for this session will be sent to this player at
* ip_address:port.
*
*/
// The Player structure used to describe players in add_player
//
// size: Should be set to the size_of(Player)
//
// type: One of the PlayerType values describing how inputs should be handled
// Local players must have their inputs updated every frame via
// add_local_inputs. Remote players values will come over the
// network.
//
// player_num: The player number. Should be between 1 and the number of players
// In the game (e.g. in a 2 player game, either 1 or 2).
//
// If type == PLAYERTYPE_REMOTE:
//
// remote.ip_address: The ip address of the ggpo session which will host this
// player.
//
// remote.port: The port where udp packets should be sent to reach this player.
// All the local inputs for this session will be sent to this player at
// ip_address:port.
Player :: struct { Player :: struct {
size: c.int, size: c.int,
type: PlayerType, type: PlayerType,
@@ -80,32 +88,29 @@ ErrorCode :: enum c.int {
INVALID_HANDLE :: PlayerHandle(-1) INVALID_HANDLE :: PlayerHandle(-1)
/* // The EventCode enumeration describes what type of event just happened.
* The EventCode enumeration describes what type of event just happened. //
* // CONNECTED_TO_PEER - Handshake with the game running on the
* CONNECTED_TO_PEER - Handshake with the game running on the // other side of the network has been completed.
* other side of the network has been completed. //
* // SYNCHRONIZING_WITH_PEER - Beginning the synchronization
* SYNCHRONIZING_WITH_PEER - Beginning the synchronization // process with the client on the other end of the networking. The count
* process with the client on the other end of the networking. The count // and total fields in the u.synchronizing struct of the Event
* and total fields in the u.synchronizing struct of the Event // object indicate progress.
* object indicate progress. //
* // SYNCHRONIZED_WITH_PEER - The synchronziation with this
* SYNCHRONIZED_WITH_PEER - The synchronziation with this // peer has finished.
* peer has finished. //
* // RUNNING - All the clients have synchronized. You may begin
* RUNNING - All the clients have synchronized. You may begin // sending inputs with synchronize_inputs.
* sending inputs with synchronize_inputs. //
* // DISCONNECTED_FROM_PEER - The network connection on
* DISCONNECTED_FROM_PEER - The network connection on // the other end of the network has closed.
* the other end of the network has closed. //
* // TIMESYNC - The time synchronziation code has determined
* TIMESYNC - The time synchronziation code has determined // that this client is too far ahead of the other one and should slow
* that this client is too far ahead of the other one and should slow // down to ensure fairness. The u.timesync.frames_ahead parameter in
* down to ensure fairness. The u.timesync.frames_ahead parameter in // the Event object indicates how many frames the client is.
* the Event object indicates how many frames the client is.
*
*/
EventCode :: enum c.int { EventCode :: enum c.int {
CONNECTED_TO_PEER = 1000, CONNECTED_TO_PEER = 1000,
SYNCHRONIZING_WITH_PEER = 1001, SYNCHRONIZING_WITH_PEER = 1001,
@@ -117,13 +122,10 @@ EventCode :: enum c.int {
CONNECTION_RESUMED = 1007, CONNECTION_RESUMED = 1007,
} }
/* // The Event structure contains an asynchronous event notification sent
* The Event structure contains an asynchronous event notification sent // by the on_event callback. See EventCode, above, for a detailed
* by the on_event callback. See EventCode, above, for a detailed // explanation of each event.
* explanation of each event. Event :: struct {
*/
Event :: struct {
code: EventCode, code: EventCode,
using u: struct #raw_union { using u: struct #raw_union {
connected: struct { connected: struct {
@@ -153,100 +155,83 @@ EventCode :: enum c.int {
}, },
} }
/* //
* The SessionCallbacks structure contains the callback functions that // The SessionCallbacks structure contains the callback functions that
* your application must implement. GGPO.net will periodically call these // your application must implement. GGPO.net will periodically call these
* functions during the game. All callback functions must be implemented. // functions during the game. All callback functions must be implemented.
*/ //
SessionCallbacks :: struct { SessionCallbacks :: struct {
/* // begin_game callback - This callback has been deprecated. You must
* begin_game callback - This callback has been deprecated. You must // implement it, but should ignore the 'game' parameter.
* implement it, but should ignore the 'game' parameter.
*/
begin_game: proc "c" (game: cstring) -> bool, begin_game: proc "c" (game: cstring) -> bool,
/* // save_game_state - The client should allocate a buffer, copy the
* save_game_state - The client should allocate a buffer, copy the // entire contents of the current game state into it, and copy the
* entire contents of the current game state into it, and copy the // length into the len parameter. Optionally, the client can compute
* length into the len parameter. Optionally, the client can compute // a checksum of the data and store it in the checksum argument.
* a checksum of the data and store it in the checksum argument.
*/
save_game_state: proc "c" (buffer: ^[^]byte, len: ^c.int, checksum: ^c.int, frame: c.int) -> bool, save_game_state: proc "c" (buffer: ^[^]byte, len: ^c.int, checksum: ^c.int, frame: c.int) -> bool,
/* // load_game_state - GGPO.net will call this function at the beginning
* load_game_state - GGPO.net will call this function at the beginning // of a rollback. The buffer and len parameters contain a previously
* of a rollback. The buffer and len parameters contain a previously // saved state returned from the save_game_state function. The client
* saved state returned from the save_game_state function. The client // should make the current game state match the state contained in the
* should make the current game state match the state contained in the // buffer.
* buffer.
*/
load_game_state: proc "c" (buffer: [^]byte, len: c.int) -> bool, load_game_state: proc "c" (buffer: [^]byte, len: c.int) -> bool,
/* // log_game_state - Used in diagnostic testing. The client should use
* log_game_state - Used in diagnostic testing. The client should use // the log function to write the contents of the specified save
* the log function to write the contents of the specified save // state in a human readible form.
* state in a human readible form.
*/
log_game_state: proc "c" (filename: cstring, buffer: [^]byte, len: c.int) -> bool, log_game_state: proc "c" (filename: cstring, buffer: [^]byte, len: c.int) -> bool,
/* // free_buffer - Frees a game state allocated in save_game_state. You
* free_buffer - Frees a game state allocated in save_game_state. You // should deallocate the memory contained in the buffer.
* should deallocate the memory contained in the buffer.
*/
free_buffer: proc "c" (buffer: rawptr), free_buffer: proc "c" (buffer: rawptr),
/* // advance_frame - Called during a rollback. You should advance your game
* advance_frame - Called during a rollback. You should advance your game // state by exactly one frame. Before each frame, call synchronize_input
* state by exactly one frame. Before each frame, call synchronize_input // to retrieve the inputs you should use for that frame. After each frame,
* to retrieve the inputs you should use for that frame. After each frame, // you should call advance_frame to notify GGPO.net that you're
* you should call advance_frame to notify GGPO.net that you're // finished.
* finished. //
* // The flags parameter is reserved. It can safely be ignored at this time.
* The flags parameter is reserved. It can safely be ignored at this time.
*/
advance_frame: proc "c" (flags: c.int) -> bool, advance_frame: proc "c" (flags: c.int) -> bool,
/* // on_event - Notification that something has happened. See the EventCode
* on_event - Notification that something has happened. See the EventCode // structure above for more information.
* structure above for more information.
*/
on_event: proc "c" (info: ^Event) -> bool, on_event: proc "c" (info: ^Event) -> bool,
} }
/* // The NetworkStats function contains some statistics about the current
* The NetworkStats function contains some statistics about the current // session.
* session. //
* // network.send_queue_len - The length of the queue containing UDP packets
* network.send_queue_len - The length of the queue containing UDP packets // which have not yet been acknowledged by the end client. The length of
* which have not yet been acknowledged by the end client. The length of // the send queue is a rough indication of the quality of the connection.
* the send queue is a rough indication of the quality of the connection. // The longer the send queue, the higher the round-trip time between the
* The longer the send queue, the higher the round-trip time between the // clients. The send queue will also be longer than usual during high
* clients. The send queue will also be longer than usual during high // packet loss situations.
* packet loss situations. //
* // network.recv_queue_len - The number of inputs currently buffered by the
* network.recv_queue_len - The number of inputs currently buffered by the // GGPO.net network layer which have yet to be validated. The length of
* GGPO.net network layer which have yet to be validated. The length of // the prediction queue is roughly equal to the current frame number
* the prediction queue is roughly equal to the current frame number // minus the frame number of the last packet in the remote queue.
* minus the frame number of the last packet in the remote queue. //
* // network.ping - The roundtrip packet transmission time as calcuated
* network.ping - The roundtrip packet transmission time as calcuated // by GGPO.net. This will be roughly equal to the actual round trip
* by GGPO.net. This will be roughly equal to the actual round trip // packet transmission time + 2 the interval at which you call idle
* packet transmission time + 2 the interval at which you call idle // or advance_frame.
* or advance_frame. //
* // network.kbps_sent - The estimated bandwidth used between the two
* network.kbps_sent - The estimated bandwidth used between the two // clients, in kilobits per second.
* clients, in kilobits per second. //
* // timesync.local_frames_behind - The number of frames GGPO.net calculates
* timesync.local_frames_behind - The number of frames GGPO.net calculates // that the local client is behind the remote client at this instant in
* that the local client is behind the remote client at this instant in // time. For example, if at this instant the current game client is running
* time. For example, if at this instant the current game client is running // frame 1002 and the remote game client is running frame 1009, this value
* frame 1002 and the remote game client is running frame 1009, this value // will mostly likely roughly equal 7.
* will mostly likely roughly equal 7. //
* // timesync.remote_frames_behind - The same as local_frames_behind, but
* timesync.remote_frames_behind - The same as local_frames_behind, but // calculated from the perspective of the remote player.
* calculated from the perspective of the remote player.
*
*/
NetworkStats :: struct { NetworkStats :: struct {
network: struct { network: struct {
send_queue_len: c.int, send_queue_len: c.int,
@@ -263,29 +248,27 @@ NetworkStats :: struct {
@(default_calling_convention="c") @(default_calling_convention="c")
@(link_prefix="ggpo_") @(link_prefix="ggpo_")
foreign lib { foreign lib {
/* // start_session --
* start_session -- //
* // Used to being a new GGPO.net session. The ggpo object returned by start_session
* Used to being a new GGPO.net session. The ggpo object returned by start_session // uniquely identifies the state for this session and should be passed to all other
* uniquely identifies the state for this session and should be passed to all other // functions.
* functions. //
* // session - An out parameter to the new ggpo session object.
* session - An out parameter to the new ggpo session object. //
* // cb - A SessionCallbacks structure which contains the callbacks you implement
* cb - A SessionCallbacks structure which contains the callbacks you implement // to help GGPO.net synchronize the two games. You must implement all functions in
* to help GGPO.net synchronize the two games. You must implement all functions in // cb, even if they do nothing but 'return true';
* cb, even if they do nothing but 'return true'; //
* // game - The name of the game. This is used internally for GGPO for logging purposes only.
* game - The name of the game. This is used internally for GGPO for logging purposes only. //
* // num_players - The number of players which will be in this game. The number of players
* num_players - The number of players which will be in this game. The number of players // per session is fixed. If you need to change the number of players or any player
* per session is fixed. If you need to change the number of players or any player // disconnects, you must start a new session.
* disconnects, you must start a new session. //
* // input_size - The size of the game inputs which will be passsed to add_local_input.
* input_size - The size of the game inputs which will be passsed to add_local_input. //
* // local_port - The port GGPO should bind to for UDP traffic.
* local_port - The port GGPO should bind to for UDP traffic.
*/
start_session :: proc(session: ^^Session, start_session :: proc(session: ^^Session,
cb: ^SessionCallbacks, cb: ^SessionCallbacks,
game: cstring, game: cstring,
@@ -294,17 +277,15 @@ foreign lib {
localport: u16) -> ErrorCode --- localport: u16) -> ErrorCode ---
/* // add_player --
* add_player -- //
* // Must be called for each player in the session (e.g. in a 3 player session, must
* Must be called for each player in the session (e.g. in a 3 player session, must // be called 3 times).
* be called 3 times). //
* // player - A Player struct used to describe the player.
* player - A Player struct used to describe the player. //
* // handle - An out parameter to a handle used to identify this player in the future.
* handle - An out parameter to a handle used to identify this player in the future. // (e.g. in the on_event callbacks).
* (e.g. in the on_event callbacks).
*/
add_player :: proc(session: ^Session, add_player :: proc(session: ^Session,
player: ^Player, player: ^Player,
handle: ^PlayerHandle) -> ErrorCode --- handle: ^PlayerHandle) -> ErrorCode ---
@@ -342,30 +323,28 @@ foreign lib {
frames: c.int) -> ErrorCode --- frames: c.int) -> ErrorCode ---
/* // start_spectating --
* start_spectating -- //
* // Start a spectator session.
* Start a spectator session. //
* // cb - A SessionCallbacks structure which contains the callbacks you implement
* cb - A SessionCallbacks structure which contains the callbacks you implement // to help GGPO.net synchronize the two games. You must implement all functions in
* to help GGPO.net synchronize the two games. You must implement all functions in // cb, even if they do nothing but 'return true';
* cb, even if they do nothing but 'return true'; //
* // game - The name of the game. This is used internally for GGPO for logging purposes only.
* game - The name of the game. This is used internally for GGPO for logging purposes only. //
* // num_players - The number of players which will be in this game. The number of players
* num_players - The number of players which will be in this game. The number of players // per session is fixed. If you need to change the number of players or any player
* per session is fixed. If you need to change the number of players or any player // disconnects, you must start a new session.
* disconnects, you must start a new session. //
* // input_size - The size of the game inputs which will be passsed to add_local_input.
* input_size - The size of the game inputs which will be passsed to add_local_input. //
* // local_port - The port GGPO should bind to for UDP traffic.
* local_port - The port GGPO should bind to for UDP traffic. //
* // host_ip - The IP address of the host who will serve you the inputs for the game. Any
* host_ip - The IP address of the host who will serve you the inputs for the game. Any // player partcipating in the session can serve as a host.
* player partcipating in the session can serve as a host. //
* // host_port - The port of the session on the host
* host_port - The port of the session on the host
*/
start_spectating :: proc(session: ^^Session, start_spectating :: proc(session: ^^Session,
cb: ^SessionCallbacks, cb: ^SessionCallbacks,
game: cstring, game: cstring,
@@ -375,152 +354,129 @@ foreign lib {
host_ip: cstring, host_ip: cstring,
host_port: u16) -> ErrorCode --- host_port: u16) -> ErrorCode ---
/* // close_session --
* close_session -- // Used to close a session. You must call close_session to
* Used to close a session. You must call close_session to // free the resources allocated in start_session.
* free the resources allocated in start_session.
*/
close_session :: proc(session: ^Session) -> ErrorCode --- close_session :: proc(session: ^Session) -> ErrorCode ---
/* // set_frame_delay --
* set_frame_delay -- //
* // Change the amount of frames ggpo will delay local input. Must be called
* Change the amount of frames ggpo will delay local input. Must be called // before the first call to synchronize_input.
* before the first call to synchronize_input.
*/
set_frame_delay :: proc(session: ^Session, set_frame_delay :: proc(session: ^Session,
player: PlayerHandle, player: PlayerHandle,
frame_delay: c.int) -> ErrorCode --- frame_delay: c.int) -> ErrorCode ---
/* // idle --
* idle -- // Should be called periodically by your application to give GGPO.net
* Should be called periodically by your application to give GGPO.net // a chance to do some work. Most packet transmissions and rollbacks occur
* a chance to do some work. Most packet transmissions and rollbacks occur // in idle.
* in idle. //
* // timeout - The amount of time GGPO.net is allowed to spend in this function,
* timeout - The amount of time GGPO.net is allowed to spend in this function, // in milliseconds.
* in milliseconds.
*/
idle :: proc(session: ^Session, idle :: proc(session: ^Session,
timeout: c.int) -> ErrorCode --- timeout: c.int) -> ErrorCode ---
/* // add_local_input --
* add_local_input -- //
* // Used to notify GGPO.net of inputs that should be trasmitted to remote
* Used to notify GGPO.net of inputs that should be trasmitted to remote // players. add_local_input must be called once every frame for
* players. add_local_input must be called once every frame for // all player of type PLAYERTYPE_LOCAL.
* all player of type PLAYERTYPE_LOCAL. //
* // player - The player handle returned for this player when you called
* player - The player handle returned for this player when you called // add_local_player.
* add_local_player. //
* // values - The controller inputs for this player.
* values - The controller inputs for this player. //
* // size - The size of the controller inputs. This must be exactly equal to the
* size - The size of the controller inputs. This must be exactly equal to the // size passed into start_session.
* size passed into start_session.
*/
add_local_input :: proc(session: ^Session, add_local_input :: proc(session: ^Session,
player: PlayerHandle, player: PlayerHandle,
values: rawptr, values: rawptr,
size: c.int) -> ErrorCode --- size: c.int) -> ErrorCode ---
/* // synchronize_input --
* synchronize_input -- //
* // You should call synchronize_input before every frame of execution,
* You should call synchronize_input before every frame of execution, // including those frames which happen during rollback.
* including those frames which happen during rollback. //
* // values - When the function returns, the values parameter will contain
* values - When the function returns, the values parameter will contain // inputs for this frame for all players. The values array must be at
* inputs for this frame for all players. The values array must be at // least (size * players) large.
* least (size * players) large. //
* // size - The size of the values array.
* size - The size of the values array. //
* // disconnect_flags - Indicated whether the input in slot (1 << flag) is
* disconnect_flags - Indicated whether the input in slot (1 << flag) is // valid. If a player has disconnected, the input in the values array for
* valid. If a player has disconnected, the input in the values array for // that player will be zeroed and the i-th flag will be set. For example,
* that player will be zeroed and the i-th flag will be set. For example, // if only player 3 has disconnected, disconnect flags will be 8 (i.e. 1 << 3).
* if only player 3 has disconnected, disconnect flags will be 8 (i.e. 1 << 3).
*/
synchronize_input :: proc(session: ^Session, synchronize_input :: proc(session: ^Session,
values: rawptr, values: rawptr,
size: c.int, size: c.int,
disconnect_flags: ^c.int) -> ErrorCode --- disconnect_flags: ^c.int) -> ErrorCode ---
/* // disconnect_player --
* disconnect_player -- //
* // Disconnects a remote player from a game. Will return ERRORCODE_PLAYER_DISCONNECTED
* Disconnects a remote player from a game. Will return ERRORCODE_PLAYER_DISCONNECTED // if you try to disconnect a player who has already been disconnected.
* if you try to disconnect a player who has already been disconnected.
*/
disconnect_player :: proc(session: ^Session, disconnect_player :: proc(session: ^Session,
player: PlayerHandle) -> ErrorCode --- player: PlayerHandle) -> ErrorCode ---
/* // advance_frame --
* advance_frame -- //
* // You should call advance_frame to notify GGPO.net that you have
* You should call advance_frame to notify GGPO.net that you have // advanced your gamestate by a single frame. You should call this everytime
* advanced your gamestate by a single frame. You should call this everytime // you advance the gamestate by a frame, even during rollbacks. GGPO.net
* you advance the gamestate by a frame, even during rollbacks. GGPO.net // may call your save_state callback before this function returns.
* may call your save_state callback before this function returns.
*/
advance_frame :: proc(session: ^Session) -> ErrorCode --- advance_frame :: proc(session: ^Session) -> ErrorCode ---
/* // get_network_stats --
* get_network_stats -- //
* // Used to fetch some statistics about the quality of the network connection.
* Used to fetch some statistics about the quality of the network connection. //
* // player - The player handle returned from the add_player function you used
* player - The player handle returned from the add_player function you used // to add the remote player.
* to add the remote player. //
* // stats - Out parameter to the network statistics.
* stats - Out parameter to the network statistics.
*/
get_network_stats :: proc(session: ^Session, get_network_stats :: proc(session: ^Session,
player: PlayerHandle, player: PlayerHandle,
stats: ^NetworkStats) -> ErrorCode --- stats: ^NetworkStats) -> ErrorCode ---
/* // set_disconnect_timeout --
* set_disconnect_timeout -- //
* // Sets the disconnect timeout. The session will automatically disconnect
* Sets the disconnect timeout. The session will automatically disconnect // from a remote peer if it has not received a packet in the timeout window.
* from a remote peer if it has not received a packet in the timeout window. // You will be notified of the disconnect via a EVENTCODE_DISCONNECTED_FROM_PEER
* You will be notified of the disconnect via a EVENTCODE_DISCONNECTED_FROM_PEER // event.
* event. //
* // Setting a timeout value of 0 will disable automatic disconnects.
* Setting a timeout value of 0 will disable automatic disconnects. //
* // timeout - The time in milliseconds to wait before disconnecting a peer.
* timeout - The time in milliseconds to wait before disconnecting a peer.
*/
set_disconnect_timeout :: proc(session: ^Session, set_disconnect_timeout :: proc(session: ^Session,
timeout: c.int) -> ErrorCode --- timeout: c.int) -> ErrorCode ---
/* // set_disconnect_notify_start --
* set_disconnect_notify_start -- //
* // The time to wait before the first EVENTCODE_NETWORK_INTERRUPTED timeout
* The time to wait before the first EVENTCODE_NETWORK_INTERRUPTED timeout // will be sent.
* will be sent. //
* // timeout - The amount of time which needs to elapse without receiving a packet
* timeout - The amount of time which needs to elapse without receiving a packet // before the EVENTCODE_NETWORK_INTERRUPTED event is sent.
* before the EVENTCODE_NETWORK_INTERRUPTED event is sent.
*/
set_disconnect_notify_start :: proc(session: ^Session, set_disconnect_notify_start :: proc(session: ^Session,
timeout: c.int) -> ErrorCode --- timeout: c.int) -> ErrorCode ---
/* // log --
* log -- //
* // Used to write to the ggpo.net log. In the current versions of the
* Used to write to the ggpo.net log. In the current versions of the // SDK, a log file is only generated if the "quark.log" environment
* SDK, a log file is only generated if the "quark.log" environment // variable is set to 1. This will change in future versions of the
* variable is set to 1. This will change in future versions of the // SDK.
* SDK.
*/
log :: proc(session: ^Session, fmt: cstring, #c_vararg args: ..any) --- log :: proc(session: ^Session, fmt: cstring, #c_vararg args: ..any) ---
/*
* logv -- // logv --
* //
* A varargs compatible version of log. See log for // A varargs compatible version of log. See log for
* more details. // more details.
*/
logv :: proc(session: ^Session, fmt: cstring, args: c.va_list) --- logv :: proc(session: ^Session, fmt: cstring, args: c.va_list) ---
} }