So I’m working on the physics part of the engine now. I think I’ve figured out how to handle the collision information. The tables background image will be 16bpp (correction 4bpp, for 16-colors) and I think I may have figured out how to allow both styles of table dimensions to work without imposing hard limits (ie. one table could be 160px wide with a 60px side area, another could choose 156px wide for a 64px side area, another could be 220px wide and 160px tall for 16px on the top/bottom or 8px on both, and yet another table could do 220x168px and only have an 8px portion at the top/bottom for score/other display, even then a table could also use the full 220x176 resolution and have the score and other information overlaid on top of the table and scroll with the table or stay in one spot on screen).
Table collision data will be broken up into 32x32x8bpp pixel chunks (1024 bytes). The collision data would be streamed from the SD cart based on the ball’s current coordinates and would stream a new 1024 byte buffer when the ball moves outside the current buffer. The angle of impact represents the angle of the normal that the balls trajectory get’s reflected across (this way it doesn’t matter what direction/velocity the ball is traveling when colliding with that pixel). The second byte could be dropped in favor of sensors/triggers being lines/circles/bboxes, though they could also be smaller collision maps that overlay the normal collision map (flippers will be handled in this way as described below).
For the flippers I’ll need 4 8bpp images.
- Flipper is in the raised position (button held) and the ball collides with it much like a wall (possibly with a bounce factor).
- Flipper is in the down position (button released) and again the ball collides with it much like a wall.
- Flipper is transitioning from the down position to the up position and the ball is somewhere in it’s path (velocity of flipper can be stored as a single value and applied to the actual angle of impact).
- Flipper is transitioning from the up position to the down position and the ball is somewhere in it’s path (treated the same as the 3rd image).
I would like to provide graphics and collision maps for default small, medium, and large flippers in flash that tables can use (changing the appropriate pallet colors to customize the flipper’s color), while also providing table’s the ability to override the sprite, collision map, or both at the cost of less space for other graphics/logic (allows tables to balance themselves according to what the designer would like to do).
I’ve got a working prototype of a ball moving at constant velocity up and down the table vertically (reversing direction when it reaches the table edge) which is able to stream the table’s background at about 27FPS if the whole table needs updating, otherwise it flags specific scanlines to be redrawn based on objects movements/animations and with just a ball moving around maxes out at 333FPS when it’s only updating the balls old location and new location (with some overlap).
On the physics side of things I’m having the physics engine perform constant 5ms steps (200 steps/second) and each frame it simply steps the physics engine until the previous time catches up with the current time. Will need to see what impact this has in the final frame rate once collision is being processed (currently a max speed of 1px/step, which is 200px/s, seems like a good terminal velocity for the ball, otherwise the ball moves so fast that it’s nigh impossible for the user to keep up with it’s movement even if it got a smooth 60 FPS).
The collision info will also be layered so that you can have ramps leading to an upper portion of the table with rails going over a lower portion. To achieve this the ball will be treated as a normal sprite and can move up or down in the list of sprites to render (thus going above/below individual sprites), with a separate pointer to the ball sprite so the physics engine can update it’s location.
Tables can have more complex sprites (think the Mewtwo bonus stage of Pokemon Pinball) that use collision maps overlaid on top of the tables collision map (allowing them to be moving targets). However, to decrease the size of basic table lights they’ll store a single palette index for their color (allowing lights to change color by changing the color in the palette) and would store their pixel data in horizontal RLE-encoded lines. The encoding would use 1-byte per off-on segment (ie. off-off-on-on-on would be stored as 0x23), and if a section has more than 15 off/on segments in a row then there would be a 0 in between them (ex. 4 pixels off followed by 20 pixels on would result in 0x4F, 0x05). This is best suited as the rendering is done one scanline at a time. If there’s enough space left in FLASH there will be a set of default lights provided as well. These would be commonly used shapes like circles, squares, and arrows, as well as circles with each letter in them (most likely as 8x8 images). The worst possible compression of the RLE would encode an 8x8 light in 32 bytes (equivalent of a 16-color image as opposed to 8 bytes as a 1bpp image), however this compression also offers performance improvements when drawing is done in scanlines.
For the memory layout the engine will allocate a large chunk of RAM as a static array which will be used to store all the currently needed information for a table (ie. sprite graphics, lights, collision maps, table logic, etc). However, through the event system tables can swap out sprites so they only have to load the ones currently being used. The editor will take the table’s designs (collision shapes, sprites, logic, and everything else) and compile it to a single file that the engine can load from the SD card. This has the added benefit of non-programmers being able to design their own custom tables with a, more or less, basic logic event system.
The events themselves will be functions in FLASH that get called and would use 1 byte to store the event type (allows for 255 different functions) ranging from basic math operations (addition, subtraction, etc) on variables, toggling switches, changing palette colors, and many more things to be determined later when I start work on the first actual table.
This has been a very lengthy documentation of the core concepts I’ve worked out so far. Stay tuned for more info as it develops. Be sure to set the tracking status of this topic to “Watching” if you want to be notified of any updates as things progress. Trying to document everything here because if things go smoothly and I can get this done in a decent amount of time with a finished table then this has the makings of a great article for the second magazine (Trials and Tribulations: The Development of a Pinball Engine for the Pokitto)