Posts

Showing posts from 2020

Ray-Tracing Experiments

Image
Inspired by the upcoming Ray-Tracing Kajam event , I decided to start fooling around with some ray-tracing code. I'm still feeling inspired by DOS limitations, so I'm rolling with that.  But I'm not so interested in making a Wolfenstein-a-like, which is a classic ray-tracing type of thing.  I also don't think I'm capable of making something as awesome as Death Taxi 3000 , which is just a phenomenal piece of work. So my mind settled on trying to get a height-map, voxel-style terrain rendering on something like a 486 PC.  Still a significant challenge, but something I feel I can get my head around. The trick to anything like this seems to be getting your data/algorithm simplifications right to make life easy for the CPU.  To that end, over the last few days, I've been playing around trying to see the effect different simplifications have and I think I'm onto something:   This experiment was done on a modern workstation running Linux.  It's a 256x256 height

RAID 6 --> ZFS pool

Today I completed the transition of my NAS machine from RAID 6 to a ZFS pool.  To document the process for my future self and any semi-interested rando who stumbles across this, here is an outline of how I did it. Part 1 - Research I found this 'ZFS for Dummies' post really useful to re-familiarise myself with the core concepts.  Once I'd done that, the Ubuntu examples here were really useful as well as this post with more detailed information than I would ever need. My RAID was nowhere near full, which meant I could manage the process without having to restore everything from backups (although I made damn sure I had working backups before I messed with it). Part 2 - Degrading the RAID and pooling the freed-up drives First, I marked two drives from the RAID as failed so I could use them in the zfs pool.  I changed their partition type with cfdisk but I had trouble making a pool out of them because they kept on being picked up and re-started as a raid device.  In the end

NAS 'Case'

Image
I dun maed a frame for my home NAS machine.  It's been sitting as an untidy pile of connected components for just too long, so I finally did something about it. And here it is in-situ under the stairs: It's made from plywood off-cuts - the back from an old cupboard and the sides and drive supports from when I put boards up in the loft. I tried holding the PSU in with battens, but the glue wouldn't hold and they split when I tried using screws.  So instead I sank dowels into the plywood.  You can see four in the photo (two on the back board and two on the side), but there's another two on the back board holding the PSU's weight from underneath.  Rather improbably, it's actually quite a strong fit and the only way to get the PSU out is to slide it upwards. The bar across the front hooks onto two dowels (one from each side-board) so I can easily get at the drives to replace any failures.  It's got corrugated card on it to dampen vibrations and provide some grip

November Projects - Review

With Christmas right there *points*, I'm not going to set any December projects for myself.   This term at school has been gruelling, close to the hardest term I've ever had in teaching.  I have managed to get through it and get some stuff done though, so it's not all gloomy defeatism. Physical make: Loganberry frame/trellis.  I did finally finish it and I'm looking forward to properly clearing up the workshop so I can get some more physical makes done.  The garden also needs a huge tidy-up, with cutting back and weeding.  Maybe I'll get out there over the Christmas break, but I'm not going to beat myself up if that doesn't happen. Coding make: Turning my Silkworm tribute into an entry for the DOS Games Fall Jam .  I submitted a playable almost-level.  It was pretty disappointing from the content side - literally less than a dozen helicopter swoops and a simple boss.  From a technical side, it was much more of a success.  During the course of it, I develo

Trellis DONE!

 OMFG, I have been intending to make this bloody loganberry trellis for SO LONG!  And I've finally done it! Somehow, this weekend, I managed to get my sorry ass out to the workshop and cut, assemble and paint the damned thing.  It's just two A-frames joined by a couple of cross beams - nothing fancy.  It is about 7ft to the top of the A-frames, and it supports the loganberry canes at about 6ft (so I can put nets over them to stop the damned pigeons getting at them). I'm still not sure why my brain was so strongly rejecting the task of building them.  It might've been the amount of wood piled up in the workshop, making it feel unsafe to even go in there.  The new school year starting was probably also a big factor.  Anyway, it's done now, and it feels great to not have it hanging over me any more. Now I can start planning my next task...a better USB joystick with SPRINGS.

November Projects

Last Month's Projects: Physical make: Loganberry frame/trellis.   This still didn't happen. :( BUT! All the timber that was clogging up the workshop has now gone (except for the bits I need for the trellis).  So this might actually get done this month.   Coding make: Turning my Silkworm tribute into an entry for the DOS Games Fall Jam .     The deadline was extended for another couple of weeks, so I'm going to continue with this.  I've learned a lot about how enormously fat the standard C++ libraries are in terms of how they bloat up the size of the final executable.  The .exe is limited to 64kB in 16-bit real mode, so having 'cout' take up 6kB of that is just unreasonable.  <iostream> also needs to go, but I don't need to murder that just yet.   Reading: My Past & Thoughts by Alexander Herzen.   I finished it! :D   The book made really interesting reading, tying together lots of disparate things I knew about 19th century Europe and really brought

October Projects

Last Month's Projects:   Physical make: CnC router. This is a weird one.  I haven't been out to my workshop all month - it's full of 8-foot lengths of 2"x1" which I had picked up on Freecycle.  My intention was to make a frame to support some loganberry plants I have in the garden before the winter weather closed in.  The howling wind and hammering rain tell me I've kinda missed that boat.  But maybe there'll be a window of some clear weather in October when I can get that sorted. To be fair, teaching Septembers are pretty tough going and the COVID measures are making routines (which would normally make things much easier) very hard to figure out.  So my energy levels have been pretty low.   Coding make: Exploring DS Homebrew   This has actually made a great start!  Three of the students have decided to team up and make a project together!  So far we have only explored backgrounds and the beginnings of rendering sprites.  I want to make a simpler sprite

Faster Mode-X Sprite Rendering

Back in June, I made a sprite rendering system for DOS/VGA Mode-X.  Running it on a pcem 386 showed that the sprite clipping code was hella slow . So I decided to rip out the clipping code.  To allow sprites to overlap the screen boundary, I set up the VGA display registers to have a 32px off-screen border around the display. The system still splits the sprite into separate planes, and it still works by skipping some pixels then drawing some. It works across a scanline (within a single plane) so I can use rep movsb.  It also hard-codes the scanline width into the number of pixel bytes to skip - that's so I don't have to multiply the display width by the number of scan-lines to skip.  That means my game can only run in a single screen resolution, but it's only going to run in Mode-X so that's not a problem. Another tweak is that as much as possible, it loads 16-bits of data at a time.  This should make better use of the bus, which can be an issue with the 386SX. The com

September Monthly Projects

Last month's projects: Physical make: CnC router   Well, I dug around in my pile of projects and pulled together all the disparate parts of this project, but not a lot else.   I now have the pi, a monitor and a motor controller running off of an ATX supply.  What I don't have is the motor, threaded rod or rotary encoder actually installed on the sliding tray. I'm going to roll this over into September.  It shouldn't be too big a step now to at least attempt getting them installed. Coding make: I did it!   It wasn't the helicopter game I imagined, but it was an entry to the jam. :) Reading: My Past & Thoughts by Alexander Herzen.   I haven't finished this yet, but I am really enjoying it!  His writing (with the translation) is really easy to read and gives loads of glimpses into 19th century Russian life.  I've just got to his letters from Paris and Italy after he's finally escaped from Russia. September's projects: Physical make: CnC router.

Joystick Realisations

Image
Yesterday I had extreme difficulty in doing air-to-air refueling in DCS World. The obvious reason for that would be that it is an extremely difficult thing to do and I am just not good enough yet. Not being happy admitting my own lack of ability, I decided to blame my homemade joystick. To be fair, my joystick was built by a numpty (me), so there could easily have been something screwy with it. When researching more expensive potentiometers, I discovered that 'linear' potentiometers do not necessarily give a linear response to changes in angle.  It depends on potentiometer model, temperature, and all sorts of other things. Seeing as the potentiometers I used were the cheapest I could possibly find, their quality is questionable at best.  So I figured I'd have to measure the response curve, then hard-code a calibration fudge. I was genuinely surprised with the results: There is a beautiful linear section for part of the response, but the bit from 55-75 degrees is just shock

Lowrezjam 2020 entry: F-Z

      This evening I submitted F-Z , my entry for Lowrezjam2020 . I was going to make a helicopter game, but in 64x64 pixels I just couldn't get anything to actually look like a helicopter!  So I completely changed my mind and made an F-Zero style racer instead. In the limited time allowed for the jam, I only managed to make a single track.  However, the game was reasonably polished: it had a title-screen, menu, AI opponents, music, sound effects and a 'finished' race outro - with a particle effect for a podium place! It was the first time I'd written a racing AI.  I basically baked the AI instructions into the track tilemap, giving each AI-sector a heading value.  The runtime code loaded the sector polygon and calculated a middle-line for the sector using the polygon vertices and the heading.  The runtime AI first checked if it was way off the heading for the sector and corrected for that.  If the heading was okay, it checked if it was too far off the sector's mi

August Monthly Projects

Image
Last month's projects: Physical make: Model Starfury DONE! :) Coding make: Write a DOS Mode-X tribute to Silk Worm .  It's getting there... I'm taking a break from it this month though. Non-coding make: Fiction sci-fi fragment about a hand-to-mouth existence on a frontier world. I didn't get round to this at all.  I might just drop to three projects each month. Reading: Russian Thinkers by Isaiah Berlin .  I finished it!  It was a really interesting read - I'd recommend it. August's projects: Physical make: CnC router.  I'd started this ages ago, and I have a platform which slides from side to side when you push it.  This month, I want to get the Raspberry Pi and motor controller to be able to control the movement of the platform.  Maybe I'll get further and build the mounting for my Dremel, but baby steps... Coding make: I'm going to write an entry for Lowrezjam 2020 .  My super-detailed plan which is in no way me making it up as I go along: to w

Babylon 5 Starfury Model

Image
After two months, I have finally 'finished' the Starfury model. The painting is really untidy in places, and I really could not be bothered with the dozens of tiny water-slide transfers.  That said, I am still stamping this as DONE because it was getting really tedious towards the end. I love the Starfury design as a nod to Newtonian mechanics in sci-fi.  It is the most believable space fighter I've ever come across and I'm really glad I have finally got round to building this. The model design itself has many flaws.  Many of the pieces didn't fit snugly together, and the lower guns had to be literally chopped in half to get them stuck on.  They must have known of these flaws and just decided to ship it anyway.  After all, it's only fanboys like me that would buy it. I didn't have the right grey to paint it, so I mixed the colour from Vallejo's Cold Grey and some cheap white acrylic.  It's come out a little more blue than I wanted, but not badly eno

DOS Coding: Sound Blaster sound

SB Documentation link . BASE_PORT = the base I/O port the SB is listening on (most often 0x220, but see 'detecting the card' below) Single vs Auto mode: For single transfer playback, you don't really need the Interrupt Service Routine. I've shifted to auto-initialise mode because I was getting clicks between each transfer. For auto-initialise mode, you set up the DMA for the whole buffer, but tell the SB/DSP it's half the buffer size.  That way, once the first half is transferred, you get an interrupt to say you can overwrite the first half.  Then when the whole lot is transferred, you get another interrupt to say you can overwrite the second half.  (By that time the DMA has already auto-reset back and started transferring the first half of the buffer) Step 1: setting up sb_read() and sb_write() subroutines You should really check if the soundblaster is ready before reading or writing. Seeing as you need to write and read to detect/reset the card, these really come

Update: SilkWorm Tribute

Lots of trial, error and frustration has got me to this stage: This video was screen-grabbed from pcem running as a 386SX. 386s are SLOW AS ALL HELL, so I had to do some trickery for the parallax scroll: Use a 'trash buffer': I set up the VGA so there is 32px of invisible data to the left and right of the display (and also above it).  This means I don't have to worry about clipping my sprites.  If they're even partially on-screen, there's enough trash VRAM around the screen that it won't wrap round or corrupt other pixel data. Shrink game area: use a status display to shrink the rendered game area.  I did this with the VGA's Line Compare functionality, so that when it reaches pixel row 176, it will reset to render from VGA offset 0x0000.  (I also had to change the Pixel Panning Mode bit in the Attribute Mode Control Register because I use hardware panning). Solid colour blanking: this can be done with an asm rep stosb and a suitably large value in cx. 

July Monthly Projects

Last month's projects Physical make: Build a model Starfury I have had in the cupboard for literally decades . This is going fairly well but isn't finished.  I've had some delays waiting for supply deliveries but mostly I've been taking my time over it. The model has plenty of gaps where the pieces don't quite fit, and a glaring design-fail with the lower gun pieces.  I'm going to keep this one going this month and post photos once it's done. Coding make: Write a DOS Mode-X tribute to Silk Worm .  This has involved so much learning.  The sprite code took a huge amount of work, and now I'm writing tilemap code that is going to have to be really fast if it's going to be usable.  Most of the screen is going to have to be rendered every frame if it's going to look anything like the original.  So I'm keeping this one on for July as well.  I really want to get something recognisable and playable (even if it's not properly complete) before I

VGA Mode-X Sprite Rendering

As part of my SilkWorm project, I've got a transparent sprite-rendering system going. It's over-complicated, but it works quite quickly.  I'm writing this more as a reminder to my future self than as a HOWTO, so I'll not go into the gory details. The system is inspired by a really nice idea from StaticSaga and 36rKATPURPY on the Discord server linked to a DOS game jam .  Their system is simpler and more data-efficient.  My code is clunky but for the moment seems to work, so I'm leaving it as is until it breaks or needs speeding-up. The problem Mode-X stores pixel data in planes.  It can use VGA hardware to copy 4 pixels at a time, but only on 4px-aligned boundaries.  Michael Abrash' Black Book covers one method of how to do transparent sprite rendering without the 4px alignment, but it involves uploading 4 copies of each sprite to VGA RAM, and setting the plane mask for every 4-pixel copy.  To me, this seemed like a waste of VGA RAM, and any speed boost would

June Monthly Projects

Last month's projects They weren't 100% successful, but I got some stuff done. Wall-mounted PC: completed Coding make: demo submitted to game jam. Still plenty of work that could be done to it, but I'm pleased with what I achieved. Non-coding make: Westworld-style Shadowrun setting.  This was slightly disappointing.  I read plenty about San Francisco and pored over maps and such.  I came up with some nebulous ideas, but with nothing concrete to show for it.  A particular stumbling block for me was that I know nothing about San Francisco.  Making a setting based on a real-world location I know nothing about seems like I'm setting myself up to fail - it'd never be believable to anyone who actually knows the city. Reading: This was hella slow going, but I wanted to study the book (and still do). Despite incomplete projects, I feel like making a shortlist was pretty useful for helping me focus on particular ideas.  So here's this month's projects: June'

May Reading Project

This month I have been mostly reading The Conscious Mind by David J. Chalmers . It's a full-on philosophy book, so it was really hard going.  But I did finish chapter 1! Why so slow? Apart from being a pretty slow reader, I only got one chapter read because I was taking Cornell notes as I worked through it. They take a lot of time and effort.  I understand better now why the students I teach hate taking them so much. There were a few important benefits for me though:    - Using them has left me with a feeling that I do understand what I've read    - For the most part I can remember the key ideas    - They provide a really nice summary to read over when I come back to take on the next chunk reading I'll continue with Cornell notes for books that I really want to study rather than just read. For books that I want to read, but might want to refer back to, I'm going to try sticky page-markers instead.  So for popular science or history books, I can just mark the key sect

Wall-mounted PC: Finished!

Image
The rest of the project went so smoothly, there's very little to add to the previous post ! The standoffs for the motherboard screwed right into drilled holes in the MDF without needing glue. The HDD and PSU are held to the board by twisty-ties that go through holes in the board.  I didn't trust twisty-ties to hold the PSU's weight though, so I drilled holes for a couple of dowels and glued them in.  The PSU rests on top of them nicely with the twisty-ties stopping it from falling forwards. The shelves are furniture board off-cuts which are screwed to the battens from behind.  Amazingly, I managed to cut accurately enough that they fitted really snugly to the battens.  There is a bit  of give if you press them, but seeing as they're not going to hold anything of real weight I left them as they are. I'm not entirely happy with the cable-mess.  A little more forethought could have had them tucked behind the MDF board, but meh. I've installed Ubuntu Ma

Wall-Mounted PC: Progress!

Image
The actual physical progress I have made is a monitor wall-mount made from battening and MDF. See the monitor hanging magically with no visible support! I made a frame for the back of the monitor from 3 pieces of 6mm MDF: I knew the bolts I had could only go in so far before I hit resistance (presumably from the internal components).  As far in as I was confident tightening them would leave ~9mm gap.  So I figured 12mm of MDF would be fine. WRONG.  It turns out you have far less wiggle-room on these things than I thought. So I had to countersink them through the outer layer.  That gave me the fear though because the outer layer would be the only thing really holding the monitor onto the wall bracket.  So I decided to glue the layers together as well as having the bolts.  It took a couple of tries to get the countersinking to the right depth, but it got there! And before I did anything else, I tested that the panel from the wall-bracket would actually slide into

Deus Heist

Image
I managed to make a playable level of a DOS heist game . It's a text-based game, built for 16-bit DOS, so in theory , it should run on a 286 (albeit as slow as a sedated two-legged dog).  I haven't had any time for optimising it, and the code is hideous, but it is  technically playable. The main feature is the visibility check, modelled on the game Monaco: What's Yours is Mine . It scans out from the player, checking if a cell blocks line-of-sight or not.  I made it fairly efficient by splitting the check into quadrants (N, E, S, W) and scanning cells between two edge-lines.  If it encountered an opaque block, it would split the scan up and recurse. On DOSBox, it gets a little slow when you can see a lot of the screen.  I imagine on a 286, this would crawl.  However, the game world does not change at all in the current version, so there are no guards going to creep up on you while you're lagging. I could also help things by designing the maps so there is

Monthly Projects

I recently took part in a games jam which took longer than a month.  It made me realise how much I prefer the longer-term work to a short, frantic game jam.  However, I know how easily I get distracted by newer, shinier projects.  So I thought I'd try listing a few projects each month that I intend to work on, and then later on in the month posting about how they went. Projects for May: Physical make: wall-mounted PC for the workshop. Coding make: Monaco / Deus Ex -style heist game for DOS Non-coding make: Shadowrun campaign setting for Westworld-style universe Reading: The Conscious Mind by David J. Chalmers Wall-mounted PC I currently use a laptop to re-slice models for my 3D printer.  Worktop-space is at an absolute premium in the outhouse I call a workshop.  Plus, I hate laptop trackpads.  So the idea is to have a wall-mounted PC with a little shelf for the keyboard and another for the mouse.  It'll need a dust-sheet cover as well otherwise all the heatsinks

Dos tidbit: register-based Watcall parameter order

It has occurred to me that in the course of writing DOS programs (some of which even work!), I spend an awful lot of time searching through documentation.  Which is, you know...fine.  It's part of the charm of retro coding. However, this ancient source has an inaccuracy which has bitten me twice (the second time because I forget about 99% of what I read).  Not that I bear the author any ill-will - if a document as detailed and comprehensive as that contained no inaccuracies at all, I would be worshiping the author as some kind of god.  It might even have been accurate at the time of writing (2010CE).  There's plenty more in that site which I intend to dig through and learn from as well. Anyway.  What bit me: When using register-based watcall* to call an asm procedure from C/C++, 16-bit parameters are passed in this order: AX, DX , BX, CX.   *in OpenWatcom V2 at time of writing. As I read it, the document says it is in the order AX, BX, CX, DX.  This caused me MUCH con