new game: Asteroid Commander

All aspects of programming on the Commander X16.
Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


I've got a bunch of buildings designed, and made some buttons.  I haven't added the building data yet but there's new buttons:

AUG3.jpg.ff12df9072cbb1b55e23ce92426aeb66.jpg

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


I mentioned that there's going to be 16 palettes.  Well, I've got started on some of the colors that will be cycling, and got the program to recognize my buttons when I click on them.  This video shows some of the code that does the color cycling, how I'm using some zero page locations as flags, and how the custom IRQ routine sets the flags to keep everything synchronized.





I also came up with some slightly more efficient code for PAL+, the palette cycling subroutine.  I saved six bytes and a bunch of jiffies.  It might not seem like much, but every tiny bit of efficiency helps.

betterpaletteswitch.jpg.b246582ecfde0651a83eab2ee9a0da6b.jpg

Snickers11001001
Posts: 140
Joined: Wed Jan 20, 2021 6:43 pm

new game: Asteroid Commander

Post by Snickers11001001 »


Gotta say, I really dig that META/L editor...     

As someone who did all my (limited) ML programming on my Plus/4 back in the day just using the built in TEDMON monitor, there's just something so cool about poking around so close to the bare metal (oh! ... I think I'm getting the naming inspiration).    And you've addressed what was always my bane:  'oh crap, I need to insert something here...' which was not a fun prospect when you worked in a monitor and had to go manually update everything to deal with the fallout of moving, adding, deleting or enlarging something.   

Also, kudos on really taking advantage of the 65c02 instructions... that bit flag system in the latest vid is clever.  

Awesome to watch a coder with skills I'll never have go through the creative process.   Cheers! 

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »



54 minutes ago, Snickers11001001 said:




Gotta say, I really dig that META/L editor...     



As someone who did all my (limited) ML programming on my Plus/4 back in the day just using the built in TEDMON monitor, there's just something so cool about poking around so close to the bare metal (oh! ... I think I'm getting the naming inspiration).    And you've addressed what was always my bane:  'oh crap, I need to insert something here...' which was not a fun prospect when you worked in a monitor and had to go manually update everything to deal with the fallout of moving, adding, deleting or enlarging something.   



Also, kudos on really taking advantage of the 65c02 instructions... that bit flag system in the latest vid is clever.  



Awesome to watch a coder with skills I'll never have go through the creative process.   Cheers! 



Yep, the name is because it's as close to the bare metal as you can get, and also it relies very heavily on metadata, in particular labels.  It is the metadata that allows me to easily insert or delete bytes in the middle of the code.

Any of the code I'm showing here is free for other people to use.  I borrow clever code from other people all the time.  Some of the IRQ stuff, for instance, I borrowed that from @SlithyMatt's video on interrupts.  I think I got the idea of using VRAM to store lookups that get called sequentially from @Jeffrey, who was working on Wolfenstein.  Keep looking at other people's code and borrowing stuff, and adapt it to your own needs; after a while you'll have lots of little tricks like that in your arsenal.

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


I still haven't figured out exactly how I'm going to populate the windows on the right and bottom left, but I moved some things around on the screen and made a bunch of other cosmetic changes.  I also added a Fast Forward button, which to my astonishment worked perfectly right off the bat.  The game is already at one second of real time = one minute of game time, but when you click on the FFWD button that changes to 1 real second = ten game minutes.  Here's what the screen looks like now:

august11.jpg.270d67ff33e57b49b0fa0a68837181aa.jpg

 

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


Oh, I'll just add some functionality to these buttons, I said.  It'll just be a few chunks of code, no big deal, I said.

Hah.  Turns out I've had to create a whole bunch of interlocking systems of code.  I've had to add the idea of Events, which are pieces of code that don't get run immediately, but await some trigger condition.  Not all Events can be armed at one time, there's just too many.  Instead I need to have an Active Trigger list.  A trigger can be a countdown timer or some combination of AND and OR bitmasks for Flag bytes.  This active trigger list is checked every time the clock display updates.  If a trigger is pulled, then what follows that trigger in the list is an address in RAM of the event to take place, and that address is pushed to another list of Triggered Events, and an event handler routine later just runs all the subroutines in the Triggered Event list.

So basically the "few chunks of code" I'm needing to write is actually most of the rest of the game engine.

Even just putting text in that message window on the right raises the question: what text exactly? After writing out a bunch of messages and stuff for the newsfeed, it quickly became apparent that I was going to run out of room just for the text data.  I've had to do some sneaky compression techniques.  Some of the less-common words are spelled out, but the most common 1, 2, 3, and a few 4-character words (128 total) are represented by codes 60-BF and E0-FF, and another list of 256 (well, about 210 of these so far) words 4 or more characters long is represented by two bytes ($10 and the index of the word).  I have a vocabulary list stored in VRAM that's about 2.5kb, and 768 index bytes in low RAM pointing to these 384 words in VRAM.   My resulting compression ratio is about 3:1 right now, but I expect that to get better as I write more text and reuse these vocabulary words.

As I've been setting all of that code up, I've also been doing a few more things like touching up some sprites and the font and adding the population display on the bottom left side of the screen.  Here's what it looks like now:

progressSept9.jpg.19c41f978787b85d104d096e53c58b95.jpg

Snickers11001001
Posts: 140
Joined: Wed Jan 20, 2021 6:43 pm

new game: Asteroid Commander

Post by Snickers11001001 »


I'm glad you're still working on this.    I don't care what happens with the X8/X16 thing/release.    I will play this game on the emulator you specify if that's all that's available.     Looks cool and its still really neat to watch someone move a project along like this in sorta real time.   

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »



3 hours ago, Snickers11001001 said:




I'm glad you're still working on this.    I don't care what happens with the X8/X16 thing/release.    I will play this game on the emulator you specify if that's all that's available.     Looks cool and its still really neat to watch someone move a project along like this in sorta real time.   



Yeah, I'm going to finish this even if emulation is the only way to play it. And if it works on x16, then I'll be able to port it to other systems too.

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


sept26.jpg.a34867372b4d6b2f51e53387180d04f9.jpg

So this was a minor triumph.  Messages are stored as compressed text, with common words in a vocabulary represented by only one or two bytes.  This is parsed into a buffer and then divided up into lines of text.

You'll notice a couple of different fonts here.  The letters UTC after the time are on two tiles on layer 1.  All the other text is on layer 0.  The first 64 tiles on layer 0 are letters, numbers, and punctuation. 

The ellipses at the bottom of the message window is tile $80, and there's six tiles for the local area name and another six for degrees latitude, degrees North, degrees South, degrees longitude, degrees East, and degrees West, and those 12 tiles are also in that $81-8F range.  I've reserved 3 tiles for future use in that $80-8F range as well.  

That leaves tiles $40-7F for the newsfeed (currently just lorem ipsum) and $90-FF for the message window.  Each of these tiles has two characters in a tiny font. This font is only 64 characters and is stored in low RAM, and I have a subroutine that takes the left character value in X, the right character value in Y, and the tile number in A, and it creates the 8 bytes for the combined tile and pushes that to the tile data in VERA. The tile map for the newsfeed is static, except for the color information.  The tiles themselves are updated every time the newsfeed scrolls one character to the left.

For the message window, that's 10 tiles wide and 15 tiles tall.  With the scrollbar on taking up the rightmost column, that leaves 135 tiles.  But, I only have 112 tiles to work with for that window.  So, as each line is being displayed the tile map in that window is being updated line by line, padding with spaces on the right.  Even so, it sometimes runs out of tiles for the display, hence the ellipsis tile.

Clicking on the up and down arrows moves the index of the item (line number) at the top of the list to change, and the message is redrawn.  I can't click and drag on the scrollbar - yet - but I think that might be possible.

It isn't just a message window.  That same window is also used to display a message archive (sort of like an email inbox), and the main Build window (which allows selection between Life Support, Infrastructure, and Production), and then each of the Build categories will have a list that you can scroll through and select the building you want.  This window will also be used for the stock market and the local info window.  There's a lot of different things that can go in there, a lot of potential mouse click hot spots, not all of which are active at once.  So I had to set up all the code structure to do things like place a tile map in that window on the fly.

I've also added Events and Triggers.  Events are subroutines that are not executed each main loop, but are intermittent or one-time-only or delayed.  For the main loop to know when to execute those events, they need to be triggered. A trigger takes one of two forms here.  First is a Timer trigger.  This is a four byte data structure.  The first two bytes are a countdown time, decremented each time the game clock updates.  The next two bytes are either the address of an event, or if the "high byte" is zero then the "low byte" is an index to a list of events.  So, when the timer reaches FFFF, the associated event is pushed onto an event list and the trigger is removed from the timer trigger list.  Later the main program looks at the length of the event list, and if non zero executes all the events in the list, simply calling all the addresses listed.

The other type of trigger is a Flag trigger.  This is a five byte structure.  The first byte is a zero page address, the second is an AND mask, the third is an OR mask, and the last two bytes are again the event address or index.  For this type of trigger the byte is loaded from the zero page address into the accumulator and ANDed with the AND mask.  If the result is the same as the AND mask, then the zero page byte is loaded into the accumulator again and ORed with the OR mask.  If the result is the same as the OR mask, then the event is put onto the event list and the trigger removed from the flag trigger list.  This can be used to look at a single bit or all 8 bits of the byte.  Any bit values that must be 1 are set to 1 in the AND mask, any bits that must be 0 are set to 0 in the OR mask, and any bits that are Don't Care are set to 0 in the AND mask and 1 in the OR mask.  If the AND mask and the OR mask are the same, then this trigger will only fire when all 8 bits of the zero page byte are the same value as the masks.  Unlike the timer triggers, the flag triggers are all checked each time the program cycles through the main loop.

So I have three dynamic lists: two lists of triggers and a list of events called by these triggers.  The events are just subroutines, which can themselves push other triggers onto the trigger lists.  So by using the timers and flag triggers I can have events that occur some time in the future.

An example of this is something I did to the cursor.  It's a 4bpp sprite, and its default palette index is 1.  When the mouse button is pushed now, I change the palette index to 3, making it blue.  Then a flag trigger is pushed to the list, looking at the zero page value where I'm storing the value of the mouse button.  Both the AND and OR mask are zero, and the event called just changes the palette index back to 1.  So now, when you click the mouse it turns blue and when you release it it goes back to black and white.

My next step is getting the Bulldoze working and the Build secondary menus. I've also figured out a way for the user to click anywhere on the asteroid image and the asteroid will rotate and snap to that spot; I just haven't coded that part yet, as it's about 4th on the to-do list.  Bulldoze and Build shouldn't be as difficult as this window was, so my next update will a little sooner.

Ed Minchau
Posts: 508
Joined: Sat Jul 11, 2020 3:30 pm

new game: Asteroid Commander

Post by Ed Minchau »


Test

Post Reply