mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2024-11-10 21:55:11 +01:00
Implemented sound transfer over the network (for Linux). This hasn't
been even the least tested yet, so don't try this code. You have been warned!
This commit is contained in:
parent
189833e30f
commit
42a6e19e0d
@ -608,7 +608,8 @@ void C64::network_vblank()
|
|||||||
/* Has the peer sent any data? */
|
/* Has the peer sent any data? */
|
||||||
if (remote->ReceiveUpdate() == true)
|
if (remote->ReceiveUpdate() == true)
|
||||||
{
|
{
|
||||||
if (remote->DecodeUpdate(remote->GetScreen(), js) == false)
|
if (remote->DecodeUpdate(remote->GetScreen(),
|
||||||
|
js, this->TheSID) == false)
|
||||||
{
|
{
|
||||||
/* Disconnect or sending crap, remove this guy! */
|
/* Disconnect or sending crap, remove this guy! */
|
||||||
delete remote;
|
delete remote;
|
||||||
@ -621,16 +622,16 @@ void C64::network_vblank()
|
|||||||
remote->ResetNetworkUpdate();
|
remote->ResetNetworkUpdate();
|
||||||
|
|
||||||
if (this->network_connection_type == MASTER &&
|
if (this->network_connection_type == MASTER &&
|
||||||
remote->ThrottleTraffic()) {
|
!remote->ThrottleTraffic()) {
|
||||||
/* Skip this frame if the data rate is too high */
|
/* Skip this frame if the data rate is too high */
|
||||||
has_throttled = true;
|
has_throttled = true;
|
||||||
return;
|
remote->EncodeDisplay(master, remote->GetScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perhaps send updates to the other side (what is determined by
|
/* Perhaps send updates to the other side (what is determined by
|
||||||
* if this is the master or not) */
|
* if this is the master or not) */
|
||||||
remote->EncodeJoystickUpdate(*js);
|
remote->EncodeJoystickUpdate(*js);
|
||||||
remote->EncodeDisplay(master, remote->GetScreen());
|
remote->EncodeSound();
|
||||||
|
|
||||||
if (remote->SendUpdate() == false)
|
if (remote->SendUpdate() == false)
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ Network::Network(const char *remote_host, int port, bool is_master)
|
|||||||
|
|
||||||
this->InitNetwork();
|
this->InitNetwork();
|
||||||
|
|
||||||
this->is_master = is_master;
|
Network::is_master = is_master;
|
||||||
this->connected = false;
|
this->connected = false;
|
||||||
|
|
||||||
/* "big enough" buffer */
|
/* "big enough" buffer */
|
||||||
@ -262,7 +262,7 @@ bool Network::CompareSquare(Uint8 *a, Uint8 *b)
|
|||||||
|
|
||||||
void Network::EncodeDisplay(Uint8 *master, Uint8 *remote)
|
void Network::EncodeDisplay(Uint8 *master, Uint8 *remote)
|
||||||
{
|
{
|
||||||
if (!this->is_master)
|
if (!Network::is_master)
|
||||||
return;
|
return;
|
||||||
for ( int sq = 0; sq < N_SQUARES_H * N_SQUARES_W; sq++ )
|
for ( int sq = 0; sq < N_SQUARES_H * N_SQUARES_W; sq++ )
|
||||||
{
|
{
|
||||||
@ -408,8 +408,8 @@ size_t Network::EncodeSoundBuffer(struct NetworkUpdate *dst, Uint8 *buf, size_t
|
|||||||
printf("Not implemented\n");
|
printf("Not implemented\n");
|
||||||
dst->size = 0;
|
dst->size = 0;
|
||||||
/* Try encoding as RLE, but if it's too large, go for RAW */
|
/* Try encoding as RLE, but if it's too large, go for RAW */
|
||||||
out = this->EncodeSoundRLE(dst, buf, len);
|
// out = this->EncodeSoundRLE(dst, buf, len);
|
||||||
if (out > len)
|
// if (out > len)
|
||||||
out = this->EncodeSoundRaw(dst, buf, len);
|
out = this->EncodeSoundRaw(dst, buf, len);
|
||||||
dst->size = out + sizeof(struct NetworkUpdate);
|
dst->size = out + sizeof(struct NetworkUpdate);
|
||||||
|
|
||||||
@ -418,14 +418,29 @@ size_t Network::EncodeSoundBuffer(struct NetworkUpdate *dst, Uint8 *buf, size_t
|
|||||||
|
|
||||||
void Network::EncodeSound()
|
void Network::EncodeSound()
|
||||||
{
|
{
|
||||||
|
NetworkUpdate *dst = (NetworkUpdate *)this->cur_ud;
|
||||||
|
static Uint8 tmp_buf[NETWORK_SOUND_BUF_SIZE];
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
/* Nothing to encode? */
|
/* Nothing to encode? */
|
||||||
if (!this->is_master ||
|
if (!Network::is_master ||
|
||||||
Network::sample_head == Network::sample_tail)
|
Network::sample_head == Network::sample_tail)
|
||||||
return;
|
return;
|
||||||
while (Network::sample_tail != Network::sample_head)
|
|
||||||
|
if (Network::sample_tail > Network::sample_head)
|
||||||
{
|
{
|
||||||
Network::sample_tail = (Network::sample_tail + 1) % NETWORK_SOUND_BUF_SIZE;
|
memcpy(tmp_buf + offset, Network::sample_buf + Network::sample_tail,
|
||||||
|
NETWORK_SOUND_BUF_SIZE - Network::sample_tail);
|
||||||
|
offset += NETWORK_SOUND_BUF_SIZE - Network::sample_tail;
|
||||||
|
Network::sample_tail = 0;
|
||||||
}
|
}
|
||||||
|
memcpy(tmp_buf + offset, Network::sample_buf + Network::sample_tail,
|
||||||
|
Network::sample_head - Network::sample_tail);
|
||||||
|
offset += Network::sample_head - Network::sample_tail;
|
||||||
|
Network::sample_tail = Network::sample_head;
|
||||||
|
|
||||||
|
this->EncodeSoundBuffer(dst, tmp_buf, offset);
|
||||||
|
this->AddNetworkUpdate(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::PushSound(uint8 vol)
|
void Network::PushSound(uint8 vol)
|
||||||
@ -439,7 +454,7 @@ void Network::EncodeJoystickUpdate(Uint8 v)
|
|||||||
struct NetworkUpdate *dst = this->cur_ud;
|
struct NetworkUpdate *dst = this->cur_ud;
|
||||||
struct NetworkUpdateJoystick *j = (NetworkUpdateJoystick *)dst->data;
|
struct NetworkUpdateJoystick *j = (NetworkUpdateJoystick *)dst->data;
|
||||||
|
|
||||||
if (this->is_master || this->cur_joystick_data == v)
|
if (Network::is_master || this->cur_joystick_data == v)
|
||||||
return;
|
return;
|
||||||
dst = InitNetworkUpdate(dst, JOYSTICK_UPDATE,
|
dst = InitNetworkUpdate(dst, JOYSTICK_UPDATE,
|
||||||
sizeof(NetworkUpdate) + sizeof(NetworkUpdateJoystick));
|
sizeof(NetworkUpdate) + sizeof(NetworkUpdateJoystick));
|
||||||
@ -450,14 +465,15 @@ void Network::EncodeJoystickUpdate(Uint8 v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t Network::DecodeSoundUpdate(struct NetworkUpdate *src, char *buf)
|
size_t Network::DecodeSoundUpdate(struct NetworkUpdate *src, MOS6581 *dst)
|
||||||
{
|
{
|
||||||
size_t out;
|
size_t out;
|
||||||
|
|
||||||
if (src->type == SOUND_UPDATE_RAW)
|
if (src->type == SOUND_UPDATE_RAW)
|
||||||
{
|
{
|
||||||
out = src->size - sizeof(struct NetworkUpdate);
|
out = src->size - sizeof(struct NetworkUpdate);
|
||||||
memcpy(buf, src->data, out);
|
for (int i = 0; i < out; i++)
|
||||||
|
dst->PushVolume(src->data[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
out = 0;
|
out = 0;
|
||||||
@ -790,7 +806,7 @@ bool Network::DeMarshalAllData(NetworkUpdate *ud, size_t max_size,
|
|||||||
return this->DeMarshalData(p);
|
return this->DeMarshalData(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::DecodeUpdate(uint8 *screen, uint8 *js)
|
bool Network::DecodeUpdate(uint8 *screen, uint8 *js, MOS6581 *dst)
|
||||||
{
|
{
|
||||||
NetworkUpdate *p = this->ud;
|
NetworkUpdate *p = this->ud;
|
||||||
bool out = true;
|
bool out = true;
|
||||||
@ -803,14 +819,14 @@ bool Network::DecodeUpdate(uint8 *screen, uint8 *js)
|
|||||||
case DISPLAY_UPDATE_RLE:
|
case DISPLAY_UPDATE_RLE:
|
||||||
case DISPLAY_UPDATE_DIFF:
|
case DISPLAY_UPDATE_DIFF:
|
||||||
/* No screen updates _to_ the master */
|
/* No screen updates _to_ the master */
|
||||||
if (this->is_master)
|
if (Network::is_master)
|
||||||
break;
|
break;
|
||||||
if (this->DecodeDisplayUpdate(screen, p) == false)
|
if (this->DecodeDisplayUpdate(screen, p) == false)
|
||||||
out = false;
|
out = false;
|
||||||
break;
|
break;
|
||||||
case JOYSTICK_UPDATE:
|
case JOYSTICK_UPDATE:
|
||||||
/* No joystick updates _from_ the master */
|
/* No joystick updates _from_ the master */
|
||||||
if (js && this->is_master)
|
if (js && Network::is_master)
|
||||||
{
|
{
|
||||||
NetworkUpdateJoystick *j = (NetworkUpdateJoystick *)p->data;
|
NetworkUpdateJoystick *j = (NetworkUpdateJoystick *)p->data;
|
||||||
*js = j->val;
|
*js = j->val;
|
||||||
@ -842,7 +858,7 @@ bool Network::ConnectToBroker()
|
|||||||
NetworkUpdatePeerInfo *pi = (NetworkUpdatePeerInfo *)ud->data;
|
NetworkUpdatePeerInfo *pi = (NetworkUpdatePeerInfo *)ud->data;
|
||||||
bool out;
|
bool out;
|
||||||
|
|
||||||
pi->is_master = this->is_master;
|
pi->is_master = Network::is_master;
|
||||||
pi->key = ThePrefs.NetworkKey;
|
pi->key = ThePrefs.NetworkKey;
|
||||||
pi->version = FRODO_NETWORK_PROTOCOL_VERSION;
|
pi->version = FRODO_NETWORK_PROTOCOL_VERSION;
|
||||||
strcpy((char*)pi->name, ThePrefs.NetworkName);
|
strcpy((char*)pi->name, ThePrefs.NetworkName);
|
||||||
@ -1062,7 +1078,7 @@ network_connection_error_t Network::ConnectFSM()
|
|||||||
case CONN_CONNECT_TO_BROKER:
|
case CONN_CONNECT_TO_BROKER:
|
||||||
if (this->ConnectToBroker() == true)
|
if (this->ConnectToBroker() == true)
|
||||||
{
|
{
|
||||||
if (this->is_master)
|
if (Network::is_master)
|
||||||
this->network_connection_state = CONN_WAIT_FOR_PEER_ADDRESS;
|
this->network_connection_state = CONN_WAIT_FOR_PEER_ADDRESS;
|
||||||
else
|
else
|
||||||
this->network_connection_state = CONN_WAIT_FOR_PEER_LIST;
|
this->network_connection_state = CONN_WAIT_FOR_PEER_LIST;
|
||||||
@ -1117,7 +1133,7 @@ bool Network::Connect()
|
|||||||
0x00, 0x80, 0x80));
|
0x00, 0x80, 0x80));
|
||||||
menu_print_font(real_screen, 255,255,0, 30, 30,
|
menu_print_font(real_screen, 255,255,0, 30, 30,
|
||||||
"Connecting... Hold Esc or 1 to abort");
|
"Connecting... Hold Esc or 1 to abort");
|
||||||
if (this->is_master)
|
if (Network::is_master)
|
||||||
menu_print_font(real_screen, 255,255,0, 30, 50,
|
menu_print_font(real_screen, 255,255,0, 30, 50,
|
||||||
"(Waiting for client connection)");
|
"(Waiting for client connection)");
|
||||||
SDL_Flip(real_screen);
|
SDL_Flip(real_screen);
|
||||||
@ -1186,6 +1202,7 @@ void Network::Disconnect()
|
|||||||
uint8 Network::sample_buf[NETWORK_SOUND_BUF_SIZE];
|
uint8 Network::sample_buf[NETWORK_SOUND_BUF_SIZE];
|
||||||
int Network::sample_head;
|
int Network::sample_head;
|
||||||
int Network::sample_tail;
|
int Network::sample_tail;
|
||||||
|
bool Network::is_master = true; /* Assume until set false */
|
||||||
|
|
||||||
#if defined(GEKKO)
|
#if defined(GEKKO)
|
||||||
#include "NetworkWii.h"
|
#include "NetworkWii.h"
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "SID.h"
|
||||||
|
|
||||||
#define FRODO_NETWORK_PROTOCOL_VERSION 2
|
#define FRODO_NETWORK_PROTOCOL_VERSION 2
|
||||||
|
|
||||||
#define FRODO_NETWORK_MAGIC 0x1976
|
#define FRODO_NETWORK_MAGIC 0x1976
|
||||||
@ -150,7 +152,7 @@ public:
|
|||||||
void EncodeJoystickUpdate(Uint8 v);
|
void EncodeJoystickUpdate(Uint8 v);
|
||||||
|
|
||||||
|
|
||||||
bool DecodeUpdate(uint8 *screen, uint8 *js);
|
bool DecodeUpdate(uint8 *screen, uint8 *js, MOS6581 *dst);
|
||||||
|
|
||||||
void ResetNetworkUpdate(void);
|
void ResetNetworkUpdate(void);
|
||||||
|
|
||||||
@ -199,12 +201,13 @@ public:
|
|||||||
|
|
||||||
static void PushSound(uint8 vol);
|
static void PushSound(uint8 vol);
|
||||||
|
|
||||||
|
static bool is_master; /* Some peers are more equal than others */
|
||||||
protected:
|
protected:
|
||||||
void InitNetwork();
|
void InitNetwork();
|
||||||
|
|
||||||
void ShutdownNetwork();
|
void ShutdownNetwork();
|
||||||
|
|
||||||
size_t DecodeSoundUpdate(struct NetworkUpdate *src, char *buf);
|
size_t DecodeSoundUpdate(struct NetworkUpdate *src, MOS6581 *dst);
|
||||||
|
|
||||||
size_t EncodeSoundRLE(struct NetworkUpdate *dst,
|
size_t EncodeSoundRLE(struct NetworkUpdate *dst,
|
||||||
Uint8 *buffer, size_t len);
|
Uint8 *buffer, size_t len);
|
||||||
@ -339,7 +342,6 @@ protected:
|
|||||||
|
|
||||||
Uint8 *screen;
|
Uint8 *screen;
|
||||||
int joystick_port;
|
int joystick_port;
|
||||||
bool is_master; /* Some peers are more equal than others */
|
|
||||||
bool connected;
|
bool connected;
|
||||||
Uint8 cur_joystick_data;
|
Uint8 cur_joystick_data;
|
||||||
|
|
||||||
|
@ -363,6 +363,7 @@ public:
|
|||||||
virtual ~DigitalRenderer();
|
virtual ~DigitalRenderer();
|
||||||
|
|
||||||
virtual void Reset(void);
|
virtual void Reset(void);
|
||||||
|
virtual void PushVolume(uint8 volume);
|
||||||
virtual void EmulateLine(void);
|
virtual void EmulateLine(void);
|
||||||
virtual void WriteRegister(uint16 adr, uint8 byte);
|
virtual void WriteRegister(uint16 adr, uint8 byte);
|
||||||
virtual void NewPrefs(Prefs *prefs);
|
virtual void NewPrefs(Prefs *prefs);
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
void GetState(MOS6581State *ss);
|
void GetState(MOS6581State *ss);
|
||||||
void SetState(MOS6581State *ss);
|
void SetState(MOS6581State *ss);
|
||||||
void EmulateLine(void);
|
void EmulateLine(void);
|
||||||
|
void PushVolume(uint8); /* For the network */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void open_close_renderer(int old_type, int new_type);
|
void open_close_renderer(int old_type, int new_type);
|
||||||
@ -66,6 +67,7 @@ public:
|
|||||||
virtual ~SIDRenderer() {}
|
virtual ~SIDRenderer() {}
|
||||||
virtual void Reset(void)=0;
|
virtual void Reset(void)=0;
|
||||||
virtual void EmulateLine(void)=0;
|
virtual void EmulateLine(void)=0;
|
||||||
|
virtual void PushVolume(uint8)=0;
|
||||||
virtual void WriteRegister(uint16 adr, uint8 byte)=0;
|
virtual void WriteRegister(uint16 adr, uint8 byte)=0;
|
||||||
virtual void NewPrefs(Prefs *prefs)=0;
|
virtual void NewPrefs(Prefs *prefs)=0;
|
||||||
virtual void Pause(void)=0;
|
virtual void Pause(void)=0;
|
||||||
@ -122,6 +124,12 @@ inline void MOS6581::EmulateLine(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void MOS6581::PushVolume(uint8 vol)
|
||||||
|
{
|
||||||
|
if (the_renderer != NULL)
|
||||||
|
the_renderer->PushVolume(vol);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read from register
|
* Read from register
|
||||||
*/
|
*/
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#define HAVE_CWSID 1
|
#define HAVE_CWSID 1
|
||||||
|
|
||||||
#include "VIC.h"
|
#include "VIC.h"
|
||||||
|
#include "Network.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization
|
* Initialization
|
||||||
@ -115,16 +115,13 @@ void DigitalRenderer::Resume(void)
|
|||||||
* Fill buffer, sample volume (for sampled voice)
|
* Fill buffer, sample volume (for sampled voice)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void DigitalRenderer::EmulateLine(void)
|
void DigitalRenderer::PushVolume(uint8 vol)
|
||||||
{
|
{
|
||||||
static int divisor = 0;
|
static int divisor = 0;
|
||||||
static int to_output = 0;
|
static int to_output = 0;
|
||||||
static int buffer_pos = 0;
|
static int buffer_pos = 0;
|
||||||
|
|
||||||
if (!ready)
|
sample_buf[sample_in_ptr] = vol;
|
||||||
return;
|
|
||||||
|
|
||||||
sample_buf[sample_in_ptr] = volume;
|
|
||||||
sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
|
sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
|
||||||
|
|
||||||
// Now see how many samples have to be added for this line
|
// Now see how many samples have to be added for this line
|
||||||
@ -143,6 +140,15 @@ void DigitalRenderer::EmulateLine(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DigitalRenderer::EmulateLine(void)
|
||||||
|
{
|
||||||
|
if (!ready)
|
||||||
|
return;
|
||||||
|
Network::PushSound(volume);
|
||||||
|
if (Network::is_master)
|
||||||
|
this->PushVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Renderer for Catweasel card
|
* Renderer for Catweasel card
|
||||||
@ -156,6 +162,7 @@ public:
|
|||||||
|
|
||||||
virtual void Reset(void);
|
virtual void Reset(void);
|
||||||
virtual void EmulateLine(void) {}
|
virtual void EmulateLine(void) {}
|
||||||
|
virtual void PushVolume(uint8) {}
|
||||||
virtual void WriteRegister(uint16 adr, uint8 byte);
|
virtual void WriteRegister(uint16 adr, uint8 byte);
|
||||||
virtual void NewPrefs(Prefs *prefs) {}
|
virtual void NewPrefs(Prefs *prefs) {}
|
||||||
virtual void Pause(void) {}
|
virtual void Pause(void) {}
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
* SID_linux.i - 6581 emulation, Linux specific stuff
|
* SID_linux.i - 6581 emulation, Linux specific stuff
|
||||||
*
|
*
|
||||||
* Frodo (C) 1994-1997,2002 Christian Bauer
|
* Frodo (C) 1994-1997,2002 Christian Bauer
|
||||||
* Linux sound stuff by Bernd Schmidt
|
* Wii sound stuff by Simon Kagstrom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gcaudio.h"
|
#include "gcaudio.h"
|
||||||
|
|
||||||
#include "VIC.h"
|
#include "VIC.h"
|
||||||
|
#include "Network.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization
|
* Initialization
|
||||||
@ -69,6 +70,7 @@ void DigitalRenderer::EmulateLine(void)
|
|||||||
if (!ready)
|
if (!ready)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Network::PushSound(volume);
|
||||||
sample_buf[sample_in_ptr] = volume;
|
sample_buf[sample_in_ptr] = volume;
|
||||||
sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
|
sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user