== Tilemaps ==
+
== The problem ==
   −
=== The problem ===
+
=== The need for speed ===
    
Early games needed fast screens full of action.  One obvious way to do this is to simply have a [[framebuffer]] representing the image, and the CPU performs animation by updating the framebuffer.  Early CPU-controlled games like Space Invaders did just that.  However, you'll notice that games on that hardware typically didn't do much drawing per frame, and in Space Invaders when the whole armada is moving it's noticably sluggish.  Simple math reveals why: these systems used 8-bit CPUs at typically 1 or 2 MHz.  If you assume an average 320x240 resolution, even at Space Invaders' 1 bit per pixel, there are (320 * 240)/8 = 9600 bytes of RAM in the framebuffer to update.  Assuming a highly idealized rate of updating 1 byte every 2 cycles, that means you need to be running at least 1.2 MHz just to update the screen at 60 frames per second.  And that's not including AI, sound, and other game logic.
 
Early games needed fast screens full of action.  One obvious way to do this is to simply have a [[framebuffer]] representing the image, and the CPU performs animation by updating the framebuffer.  Early CPU-controlled games like Space Invaders did just that.  However, you'll notice that games on that hardware typically didn't do much drawing per frame, and in Space Invaders when the whole armada is moving it's noticably sluggish.  Simple math reveals why: these systems used 8-bit CPUs at typically 1 or 2 MHz.  If you assume an average 320x240 resolution, even at Space Invaders' 1 bit per pixel, there are (320 * 240)/8 = 9600 bytes of RAM in the framebuffer to update.  Assuming a highly idealized rate of updating 1 byte every 2 cycles, that means you need to be running at least 1.2 MHz just to update the screen at 60 frames per second.  And that's not including AI, sound, and other game logic.
 
This got worse when color was introduced: suddenly that 9600 bytes becomes 19200 bytes for 4 colors or 38400 bytes for 16 colors, with corresponding CPU requirements increasing to 2.3 and 4.6 MHz, which starts to be out of the reach of affordable early 80s microprocessors.
 
This got worse when color was introduced: suddenly that 9600 bytes becomes 19200 bytes for 4 colors or 38400 bytes for 16 colors, with corresponding CPU requirements increasing to 2.3 and 4.6 MHz, which starts to be out of the reach of affordable early 80s microprocessors.
  
( ! ) Fatal error: Uncaught TypeError: MWExceptionHandler::rollbackMasterChangesAndLog(): Argument #1 ($e) must be of type Exception, Error given, called in /home/mamedev/wiki.mamedev.org/public_html/includes/exception/MWExceptionHandler.php on line 137 and defined in /home/mamedev/wiki.mamedev.org/public_html/includes/exception/MWExceptionHandler.php on line 111
( ! ) TypeError: MWExceptionHandler::rollbackMasterChangesAndLog(): Argument #1 ($e) must be of type Exception, Error given, called in /home/mamedev/wiki.mamedev.org/public_html/includes/exception/MWExceptionHandler.php on line 137 in /home/mamedev/wiki.mamedev.org/public_html/includes/exception/MWExceptionHandler.php on line 111
Call Stack
#TimeMemoryFunctionLocation
10.08992769856MWExceptionHandler::handle( $e = class Error { protected $message = 'Call to undefined function each()'; private $string = ''; protected $code = 0; protected $file = '/home/mamedev/wiki.mamedev.org/public_html/includes/diff/DairikiDiff.php'; protected $line = 436; private array $trace = [0 => [...], 1 => [...], 2 => [...], 3 => [...], 4 => [...], 5 => [...], 6 => [...], 7 => [...], 8 => [...], 9 => [...], 10 => [...], 11 => [...], 12 => [...], 13 => [...], 14 => [...], 15 => [...], 16 => [...], 17 => [...], 18 => [...], 19 => [...], 20 => [...], 21 => [...], 22 => [...]]; private ?Throwable $previous = NULL; public $xdebug_message = '<tr><th align=\'left\' bgcolor=\'#f57900\' colspan="5"><span style=\'background-color: #cc0000; color: #fce94f; font-size: x-large;\'>( ! )</span> Error: Call to undefined function each() in /home/mamedev/wiki.mamedev.org/public_html/includes/diff/DairikiDiff.php on line <i>436</i></th></tr>\n<tr><th align=\'left\' bgcolor=\'#e9b96e\' colspan=\'5\'>Call Stack</th></tr>\n<tr><th align=\'center\' bgcolor=\'#eeeeec\'>#</th><th align=\'left\' bgcolor=\'#eeeeec\'>Time</th><th align=\'left\' bgcolor=\'#eeeeec\'>M' } ).../MWExceptionHandler.php:0
20.08992769888MWExceptionHandler::rollbackMasterChangesAndLog( $e = class Error { protected $message = 'Call to undefined function each()'; private $string = ''; protected $code = 0; protected $file = '/home/mamedev/wiki.mamedev.org/public_html/includes/diff/DairikiDiff.php'; protected $line = 436; private array $trace = [0 => [...], 1 => [...], 2 => [...], 3 => [...], 4 => [...], 5 => [...], 6 => [...], 7 => [...], 8 => [...], 9 => [...], 10 => [...], 11 => [...], 12 => [...], 13 => [...], 14 => [...], 15 => [...], 16 => [...], 17 => [...], 18 => [...], 19 => [...], 20 => [...], 21 => [...], 22 => [...]]; private ?Throwable $previous = NULL; public $xdebug_message = '<tr><th align=\'left\' bgcolor=\'#f57900\' colspan="5"><span style=\'background-color: #cc0000; color: #fce94f; font-size: x-large;\'>( ! )</span> Error: Call to undefined function each() in /home/mamedev/wiki.mamedev.org/public_html/includes/diff/DairikiDiff.php on line <i>436</i></th></tr>\n<tr><th align=\'left\' bgcolor=\'#e9b96e\' colspan=\'5\'>Call Stack</th></tr>\n<tr><th align=\'center\' bgcolor=\'#eeeeec\'>#</th><th align=\'left\' bgcolor=\'#eeeeec\'>Time</th><th align=\'left\' bgcolor=\'#eeeeec\'>M' } ).../MWExceptionHandler.php:137