Jump to content

Recommended Posts

  • 3 months later...

Quick update: Most of my time on this project lately has focused on fixing previously undiscovered bugs as well as streamlining some of the existing code, It's amazing how much a thorough review of the old code uncovers...

The good news is that I now have a solid bug-free base to add to, which I plan to do starting tonight. To be honest, the complexity of this project is staggering, and I'm trying to take on only small sections at a time so as not to get discouraged. While it's unlikely as things stand that I will have a finished game by Faire time, I will however likely be able to have a more advanced demo to present.

I have tried to be disciplined and dedicate an hour each evening on this, but unfortunately I get sucked in every time without fail, and last night I forced myself to go to bed at 1 am after starting at 9pm. I need coffee :P

  • Like 1
  • 1 month later...

Unit drifting code added.

Drifting of a unit is one possible outcome of combat, where the affected unit is disabled for up to 3 turns, and during that time drifts randomly. This situation creates interesting tactical situations because a drifting unit which collides with other units could potentially destroy them depending on the types of units colliding. In other words, targeting say a large cruiser which is surrounded by a protective fighter shield could wreak havoc with that convoy through successive collisions with the fighters during the drifting turns. Furthermore, a unit which drifts onto the planetary surface will destroy any unit found at the point of impact as well as itself. Fun :)

I also added code for frame centering in order to keep the drifting units around the middle of the play field frame. This will also be helpful for displaying combats as they occur across the entire field with the frame automatically scrolling around to center around each combat zone.

  • Like 1

It was snowing all day in Chicago today, so it was the perfect opportunity to just relax and work on this project. As it turned out, my frame centering routine worked fine in most situations, but missed some special cases. This was actually bad enough that I had to rewrite the whole damn thing from scratch! As it stands right now, it identifies in which of the 4 game field quadrants the unit of interest is located and snaps the frame window to it, then it goes on to fine tune the frame position depending on how close the unit is to the edges of the frame. As a reminder, the game field consists of 4 equal quadrants arranged in a large square with each quadrant being a full bitmap screen, and the frame window moves around within that larger field and displays only what is visible within its boundaries.

 

On a side note, whenever I code, I replace my usual Alienware gaming keyboard with a fantastic made to order Unicomp keyboard which is a faithful clone of the classic IBM "clicky" keyboard of old. These keyboards just had the perfect tactile and audible feedback, and Unicomp is currently licensing the reproduction rights from the entire line of IBM keyboards and builds these to order (http://www.pckeyboard.com/). I have the Classic 104 model, but they have a large variety of models to choose from for around $80. Given that these keyboards have absolutely no frills, they are a bit pricey, but once you start using them, there is no going back... And I should add that they are huge and hefty (mine is 4.8 lbs).

 

gallery_25753_1039_350662.jpg

Edited by Vorticon
  • Like 1
  • 1 year later...

For some reason I started thinking about this beast of a game again as I pondered what kind of project I wanted to do next, and it hit me that I was never really satisfied with my map scrolling scheme.

To recap, the game World consists of 4 bitmap screens arranged in a square. The background hex field is static, and all screen elements are stored in a large master table which also includes other identifiers and game data for each element such as world coordinates, ID, movement potential and such. There is a View window equivalent to a single bitmap screen which can be moved around the World via keyboard commands, either a full bitmap screen or 2 hexes at a time. So scrolling is simply achieved by updating the contents of the view window on the fly, and this done by first erasing all the current screen elements except the background hex grid, then going through the master table, finding out which screen elements' World coordinates are actually visible in the View window, and drawing them on screen. Because the master table is quite large, and all screen elements have to be drawn pixel by pixel, this is still a rather slow process (about 2 seconds) even at assembly speed.

 

So my question here is: are there any other faster options for me out there? I am not aware of any TI game out there which uses a scrolling bitmap screen to use for inspiration. Storing full bit map screens in RAM is not possible given that each will eat up over 6K (PDT only), and storing on disk will be just as slow if not slower...

I do have a SAMS card, but I have resisted using it because this would preclude running the game on real hardware for the vast majority of TIers. It is tempting though, but will it be much faster? I could store the starting World (4 bitmap screen) sequentially, and as individual screen elements move, I will have to update that map on the fly which will mean erasing the screen element and redrawing it at its new location, and this will have to be done twice, both on screen and in the SAMS card RAM space. Furthermore, for simple scrolling, if the View window straddles bitmap screens which are not contiguous in RAM, then this introduces additional computational complications. Add to that the fact that the SAMS card is subdivided into 4K RAM sections and we end up with a lot of computational overhead...

 

Any thoughts?

Only a couple of things come to mind, and I don't know how feasible they are in your engine.

 

One is to throw away that erase phase and just repaint the ENTIRE screen - either include the hex grid in your update, or erase the screen by drawing the hex grid from scratch (rather than erasing each independent object). Since this might be a dumb, blind copy, it may be faster.

 

The other is to treat your objects as bytes instead of pixels, and update at least entire bytes at a time. If you need to get pixel accurate placement, you can shift your byte inside a 16-bit word pretty cheaply and just write both bytes.

 

While drawing a single object, don't keep recalculating the address on the screen. Once you have the address of the first byte, you can use addition to get around more quickly. the byte below is address+1, the byte to the right is address+8. There is a gotcha with the byte below if you are not working with character boundaries, you need to check for that and add a larger value. (So at that point it might be simpler to recalculate the address for rows and draw all horizontal bytes at a time).

 

The big one with VDP access is Read/Modify/Write, which I assume you are doing. Since the Read and Write step each require two additional writes to VDP to set the address, it's best to minimize how often you do that. For instance, if you are going to update a 16x16 pixel object, it may be faster to read the relevant VDP bytes into a small CPU buffer, merge the pixels (or bytes!) there, and then write the entire block back to VDP, than to work on one byte at a time.

Maybe things have been mentioned before etc. ;)

 

To recap, the game World consists of 4 bitmap screens arranged in a square. The background hex field is static, and all screen elements are stored in a large master table which also includes other identifiers and game data for each element such as world coordinates, ID, movement potential and such. There is a View window equivalent to a single bitmap screen which can be moved around the World via keyboard commands, either a full bitmap screen or 2 hexes at a time.

UP1.GIF

 

Now, as you mention "4 bitmap screens" and the "SAMS", I get the impression that you may want to try and store the actually bitmaps in memory. And, on its own, this technique is probably the easiest and fastest way to scroll around the game world.

 

If we assume true bitmap (or as close as we get) where the SIT (Screen Image Table) is initialized once and for all (forget about the status area for now), then the patterns and colors take up 12K. 4 bitmap screens in memory would take 4 * 12K = 48K. Either way this would have to be chopped up (32K is our max), slightly compromising the benefits of the technique.

 

Scrolling in games and applications have been done using buffers (like the above) and data areas (held in memory or other devices), but of course also sometimes using hardware (the Amiga could easily do that (scroll the screen updating only one register)).

 

I would redraw the visual bitmap (the one on screen) based on data - as I think you already do. Like the principle of only storing the byte 65 in memory to represent the letter A, instead of storing the bitmap patterns and colors for the letter A - also in memory for later retrieval. And doing it for all the letters A in your text.

 

I could be mistaking, but I hope your "large master table" is less than 48K. And that it's held in CPU memory at all times ?

 

So scrolling is simply achieved by updating the contents of the view window on the fly, and this done by first erasing all the current screen elements except the background hex grid, then going through the master table, finding out which screen elements' World coordinates are actually visible in the View window, and drawing them on screen.

So you're already doing the redraw based on data (not scrolling the screen based on stored bitmaps).

 

I wouldn't try and preserve the background hex grid, but simply make the grid part of the redraw. Again, the redraw includes an initial clear.

 

Doing it to a buffer in CPU RAM, to get that more instant screen update, or doing it directly to VDP is a matter of taste. Visually you could argue that the first is more pleasing. If you don't have the CPU RAM to spare, then consider not using a buffer.

 

Because the master table is quite large, and all screen elements have to be drawn pixel by pixel, this is still a rather slow process (about 2 seconds) even at assembly speed.

2 seconds is 120 frames. I'm actually hoping you are drawing pixel by pixel.

 

Looking at the screen layout I suspect that things are actually not byte aligned - at least horizontally. Is the hex size 18 by 12 pixels ?

 

I would redesign the screen layout/representation so that things become byte aligned. To me it looks feasible without sacrificing too much. I suggest going for 16 by 12 pixels or 24 by 12.

 

Your master table may be complex in design, it may even be a linked hierarchy of different objects, but I guess the logic for updating the table should be the complex part, and drawing the screen from the master table should be the "easier" part. Consider maybe a slight redesign or even extending the master table to make drawing easier.

 

:)

Edited by sometimes99er
  • Like 3

I'm with sometimes99er, you should probably try to align your hex grid on character boundaries. Then, you can presumably store the patterns in VRAM and redraw by simply updating the nametable. You would be able to do nice character-based scrolling, hex-based scrolling or zelda-style screen scrolling.

 

I wanted to see what it would look like, and granted it isn't as dense and elegant as your original, but it would still be usable enough and would probably be smoother/nicer to play. You'd also neatly avoid any color clash with your tiles :).

 

post-33891-0-54651200-1432116551_thumb.png

Thanks for all the feedback guys :)

 

 

One is to throw away that erase phase and just repaint the ENTIRE screen - either include the hex grid in your update, or erase the screen by drawing the hex grid from scratch (rather than erasing each independent object). Since this might be a dumb, blind copy, it may be faster.

 

The other is to treat your objects as bytes instead of pixels, and update at least entire bytes at a time. If you need to get pixel accurate placement, you can shift your byte inside a 16-bit word pretty cheaply and just write both bytes.

 

Each screen element is already defined as bytes in a character definition table, 8 bytes per character. What I do is calculate the starting location of the first byte on the screen and plot it pixel by pixel, move down one row and repeat x8. While the elements do not fall on character boundaries, I believe however that the offset from from any boundary will be fixed for all since the field is a hex grid with static proportions. What I could do is recreate my character definition table with 2 bytes for each character row instead of 1 and simply AND it with the corresponding 2 bytes in the PDP. Interesting idea!

 

 

 

If you have room I would write the whole viewport to a CPU RAM buffer first and then send it to the VDP in a single loop. The latter should take 100ms max.

 

Frankly I'm not sure how much more memory the game will need as I still have to write the AI and a slew of other ancillary routines. I doubt I will have the needed space for a viewport buffer in RAM unfortunately...

 

 

Maybe things have been mentioned before etc. ;)


Now, as you mention "4 bitmap screens" and the "SAMS", I get the impression that you may want to try and store the actually bitmaps in memory. And, on its own, this technique is probably the easiest and fastest way to scroll around the game world.

 

Yup!

If we assume true bitmap (or as close as we get) where the SIT (Screen Image Table) is initialized once and for all (forget about the status area for now), then the patterns and colors take up 12K. 4 bitmap screens in memory would take 4 * 12K = 48K. Either way this would have to be chopped up (32K is our max), slightly compromising the benefits of the technique.

 

Hence the thought of using the SAMS RAM space...

I could be mistaking, but I hope your "large master table" is less than 48K. And that it's held in CPU memory at all times ?

 

The master table is just a hair over 2K, and yes it is held in RAM at all times.


I wouldn't try and preserve the background hex grid, but simply make the grid part of the redraw. Again, the redraw includes an initial clear.

 

I had initially thought of that when designing the game, but since I am drawing the screen based on data, that will not work unless I include in the master table the screen elements for the hex grid which would be costly memory wise and will have to be interlaced with the screen elements.


2 seconds is 120 frames. I'm actually hoping you are drawing pixel by pixel.

 

It's actually probably closer to a 1.5 seconds :) Yes, pixel drawing is incredibly time consuming... But Tursi's suggestion above may be feasible and possibly shave off a non-trivial portion of that delay.

Looking at the screen layout I suspect that things are actually not byte aligned - at least horizontally. Is the hex size 18 by 12 pixels ?

 

Each hex side is 7 pixels long. The offset is 12 pixels to move up/down one hex, and a combination of 12 and 6 pixels to move diagonally. I didn't make it easy on myself, didn't I :D

I would redesign the screen layout/representation so that things become byte aligned. To me it looks feasible without sacrificing too much. I suggest going for 16 by 12 pixels or 24 by 12.

 

Yes, that is an option, but then I would need more bitmap screens to cover the entire field and thus more scrolling and a narrower field of view. In a wargame, having as much of a tactical view of the battlefield as possible is important. I have played some computer wargames on the Apple IIe and the Commodore 64 in the past, and I always found the small visible field a huge annoyance when trying to grasp the tactical situation.

Your master table may be complex in design, it may even be a linked hierarchy of different objects, but I guess the logic for updating the table should be the complex part, and drawing the screen from the master table should be the "easier" part. Consider maybe a slight redesign or even extending the master table to make drawing easier.

 

The master table does link to only one other table, which is the character definitions table. It's really not that complex:

 

ID,X(global),Y(global), character def table offset, color, base movement, remaining movement. Each row is 10 bytes. There are of course several other unlinked tables dealing with other aspects of the units.

 

 

I'm with sometimes99er, you should probably try to align your hex grid on character boundaries. Then, you can presumably store the patterns in VRAM and redraw by simply updating the nametable. You would be able to do nice character-based scrolling, hex-based scrolling or zelda-style screen scrolling.

 

I wanted to see what it would look like, and granted it isn't as dense and elegant as your original, but it would still be usable enough and would probably be smoother/nicer to play. You'd also neatly avoid any color clash with your tiles :).

 

attachicon.gifultimateplanet.png

 

It's nice to see how it would look with alignment with the character boundaries :) How did you do that? But see my response above as to why I prefer not to go that route.

Yep. If you'd be willing to sacrifice a bit on the number of cells on screen, then you might even go for ordinary graphic mode. No color clashes. The game world excluding status would maybe take 4-6K of CPU RAM and you'd "simply" have to "dump" well below 1K per move.

ultimate.planet.png

I need to take a closer look at Magellan one day...

Unfortunately, I really don't want to reduce the visible field as I feel it would take away from the tactical aspects of the game. I do agree though that it's definitely neater without color clashes.

I'm going to give Tursi's suggestion a try and see if I can pull it off. More to come.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...