Blue Drava

Slips of the tongue and tricks of the light

PI Spectrum

June 18, 2018


Ever since the Raspberry Pi came along, I have always wanted to put one inside the microcomputer of my youth, The Sinclair ZX Spectrum. This weekend I finally did it!

Replica Case

Through the Spectrum Next project, I discovered Retroradionics. They produce replacement cases for the 48k ZX Spectrum complete with faceplate, ‘dead flesh’ keys and keyboard membrane. Not only that, but they are in a wide range of colours to mix and match aside from the classic black and dark green.

I decided to go with an all blue selection. Unfortunately however by the time I ordered, Retroradionics and just completed a kickstarter for the Omni 128, a Spectrum clone in both desktop and laptop forms and so my order took 6 months to be shipped from China and another month to arrive to me in Croatia. When it did arrive I was really pleased and didn’t mind the wait.

Raspberry Pi Zero

Inspired by a series of blogs by P J Evans I dug out my Pi Zero for this project. He originally hooked up the keyboard membrane to an Arduino board which could connect to a full sized Raspberry Pi 2 as a USB keyboard. However the people he showed it to commented on the lag produced. And so he realized that he could wire up the keyboard directly to the GPIO connectors. I’ve done the same.

It’s a bit messy but I wasn’t sure how much I would have to move the membrane connectors so I kept plenty of ribbon cable. The ribbon was from an old floppy cable and the membrane connectors I ordered from a retro electronics supplier in the UK.

In the spot where the 9v power input would have been I added a button to switch keyboard modes. The Speccy has no Function keys but Fuse, the Spectrum emulator does need them for opening the menu. Not shown in these pictures I also added 2 LEDs sticking out of the EAR and MIC ports. A red one is wired to a 3.3v pin to just be a power indicator and a green one turns on when the keyboard function is switched.

I’m pretty happy with how it has turned out. I have some ideas for improvements. One thing I think is possible is to put the Pi Zero in gadget mode and have it work as a USB keyboard when you plug it into a full PC.

The remaining hole on the back, originally for TV out looks to be just the right size for an Ethernet port but could also be for an actual TV output. I would have to change some pins around in order to get PCM sound out of the Pi Zero and into an internal speaker.

There could be enough pins for a classic DB9 joystick connector. Alternatively I could maybe piggyback 2 joysticks on the connections for the top row of keys like the ZX Interface 2 did.


PRISM: A library to simulate the ZX Spectrum display in LÖVE

May 22, 2017


I’ve done some refactoring and separated my display code into a simple library called PRISM. I’ll think of a funny backronym some day but it’s in reference to the Spectrum logo.

In a previous blog I talked about how I’m rendering the sprites to the screen. Since then I have added a way to dynamically rotate the sprites and to simulate the border and Attribute Clash of these old display methods.

Colour Clash

The displays of the early 8-bit machines often could only manage 2 colours per 8×8 pixel cell, so if 2 sprites overlapped the colours would change depending on which sprite was drawn last. There may be a better way to make this work but here is my method.

I have 3 canvases; paper, ink and sprite. Each are 256×192 pixels, the resolution of the original Spectrum display. When the sprite function is called it draws an 8×8 rectangle of the paper and ink colours to their respective canvas. Then the sprite itself is drawn in monochrome to the sprite canvas.

When the PRISM draw function is called it sets a custom shader I made and passes the ink and paper canvases to it before drawing the sprite canvas. The shader simply checks each sprite pixel and returns the colour of the same pixel from the ink canvas if the sprite pixel is white and the paper pixel colour if the sprite pixel is black.

It runs fine on my PC but I feel it needs a lot of optimization before it runs ok on mobile.

Download

You can grab my current version here. Zlib licence (same as LÖVE). Inside is a main.lua which runs the demo in the video above.


Editor coming together

January 5, 2017


I’ve been working on my level editor for Teratree. The video above will give you the basic idea of how it works.

All the world data is saved in one big nested table.

world
    name
    author
    cells
        room
            name
            tiles
                tile
                    name
                    ink
                    paper
                    bright
                    cells
                        sprites
            cells
                block
                    celltype
                    health

Each table called cells is a 2d array, the rooms in the world, blocks in the room and pixels in the sprites are all handled in the same way.

Currently the world table gets dumped to a lua file using this library but it’s not very human readable. I may work on a custom exporter when I’m happy with the format of the table.

Since the video I’ve added the ability to change the text like the room names and given the tiles multiple sprites for animation. I’ve had to start on a menu/ui module to make things easier to build buttons and text inputs. More on that another time.


Sprites and Strings

November 16, 2016


It took me a while to decide where to start with this refactoring of my code. In the end I decided to work on display stuff. I need a way to draw my game in a ZX Spectrum style.

Display

The display of the ZX Spectrum was 256×192 with a border to fill the rest of the screen. I want to keep that resolution but have it scale to the window size.

function display:scale()
    local winx,winy = love.window.getMode()
    local xres, yres = 256, 192
    
    local xscale = winx/xres
    local yscale = winy/yres
    local transx, transy = 0,0
    
    if yscale*xres > winx then
        scale=xscale
        transx, transy = 0, winy/2 - (yres*scale)/2
    else
        scale=yscale
        transx, transy = winx/2 - (xres*scale)/2, 0
    end
    love.graphics.translate(transx, transy)
    love.graphics.scale(scale)
end

I run this at the start of the draw callback and, no matter what size or orientation, the play area scales to the shorter dimension and center on the longer. I may adjust the scale slightly if I want to have a border on all sides but this works for now.

teratree-scaling

Sprites

LOVE can of course draw image files on the screen but I decided I wanted my game to handle sprites in the program. Each sprite will be a 2-dimensional array of bits and when it is drawn you give it the colour of “paper” and “ink”.

ZX Spectrum Colours

ZX Spectrum Colours

The Spectrum has 8 colours, each with a dark or bright variant. I’m using the number to indicate the colour I want and another bit to indicate the “bright” variant. To make this work with LOVE’s setColor function, I do a simple function to convert the number I have into an array of RGB values.

if bright == 1 then
            value = 255
        else
            value = 215
        end
    
        if number == 1 then
            colour = {0,0,value}
        elseif number == 2 then... etc

return colour

Next I parse the 2d array sprite I want to draw. For each pixel I use love.graphics.rectangle to draw a 1×1 square. To save drawing every single pixel I draw a rectangle the size of the sprite with the “paper” colour and then just draw individual pixels for the “ink”.

Test sprites

I want to do some kind of “colour-clash” mode but I’ll probably have to do some kind of shader for that. For now I need to allow a moving sprite to not draw it’s “paper” over the background. If the colour number for the paper is not 0-7, the “paper” rectangle isn’t drawn.

Transparent "paper"

Strings

The final thing today is writing strings with a sprite font. I already had a version of the Spectrum font as binary arrays from the last time I worked on this. I had used a Python PNG library to convert an image of the font into bits. Lots of trial and error on my part. Once I had these sprites I put them into a dictionary list, named for each character. All that was needed then was to take whichever string I wanted, split it using gmatch”.” and printing the corresponding sprite to the screen for each character.

Hello World!

I was missing an exclamation mark… fixed now.


Start of Devblog for Teratree: a Miner Willy engine clone.

November 11, 2016


This year I have started this project 3 times, each time realizing a better way to do it as I learn to use Lua and LÖVE.

I am about to start again, refactoring everything to keep the code clean an expandable. Will I succeed this time? We shall see.

The dream is to have the main project executable standalone with a menu that can load levels, edit worlds and sprites and play the games. All that will be nice and open source, as will any games I make myself with the engine. I will be making versions of MM and JSW too, if nothing else to make sure the engine feels right.

Here are some videos of previous attempts:


Youtube Channel

November 20, 2015


Blue Drava now has a Youtube channel. I’ll be posting the podcasts as a video with a static image for now.