mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2024-11-10 21:55:11 +01:00
Merged the display encoding
This commit is contained in:
parent
5eca531105
commit
bdcad56361
@ -1,4 +1,7 @@
|
||||
version 7:
|
||||
TODO: Would it be possible for you to implement the
|
||||
binding of Joystick directions to buttons?
|
||||
|
||||
TODO: Multiple frodo versions, switch between
|
||||
|
||||
TODO: D-pad less responsive in v6 than v5
|
||||
|
135
Src/Network.cpp
135
Src/Network.cpp
@ -31,7 +31,10 @@
|
||||
#define SQUARE_TO_X(square) ( ((square) % N_SQUARES_W) * SQUARE_W )
|
||||
#define SQUARE_TO_Y(square) ( ((square) / N_SQUARES_W) * SQUARE_H )
|
||||
|
||||
/* Worst cases for RLE and DIFF */
|
||||
#define RAW_SIZE ( (SQUARE_W * SQUARE_H) / 2 )
|
||||
#define RLE_SIZE ( RAW_SIZE * 4 + 8)
|
||||
#define DIFF_SIZE ( RAW_SIZE * 4 + 8)
|
||||
|
||||
Network::Network()
|
||||
{
|
||||
@ -45,6 +48,11 @@ Network::Network()
|
||||
this->ResetNetworkUpdate();
|
||||
this->bytes_sent = 0;
|
||||
|
||||
this->raw_buf = (Uint8*)malloc(RAW_SIZE);
|
||||
this->rle_buf = (Uint8*)malloc(RLE_SIZE);
|
||||
this->diff_buf = (Uint8*)malloc(DIFF_SIZE);
|
||||
assert(this->raw_buf && this->rle_buf && this->diff_buf);
|
||||
|
||||
this->square_updated = (Uint32*)malloc( N_SQUARES_W * N_SQUARES_H * sizeof(Uint32));
|
||||
assert(this->square_updated);
|
||||
memset(this->square_updated, 0, N_SQUARES_W * N_SQUARES_H * sizeof(Uint32));
|
||||
@ -54,6 +62,10 @@ Network::~Network()
|
||||
{
|
||||
free(this->ud);
|
||||
free(this->tmp_ud);
|
||||
free(this->square_updated);
|
||||
free(this->raw_buf);
|
||||
free(this->rle_buf);
|
||||
free(this->diff_buf);
|
||||
}
|
||||
|
||||
size_t Network::EncodeDisplayRaw(struct NetworkUpdate *dst, Uint8 *screen,
|
||||
@ -269,40 +281,6 @@ bool Network::DecodeDisplayRaw(Uint8 *screen, struct NetworkUpdate *src,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Public methods */
|
||||
size_t Network::EncodeDisplaySquare(struct NetworkUpdate *dst,
|
||||
Uint8 *screen, Uint8 *remote, int square)
|
||||
{
|
||||
const int square_x = SQUARE_TO_X(square);
|
||||
const int square_y = SQUARE_TO_Y(square);
|
||||
size_t out, diff_out;
|
||||
|
||||
dst->u.display.square = square;
|
||||
|
||||
/* Try encoding as RLE and diff, but if it's too large, go for RAW */
|
||||
diff_out = this->EncodeDisplayDiff(tmp_ud, screen,
|
||||
remote, square_x, square_y);
|
||||
this->square_updated[square] = out | (2 << 16);
|
||||
out = this->EncodeDisplayRLE(dst, screen, square_x, square_y);
|
||||
this->square_updated[square] = out | (1 << 16);
|
||||
|
||||
if (out > diff_out) {
|
||||
/* The diff is best, use that */
|
||||
this->square_updated[square] = out | (2 << 16);
|
||||
memcpy(dst->data, this->tmp_ud->data, out);
|
||||
dst->type = this->tmp_ud->type;
|
||||
out = diff_out;
|
||||
}
|
||||
if (out > RAW_SIZE) {
|
||||
out = this->EncodeDisplayRaw(dst, screen, square_x, square_y);
|
||||
this->square_updated[square] = out;
|
||||
}
|
||||
|
||||
dst->size = out + sizeof(struct NetworkUpdate);
|
||||
|
||||
return dst->size;
|
||||
}
|
||||
|
||||
bool Network::CompareSquare(Uint8 *a, Uint8 *b)
|
||||
{
|
||||
for (int y = 0; y < SQUARE_H; y++)
|
||||
@ -342,6 +320,91 @@ size_t Network::EncodeDisplay(Uint8 *master, Uint8 *remote)
|
||||
}
|
||||
|
||||
|
||||
size_t Network::EncodeDisplaySquare(struct NetworkUpdate *dst,
|
||||
Uint8 *screen, Uint8 *remote, int square)
|
||||
{
|
||||
const int x_start = SQUARE_TO_X(square);
|
||||
const int y_start = SQUARE_TO_Y(square);
|
||||
Uint8 rle_color = screen[ y_start * DISPLAY_X + x_start ];
|
||||
int rle_len = 0, diff_len = 0;
|
||||
size_t rle_sz = 0, diff_sz = 0;
|
||||
const int raw_w = SQUARE_W / 2;
|
||||
int type = DISPLAY_UPDATE_RAW;
|
||||
size_t out;
|
||||
|
||||
for (int y = y_start; y < y_start + SQUARE_H; y++)
|
||||
{
|
||||
memset( &this->raw_buf[(y - y_start) * raw_w], 0, raw_w );
|
||||
|
||||
for (int x = x_start; x < x_start + SQUARE_W; x++)
|
||||
{
|
||||
Uint8 col_s = screen[ y * DISPLAY_X + x ];
|
||||
Uint8 col_r = remote[ y * DISPLAY_X + x ];
|
||||
bool is_odd = (x & 1) == 1;
|
||||
int raw_shift = (is_odd ? 0 : 4);
|
||||
|
||||
/* Every second is shifted */
|
||||
this->raw_buf[ (y - y_start) * raw_w + (x - x_start) / 2 ] |=
|
||||
(col_s << raw_shift);
|
||||
|
||||
if (rle_color != col_s ||
|
||||
rle_len >= 255)
|
||||
{
|
||||
this->rle_buf[rle_sz] = rle_len;
|
||||
this->rle_buf[rle_sz + 1] = rle_color;
|
||||
rle_sz += 2;
|
||||
|
||||
rle_len = 0;
|
||||
rle_color = col_s;
|
||||
}
|
||||
|
||||
if (col_r != col_s || diff_len >= 255)
|
||||
{
|
||||
this->diff_buf[diff_sz] = diff_len;
|
||||
this->diff_buf[diff_sz + 1] = col_s;
|
||||
diff_sz += 2;
|
||||
diff_len = 0;
|
||||
}
|
||||
|
||||
diff_len++;
|
||||
rle_len++;
|
||||
}
|
||||
}
|
||||
|
||||
/* The last section for RLE */
|
||||
if (rle_len != 0)
|
||||
{
|
||||
this->rle_buf[rle_sz] = rle_len;
|
||||
this->rle_buf[rle_sz + 1] = rle_color;
|
||||
|
||||
rle_sz += 2;
|
||||
}
|
||||
|
||||
out = RAW_SIZE;
|
||||
if (diff_sz < rle_sz && diff_sz < RAW_SIZE)
|
||||
{
|
||||
memcpy(dst->data, this->diff_buf, diff_sz);
|
||||
type = DISPLAY_UPDATE_DIFF;
|
||||
out = diff_sz;
|
||||
}
|
||||
else if (rle_sz < RAW_SIZE)
|
||||
{
|
||||
memcpy(dst->data, this->rle_buf, rle_sz);
|
||||
type = DISPLAY_UPDATE_RLE;
|
||||
out = rle_sz;
|
||||
}
|
||||
else
|
||||
memcpy(dst->data, this->raw_buf, RAW_SIZE);
|
||||
|
||||
/* Setup the structure */
|
||||
dst->type = type;
|
||||
dst->u.display.square = square;
|
||||
dst->size = out + sizeof(struct NetworkUpdate);
|
||||
this->square_updated[square] = out | (type << 16);
|
||||
|
||||
return dst->size;
|
||||
}
|
||||
|
||||
bool Network::DecodeDisplayUpdate(Uint8 *screen,
|
||||
struct NetworkUpdate *src)
|
||||
{
|
||||
@ -428,9 +491,9 @@ void Network::DrawTransferredBlocks(SDL_Surface *screen)
|
||||
SDL_Rect size = {x, y, 2 * ((raw & 0xffff) / 17), 4};
|
||||
Uint32 color = 4;
|
||||
|
||||
if ((raw >> 16) == 1)
|
||||
if ((raw >> 16) == DISPLAY_UPDATE_RLE)
|
||||
color = 5;
|
||||
else if ((raw >> 16) == 2)
|
||||
else if ((raw >> 16) == DISPLAY_UPDATE_DIFF)
|
||||
color = 6;
|
||||
|
||||
SDL_FillRect(screen, &l, 19);
|
||||
|
@ -71,17 +71,6 @@ public:
|
||||
protected:
|
||||
size_t DecodeSoundUpdate(struct NetworkUpdate *src, char *buf);
|
||||
|
||||
/** Encode part of a screen into @a dst
|
||||
*
|
||||
* @param dst the destination update structure
|
||||
* @param screen the screen to encode
|
||||
* @param square the square index of the screen to encode
|
||||
*
|
||||
* @return the size of the encoded message
|
||||
*/
|
||||
size_t EncodeDisplaySquare(struct NetworkUpdate *dst,
|
||||
Uint8 *screen, Uint8 *remote, int square);
|
||||
|
||||
size_t EncodeDisplayDiff(struct NetworkUpdate *dst, Uint8 *screen,
|
||||
int x, int y);
|
||||
|
||||
@ -96,6 +85,18 @@ protected:
|
||||
size_t EncodeSoundRaw(struct NetworkUpdate *dst,
|
||||
Uint8 *buffer, size_t len);
|
||||
|
||||
/** Encode part of a screen into @a dst in a single sweep
|
||||
*
|
||||
* @param dst the destination update structure
|
||||
* @param screen the screen to encode
|
||||
* @param remote the current remote screen
|
||||
* @param square the square index of the screen to encode
|
||||
*
|
||||
* @return the size of the encoded message
|
||||
*/
|
||||
size_t EncodeDisplaySquare(struct NetworkUpdate *dst,
|
||||
Uint8 *screen, Uint8 *remote, int square);
|
||||
|
||||
/**
|
||||
* Encode the @a buf sound buffer into @a dst
|
||||
*
|
||||
@ -165,6 +166,9 @@ protected:
|
||||
NetworkUpdate *ud;
|
||||
NetworkUpdate *tmp_ud;
|
||||
NetworkUpdate *cur_ud;
|
||||
Uint8 *raw_buf;
|
||||
Uint8 *rle_buf;
|
||||
Uint8 *diff_buf;
|
||||
size_t bytes_sent;
|
||||
Uint32 *square_updated;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user