/*
 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
 *
 * (c) Copyright 1996, 1997, 1998 Gary Henderson (gary@daniver.demon.co.uk) and
 *                                Jerremy Koot (jkoot@snes9x.com)
 *
 * Super FX C emulator code 
 * (c) Copyright 1997, 1998 Ivar (Ivar@snes9x.com) and
 *                          Gary Henderson.
 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
 *
 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
 * DOS port code contains the works of other authors. See headers in
 * individual files.
 *
 * Snes9x homepage: www.snes9x.com
 *
 * Permission to use, copy, modify and distribute Snes9x in both binary and
 * source form, for non-commercial purposes, is hereby granted without fee,
 * providing that this license information and copyright notice appear with
 * all copies and any derived work.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event shall the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Snes9x is freeware for PERSONAL USE only. Commercial users should
 * seek permission of the copyright holders first. Commercial use includes
 * charging money for Snes9x or software derived from Snes9x.
 *
 * The copyright holders request that bug fixes and improvements to the code
 * should be forwarded to them so everyone can benefit from the modifications
 * in future versions.
 *
 * Super NES and Super Nintendo Entertainment System are trademarks of
 * Nintendo Co., Limited and its subsidiary companies.
 */

#ifndef _NETPLAY_H_
#define _NETPLAY_H_

/* Server to client header format:
 *
 * magic	4
 * version	1
 * opcode	1
 * len		4
 * sequence_no	4
 * joypads	4 * 5
 * additional data...
 */

 /* Client to server packet format:
  * magic	4
  * version	1
  * opcode	1
  * len		4
  * data	?
  */
  
typedef struct {
    char   magic [4];
    uint8  version;
    uint8  opcode;
    uint32 len;
    uint32 sequence_no;
} SCNetPlay;

#define NETPLAY_SERVER_VERSION_OFFSET 4
#define NETPLAY_SERVER_OPCODE_OFFSET 5
#define NETPLAY_SERVER_LEN_OFFSET 6
#define NETPLAY_SERVER_SEQUENCE_NO_OFFSET 10
#define NETPLAY_SERVER_JOYPAD_OFFSET 14
#define NETPLAY_SERVER_TO_CLIENT_HEADER_SIZE (4 + 1 + 1 + 4 + 4)

typedef struct {
    char   magic [4];
    uint8  version;
    uint8  opcode;
    uint32 len;
    uint32 sequence_no;
} CSNetPlay;

#define NETPLAY_MAGIC "S9X"
#define NETPLAY_VERSION 1
#define NETPLAY_CLIENT_TO_SERVER_HEADER_SIZE (4 + 1 + 1 + 4)
#define NETPLAY_CLIENT_VERSION_OFFSET 4
#define NETPLAY_CLIENT_OPCODE_OFFSET 5
#define NETPLAY_CLIENT_LEN_OFFSET 6
#define NETPLAY_CLIENT_SEQUENCE_NO_OFFSET 10

#define NETPLAY_DEFAULT_PORT 6096

/* Server to client */
enum {
    NETPLAY_SERVER_HELLO,
    NETPLAY_SERVER_JOYPAD_UPDATE,
    NETPLAY_SERVER_RESET,
    NETPLAY_SERVER_PAUSE,
    NETPLAY_SERVER_ROM_NAME
};

/* Client to server */
enum {
    NETPLAY_CLIENT_HELLO,
    NETPLAY_CLIENT_JOYPAD_UPDATE,
    NETPLAY_CLIENT_GOODBYE
};

//
// NETPLAY_CLIENT_HELLO message format:
// header
// frame_time (4)
// ROMName (variable)

#define WRITE_LONG(p, v) { \
*((p) + 0) = (uint8) (v >> 24); \
*((p) + 1) = (uint8) (v >> 16); \
*((p) + 2) = (uint8) (v >> 8); \
*((p) + 3) = (uint8) (v >> 0); \
}

#define READ_LONG(p, v) \
v = ((uint8) *((p) + 0) << 24) | \
    ((uint8) *((p) + 1) << 16) | \
    ((uint8) *((p) + 2) <<  8) | \
    ((uint8) *((p) + 3) <<  0)

bool8 S9xNetPlayConnectToServer (const char *server_name, int port,
				 const char *rom_name, int &player_number_return);
bool8 S9xNetPlayCheckForHeartBeat ();
uint32 S9xNetPlayGetJoypad (int which1);
bool8 S9xNetPlaySendJoypadUpdate (uint32 joypad);
void S9xNetPlayDisconnect ();

bool8 S9xNetPlaySend (void *fd, const char *data, int len);
char *S9xNetPlayReceivePacket (void *fd, int &len);
#endif
