![sept26.jpg.a34867372b4d6b2f51e53387180d04f9.jpg](<___base_url___>/applications/core/interface/js/spacer.png)
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.