4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TinyGoAdvent Calendar 2024

Day 17

GameLink: multiplayer gaming with TinyGo Keeb

Last updated at Posted at 2024-12-16

gamelink.jpg

What is a GameLink!?

If you grew up in the 80s and 90s like me, you might remember the tech wonder that Nintendo Game Boy Game Link Cable was, a cable that allowed you to connect two Game Boy systems for multiplayer gaming, way before online gaming was a thing. As a kid, it was like magic, so as soon as I played a little with TinyGo Keeb zero-kb02, I decided I needed to make one for them.

TinyGo, TinyGo Keeb and zero-kb02

So the logical next question is, what does it mean any of those words?

  • TinyGo is a project to bring the Go programming language to microcontrollers and modern web browsers by creating a new compiler based on LLVM
  • TinyGo Keeb is how I referred to customs keyboards that have a TinyGo firmware, the series of workshops called TinyGo Keeb Tour and the most popular model zero-kb02. (it should be noted that the official repository is called tinygo-keyboard)
  • zero-kb02 is probably the most popular of such keyboards (or keebs as called in jargon). Both TinyGo Keeb and zero-kb02 is the work of @sago35, none of this would be possible without him
  • TinyGo Keeb Tour 2024 & 2025 is a series of workshops held in several cities of Japan where the attendees solder and build the keyboard zero-kb02 and runs a few example programs on them

keeb.jpg

TinyGo Keeb zero-kb02

Connecting two devices

We are going to use the I²C interface of the zero-kb02 to talk to each other. To make everything easier we are going to use a Waveshare zero RP2040 (it could be another board, but those are very cheap and I have many) to handle all the messages from one device to another. Connect one I²C port to each different device, like shown in the image below.

circuit.png

*the 5V/VCC>red wire is not needed

i2c_detail.jpg

shown in detail the I²C connector of zero-kb02 below the USB-C

The firmware of the GameLink is very simple too. Two ring buffers that can holds several "messages", device A writes a message in buffer A, then device B read the message from buffer A and viceversa. The magic of it resides in the I2C.Listen(port) func, which configures to port to listen to incomming I²C messages. Then it's a matter to reply with an appropriate response:

for {
    evt, n, err := ports[port].WaitForEvent(buf)
    if err != nil {
    }

    switch evt {
    case machine.I2CReceive: // store received message
        if n > dataSize {
            n = dataSize
        }
        stacks[port].writePtr = (stacks[port].writePtr + 1) % stackSize
        for o := 0; o < n; o++ {
            stacks[port].stack[stacks[port].writePtr].data[o] = buf[o]
        }
        for o := n; o < dataSize; o++ {
            stacks[port].stack[stacks[port].writePtr].data[o] = 0
        }
        stacks[port].stack[stacks[port].writePtr].read = false

    case machine.I2CRequest: // return the oldest unread message
        portClient := (port + 1) % 2
        ptr := (stacks[portClient].readPtr + 1) % stackSize
        if stacks[portClient].stack[ptr].read {
            ports[port].Reply([]byte{0})
            continue
        }
        stacks[portClient].readPtr = ptr
        ports[port].Reply(stacks[portClient].stack[ptr].data[:])
        stacks[portClient].stack[ptr].read = true

    case machine.I2CFinish:

    default:
    }
}

GameLink driver

And finally our TinyGo Keebs need a driver to talk to the GameLink. The driver itself will be very simple for this Proof of Concept

// Write sends a message to the GameLink to be read later by the other device connected to
func (d *Device) Write(data []uint8) error {
	return d.bus.Tx(d.Address, data, nil)
}

// Read returns a message from the GameLink sent by the other device connected to
func (d *Device) Read() ([]uint8, error) {
	data := make([]uint8, 10)
	err := d.bus.Tx(d.Address, nil, data)
	return data, err
}

gamelink_keebs.jpg

two zero-kb02 connected via a GameLink

Tic-tac-four?

To showcase the GameLink I created a small Proof of Concept game of tic-tac-toe played on a 4x3 matrix, you can see and download the code in the official github repository. Please, be aware this is a PoC and as any software in the early stages, it contains multiple errors, lacks features and a lot of wrong decissions were made during its making.

tic-tac-four

demo of a tic-tac-four gameplay

This article is part of TinyGo - Qiita Advent Calendar 2024

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?