[Open thread]Multiplayer discussion

There is no networking code as a class yet. I’m simply routing signals at this point.

The client-server NAT problem was the biggest problem to tackle.

I am now making the client (Win/Mac/Linux) that handles the comms between Pokitto and the server.

Eventually you will be able to roll and run your own server, the client is just a means of converting serial to ethernet.

If you want (and would be much appreciated) you could already make a network class that pretends it is sending and receiving data, with a dummy send and poll methods. We can then hook those up to the client.

Edit: actually lets be a bit more specific

The network connection code needs the following methods:

  • connect (to the server)
  • disconnect
  • isConnected ?
  • write data
  • check for data (poll)
  • read data to a buffer

… and that’s pretty much it.

1 Like

How does this work physically?
The pokitto needs to be connected to a computer via a usb cable?

  • You load your pokitto with the game/app binary that has USBSerial built in
  • You start Pokitto Internet client on your PC
  • connect pokitto with usb cable, the client notices it as new port
  • press button to connect to game server

= traffic (button presses etc) get routed from Pokitto to game server and vice versa

2 Likes

The next step would then be to get rid of the cable and use a hat? :slight_smile:

1 Like

Yes. That is the whole idea. My objective is to make it so that each layer is independent. If you want to connect via hat, OK, cable, OK etc.

EDIT: I hope to be able to demo something soon

3 Likes

Ah, I forgot this was a serial-pc-server-pc-serial setup,
I was thinking you had a wifi hat.

In that case I could get serial working and try it myself using a serial-pc-serial setup.

When you pushed the serial driver did you update both PokittoLib and PokittoIO?
(If not I might have to dig out EmBitz.)

Testing serial was on my todo list, but it slipped down the list.

Easy enough to do.

I’d normally favour a RAII approach to this, but since exceptions are disabled I’d probably need a slightly different approach.

Basic version:

(Edit: add missing consts, demonstrate template implementations.)

class NetworkStream
{
public:
	bool isConnected() const;
	
	std::size_t getBytesAvailableForRead() const;
	
	template<std::size_t bufferSize>
	std::size_t read(char buffer[bufferSize], std::size_t count = bufferSize)
	{
		return this->read(&buffer[0], bufferSize, count);
	}
	
	// C++11
	template<std::size_t bufferSize>
	std::size_t read(std::array<char, bufferSize> buffer, std::size_t count = bufferSize)
	{
		return this->read(buffer.data(), bufferSize, count);
	}

	std::size_t read(char * buffer, std::size_t bufferSize, std::size_t count);
	
	template<std::size_t bufferSize>
	std::size_t write(const char buffer[bufferSize], std::size_t count)
	{
		return this->write(&buffer[0], bufferSize, count);
	}
	
	// C++11
	template<std::size_t bufferSize>
	std::size_t write(const std::array<char, bufferSize> buffer, std::size_t count = bufferSize)
	{
		return this->write(buffer.data(), bufferSize, count);
	}
	
	std::size_t write(const char * buffer, std::size_t bufferSize, std::size_t count = bufferSize);
	
	// Later add some read and send variants that have timeouts
};
1 Like

I actually removed the serial driver. I have an another one from NXP, I haven’t tested it yet

Is the new one signed?

I reread the comment from before and remembered that the issue was that the driver wasn’t signed.


It seems you didn’t?

Never mind, I see the ‘removed USB driver in breach of FOSS’ commit.

Yes its a signed driver, official

1 Like

Ah good, that will make life much easier.

When you’ve got chance to upload it somewhere I’ll tweak N&C so it can do 2-player over serial.

I will host the driver separately in order for @drummyfish to have peace of mind. It is copyrighted by NXP but Brendon essentially said it can be used, still clarifying. It’s part of application notes / examples.

2 Likes

Copyrighting and licensing are two separate things, but I think I know what you mean - it was either unlicensed or it was under that ‘must only be used with NXP chips’ licence.

Personally I have no issue with the ‘NXP chip only’ licence for as long and the Pokitto is using an NXP chip, but hosting separately will probably suit everyone.


As it happens I dug out the ‘working signed CDCinf’ from the repo’s history,
and it still didn’t work because “the hash for the file is not present in the specified catalogue file”.

I sent you the working Microchip driver. I will replace that with the NXP as soon as I have time to test it out.

2 Likes

We have first Pokitto to gameserver connection working!

It’s official

Oops! I revealed how I hacked around the NAT issue! :stuck_out_tongue_winking_eye:

A round of applause to the venerable old telnet that came to the rescue

6 Likes

First release of multiplayer features soon

I will be making a number of utilities for connecting Pokittos together

First one to be released (as soon as I have tested on Mac and Linux) will be a tool for Pokitto->PC->Pokitto linking, demonstrated below

5 Likes

Incidentally, @FManga, could we add some sort of serial out emulation to the emulator?

Because if you could make localhost IP endpoints for the emu, I could make it possible to link the emu with a real device, thereby allowing multiplayer development even if you have only one hw device

4 Likes

Here is the Windows executable

http://www.pokitto.com/shared/PokittoLinkWin.zip

And here is a test binary to put on pokitto

serial.bin (55.5 KB)

And here is a windows test driver

CDCinf.zip (6.3 KB)

Here is the code (its in the PokittoLib repo, Serial2PC examples)

#include "Pokitto.h"
#include "USBSerial.h"

Pokitto::Core game;

USBSerial pc;

class PokSer : USBSerial {
public:
    bool isMessage();
    char* getMessage();
    bool discardAfterRead = true;

private:
    void update();
    bool _messageWaiting = false;
    int _currentMessage = 0;
    int _head=0;
    char _messages[2][30];


};

bool PokSer::isMessage() { return _messageWaiting; }

char* PokSer::getMessage() {
                if (!_messageWaiting) return 0;
                return &(_messages[1-_currentMessage][0]);
                if (discardAfterRead) {_messageWaiting = false;}
}

void PokSer::update() {
        while (readable()) {
                char t = getc();
                if (t=='\n' || t=='\r' || t == 0) {
                    _messageWaiting = true;
                    _messages[_currentMessage][_head] = 0;
                    _currentMessage = 1 - _currentMessage;
                    _head = 0;
                } else {
                    _messages[_currentMessage][_head++] = t;
                    if (_head == 30) {
                       _currentMessage = 1 - _currentMessage;
                       _head = 0;
                    }
                }
        }
    }


int main () {
game.display.palette[0]=COLOR_BLUE;
game.display.palette[1]=COLOR_WHITE;
game.begin();
game.display.persistence=1;
game.display.setFont(fontC64);

game.display.adjustCharStep = 0; //needed for the non-proportional C64 font (normal value=1)

game.display.print("Serial test");

while (game.isRunning()) {
        if (game.update()) {
            if (game.buttons.aBtn()) pc.printf("A\n");
            if (game.buttons.bBtn()) pc.printf("B\n");
			if (pc.readable()) {
			        game.display.print((char)pc.getc());
                    //pc.printf("OK\n");
			}

        }
}

return 1;
}


1 Like

You want the emulator to create a virtual COM port? I’ve no idea how to do that, though I could look in to it this weekend. I imagine OSX/Linux would require completely different implementations as well.

Or should the emulator provide its own serial-to-network bridge?

Yes I realized also this is far more complicated than what it initially sounds. A virtual COM port has to handle all the CTS/RTS/DTR handshaking and so.

But, since you’ve shown you’re capable of magic several times, possibly its a piece of cake, who knows?

Works in Mac, need to fix the linefeed coding on the display

image

2 Likes