Sunday, 21 March 2021

Leilei Relay

Baby UFOs in UFOland have to train arduously before they can leave their homeworld.

Historically, the most infamous of these training grounds was the Lei Lei Relay.

Collect the lanterns to advance to the next field, up until you reach the UFO cathedral. There you will attain the title of UFO master.

Guide the UFO using Joystick in Joystick port 2. Left and Right turns the ship, while Up is thrust and so is Fire. Pressing key '1' on the keyboard switches the musics on/off.


On and off I have been working on new Commodore 64 games. Most of them do not get much farther than early stages, so I really, really wanted to do something so small that it would get finished.

Even then, this game turned out to be somewhat bloated compared to my original intentions. So it's a small game that became slightly bigger than I wanted to.

It does have multicolor character graphics, sprites, smooth vertical scrolling, inertia, polar coordinate tables, multiple SID tunes and sound effects.

My original intention was to make a one-screen lander-type game. Some inspiration has been drawn from lander games and Space Taxi.

But it's closer to a gravity game like Thrust in the sense there's no actual landing involved. Instead, you need to collect all the lanterns from each room to proceed to the next one. The quicker this can be done, the more bonus points can be achieved. And that's it.

The weird shape of the player ship gives the game some additional spice. It needs to be turned into a vertical position to help squeeze it through some of the more narrow passages.

Unlike with Fort Django and Digiloi, there's no shooting, which makes this game simpler. But it's likely to be infernally difficult.

There's no PETSCII character graphics this time, I have some ideas about their use for other games, which may or may not be completed!

Tile map layout

As usual, I have come to trust Tiled for map-making. Instead of PETSCII I now used multicolor character graphics. The pipeline from character editing to "meta-tiles" would deserve a closer look but I'll leave that for another time. Let's just say experience in PETSCII gives a good start for optimizing character graphics, but it does have its own peculiarities.

First level in Tiled

At the center of the game routine is the scrolling screen buffer. Instead of updating screen portions piece by piece, the whole screen is redrawn for each frame.

I abandoned the character-specific colors to make this easier. This gives the game a somewhat monochromatic appearance. I tried to alleviate it by using different colors for different levels, and mixing the colors when possible.

There's a huge ordered buffer in the memory, but at least it made some other things easier for me. The level data in itself takes very little space, but testing levels and putting them in a reasonable order is time consuming so I went for a fairly low number.

More technical parts

The brutal redraw routine means I can scroll the area in whatever speed I like, and also if I draw changes into the buffer, these are rather simple to calculate, as all Y-coordinates work as increments to the HI-portion of the address. So if the first line of the buffer is at $8000, the next line is at $8100 and so on.

A new thing to me was polar coordinates and inertia, although I already made the routines for a more complex game idea, they found a better home in Leilei Relay.

The UFO coordinates are 24-bit values, but this is less complex than might sound.

24-bit coordinate:

[Low byte][High byte ][Highest byte  ]

Sprite coordinate:

          [Sprite LSB][Sprite MSB bit]

The high and highest byte are transferred directly to sprite screen coordinates, so that "highest" gives the MSB bit for the sprite coordinates higher than 255.

Low byte is kind of sub-pixel coordinates, as they increment over 255, the sprite has moved visibly one pixel.

For thrusting the craft forward, a polar coordinate table is needed. These are 8-bit values centred around the point 128,128 ($80,$80). They have been generated using Processing.

.byte $80,$80,$81,$81,$82,$82,$82,$83,$83,$84,$84, [...]
.byte $70,$70,$70,$70,$70,$70,$70,$70,$70,$70,$70, [...]

So the first values are $80 and $70, which indicates 128 and 112, denoting a 0,-16 vector.

I have 256 values in the table although the UFO has only 32 visible angles. I won't go into the confusion this might create, I initially thought it would be nice to have more functional angles than visible angles, but after experimenting with it, this is really a no-no. 

It's really annoying to see the ship move to a direction it is not pointing at even if the difference is very subtle.

So, it may be just as well assumed the table is 32 values long.

Oh, and the above table is not directly applied to the sprite coordinates, but to the ship inertia X/Y values, which are in turn 16-bit values.

These again have the initial value of $8000, $8000. (low byte=$0, high byte=$80)

If the ship angle is stored in register Y, then the above table can be used to alter inertia.

lda inertia_x_lo
sbc #$80
sta inertia_x_lo

lda inertia_x_hi
sbc #$0
sta inertia_x_hi

lda inertia_y_lo
sbc #$80
sta inertia_y_lo

lda inertia_y_hi
sbc #$0
sta inertia_y_hi

lda inertia_x_lo
adc move_anglex,y
sta inertia_x_lo

lda inertia_x_hi
adc #$0
sta inertia_x_hi

lda inertia_y_lo
adc move_angley,y
sta inertia_y_lo

lda inertia_y_hi
adc #$0
sta inertia_y_hi

Sooo the $80 is first subtracted from the inertia values, and then the motion (with the $80 baked in the values) is added. There must be a more clever way but this is the one I used.

The inertia values are then used similarly to affect the ship (24-bit) coordinates.

This is for the x coordinate, for the y coordinate it's the same. It may be useful to keep them separate.

lda ship_x_lo
sbc #$0
sta ship_x_lo

lda ship_x_hi
sbc #$80
sta ship_x_hi

lda ship_x_highest
sbc #$0
sta ship_x_highest

lda ship_x_lo
adc inertia_x_lo
sta ship_x_lo

lda ship_x_hi
adc inertia_x_hi
sta ship_x_hi

lda ship_x_highest
adc #$0
sta ship_x_highest

The main game sprite is simple, but it does have a layer of anti-aliasing, using another sprite. These were generated using Processing. There are 32 frames, making a total of 64 sprite frames for the UFO.

For each frame, the sprite graphics data are copied from outside the video bank area to the visible sprite frame, as 64 sprites would take a huge chunk of the video bank and this didn't fit into my plan. I'm now getting to understand how important it is in C64 programming to have a good plan for locating the graphic data and the video bank.

With this technique I could have had 64 frames (128 with anti-aliasing), but I felt it easier for the player if the vertical and horizontal positions can be more clearly discerned.

The thruster flame has only one frame but it is positioned differently in alternating frames to give it more direction and a tiny bit of transparency, again using a polar coordinate shift.

Four sprites are used on the lanterns, although with multiplexing they could have used up less. But I didn't want to practice multiplexing this time, it was enough to handle the above issues and sprite-to-sprite and sprite-to-background collisions.

Wrap up

Looking at my notes, I worked on the game intensively for a few weeks in May 2020. Some of the routines had been done previously so I didn't have to "invent" the inertia, polar coordinate and precision coordinate routines then. So adding that I might have worked on this for about month.

It appears I considered a release at end of June 2020, but decided to wait. Then I picked it up on this weekend, with the idea I might be heading towards a phase of adding things to the game. 

But instead I simply cut off loose ends, adjusted some of the musics, added some graphic variety, removed anything that still looked like a bug, tested it on a real C64 and released it.

Design-wise, there was a lot that could have been added, but at this point every addition would have needed another round of testing and assessing the whole game, so it was better to keep the original promise of a "small game".

Leilei Relay at csdb

Monday, 15 March 2021

GeForce NOW

I tried this tip to run GeForce NOW on my Linux and run streamed games through the browser. To be honest I'm not sure if this is needed anymore, but I followed the instructions to the letter and now have the service.

The nice thing is that I can "buy" a game in Epic or Steam but don't have to download them.

I was motivated to get games like Fortnite and Apex Legends running, so I could have some first-hand experience about these games. Also, I could try less interesting free-to-play games like War Thunder without having to waste hard drive space.

But as I could also "sync" my existing Steam library, it might be revealing to check games I already know well.

What I noticed is apparently no Steam savegames are translated to the service, so I had to begin the games from the beginning. The other immediate thing is that the streaming computer has a different keymap, affecting some games in (very minor) ways. E.g. Fortnite has auto-run key on = but it's not at shift+0. The key is not really needed, though.

The stream picture quality with 1920x1200 is high. On occasions I tried a lower display resolution to see if it would affect the evenness of the stream, but to be honest it might not have done much.

My observations are not serious comparisons, just how I felt about it.

Rise of the Tomb Raider cutscene

Above: Streaming from Geforce NOW

Below: Running on my Linux and GTX 1060 3GB with my preferred settings.

Rise of the Tomb Raider cutscene

In this scene there is a minor difference in how the pendant casts a shadow, more hair detail, and the leather jacket is rendered perhaps slightly differently. There may be different reasons for this than just the game settings, though, e.g. driver versions and such. Oh and the local screen might be scaled up from a 1440x900 or something,  and this might already explain the difference in materials.

The basic gameplay of Rise of the Tomb Raider is so loaded with "inertia" so a slight lag didn't matter. I felt more doubtful about the quicktime events, though.

Just Cause 3 is a game which I played with some intensity last year. Arguably it has more crisp controls than Tomb Raider, but still I didn't notice any great disadvantage here. The game itself eventually crashed, I think, which is what happened few times when running on my Linux too.

Just Cause 3

I didn't do a comparison of graphic settings, but it may be that using best quality shadows helps give the above effect. I don't know, but blurred and less definite shadows may actually look better in games.

I went through a few battles in Everspace. This was quite playable through the stream. Granted, here the cursor might not exactly follow the mouse, but the ship control itself is sufficiently sluggish so it translates well to the streaming environment. 

The loading hiccups I've sometimes experienced when playing this on my computer, were completely absent on the streamed version. Full graphic detail is active with no slowdown.


Elite: Dangerous is a good match for the service, as the game has a slower pace to begin with, and my experiences with Steam/Proton had been a mixed bag. Yes, I initially got it working via Proton, but after later updates I had difficulties in getting the game to run and have no incentive to troubleshoot it. 

After various arrangements and recovering lost passwords and verifying the account, and waiting for shaders to load and planets to generate, I got to my Elite: Dangerous via GeForce NOW. The nice thing here is that the game account is at Frontier, so I guess I am continuing my saved game. 

Oh, and the Geforce NOW tends to have DLC and additional content of the games pre-loaded so the Horizons addition was already plugged in. This is interesting, as I don't really own the Horizons content at Steam. (Horizons is what makes it possible to visit the surfaces of the planets.)

Elite: Dangerous

But so, Fortnite. Twice I tried the free variant of the Geforce service and had 200+ players in line before I could have a go. This meant about an hour of waiting. Then I paid the 6 month fee to get rid of the queue and the one-hour playing limit. The stream itself doesn't seem better, but I guess they wouldn't want to demonstrate a crappy stream in the free service.

I have now played a few hours of Fortnite. One time, the game got stuck in mid-stream, and I used the terminal to shut the browser window.

There was some choppiness as the session starts which I believe is due to the MMO logistics and not the stream really.

Apex Legends was offline and in "maintenance" which I'll have to see as a minus as it shows the service content might change on a whim.


This kind of streamed gaming requires some tolerance towards minor screen effects, as I wouldn't say the stream is perfectly smooth. But it's not always clear what is caused by the stream and what comes from the game itself, or even my setup.

Generally I don't see much point in running a game like Tomb Raider over the stream, if I already have it downloaded on Linux. If the streamed games are from a high-end "rig", then compared to that the 1060 already renders games rather well.

Using full graphics settings is fun to try but reveals that the additions are mostly in details I wouldn't care so much about. Granted, these are already slightly old games.

All in all there's a strange feeling this is not quite "real", but at least for trying out new games and especially games otherwise unavailable for Linux, it is a nice addition. The selection of games is not super-huge, especially at the indie end. But it's just a fact now that many major games are exclusive to different platforms and services.

Saturday, 6 March 2021

Sharp MZ800 Unicard installation

I got this Unicard for Sharp MZ-800 from Marq. The first idea was just to borrow this to see if my Sharp showed similar problems, but I became an owner in the process.

For him, the 4-colour screen appeared 2-color, plus there were other hiccups. This might have been a faulty VRAM problem, but who knows. But at least 4-color screens are possibly only for 32K VRAM. Some kind of palette glitch could not be absolutely ruled out, either.

Well, after fitting the unit this much was immediately clear: my Sharp works and the Unicard manager screen has the proper 4 colors.

But in the process I found out a thing about my Sharp I did not remember: There were already two cards inside instead of one. Though my blog post about Sharp mentions the ports I'm not sure if I understood there were two separate cards.

In addition to the disc drive controller there is indeed a serial port card that gives 2 RS-232 connectors. This is the Sharp MZ-1E24, which is probably so LOOK!RARE!!11! I couldn't even see one on eBay.

But I got more curious about why the Unicard couldn't fit correctly to the backside, and it looked like the custom fitting of the two-card system was to blame.

First I thought it was just the RS232 on-board plug getting caught in the roof of the metal sled holding the top card. Then it appeared the sled itself had become mangled, which made me really worry.

To cut a short story even shorter, turns out the RS-232 connector (Edit: not the VGA as I hastily wrote previously) at the panel doesn't fit well with the roof of the metal sled that houses the card. So the screws are impossible to fit and trying to force the card too much might break it.

After some consideration I pulled the Sharp top cover out. After all the case is modular and can be removed very easily.

Looking at the metal sled it wasn't really that damaged. Still, as the material was soft enough I beat it into slightly better shape.

As a remedy for the VGA connector conflict I cut away a portion of the sled. Computer museum enthusiasts may facepalm now.

Digging out the correct sawblades sounded like inviting a wasted afternoon so I drilled holes using a metal drill and yanked the piece out with pliers.

More advanced pliers could have cut into that material without doing the drilling. It's ugly but won't show out.

Now that I'd pulled the cover out I could conveniently pre-fit the card.

Finally, the screws fit. 

The end result is not very pretty because the already previously modded new opening below the proper expansion slot hole. 

What does it do, then? That's a story for some other time and another blog post. It does have VGA, SD-Card, probably RS232, PS/2, Internet thingy and a micro-USB.

But at least as Marq had already put the software and firmware into shape, I can play Flappy. The composite image is very solid but very "patterned". That VGA connector might be put into good use later.