[Open thread]Multiplayer discussion

  • 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

A quick googling says I’m not going to be so lucky: I’d have to write a device driver for Windows.

Alternatively… could we use com0com?

It could be shortened to this:

#include <Pokitto.h>
#include <USBSerial.h>

Pokitto::Core game;

USBSerial pc;

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;
}

The PokSer class is never used.

Why would you need a device driver?


Also the pc.printf calls aren’t working for me.

They work on the ArduinoIDE but not my custom program for some reason.

I’m guessing I’ve got the settings wrong.
I’ve got a baud rate of 9600, no parity bit, 8 data bits, 1 stop bit and rts enabled.
Any idea which of those is wrong?