<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dreamcast.wiki/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cooljerk</id>
	<title>dreamcast.wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://dreamcast.wiki/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Cooljerk"/>
	<link rel="alternate" type="text/html" href="https://dreamcast.wiki/Special:Contributions/Cooljerk"/>
	<updated>2026-05-12T22:14:14Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Twiddling&amp;diff=3783</id>
		<title>Twiddling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Twiddling&amp;diff=3783"/>
		<updated>2025-07-18T12:53:49Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Idea ==&lt;br /&gt;
How to generated the twiddled index from an untwiddled texture:&lt;br /&gt;
&lt;br /&gt;
 Original:        Twiddled:&lt;br /&gt;
 &lt;br /&gt;
 0 1 2 3          0 2 8 A&lt;br /&gt;
 4 5 6 7          1 3 9 B&lt;br /&gt;
 8 9 A B          4 6 C E&lt;br /&gt;
 C D E F          5 7 D F&lt;br /&gt;
 G H I J          G I O Q&lt;br /&gt;
 K L M N          H J P R&lt;br /&gt;
 O P Q R          K M S U&lt;br /&gt;
 S T U V          L N T V&lt;br /&gt;
 W X Y Z          W Y % &amp;amp;&lt;br /&gt;
 ~ ! # $          X Z ^ *&lt;br /&gt;
 % ^ &amp;amp; *          ~ # ( _&lt;br /&gt;
 ( ) _ +          ! $ ) +&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The matching characters between the two images represent the same pixel, just relocated. These images would be 4 * 12 pixel images, but the steps work for any valid &#039;&#039;&#039;2^x * 2^&#039;&#039;&#039;y sizes, where x and y are whole numbers.&lt;br /&gt;
&lt;br /&gt;
Now lets say we want to find the twiddled index of the untwiddled &#039;&#039;&#039;&amp;quot;O&amp;quot;&#039;&#039;&#039; pixel (index 24). By hand we can work it out and tell the twiddle index should be &amp;quot;18&amp;quot;, but what algorithm/logic can we use to find this automatically for any &#039;&#039;&#039;i&#039;&#039;&#039;?&lt;br /&gt;
&lt;br /&gt;
Here are my steps:&lt;br /&gt;
* We first need to start by figuring out the &amp;quot;Biggest-Order Inverted-N&amp;quot; (&#039;&#039;&#039;BOIN&#039;&#039;&#039;) that fits in this image.&lt;br /&gt;
* Now if our starting image was a square, then the BOIN is the same size as the image&lt;br /&gt;
* For rectangles like this, we have to find the smallest side first (width) then our BOIN is width * width&lt;br /&gt;
* If we start off with a rectangle, then we need to do an extra step that squares can skip.&lt;br /&gt;
* Notice how we can completely encapsulate the whole image with &#039;&#039;&#039;(bigger_side / smaller_side) == 3&#039;&#039;&#039; BOINs? Our first step is to determine which of these BOINs our index &#039;&#039;&#039;i&#039;&#039;&#039; belongs in.&lt;br /&gt;
* We can take advantage of a quirk I mentioned earlier. Notice how the first BOIN contains the first 1/3 of the original pixels, the 2nd BOIN contains the next 1/3 and the 3rd BOIN contains the last 1/3.&lt;br /&gt;
* Therefore using the formula &#039;&#039;&#039;k = floor(i / (BOIN area == 4 * 4 = 16)) == 1&#039;&#039;&#039; we can determine that our twiddled index is somewhere in the middle/2nd BOIN (Since &#039;&#039;&#039;k&#039;&#039;&#039; is of the set &#039;&#039;&#039;{0,1,2}&#039;&#039;&#039;)&lt;br /&gt;
* Note the index where our BOIN starts according to the original texture. The first index in the 2nd BOIN is &amp;quot;16&amp;quot;. Keep track of this value, lets call it &#039;&#039;&#039;d&#039;&#039;&#039;&lt;br /&gt;
* Also keep track of the index where our BOIN starts according to the twiddled texture, this is also &#039;&#039;&#039;16&#039;&#039;&#039; in this case. Lets add this to a running sum &#039;&#039;&#039;s&#039;&#039;&#039;&lt;br /&gt;
* Forget about the other two BOINs and subtract &#039;&#039;&#039;d&#039;&#039;&#039; from the indexes in our new BOIN as well as &#039;&#039;&#039;i&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So now we have:&lt;br /&gt;
&lt;br /&gt;
 i == 8&lt;br /&gt;
 0 2 8 A&lt;br /&gt;
 1 3 9 B&lt;br /&gt;
 4 6 C E&lt;br /&gt;
 5 7 D F&lt;br /&gt;
&lt;br /&gt;
Great! We can already see by hand that this still looks right, but how do we automatically solve square BOINs?&lt;br /&gt;
* In order to solve a square BOIN, we need to determine what quadrant our pixel is in&lt;br /&gt;
* So we determine how many pixels are in each quadrant (4 per quadrant here, &#039;&#039;&#039;== a&#039;&#039;&#039;), Then calculate &#039;&#039;&#039;k = floor(i / a) == 2&#039;&#039;&#039; to know its in the 3rd quadrant (&#039;&#039;&#039;k&#039;&#039;&#039; is in the set &#039;&#039;&#039;{0,1,2,3}&#039;&#039;&#039;).&lt;br /&gt;
* That means its in the top right. So we need to set &#039;&#039;&#039;d = a * k&#039;&#039;&#039;), add our new &#039;&#039;&#039;s&#039;&#039;&#039; value to the running sum, discard the other quadrants, then subtract &#039;&#039;&#039;i&#039;&#039;&#039; and the new BOIN&#039;s indexes by &#039;&#039;&#039;d&#039;&#039;&#039;&lt;br /&gt;
* The easy way to calculate the new part of &#039;&#039;&#039;s&#039;&#039;&#039; is that:&lt;br /&gt;
** top left quadrant is &#039;&#039;&#039;0&#039;&#039;&#039;&lt;br /&gt;
** top right quad is &#039;&#039;&#039;BOIN-width / 2&#039;&#039;&#039;&lt;br /&gt;
** bottom left is &#039;&#039;&#039;BOIN-width * (BOIN-height / 2)&#039;&#039;&#039;&lt;br /&gt;
** bottom right is &#039;&#039;&#039;(BOIN-width * (BOIN-height / 2)) + (BOIN-width / 2)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Now we have:&lt;br /&gt;
&lt;br /&gt;
 i == 0&lt;br /&gt;
 0 2&lt;br /&gt;
 1 3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You would repeat until we have a single pixel. Once we have the last pixel, our new twiddled index should be the running sum &#039;&#039;&#039;s&#039;&#039;&#039; (16 + 2 + 0 == 18)&lt;br /&gt;
&lt;br /&gt;
== DISCLAIMER ==&lt;br /&gt;
&lt;br /&gt;
This theorized solution has only been tested on a few examples by hand, so I might have missed something. But I believe at least the general logic of this is sound. Also note for implementation, some of the divisions could be replaced with bit-shifting since some of those numbers are guaranteed to be powers of 2.&lt;br /&gt;
&lt;br /&gt;
For an example of an algorithm that does the reverse (Convert twiddled index to untwiddled), you can refer to [https://github.com/Protofall/Crayon-Utilities/blob/master/DtexToRGBA8888/DtexToRGBA8888.c#L146 this code made by JamoHTP]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3782</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3782"/>
		<updated>2025-07-18T12:52:39Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3781</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3781"/>
		<updated>2025-07-18T12:52:08Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Getting started ===&lt;br /&gt;
* [[Getting Started with Dreamcast development]] -- start here!&lt;br /&gt;
====Ready-to-use environments====&lt;br /&gt;
* [[Codespaces]] (Browser-based development)&lt;br /&gt;
* [[Docker images]]&lt;br /&gt;
* [[DreamSDK]] (Windows only)&lt;br /&gt;
&lt;br /&gt;
====[[KallistiOS]]====&lt;br /&gt;
* Building on Linux, macOS, Windows Subsystem for Linux&lt;br /&gt;
** see [[Getting Started with Dreamcast development|&#039;&#039;Getting Started with Dreamcast development&#039;&#039;]]&lt;br /&gt;
* [[Building KOS on Cygwin]]&lt;br /&gt;
* [[Building KOS on MinGW/MSYS]]&lt;br /&gt;
* [[Building KOS on MinGW-w64/MSYS2]]&lt;br /&gt;
* [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
* [[Using Ruby for Sega Dreamcast development]] (experimental)&lt;br /&gt;
* [[Compiling for Naomi]]&lt;br /&gt;
&lt;br /&gt;
=== Build &amp;amp; test ===&lt;br /&gt;
* [[Building your project]]&lt;br /&gt;
* [[Emulators]]&lt;br /&gt;
* [[Broadband adapter]] / [[LAN adapter]]&lt;br /&gt;
** [[Using dcload-ip with Linux]]&lt;br /&gt;
** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux)&lt;br /&gt;
* [[Coder&#039;s cable]]&lt;br /&gt;
&lt;br /&gt;
=== Environments and IDEs ===&lt;br /&gt;
* [[CLion Debugging]]&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
&lt;br /&gt;
=== Tools &amp;amp; utilities ===&lt;br /&gt;
* [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]]&lt;br /&gt;
* [[Using dcprof]]&lt;br /&gt;
&lt;br /&gt;
=== Releasing your project ===&lt;br /&gt;
* Plain files&lt;br /&gt;
* Disc image&lt;br /&gt;
* Selfboot Inducer package&lt;br /&gt;
&lt;br /&gt;
=== Engines ===&lt;br /&gt;
&#039;&#039;See&#039;&#039; [[Engine &amp;amp; Library]]&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
* [[Store Queues]]&lt;br /&gt;
* [[Romdisk Swapping]]&lt;br /&gt;
* [https://mc.pp.se/dc/hw.html Marcus Comstedt&#039;s Dreamcast Hardware Reference]&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
* [[Texture Formats]]&lt;br /&gt;
* [[Graphics APIs]]&lt;br /&gt;
* [[Paletted Textures]]&lt;br /&gt;
* [[2D Rendering Without PVR]]&lt;br /&gt;
* [[Twiddling]]&lt;br /&gt;
&lt;br /&gt;
* PVR&lt;br /&gt;
** [[PowerVR Introduction]]&lt;br /&gt;
** [[PVR Spritesheets]]&lt;br /&gt;
* [[GLdc]]&lt;br /&gt;
** [[Drawing 2D sprites using GLdc]]&lt;br /&gt;
** [[Drawing 3D shapes using GLdc]]&lt;br /&gt;
** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer]&lt;br /&gt;
* Others&lt;br /&gt;
** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture]&lt;br /&gt;
** [[Notes on fillrate and drawing large textures]]&lt;br /&gt;
** [[KMG Textures]]&lt;br /&gt;
** [[Loading PNG images as OpenGL textures]]&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
=== Maple ===&lt;br /&gt;
* Controller input&lt;br /&gt;
&lt;br /&gt;
=== VMU ===&lt;br /&gt;
* [[Save/Load file]]&lt;br /&gt;
* [[Show icon]]&lt;br /&gt;
* [[Play tone]]&lt;br /&gt;
&lt;br /&gt;
=== Optimization ===&lt;br /&gt;
* [[GCC-SH4 tips]]&lt;br /&gt;
* [[Fast SH4 Vertex Processing]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[Efficient usage of the Dreamcast RAM]]&lt;br /&gt;
* Registers&lt;br /&gt;
* DMA&lt;br /&gt;
* TA&lt;br /&gt;
* PVR&lt;br /&gt;
&lt;br /&gt;
=== Website Development ===&lt;br /&gt;
*[[Development Resources]]&lt;br /&gt;
&lt;br /&gt;
=== Random Snippets ===&lt;br /&gt;
* [[Objdump]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3780</id>
		<title>Dreamcast Tutorial</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3780"/>
		<updated>2025-07-18T12:51:33Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3779</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3779"/>
		<updated>2025-07-18T12:51:24Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3778</id>
		<title>Text Rendering</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3778"/>
		<updated>2025-07-18T12:51:13Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3777</id>
		<title>Transparent Textures</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3777"/>
		<updated>2025-07-18T12:51:04Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3776</id>
		<title>Textures and Meshes</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3776"/>
		<updated>2025-07-18T12:50:52Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3775</id>
		<title>Drawing a Texture</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3775"/>
		<updated>2025-07-18T12:50:38Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Adding_a_Romdisk&amp;diff=3774</id>
		<title>Adding a Romdisk</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Adding_a_Romdisk&amp;diff=3774"/>
		<updated>2025-07-18T12:50:26Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3773</id>
		<title>Main.cpp</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3773"/>
		<updated>2025-07-18T12:50:14Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Makefile&amp;diff=3772</id>
		<title>Makefile</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Makefile&amp;diff=3772"/>
		<updated>2025-07-18T12:49:57Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3750</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3750"/>
		<updated>2025-04-06T05:50:47Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Getting started ===&lt;br /&gt;
* [[Getting Started with Dreamcast development]] -- start here!&lt;br /&gt;
====Ready-to-use environments====&lt;br /&gt;
* [[Codespaces]] (Browser-based development)&lt;br /&gt;
* [[Docker images]]&lt;br /&gt;
* [[DreamSDK]] (Windows only)&lt;br /&gt;
&lt;br /&gt;
====[[KallistiOS]]====&lt;br /&gt;
* Building on Linux, macOS, Windows Subsystem for Linux&lt;br /&gt;
** see [[Getting Started with Dreamcast development|&#039;&#039;Getting Started with Dreamcast development&#039;&#039;]]&lt;br /&gt;
* [[Building KOS on Cygwin]]&lt;br /&gt;
* [[Building KOS on MinGW/MSYS]]&lt;br /&gt;
* [[Building KOS on MinGW-w64/MSYS2]]&lt;br /&gt;
* [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
* [[Using Ruby for Sega Dreamcast development]] (experimental)&lt;br /&gt;
* [[Compiling for Naomi]]&lt;br /&gt;
&lt;br /&gt;
=== Build &amp;amp; test ===&lt;br /&gt;
* [[Building your project]]&lt;br /&gt;
* [[Emulators]]&lt;br /&gt;
* [[Broadband adapter]] / [[LAN adapter]]&lt;br /&gt;
** [[Using dcload-ip with Linux]]&lt;br /&gt;
** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux)&lt;br /&gt;
* [[Coder&#039;s cable]]&lt;br /&gt;
&lt;br /&gt;
=== Environments and IDEs ===&lt;br /&gt;
* [[CLion Debugging]]&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
&lt;br /&gt;
=== Tools &amp;amp; utilities ===&lt;br /&gt;
* [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]]&lt;br /&gt;
* [[Using dcprof]]&lt;br /&gt;
&lt;br /&gt;
=== Releasing your project ===&lt;br /&gt;
* Plain files&lt;br /&gt;
* Disc image&lt;br /&gt;
* Selfboot Inducer package&lt;br /&gt;
&lt;br /&gt;
=== Engines ===&lt;br /&gt;
&#039;&#039;See&#039;&#039; [[Engine &amp;amp; Library]]&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
* [[Store Queues]]&lt;br /&gt;
* [[Romdisk Swapping]]&lt;br /&gt;
* [https://mc.pp.se/dc/hw.html Marcus Comstedt&#039;s Dreamcast Hardware Reference]&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
* [[Texture Formats]]&lt;br /&gt;
* [[Graphics APIs]]&lt;br /&gt;
* [[Paletted Textures]]&lt;br /&gt;
* [[2D Rendering Without PVR]]&lt;br /&gt;
* [[Twiddling]]&lt;br /&gt;
&lt;br /&gt;
* PVR&lt;br /&gt;
** [[PowerVR Introduction]]&lt;br /&gt;
** [[PVR Spritesheets]]&lt;br /&gt;
* [[GLdc]]&lt;br /&gt;
** [[Drawing 2D sprites using GLdc]]&lt;br /&gt;
** [[Drawing 3D shapes using GLdc]]&lt;br /&gt;
** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer]&lt;br /&gt;
* Others&lt;br /&gt;
** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture]&lt;br /&gt;
** [[Notes on fillrate and drawing large textures]]&lt;br /&gt;
** [[KMG Textures]]&lt;br /&gt;
** [[Loading PNG images as OpenGL textures]]&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
=== Maple ===&lt;br /&gt;
* Controller input&lt;br /&gt;
&lt;br /&gt;
=== VMU ===&lt;br /&gt;
* [[Save/Load file]]&lt;br /&gt;
* [[Show icon]]&lt;br /&gt;
* [[Play tone]]&lt;br /&gt;
&lt;br /&gt;
=== Optimization ===&lt;br /&gt;
* [[GCC-SH4 tips]]&lt;br /&gt;
* [[Fast SH4 Vertex Processing]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[Efficient usage of the Dreamcast RAM]]&lt;br /&gt;
* Registers&lt;br /&gt;
* DMA&lt;br /&gt;
* TA&lt;br /&gt;
* PVR&lt;br /&gt;
&lt;br /&gt;
=== Dreamcast Tutorial ===&lt;br /&gt;
==== First Steps ====&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
==== Texturing ====&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Transparent Textures]]&lt;br /&gt;
==== Systems ====&lt;br /&gt;
* [[Text Rendering]]&lt;br /&gt;
* [[Event Handling]]&lt;br /&gt;
&lt;br /&gt;
=== Website Development ===&lt;br /&gt;
*[[Development Resources]]&lt;br /&gt;
&lt;br /&gt;
=== Random Snippets ===&lt;br /&gt;
* [[Objdump]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3749</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3749"/>
		<updated>2025-04-06T05:50:25Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Getting started ===&lt;br /&gt;
* [[Getting Started with Dreamcast development]] -- start here!&lt;br /&gt;
====Ready-to-use environments====&lt;br /&gt;
* [[Codespaces]] (Browser-based development)&lt;br /&gt;
* [[Docker images]]&lt;br /&gt;
* [[DreamSDK]] (Windows only)&lt;br /&gt;
&lt;br /&gt;
====[[KallistiOS]]====&lt;br /&gt;
* Building on Linux, macOS, Windows Subsystem for Linux&lt;br /&gt;
** see [[Getting Started with Dreamcast development|&#039;&#039;Getting Started with Dreamcast development&#039;&#039;]]&lt;br /&gt;
* [[Building KOS on Cygwin]]&lt;br /&gt;
* [[Building KOS on MinGW/MSYS]]&lt;br /&gt;
* [[Building KOS on MinGW-w64/MSYS2]]&lt;br /&gt;
* [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
* [[Using Ruby for Sega Dreamcast development]] (experimental)&lt;br /&gt;
* [[Compiling for Naomi]]&lt;br /&gt;
&lt;br /&gt;
=== Build &amp;amp; test ===&lt;br /&gt;
* [[Building your project]]&lt;br /&gt;
* [[Emulators]]&lt;br /&gt;
* [[Broadband adapter]] / [[LAN adapter]]&lt;br /&gt;
** [[Using dcload-ip with Linux]]&lt;br /&gt;
** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux)&lt;br /&gt;
* [[Coder&#039;s cable]]&lt;br /&gt;
&lt;br /&gt;
=== Environments and IDEs ===&lt;br /&gt;
* [[CLion Debugging]]&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
&lt;br /&gt;
=== Tools &amp;amp; utilities ===&lt;br /&gt;
* [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]]&lt;br /&gt;
* [[Using dcprof]]&lt;br /&gt;
&lt;br /&gt;
=== Releasing your project ===&lt;br /&gt;
* Plain files&lt;br /&gt;
* Disc image&lt;br /&gt;
* Selfboot Inducer package&lt;br /&gt;
&lt;br /&gt;
=== Engines ===&lt;br /&gt;
&#039;&#039;See&#039;&#039; [[Engine &amp;amp; Library]]&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
* [[Store Queues]]&lt;br /&gt;
* [[Romdisk Swapping]]&lt;br /&gt;
* [https://mc.pp.se/dc/hw.html Marcus Comstedt&#039;s Dreamcast Hardware Reference]&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
* [[Texture Formats]]&lt;br /&gt;
* [[Graphics APIs]]&lt;br /&gt;
* [[Paletted Textures]]&lt;br /&gt;
* [[2D Rendering Without PVR]]&lt;br /&gt;
* [[Twiddling]]&lt;br /&gt;
&lt;br /&gt;
* PVR&lt;br /&gt;
** [[PowerVR Introduction]]&lt;br /&gt;
** [[PVR Spritesheets]]&lt;br /&gt;
* [[GLdc]]&lt;br /&gt;
** [[Drawing 2D sprites using GLdc]]&lt;br /&gt;
** [[Drawing 3D shapes using GLdc]]&lt;br /&gt;
** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer]&lt;br /&gt;
* Others&lt;br /&gt;
** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture]&lt;br /&gt;
** [[Notes on fillrate and drawing large textures]]&lt;br /&gt;
** [[KMG Textures]]&lt;br /&gt;
** [[Loading PNG images as OpenGL textures]]&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
=== Maple ===&lt;br /&gt;
* Controller input&lt;br /&gt;
&lt;br /&gt;
=== VMU ===&lt;br /&gt;
* [[Save/Load file]]&lt;br /&gt;
* [[Show icon]]&lt;br /&gt;
* [[Play tone]]&lt;br /&gt;
&lt;br /&gt;
=== Optimization ===&lt;br /&gt;
* [[GCC-SH4 tips]]&lt;br /&gt;
* [[Fast SH4 Vertex Processing]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[Efficient usage of the Dreamcast RAM]]&lt;br /&gt;
* Registers&lt;br /&gt;
* DMA&lt;br /&gt;
* TA&lt;br /&gt;
* PVR&lt;br /&gt;
&lt;br /&gt;
=== Dreamcast Tutorial ===&lt;br /&gt;
==== First Steps =====&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
==== Texturing ====&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Transparent Textures]]&lt;br /&gt;
==== Systems ====&lt;br /&gt;
* [[Text Rendering]]&lt;br /&gt;
* [[Event Handling]]&lt;br /&gt;
&lt;br /&gt;
=== Website Development ===&lt;br /&gt;
*[[Development Resources]]&lt;br /&gt;
&lt;br /&gt;
=== Random Snippets ===&lt;br /&gt;
* [[Objdump]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3748</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Development&amp;diff=3748"/>
		<updated>2025-04-06T05:48:52Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Getting started ===&lt;br /&gt;
* [[Getting Started with Dreamcast development]] -- start here!&lt;br /&gt;
====Ready-to-use environments====&lt;br /&gt;
* [[Codespaces]] (Browser-based development)&lt;br /&gt;
* [[Docker images]]&lt;br /&gt;
* [[DreamSDK]] (Windows only)&lt;br /&gt;
&lt;br /&gt;
====[[KallistiOS]]====&lt;br /&gt;
* Building on Linux, macOS, Windows Subsystem for Linux&lt;br /&gt;
** see [[Getting Started with Dreamcast development|&#039;&#039;Getting Started with Dreamcast development&#039;&#039;]]&lt;br /&gt;
* [[Building KOS on Cygwin]]&lt;br /&gt;
* [[Building KOS on MinGW/MSYS]]&lt;br /&gt;
* [[Building KOS on MinGW-w64/MSYS2]]&lt;br /&gt;
* [https://kos-docs.dreamcast.wiki/ KallistiOS Doxygen documentation]&lt;br /&gt;
&lt;br /&gt;
====Other====&lt;br /&gt;
* [[Using Ruby for Sega Dreamcast development]] (experimental)&lt;br /&gt;
* [[Compiling for Naomi]]&lt;br /&gt;
&lt;br /&gt;
=== Build &amp;amp; test ===&lt;br /&gt;
* [[Building your project]]&lt;br /&gt;
* [[Emulators]]&lt;br /&gt;
* [[Broadband adapter]] / [[LAN adapter]]&lt;br /&gt;
** [[Using dcload-ip with Linux]]&lt;br /&gt;
** [[Using dcload-ip with Windows Subsystem for Linux|Using dcload-ip with Windows 10]] (via Windows Subsystem for Linux)&lt;br /&gt;
* [[Coder&#039;s cable]]&lt;br /&gt;
&lt;br /&gt;
=== Environments and IDEs ===&lt;br /&gt;
* [[CLion Debugging]]&lt;br /&gt;
* [[Visual Studio Code]]&lt;br /&gt;
&lt;br /&gt;
=== Tools &amp;amp; utilities ===&lt;br /&gt;
* [[Debugging throught GNU Debugger (GDB) and dcload/dc-tool]]&lt;br /&gt;
* [[Using dcprof]]&lt;br /&gt;
&lt;br /&gt;
=== Releasing your project ===&lt;br /&gt;
* Plain files&lt;br /&gt;
* Disc image&lt;br /&gt;
* Selfboot Inducer package&lt;br /&gt;
&lt;br /&gt;
=== Engines ===&lt;br /&gt;
&#039;&#039;See&#039;&#039; [[Engine &amp;amp; Library]]&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
* [[Store Queues]]&lt;br /&gt;
* [[Romdisk Swapping]]&lt;br /&gt;
* [https://mc.pp.se/dc/hw.html Marcus Comstedt&#039;s Dreamcast Hardware Reference]&lt;br /&gt;
&lt;br /&gt;
=== Graphics ===&lt;br /&gt;
* [[Texture Formats]]&lt;br /&gt;
* [[Graphics APIs]]&lt;br /&gt;
* [[Paletted Textures]]&lt;br /&gt;
* [[2D Rendering Without PVR]]&lt;br /&gt;
* [[Twiddling]]&lt;br /&gt;
&lt;br /&gt;
* PVR&lt;br /&gt;
** [[PowerVR Introduction]]&lt;br /&gt;
** [[PVR Spritesheets]]&lt;br /&gt;
* [[GLdc]]&lt;br /&gt;
** [[Drawing 2D sprites using GLdc]]&lt;br /&gt;
** [[Drawing 3D shapes using GLdc]]&lt;br /&gt;
** [https://hkowsoftware.com/articles/gldc-vertex-formats-from-vec3f-to-fastpath-to-map_buffer/ GLdc Vertex Formats: From vec3f to fastpath to map_buffer]&lt;br /&gt;
* Others&lt;br /&gt;
** [http://www.numechanix.com/blog/index.php/2015/10/03/20/ Procedural texture]&lt;br /&gt;
** [[Notes on fillrate and drawing large textures]]&lt;br /&gt;
** [[KMG Textures]]&lt;br /&gt;
** [[Loading PNG images as OpenGL textures]]&lt;br /&gt;
&lt;br /&gt;
=== Audio ===&lt;br /&gt;
&lt;br /&gt;
=== Maple ===&lt;br /&gt;
* Controller input&lt;br /&gt;
&lt;br /&gt;
=== VMU ===&lt;br /&gt;
* [[Save/Load file]]&lt;br /&gt;
* [[Show icon]]&lt;br /&gt;
* [[Play tone]]&lt;br /&gt;
&lt;br /&gt;
=== Optimization ===&lt;br /&gt;
* [[GCC-SH4 tips]]&lt;br /&gt;
* [[Fast SH4 Vertex Processing]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[Efficient usage of the Dreamcast RAM]]&lt;br /&gt;
* Registers&lt;br /&gt;
* DMA&lt;br /&gt;
* TA&lt;br /&gt;
* PVR&lt;br /&gt;
&lt;br /&gt;
=== Dreamcast Tutorial ===&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Transparent Textures]]&lt;br /&gt;
* [[Text Rendering]]&lt;br /&gt;
* [[Event Handling]]&lt;br /&gt;
&lt;br /&gt;
=== Website Development ===&lt;br /&gt;
*[[Development Resources]]&lt;br /&gt;
&lt;br /&gt;
=== Random Snippets ===&lt;br /&gt;
* [[Objdump]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3747</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3747"/>
		<updated>2025-04-06T00:56:47Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
 	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
 	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Down);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Left);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Right);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
 		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
 									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3746</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3746"/>
		<updated>2025-04-06T00:56:06Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
 	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
 	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Down);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Left);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Right);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
 		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
 									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3745</id>
		<title>Drawing a Texture</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3745"/>
		<updated>2025-04-05T15:03:46Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dreamcast does not draw like a modern GPU, it doesn’t have a GPU at all. It has a PVR Core which uses deferred rendering. The way this works is that a small amount of memory inside the Dreamcast VRAM is set aside to hold vertex data. Instead of rasterizing each polygon as they are sent to the dreamcast and immediately drawing it to the destination, the Dreamcast instead caches all polygons upfront. Once all the vertecies for the polygons in the scene are collected, it renders the output in steps, one 32x32 pixel tiles at a time. This has a bunch of really cool added benefits, notably that you do not have to sort polygons for transparancies to work. Overdraw is also generally not a thing, since only the exact amount of pixels needed for the destination are drawn. Every single pixel drawn is depth tested against all polygons around it during rasterization. This means pixel perfect z-buffers!&lt;br /&gt;
&lt;br /&gt;
=== Types of Polygons ===&lt;br /&gt;
&lt;br /&gt;
There are 5 types of polygons that are rendered. They are the Opaque Polygons, the Opaque Modifier Polygons, the Translucent polygons, the Translucent modifier polygons, and punch-thru polygons. Opaque Polygons are fully visible, no holes in it. If it is texture mapped, then the texture cannot have an alpha channel in it, it must be only RGB. Translucent Polygons are what we would think of as true-color 32-bit in modern computing. It means colors are represented as ARGB, providing an alpha channel. When used on a texture mapped polygon, the individual alpha channels of pixels in the texture determine the visibility. Instead of per-polygon transparency, the dreamcast does per-pixel! Pixels can be transparent in a range depending on the bitdepth. An offshoot of Translucent Polygons are Punch-Thru polygons. Data-wise, these are basically the same as a translucent polygon, except any value in the alpha channel besides 0 is treated as 100% transparent. That means pixels are either entirely visible, or entirely transparent. It is said to “punch-through” because the transparent pixels look like holes punched through the polygon.&lt;br /&gt;
&lt;br /&gt;
We need to determine how much VRAM space to reserve to hold references to these polygons. Since the output is divided into 32x32 tiles during render, every tile needs space to hold polygon references that keep track of which polygons reside in that tile. Polygon references in a tile are stored in a linked list known as the Object List. Nodes in the linked list can hold a set number of polygon references, and can point to each other for an arbitrary number of polygon references to be stored. These nodes are known as Object Pointer Blocks. We can set the size of each OPB for each polygon type with a KOS structure called pvr_init_params:&lt;br /&gt;
&lt;br /&gt;
 static pvr_init_params_t pvr_params = {&lt;br /&gt;
    /* OPB (Object Pointer Block) node: */&lt;br /&gt;
    {&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Opaque Poly OPB: 32 word (128 byte) length */&lt;br /&gt;
        PVR_BINSIZE_0, /* Disable Opaque Modifier Poly OPB  */&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Translucent Poly OPB: 32 word (128 byte) length  */&lt;br /&gt;
        PVR_BINSIZE_0, /* Disable Translucent Modifier Poly OPB  */&lt;br /&gt;
        PVR_BINSIZE_0  /* Disable Punch-thru Poly OPB*/},&lt;br /&gt;
    /* Vertex buffer size 512K */&lt;br /&gt;
    512 * 1024,&lt;br /&gt;
    /* DMA Enable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* FSAA Enable: Off*/&lt;br /&gt;
    0,&lt;br /&gt;
    /* Translucent Autosort Disable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* OPB Overflow count: Preallocates this many extra OPBs (sets of tile bins), allowing the PVR to use the extra space when there&#039;s too much geometry in the first OPB. */&lt;br /&gt;
    0&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
The available sizes for allocation for each bin are as follows:&lt;br /&gt;
 PVR_BINSIZE_0: 0-length, which disables the list&lt;br /&gt;
 PVR_BINSIZE_8: 8-word (32-byte) length&lt;br /&gt;
 PVR_BINSIZE_16: 16-word (64-byte) length&lt;br /&gt;
 PVR_BINSIZE_32: 32-word (128-byte) length&lt;br /&gt;
&lt;br /&gt;
The number of references that can be stored is equal to the binsize. I.e. PVR_BINSIZE_8 can store 8 polygon references in this OPB node. In the above example, we’re allocating 128-bytes to the Opaque Polygon bin, and 128-bytes to the Translucent Polygon bin. With our VRAM memory allocated for our OPBs, it’s time to create some textures. Let’s define some pointers to vram memory in our source code as global variables:&lt;br /&gt;
 pvr_ptr_t tex_blue;&lt;br /&gt;
 pvr_ptr_t back_tex;&lt;br /&gt;
&lt;br /&gt;
These pointers will hold the address of our textures in vram, making them our system handles for those textures. Let’s create a function that will let us allocate some memory for these textures in vram, then fill them up:&lt;br /&gt;
 void textures_init(void) {&lt;br /&gt;
    tex_blue = pvr_mem_malloc(128 * 128 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/blue.png&amp;quot;, tex_blue, PNG_FULL_ALPHA);&lt;br /&gt;
    back_tex = pvr_mem_malloc(512 * 512 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/background.png&amp;quot;, back_tex, PNG_NO_ALPHA);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function begins by calling pvr_mem_malloc(). This function takes a number which represents how many bytes to allocate. We want enough room to hold all the pixels in our textures. Our Blue Texture is 128x128 pixels big, and the Dreamcast uses 16-bit color internally, despite supporting 24-bit color. 16-bits is the same as 2-bytes, which is where the 2 comes from in the above formula. Thus we need 2-bytes for each pixel, and there are 128x128 pixels. We can add the math into the parameters so it’s more readable. Pvr_mem_malloc returns the vram address where it allocated the space, which we save in our tex_blue pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We do the same with back_tex. This time, our background.png image is 512x512 pixels big. We adjust the parameter to account, and store the pointer in the appropriate pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We use each pointer to direct our png_to_texture function where to deposite the pixels it loads. png_to_texture opens a png file and returns the raw pixel data in a dreamcast pixel format. It takes a char* string that is the filepath to the png, along with a pvr_ptr that points to an allocated area of VRAM, and a flag. The flag determines how the function treats the png, and how it orders the data. There are 3 enums that an be set as the flag:&lt;br /&gt;
&lt;br /&gt;
 PNG_FULL_ALPHA: The png loaded has an alpha channel. It will be turned into ARGB4444.&lt;br /&gt;
 PNG_NO_ALPHA: The png loaded has no alpha channel. It will be turned into RGB565. &lt;br /&gt;
 PNG_MASK_ALPHA: The png loaded has an alpha channel, but will be a punch-thru texture. It will be turned into ARGB1555.&lt;br /&gt;
&lt;br /&gt;
We will need to know the pixel format of the texture in a moment, so take note of which flag you have set. We used FULL_ALPHA for the blue texture, and NO_ALPHA for the background texture.&lt;br /&gt;
&lt;br /&gt;
We need a function to call that will actually Submit vertices to the Dreamcast and command it to draw. We’ll call that function DrawFrame(), although that’s a misnomer. It’s actually just submitting frame data, and the frame is drawn later. Regardless of semantics, let’s create such a function:&lt;br /&gt;
 void DrawFrame(void)&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        // Rendering code in here&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our DrawFrame function begins with pvr_wait_ready(). This is a function that gets the PVR ready to accept vertices. This means doing some internal house keeping, as well as generally waiting for vblank to start a new frame. That means calling pvr_wait_ready(); ends the previous frame in a loop and waits for a new one to begin. If you call this twice in a loop, then your loop will run at 30 FPS. If you call it 3 times, your loop will run at 20 FPS. And so forth.&lt;br /&gt;
&lt;br /&gt;
After the PVR is ready, we have a pair of calls, pvr_scene_begin() and pvr_scene_end. Everything that goes in between these calls encapsulates a full frame of the scene being drawn. In between these calls, we can further breakdown which polygon bin we are going to be working on:&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            // Vertex code here for Opaque polygons&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
This is a pair of calls, pvr_list_begin(int) and pvr_list_finish(). pvr_list_begin takes an enum that tells it which list to bind. When a list is bound, all pvr functions will be directed towards that one. pvr_list_finish closes the bin for the scene, once a bin is closed it cannot be reopened until the next frame. In this example, we are opening the bin for opaque polygons, meaning any vertex we submit will go to that bin.&lt;br /&gt;
&lt;br /&gt;
Inside our Opaque Polygon list functions, we can create vertices and submit them. We can also create a command to let the PVR know which texture we want to use when texture mapping the polygon. We need to first create some variables:&lt;br /&gt;
    pvr_poly_cxt_t cxt;&lt;br /&gt;
    pvr_poly_hdr_t hdr;&lt;br /&gt;
    pvr_vertex_t vert;&lt;br /&gt;
&lt;br /&gt;
First, we need to create a variable to hold our polygon context. A context is an instance of the polygon parameter data, encapsulated into an object. This context is where we set which texture to draw with for the next polygon, along with the parameters for the texture. Once we have our polygon context defined, we can compile it into a pvr polygon header. A PVR Polygon Header is an object that represents a command to the PVR to setup the next polygon. It is the same size as an vertex, and thus behaves like one. You submit the polygon header the same way you submit a vertex. In fact, you can store a bunch of vertices into an array, and insert polygon headers into the array, and submit all the polygon data at once, which we’ll get into later. For now, let’s concentrate on submitting one vertex (or header) at a time.&lt;br /&gt;
&lt;br /&gt;
Our actual vertices will be stored in a structure called pvr_vertex_t. The Dreamcast and KOS have a number of predefined vertex types, which have more or less attributes depending on rendering mode. The more features a vertex or render mode has, the more space it consumes. Vertices are either 32-bytes big, or 64-bytes big. A special case is a Sprite object, which is 4 vertices squished together into one 64-byte object, meaning you can define a sprite in one vertex instead of needing 4 vertices. The types of vertices available are:&lt;br /&gt;
pvr_vertex_t: the generic, default vertex.&lt;br /&gt;
We are going with the default type. When we submit vertices to the PVR, we will use this variable and fill out the fields inside of it as needed.&lt;br /&gt;
&lt;br /&gt;
Let’s begin by creating our Polygon context. We want to draw the background texture to the entire screen. We can do that like so:&lt;br /&gt;
    pvr_poly_cxt_txr(	&amp;amp;cxt, 			/* Destination Context */&lt;br /&gt;
 				PVR_LIST_OP_POLY, 	/* Flags */&lt;br /&gt;
 				PVR_TXRFMT_RGB565, 	/* Texture Format */&lt;br /&gt;
 				512, 				/* Texture Width */&lt;br /&gt;
 				512, 				/* Texture Height */&lt;br /&gt;
 				back_tex, 			/* TextureID */&lt;br /&gt;
 			PVR_FILTER_BILINEAR);		/* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;hdr, &amp;amp;cxt);&lt;br /&gt;
    pvr_prim(&amp;amp;hdr, sizeof(hdr));&lt;br /&gt;
&lt;br /&gt;
We need to create a polygon context for our background texture. We fill in the appropriate fields: this is going to the opaque polygon bin, the texture has no alpha channel so it’s RGB565, the width and height are 512x512, the pointer to the texture in memory is back_tex, and we will be using bilinear filtering. With this context object created, we compile it into our header. PVR_prim() is a function that takes a vertex or header file, and send its data over to the VRAM polygon bin. It takes a second parameter with a size to know how many bytes to send to VRAM. We send our header that tells our PVR that the next polygon renders with the back_tex using bilinear filtering as an opaque polygon.&lt;br /&gt;
&lt;br /&gt;
Now, let’s set some general parameters for our vertices:&lt;br /&gt;
    vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    vert.oargb = 0;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
&lt;br /&gt;
Our vertex contains a field for an argb definition, to give the vertex a diffuse color. We set it to pure white, 1.0 (100%) in RGBA. Our vertex also has an offset argb value, this is for specular highlights. We’ll leave it set to 0, unused. We set a command in the flag field: PVR_CMD_VERTEX. This tells the PVR to begin taking in vertices for a polygon strip. When a command is given telling the PVR that it’s the EOL for the strip, it’ll end the polygon and move onto a new one.&lt;br /&gt;
&lt;br /&gt;
With our general parameters set, lets begin making the actual position data in the vertices and uploading them to VRAM:&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
each one of these sections is a single vertex. We are manually changing the XYZ coordinates of the vertex, along with the UV coordinates, before sending it to the PVR. This vertex is at 0,0,1.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
The next vertex resides at 640,0,1. Our two vertices so far have drawn a 640-pixel straight line from the left side of the screen to the right side, at Y position 0, which is the very top.&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
Our next vertex is at 0,480,1. This has shot back to the left side of the screen, then all the way down to the bottom row of pixels, Y at 480. This has formed a triangle between our previous 3 vertices. However, we have not given the command that this the end of line for the triangle strip, so we can submit another vertex.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
This final vertex is at 640,480,1. It’s at the very bottom right corner of the screen. Given the previous 3 vertices, this forms a second triangle, with the area of both filling the entire 640x480 screen. We pack a command into the flag of this final vertex, “PVR_CMD_VERTEX_EOL.” This tells the PVR that this strip of 4 vertices is a single long polygon that is finished. In the end, we wound up defining a screen-filling square and filled it with our back_tex.&lt;br /&gt;
Place this call within our Main() loop and run the program, and we should get the background texture filling our screen:&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        //Counter++;&lt;br /&gt;
        EvHandler.PollEvent(&amp;amp;Game);&lt;br /&gt;
        HandleInput(&amp;amp;Game);&lt;br /&gt;
        DrawFrame();    }&lt;br /&gt;
&lt;br /&gt;
We have successfully loaded and displayed a texture. We will come back shortly and continue learning how to use the PVR. However, our program currently has no way of responding, every time we want to make a change we have to turn off the dreamcast and wait for it to boot back up. Let’s give ourselves the ability to communicate with our program using our gamepads.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3744</id>
		<title>Main.cpp</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3744"/>
		<updated>2025-04-05T15:01:47Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A main source file is the starting point for any Dreamcast program. The first run function will be int main(int argc, char **argv), and thus the file it resides in is considered the main source file. It is typical to name this file something like main.cpp, or perhaps game.cpp, or the name of your program with .cpp attached. For the purpose of this tutorial, we will refer to it as Main.cpp.&lt;br /&gt;
&lt;br /&gt;
Create a new text file called Main.cpp, and open it to begin editing. &lt;br /&gt;
&lt;br /&gt;
=== Headers ===&lt;br /&gt;
&lt;br /&gt;
Let’s start by adding some header files to the top of our main.cpp:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
&lt;br /&gt;
The top are KOS files. KOS it the dreamcast system SDK we use to talk to the console. We’re including the main KOS calls, along with some files needed for GDB debugging. I’m also including the png library, as we’ll be using pngs as textures in our program. Stdio.h and stdint.h are standard libraries related to input/output, and integer types specifically. The latter defines standard types like uint32_t and uint8_t. These types are important as they let us explicitly define our variables by size.&lt;br /&gt;
&lt;br /&gt;
=== int main(int argc, char** argv) ===&lt;br /&gt;
&lt;br /&gt;
Our program begins execution here:&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
 #ifdef GAME_DEBUG&lt;br /&gt;
     gdb_init();&lt;br /&gt;
 #endif&lt;br /&gt;
     /* init kos  */&lt;br /&gt;
     pvr_init_defaults();&lt;br /&gt;
 	/* Main loop */&lt;br /&gt;
     while(1)&lt;br /&gt;
     {&lt;br /&gt;
 		printf(“running!\n”);&lt;br /&gt;
     }&lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
the function gdb_init() is included in #ifdef tags for GAME_DEBUG. This function will only be called if a GAME_DEBUG flag is set from our compiler. When this is called, we will see our program pause in the console output and declare that it’s waiting for a GDB debugger. When this happens, we can remote connect to our gdb port, and our dreamcast will begin interfacing and debugging with our computer.&lt;br /&gt;
&lt;br /&gt;
After that, we call and initialize PVR, then move into our main loop. Right now, our main loop never ends, and just prints that it’s running. You can test this program out, but it’s not worth running at the moment. For now, we have our basic shell of a program, along with our makefile.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3743</id>
		<title>Main.cpp</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Main.cpp&amp;diff=3743"/>
		<updated>2025-04-05T15:01:25Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A main source file is the starting point for any Dreamcast program. The first run function will be int main(int argc, char **argv), and thus the file it resides in is considered the main source file. It is typical to name this file something like main.cpp, or perhaps game.cpp, or the name of your program with .cpp attached. For the purpose of this tutorial, we will refer to it as Main.cpp.&lt;br /&gt;
&lt;br /&gt;
Create a new text file called Main.cpp, and open it to begin editing. &lt;br /&gt;
&lt;br /&gt;
=== Headers ===&lt;br /&gt;
&lt;br /&gt;
Let’s start by adding some header files to the top of our main.cpp:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 &lt;br /&gt;
 /*** C Library forward declarations ***/&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif&lt;br /&gt;
     #include &amp;lt;zlib/zlib.h&amp;gt;    /* Z-Lib library, used to decompress gzip files */&lt;br /&gt;
     extern int zlib_getlength(char*);&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 }&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
The top are KOS files. KOS it the dreamcast system SDK we use to talk to the console. We’re including the main KOS calls, along with some files needed for GDB debugging. I’m also including the png library, as we’ll be using pngs as textures in our program. Stdio.h and stdint.h are standard libraries related to input/output, and integer types specifically. The latter defines standard types like uint32_t and uint8_t. These types are important as they let us explicitly define our variables by size.&lt;br /&gt;
&lt;br /&gt;
=== int main(int argc, char** argv) ===&lt;br /&gt;
&lt;br /&gt;
Our program begins execution here:&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
 #ifdef GAME_DEBUG&lt;br /&gt;
     gdb_init();&lt;br /&gt;
 #endif&lt;br /&gt;
     /* init kos  */&lt;br /&gt;
     pvr_init_defaults();&lt;br /&gt;
 	/* Main loop */&lt;br /&gt;
     while(1)&lt;br /&gt;
     {&lt;br /&gt;
 		printf(“running!\n”);&lt;br /&gt;
     }&lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
the function gdb_init() is included in #ifdef tags for GAME_DEBUG. This function will only be called if a GAME_DEBUG flag is set from our compiler. When this is called, we will see our program pause in the console output and declare that it’s waiting for a GDB debugger. When this happens, we can remote connect to our gdb port, and our dreamcast will begin interfacing and debugging with our computer.&lt;br /&gt;
&lt;br /&gt;
After that, we call and initialize PVR, then move into our main loop. Right now, our main loop never ends, and just prints that it’s running. You can test this program out, but it’s not worth running at the moment. For now, we have our basic shell of a program, along with our makefile.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3742</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3742"/>
		<updated>2025-04-05T15:00:09Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
** [[Dreamcast Tutorial]]&lt;br /&gt;
*** [[Makefile]]&lt;br /&gt;
*** [[Main.cpp]]&lt;br /&gt;
*** [[Adding a Romdisk]]&lt;br /&gt;
*** [[Drawing a Texture]]&lt;br /&gt;
*** [[Textures and Meshes]]&lt;br /&gt;
*** [[Transparent Textures]]&lt;br /&gt;
*** [[Text Rendering]]&lt;br /&gt;
*** [[Event Handling]]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3741</id>
		<title>Text Rendering</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3741"/>
		<updated>2025-04-05T14:59:23Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Now that we can display our font texture with transparency correctly, let’s build our function to render text. To do this, we’ll have to manipulate the UV coordinates of the texture we render with.&lt;br /&gt;
&lt;br /&gt;
We start by making a clone of our SubmitQuad function, which we’ll call SubmitText. This will take some different parameters. First, it’ll take a const char* Input string. This is a c-style string, which is just an array of bytes on the stack. We want to take a font color, since our font.png texture has 4 different font colors. Each font in our texture atlus has 2 sizes, so we’ll take a flag to switch between them. Finally, we’ll take an X and Y coordinate to place the text on screen. Our Function should look like this:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
 			/* Function code in here */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Don’t forget to add this function declaration in Gamestate.h. This function is only for rendering text, so we can assume some things about it that we didn’t have to assume in the Quad function. We don’t want our text to have an opaque background, only transparent, so we’ll add a check to ensure we’re in the PVR_LIST_TR_POLY list:&lt;br /&gt;
&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
 		/* Transparent Polygon Bin code in here */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Our font atlus follows some rules that makes it organized well for our task. I drew the font so that every cell is 16x16 pixels big on the texture. There is an 8x8 font included on every other row, but they stick to the 16x16 grid. When the font is 8x8, it simply is stuck in the upper left corner of the 16x16 pixel grid. That makes the math involved in selecting which character to render a lot easier.&lt;br /&gt;
&lt;br /&gt;
We want to avoid if statements as much as possible when programming, they make our code unpredictable. It is better to use weighted math when possible to avoid branching conditions. This is a perfect example of when to use this. We have two font sizes we want to choose from, and how we choose them is by altering the vertical axis of our texture mapping coordinate by 16 pixels. Either our texture mapping coordinate will be X, or it’ll be X + 16. We can think of that as X + (0)*16, and X + (1)*16. By changing the variable from 0 to 1, our answer changes by 16 pixels each time, without needing an if branch. We can accomplish something like this in our code by using our SizeFlag in the parameters. Let’s create a final FontSize scaling factor:&lt;br /&gt;
        uint32_t Font_Scale = 8 * SizeFlag;&lt;br /&gt;
&lt;br /&gt;
This variable, Font_Scale, represents how many pixels downward our bottom UV coordinate is, from the top of our texture map. Our sizeFlag parameter can either be 1 or 2. If it’s 1, then we use 8 pixel tall fonts. If it’s 2, then we use 16 pixel tall fonts.&lt;br /&gt;
&lt;br /&gt;
After that, we create our texture mapping context header. This will use font_png exclusively, since it renders text, so we don’t need a variable for the texture enum:&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(font_png);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
&lt;br /&gt;
We can now start working on our vertices. We still use a temporary vertex, T_Vertex, to work on, and a pointer, Vertex_Ptr, to hold the mesh vertex we’re working on, as convinence labels for readability. We also introduce a couple of new variables. One is a uint8_t flag called Input_String_EOL. It is used to control the loop that we use to read the character array string containing our text to render. We also have a uint8_t variable called FontSelector. This variable chooses which vertical value to use for our uv texture map, to select between one of the four font types. Since each font has 2 sizes, and each font row is always 16 pixels tall, we can multiply our FontSelector_Input parameter, which goes from 0-3, by 2, so it skips both font lines. Lastly, we add the result of the SizeFlag parameter with modulus division by 2. This gives us the remainder of division. Our SizeFlag choices are 1 or 2, with 2 being big font (16) and 1 being small font (8). When we use the big font, we’re using the first line in our font atlus, when we use the small font, we’re using the second line. Thus, when we pass 2 by our SizeFlag parameter, we need it to turn into 0 for our Line Selector. And if we pass 1 by our SizeFlag parameter, we need it to turn into 1 for our Line Selector. Modulus division does this. 2%2 = 0, since we have a remainder of 0 when we do 2/2. Likewise, 2%1 = 1, because we have a remainder of 1 when we do 2/1. We add this modulus division to our FontSelector value, which shifts the row selected by 0 or 1.&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            uint8_t Input_String_EOL = 0;&lt;br /&gt;
            uint8_t FontSelector = 2*FontSelector_Input;&lt;br /&gt;
            FontSelector+=SizeFlag%2;&lt;br /&gt;
With our LineSelector determining which font row we’re using, we’re ready to start rendering the text. We’ll create a for-loop to iterate through the Input_String array, byte by byte:&lt;br /&gt;
&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
 	 }&lt;br /&gt;
&lt;br /&gt;
The condition for the loop to terminate is that Input_String_EOL is something other than 0, so that flag is our loop terminator. Input_String[Idx] is a byte containing a single character of our text string:&lt;br /&gt;
&lt;br /&gt;
 if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
 {&lt;br /&gt;
 	Input_String_EOL = 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The first condition to consider is if that character is ‘\0’. This is a special character called a “NULL Terminator.” It’s a character which means “nothing,” that is used to mark special conditions. When encountered in a C-Style String, it means that is the end of the String, called EOL. So we set our Input_String_EOL flag to 1 to end the loop.&lt;br /&gt;
&lt;br /&gt;
 else if(Input_String[Idx] &amp;lt; 33 || Input_String[Idx] &amp;gt; 122)&lt;br /&gt;
            {&lt;br /&gt;
                /* We only print the error if it&#039;s 31 or below, because 32 is space */&lt;br /&gt;
                if(Input_String[Idx] &amp;lt; 32)&lt;br /&gt;
                    printf(&amp;quot;Invalid Character to Render: %c\n&amp;quot;, Input_String[Idx]);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
The first if conditional is appended with an else if statement. This condition considers that our character that we’re examining isn’t EOL, but also isn’t valid. According to the ASCII map, the only inputs we are considering is 32 to 122, with 32 being a space character. We don’t render anything for space, so we check to make sure our value is between 33 and 122. If it’s not, skip rendering and give a small message letting us know we encountered an unknown character.&lt;br /&gt;
&lt;br /&gt;
 else /* Render the character to the screen as a quad */&lt;br /&gt;
            {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
We append one last else condition. This is what happens if this is a valid character between 33 and 122. We need to do some more math on it. Characters after the value of 96 are actually lower case characters, and our font set does not cover those. So we can subtract 32 from our value if it’s after 96, which will turn lower case characters into upper case characters:&lt;br /&gt;
&lt;br /&gt;
                int32_t CharIdx = (uint8_t)Input_String[Idx];&lt;br /&gt;
                if(Input_String[Idx] &amp;gt; 96)&lt;br /&gt;
                {&lt;br /&gt;
                    CharIdx = CharIdx - 32;&lt;br /&gt;
                }&lt;br /&gt;
This ensures our index is now between 33 and 96. We want to turn this into an index from the range of 0-63, with each number being a horizontal cell index in our font texture. 64 x 16 = 1024:&lt;br /&gt;
CharIdx = CharIdx - 33;     /* Turn our CharIdx into a index for our array, we use 33 to turn space into -1 */&lt;br /&gt;
&lt;br /&gt;
With our Index now correctly configured, we can begin drawing the character. We need to call to get a vertex from our quad mesh, and we need to do it for 4 times as this is a quad. m_Meshes.Get(e_Quad)→m_VtxCount returns 4 programmatically:&lt;br /&gt;
&lt;br /&gt;
 for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now we’re ready to prime and submit our vertex. We use Vertex_Ptr to hold our vertex in our Quad Mesh:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + (Idx * Font_Scale)  + (Vertex_ptr-&amp;gt;x * Font_Scale);&lt;br /&gt;
                    T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                    &lt;br /&gt;
The main bit of this text rendering algorithm comes from how we set T_Vertex.x and T_Vertex.y, as well as T_Vertex.u and T_Vertex.v.&lt;br /&gt;
&lt;br /&gt;
T_Vertex.x is what determines the horizontal position of the quad being drawn. We start with our base X_In parameter, which becomes the origin of our Text Renderer. We add to this X_In origin the result of multiplication of the Index by the Font_Scale. Font_Scale will be either 8 or 16, and the Idx is choosing how many of these 8 or 16 pixel steps to move over. This makes the spot where we render our next character quad to shift over so we’re not rendering on top of ourselves.&lt;br /&gt;
&lt;br /&gt;
This same formula will be run on all 4 vertices of the quad. 2 of the vertices are on the left side of the edge of the quad, which is equal to our origin at X_Int. However, the other 2 vertices are on the right side of the quad, which is Font_Scale pixels to the right (either 8 or 16). When we made our Quad Mesh, the vertices on the left had a 0 in their x variable, and the vertices on the right had a 1. We can use this variable, Vertex_ptr-&amp;gt;x, as an on/off switch for our Font_Scale variable. This creates the XY coordinates for the quad that will make up our text character on screen, next we need to select it from the texture.&lt;br /&gt;
&lt;br /&gt;
When we do texture mapping, we are assigning an X,Y coordinate to each vertex that tells it where that corner should map to on our texture. Because X,Y are already used in our vertex to describe the position, we use UV instead. Anytime we see UV, we are likely talking about texture coordinates. In addition to knowing their use intuitively, the choice of UV also tells us that our values are normalized. Recall that normalizing a value restricts it between a range of 0.00 to 1.00. This turns our value into a percentage. That means when we describe our texture mapping coordinates, we do not do so in terms of pixel values. Rather, we describe our coordinates as “percentage to the right of our texture” and “percentage to the bottom of our texture.”&lt;br /&gt;
&lt;br /&gt;
You might think this method of storing coordinates is silly, but it’s very useful for textures. This is because we don’t always use the same size for our texture. A method to reduce computation for texture scaling is mipmapping, which involves creating the same texture multiple times in memory at different pre-scaled resolutions. If we described our texture mapping in terms of pixel coordinates, this wouldn’t work. If our texture at full resolution is 640 pixels horizontally, and we are at 50% mipmap level, and we tell our vertex to map to texel 640, it wouldn’t know what to do. At 50% mipmap level, our horizontal span is only 320. By describing our coordinate as a percentage, it remains the same no matter what size the texture.&lt;br /&gt;
&lt;br /&gt;
For example, if our right edge corner of our quad needs to map to the far right edge of the texture, we can say it’s 100% to the right. That way, if we are using 100% mipmap level, that’s pixel 640. And if we are using 50% mipmap level, then that’s pixel 320. Using UV coordinates as percentages, and thus describing them as normalized floats, keeps everything working as intended.&lt;br /&gt;
&lt;br /&gt;
Luckily the formula to translate from pixel space to normalized percentage is easy. U = X/Width, and V= Y/Height. To give an example, if we wanted to get a texel on the far right edge of a 640 pixel texture, then U = 640/640 = 1 = 100%. If we wanted to get a texel on the dead center of the texture, then U = 320/640 = .5 = 50%. This works for the V coordinate as well. We are doing exactly this in our T_Vertex.u calculation, just with more variables worked in:&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
                    T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
                    T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                    T_vertex.oargb = Vertex_ptr→oargb;&lt;br /&gt;
&lt;br /&gt;
The left edge of our texture map moves over by 16 pixels times our character index. This selects the character on the texture map. Our vertex was created with UV coordinates that change between 0 and 1, just like our position coordinates, so we can use them as a flag for turning off an offset in our calculation. In this case, the UV flag adds our Font_Scale variable (8 or 16 pixels). We then divide all of this by 1024.0f, our font.png width. That gives us the left and right edges of our texture map.&lt;br /&gt;
&lt;br /&gt;
We do the same for V using the Y coordinates. Instead of 1024.0f as our width, we use 128.0f as our height. &lt;br /&gt;
&lt;br /&gt;
With our Vertices calculated correctly for the text, we can submit them as we finish each loop:&lt;br /&gt;
&lt;br /&gt;
 /* Submit data */&lt;br /&gt;
                    pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
Everytime we submit a quad, we need to increment RenderDepth so we avoid z-fighting:&lt;br /&gt;
&lt;br /&gt;
 RenderDepth += 0.1;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
   } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
&lt;br /&gt;
We attach an else condition at the end of our close braces. At the very beginning of this function, we checked if we were on the PVR_LIST_TR_POLY bin list. If we’re not, we print a little error:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
        if(m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            printf(&amp;quot;Could not render text, font texture format is not PVR_LIST_TR_POLY\n&amp;quot;);&lt;br /&gt;
            m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
With all this done, let’s draw some text to the screen. In our gamestate.cpp render() function:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY;&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                SubmitText(&amp;quot;Hello World!!&amp;quot;, FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
 	     OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see “HELLO WORLD!” rendered over the background!&lt;br /&gt;
&lt;br /&gt;
We can do other things with our SubmitText function. It can take a std::string if we use the c_str() function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Hello World!!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
We can also use variables in our string, with the built-in to_string function from &amp;lt;string&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Counter: &amp;quot;;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                Test += std::to_string(a);&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
You can use to_string to directly print a variable in our SubmitText function by using c_str() as well:&lt;br /&gt;
&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(std::to_string(a).c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
The 8x8 font actually looks pretty small on a 640x480 resolution, it was made for a 320x240 resolution in mind. The Dreamcast supports 320x240, but it’s sort of a hack. We can fake a 320x240 resolution by applying a scaling factor to all of our video functions. Let’s do that, in our gamestate class in gamestate.h, add the following private variable:&lt;br /&gt;
&lt;br /&gt;
    uint32_t VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will scale everything by a factor. We’ll set it to 2 to start in our constructor:&lt;br /&gt;
&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
    PrevControllerState.buttons = 0;&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    VideoScale = 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now, in our SubmitText function, let’s apply the scale:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
 T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
 T_vertex.x = X_In + (Idx * Font_Scale * VideoScale)  + (Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale;&lt;br /&gt;
 T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale * VideoScale);&lt;br /&gt;
 T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
 T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
 T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
 T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
&lt;br /&gt;
With our VideoScale set to 2, our 640x480 screen is treated like a 320x240 screen, or rather our text is rendered at double resolution!&lt;br /&gt;
&lt;br /&gt;
It would be very useful if our text rendering code could handle carriage returns. These are characters which starts a new line. We could pass a parameter to indicate the number of NewLines to start rendering at, and every time we encounter a ‘\n’ character we could add to it. Let’s build this out. In our Gamestate.h header, let’s clone our SubmitText function to overload it with an extra parameter for new lines:&lt;br /&gt;
&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In);&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In, uint32_t NewLines);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
    float VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
We need to create these functions. We’ll turn our existing function into the new function with the added parameter, then create a version of the original that calls our new function with new lines set to 0:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
    SubmitText(Input_String, FontSelector_Input, SizeFlag, X_In, Y_In, 0);&lt;br /&gt;
 }&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In, uint32_t NewLines)&lt;br /&gt;
 {&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
We are going to have a new variable called X_Position in our function to keep track of where we are drawing, so when we do a newline, we start at the beginning of the line. Previously we were using Idx as our value for the x position, but that wouldn’t reset with a new line character:&lt;br /&gt;
&lt;br /&gt;
      uint32_t X_Position = 0;&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
            if(Input_String[Idx] == &#039;\n&#039;)&lt;br /&gt;
            {&lt;br /&gt;
                NewLines++;&lt;br /&gt;
                X_Position = (-1);&lt;br /&gt;
            } else if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
We modify our if condition to add a check before our NULL Terminator check. This time, we’re looking for ‘\n’, which is the new line character. If we encounter it, increase our NewLines counter and reset our X_Position to -1. We set it to -1 instead of 0, because at the end of our loop we increase X_Position:&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
            X_Position++;&lt;br /&gt;
        }&lt;br /&gt;
    } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
Now, we need to change our vertex setting code to use X_Position  for the character position:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + ((X_Position * Font_Scale) * VideoScale)  + ((Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.y = Y_In + ((NewLines * Font_Scale) * VideoScale) + ((Vertex_ptr-&amp;gt;y * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
&lt;br /&gt;
With all this, we can now render newlines. Let’s test it in our Render function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
            std::string Test = &amp;quot;Hello World!! My name is gabriel\n&amp;quot;&lt;br /&gt;
                               &amp;quot;and I am typing this on my Sega \n&amp;quot;&lt;br /&gt;
                               &amp;quot;Dreamcast! \n\n&amp;quot;&lt;br /&gt;
                               &amp;quot;My email is support@aol.com!&amp;quot;;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_BIG, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
Every time we type \n, we get a new line in our text renderer!&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3740</id>
		<title>Text Rendering</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3740"/>
		<updated>2025-04-05T14:58:50Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Now that we can display our font texture with transparency correctly, let’s build our function to render text. To do this, we’ll have to manipulate the UV coordinates of the texture we render with.&lt;br /&gt;
&lt;br /&gt;
We start by making a clone of our SubmitQuad function, which we’ll call SubmitText. This will take some different parameters. First, it’ll take a const char* Input string. This is a c-style string, which is just an array of bytes on the stack. We want to take a font color, since our font.png texture has 4 different font colors. Each font in our texture atlus has 2 sizes, so we’ll take a flag to switch between them. Finally, we’ll take an X and Y coordinate to place the text on screen. Our Function should look like this:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
 			/* Function code in here */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Don’t forget to add this function declaration in Gamestate.h. This function is only for rendering text, so we can assume some things about it that we didn’t have to assume in the Quad function. We don’t want our text to have an opaque background, only transparent, so we’ll add a check to ensure we’re in the PVR_LIST_TR_POLY list:&lt;br /&gt;
&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
 		/* Transparent Polygon Bin code in here */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Our font atlus follows some rules that makes it organized well for our task. I drew the font so that every cell is 16x16 pixels big on the texture. There is an 8x8 font included on every other row, but they stick to the 16x16 grid. When the font is 8x8, it simply is stuck in the upper left corner of the 16x16 pixel grid. That makes the math involved in selecting which character to render a lot easier.&lt;br /&gt;
&lt;br /&gt;
We want to avoid if statements as much as possible when programming, they make our code unpredictable. It is better to use weighted math when possible to avoid branching conditions. This is a perfect example of when to use this. We have two font sizes we want to choose from, and how we choose them is by altering the vertical axis of our texture mapping coordinate by 16 pixels. Either our texture mapping coordinate will be X, or it’ll be X + 16. We can think of that as X + (0)*16, and X + (1)*16. By changing the variable from 0 to 1, our answer changes by 16 pixels each time, without needing an if branch. We can accomplish something like this in our code by using our SizeFlag in the parameters. Let’s create a final FontSize scaling factor:&lt;br /&gt;
        uint32_t Font_Scale = 8 * SizeFlag;&lt;br /&gt;
&lt;br /&gt;
This variable, Font_Scale, represents how many pixels downward our bottom UV coordinate is, from the top of our texture map. Our sizeFlag parameter can either be 1 or 2. If it’s 1, then we use 8 pixel tall fonts. If it’s 2, then we use 16 pixel tall fonts.&lt;br /&gt;
&lt;br /&gt;
After that, we create our texture mapping context header. This will use font_png exclusively, since it renders text, so we don’t need a variable for the texture enum:&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(font_png);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
&lt;br /&gt;
We can now start working on our vertices. We still use a temporary vertex, T_Vertex, to work on, and a pointer, Vertex_Ptr, to hold the mesh vertex we’re working on, as convinence labels for readability. We also introduce a couple of new variables. One is a uint8_t flag called Input_String_EOL. It is used to control the loop that we use to read the character array string containing our text to render. We also have a uint8_t variable called FontSelector. This variable chooses which vertical value to use for our uv texture map, to select between one of the four font types. Since each font has 2 sizes, and each font row is always 16 pixels tall, we can multiply our FontSelector_Input parameter, which goes from 0-3, by 2, so it skips both font lines. Lastly, we add the result of the SizeFlag parameter with modulus division by 2. This gives us the remainder of division. Our SizeFlag choices are 1 or 2, with 2 being big font (16) and 1 being small font (8). When we use the big font, we’re using the first line in our font atlus, when we use the small font, we’re using the second line. Thus, when we pass 2 by our SizeFlag parameter, we need it to turn into 0 for our Line Selector. And if we pass 1 by our SizeFlag parameter, we need it to turn into 1 for our Line Selector. Modulus division does this. 2%2 = 0, since we have a remainder of 0 when we do 2/2. Likewise, 2%1 = 1, because we have a remainder of 1 when we do 2/1. We add this modulus division to our FontSelector value, which shifts the row selected by 0 or 1.&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            uint8_t Input_String_EOL = 0;&lt;br /&gt;
            uint8_t FontSelector = 2*FontSelector_Input;&lt;br /&gt;
            FontSelector+=SizeFlag%2;&lt;br /&gt;
With our LineSelector determining which font row we’re using, we’re ready to start rendering the text. We’ll create a for-loop to iterate through the Input_String array, byte by byte:&lt;br /&gt;
&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
 	 }&lt;br /&gt;
&lt;br /&gt;
The condition for the loop to terminate is that Input_String_EOL is something other than 0, so that flag is our loop terminator. Input_String[Idx] is a byte containing a single character of our text string:&lt;br /&gt;
&lt;br /&gt;
 if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
 {&lt;br /&gt;
 	Input_String_EOL = 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The first condition to consider is if that character is ‘\0’. This is a special character called a “NULL Terminator.” It’s a character which means “nothing,” that is used to mark special conditions. When encountered in a C-Style String, it means that is the end of the String, called EOL. So we set our Input_String_EOL flag to 1 to end the loop.&lt;br /&gt;
&lt;br /&gt;
 else if(Input_String[Idx] &amp;lt; 33 || Input_String[Idx] &amp;gt; 122)&lt;br /&gt;
            {&lt;br /&gt;
                /* We only print the error if it&#039;s 31 or below, because 32 is space */&lt;br /&gt;
                if(Input_String[Idx] &amp;lt; 32)&lt;br /&gt;
                    printf(&amp;quot;Invalid Character to Render: %c\n&amp;quot;, Input_String[Idx]);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
The first if conditional is appended with an else if statement. This condition considers that our character that we’re examining isn’t EOL, but also isn’t valid. According to the ASCII map, the only inputs we are considering is 32 to 122, with 32 being a space character. We don’t render anything for space, so we check to make sure our value is between 33 and 122. If it’s not, skip rendering and give a small message letting us know we encountered an unknown character.&lt;br /&gt;
&lt;br /&gt;
 else /* Render the character to the screen as a quad */&lt;br /&gt;
            {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
We append one last else condition. This is what happens if this is a valid character between 33 and 122. We need to do some more math on it. Characters after the value of 96 are actually lower case characters, and our font set does not cover those. So we can subtract 32 from our value if it’s after 96, which will turn lower case characters into upper case characters:&lt;br /&gt;
&lt;br /&gt;
                int32_t CharIdx = (uint8_t)Input_String[Idx];&lt;br /&gt;
                if(Input_String[Idx] &amp;gt; 96)&lt;br /&gt;
                {&lt;br /&gt;
                    CharIdx = CharIdx - 32;&lt;br /&gt;
                }&lt;br /&gt;
This ensures our index is now between 33 and 96. We want to turn this into an index from the range of 0-63, with each number being a horizontal cell index in our font texture. 64 x 16 = 1024:&lt;br /&gt;
CharIdx = CharIdx - 33;     /* Turn our CharIdx into a index for our array, we use 33 to turn space into -1 */&lt;br /&gt;
&lt;br /&gt;
With our Index now correctly configured, we can begin drawing the character. We need to call to get a vertex from our quad mesh, and we need to do it for 4 times as this is a quad. m_Meshes.Get(e_Quad)→m_VtxCount returns 4 programmatically:&lt;br /&gt;
&lt;br /&gt;
 for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now we’re ready to prime and submit our vertex. We use Vertex_Ptr to hold our vertex in our Quad Mesh:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + (Idx * Font_Scale)  + (Vertex_ptr-&amp;gt;x * Font_Scale);&lt;br /&gt;
                    T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                    &lt;br /&gt;
The main bit of this text rendering algorithm comes from how we set T_Vertex.x and T_Vertex.y, as well as T_Vertex.u and T_Vertex.v.&lt;br /&gt;
&lt;br /&gt;
T_Vertex.x is what determines the horizontal position of the quad being drawn. We start with our base X_In parameter, which becomes the origin of our Text Renderer. We add to this X_In origin the result of multiplication of the Index by the Font_Scale. Font_Scale will be either 8 or 16, and the Idx is choosing how many of these 8 or 16 pixel steps to move over. This makes the spot where we render our next character quad to shift over so we’re not rendering on top of ourselves.&lt;br /&gt;
&lt;br /&gt;
This same formula will be run on all 4 vertices of the quad. 2 of the vertices are on the left side of the edge of the quad, which is equal to our origin at X_Int. However, the other 2 vertices are on the right side of the quad, which is Font_Scale pixels to the right (either 8 or 16). When we made our Quad Mesh, the vertices on the left had a 0 in their x variable, and the vertices on the right had a 1. We can use this variable, Vertex_ptr-&amp;gt;x, as an on/off switch for our Font_Scale variable. This creates the XY coordinates for the quad that will make up our text character on screen, next we need to select it from the texture.&lt;br /&gt;
&lt;br /&gt;
When we do texture mapping, we are assigning an X,Y coordinate to each vertex that tells it where that corner should map to on our texture. Because X,Y are already used in our vertex to describe the position, we use UV instead. Anytime we see UV, we are likely talking about texture coordinates. In addition to knowing their use intuitively, the choice of UV also tells us that our values are normalized. Recall that normalizing a value restricts it between a range of 0.00 to 1.00. This turns our value into a percentage. That means when we describe our texture mapping coordinates, we do not do so in terms of pixel values. Rather, we describe our coordinates as “percentage to the right of our texture” and “percentage to the bottom of our texture.”&lt;br /&gt;
&lt;br /&gt;
You might think this method of storing coordinates is silly, but it’s very useful for textures. This is because we don’t always use the same size for our texture. A method to reduce computation for texture scaling is mipmapping, which involves creating the same texture multiple times in memory at different pre-scaled resolutions. If we described our texture mapping in terms of pixel coordinates, this wouldn’t work. If our texture at full resolution is 640 pixels horizontally, and we are at 50% mipmap level, and we tell our vertex to map to texel 640, it wouldn’t know what to do. At 50% mipmap level, our horizontal span is only 320. By describing our coordinate as a percentage, it remains the same no matter what size the texture.&lt;br /&gt;
&lt;br /&gt;
For example, if our right edge corner of our quad needs to map to the far right edge of the texture, we can say it’s 100% to the right. That way, if we are using 100% mipmap level, that’s pixel 640. And if we are using 50% mipmap level, then that’s pixel 320. Using UV coordinates as percentages, and thus describing them as normalized floats, keeps everything working as intended.&lt;br /&gt;
&lt;br /&gt;
Luckily the formula to translate from pixel space to normalized percentage is easy. U = X/Width, and V= Y/Height. To give an example, if we wanted to get a texel on the far right edge of a 640 pixel texture, then U = 640/640 = 1 = 100%. If we wanted to get a texel on the dead center of the texture, then U = 320/640 = .5 = 50%. This works for the V coordinate as well. We are doing exactly this in our T_Vertex.u calculation, just with more variables worked in:&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
                    T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
                    T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                    T_vertex.oargb = Vertex_ptr→oargb;&lt;br /&gt;
&lt;br /&gt;
The left edge of our texture map moves over by 16 pixels times our character index. This selects the character on the texture map. Our vertex was created with UV coordinates that change between 0 and 1, just like our position coordinates, so we can use them as a flag for turning off an offset in our calculation. In this case, the UV flag adds our Font_Scale variable (8 or 16 pixels). We then divide all of this by 1024.0f, our font.png width. That gives us the left and right edges of our texture map.&lt;br /&gt;
&lt;br /&gt;
We do the same for V using the Y coordinates. Instead of 1024.0f as our width, we use 128.0f as our height. &lt;br /&gt;
&lt;br /&gt;
With our Vertices calculated correctly for the text, we can submit them as we finish each loop:&lt;br /&gt;
&lt;br /&gt;
 /* Submit data */&lt;br /&gt;
                    pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
Everytime we submit a quad, we need to increment RenderDepth so we avoid z-fighting:&lt;br /&gt;
&lt;br /&gt;
 RenderDepth += 0.1;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
   } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
&lt;br /&gt;
We attach an else condition at the end of our close braces. At the very beginning of this function, we checked if we were on the PVR_LIST_TR_POLY bin list. If we’re not, we print a little error:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
        if(m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            printf(&amp;quot;Could not render text, font texture format is not PVR_LIST_TR_POLY\n&amp;quot;);&lt;br /&gt;
            m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
With all this done, let’s draw some text to the screen. In our gamestate.cpp render() function:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY;&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                SubmitText(&amp;quot;Hello World!!&amp;quot;, FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
	     OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see “HELLO WORLD!” rendered over the background!&lt;br /&gt;
&lt;br /&gt;
We can do other things with our SubmitText function. It can take a std::string if we use the c_str() function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Hello World!!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
We can also use variables in our string, with the built-in to_string function from &amp;lt;string&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Counter: &amp;quot;;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                Test += std::to_string(a);&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
You can use to_string to directly print a variable in our SubmitText function by using c_str() as well:&lt;br /&gt;
&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(std::to_string(a).c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
The 8x8 font actually looks pretty small on a 640x480 resolution, it was made for a 320x240 resolution in mind. The Dreamcast supports 320x240, but it’s sort of a hack. We can fake a 320x240 resolution by applying a scaling factor to all of our video functions. Let’s do that, in our gamestate class in gamestate.h, add the following private variable:&lt;br /&gt;
&lt;br /&gt;
    uint32_t VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will scale everything by a factor. We’ll set it to 2 to start in our constructor:&lt;br /&gt;
&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
    PrevControllerState.buttons = 0;&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    VideoScale = 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now, in our SubmitText function, let’s apply the scale:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
 T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
 T_vertex.x = X_In + (Idx * Font_Scale * VideoScale)  + (Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale;&lt;br /&gt;
 T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale * VideoScale);&lt;br /&gt;
 T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
 T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
 T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
 T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
&lt;br /&gt;
With our VideoScale set to 2, our 640x480 screen is treated like a 320x240 screen, or rather our text is rendered at double resolution!&lt;br /&gt;
&lt;br /&gt;
It would be very useful if our text rendering code could handle carriage returns. These are characters which starts a new line. We could pass a parameter to indicate the number of NewLines to start rendering at, and every time we encounter a ‘\n’ character we could add to it. Let’s build this out. In our Gamestate.h header, let’s clone our SubmitText function to overload it with an extra parameter for new lines:&lt;br /&gt;
&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In);&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In, uint32_t NewLines);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
    float VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
We need to create these functions. We’ll turn our existing function into the new function with the added parameter, then create a version of the original that calls our new function with new lines set to 0:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
    SubmitText(Input_String, FontSelector_Input, SizeFlag, X_In, Y_In, 0);&lt;br /&gt;
 }&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In, uint32_t NewLines)&lt;br /&gt;
 {&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
We are going to have a new variable called X_Position in our function to keep track of where we are drawing, so when we do a newline, we start at the beginning of the line. Previously we were using Idx as our value for the x position, but that wouldn’t reset with a new line character:&lt;br /&gt;
&lt;br /&gt;
      uint32_t X_Position = 0;&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
            if(Input_String[Idx] == &#039;\n&#039;)&lt;br /&gt;
            {&lt;br /&gt;
                NewLines++;&lt;br /&gt;
                X_Position = (-1);&lt;br /&gt;
            } else if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
We modify our if condition to add a check before our NULL Terminator check. This time, we’re looking for ‘\n’, which is the new line character. If we encounter it, increase our NewLines counter and reset our X_Position to -1. We set it to -1 instead of 0, because at the end of our loop we increase X_Position:&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
            X_Position++;&lt;br /&gt;
        }&lt;br /&gt;
    } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
Now, we need to change our vertex setting code to use X_Position  for the character position:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + ((X_Position * Font_Scale) * VideoScale)  + ((Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.y = Y_In + ((NewLines * Font_Scale) * VideoScale) + ((Vertex_ptr-&amp;gt;y * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
&lt;br /&gt;
With all this, we can now render newlines. Let’s test it in our Render function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
            std::string Test = &amp;quot;Hello World!! My name is gabriel\n&amp;quot;&lt;br /&gt;
                               &amp;quot;and I am typing this on my Sega \n&amp;quot;&lt;br /&gt;
                               &amp;quot;Dreamcast! \n\n&amp;quot;&lt;br /&gt;
                               &amp;quot;My email is support@aol.com!&amp;quot;;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_BIG, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
Every time we type \n, we get a new line in our text renderer!&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3739</id>
		<title>Text Rendering</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3739"/>
		<updated>2025-04-05T14:57:21Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Now that we can display our font texture with transparency correctly, let’s build our function to render text. To do this, we’ll have to manipulate the UV coordinates of the texture we render with.&lt;br /&gt;
&lt;br /&gt;
We start by making a clone of our SubmitQuad function, which we’ll call SubmitText. This will take some different parameters. First, it’ll take a const char* Input string. This is a c-style string, which is just an array of bytes on the stack. We want to take a font color, since our font.png texture has 4 different font colors. Each font in our texture atlus has 2 sizes, so we’ll take a flag to switch between them. Finally, we’ll take an X and Y coordinate to place the text on screen. Our Function should look like this:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
 			/* Function code in here */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Don’t forget to add this function declaration in Gamestate.h. This function is only for rendering text, so we can assume some things about it that we didn’t have to assume in the Quad function. We don’t want our text to have an opaque background, only transparent, so we’ll add a check to ensure we’re in the PVR_LIST_TR_POLY list:&lt;br /&gt;
&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
 		/* Transparent Polygon Bin code in here */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Our font atlus follows some rules that makes it organized well for our task. I drew the font so that every cell is 16x16 pixels big on the texture. There is an 8x8 font included on every other row, but they stick to the 16x16 grid. When the font is 8x8, it simply is stuck in the upper left corner of the 16x16 pixel grid. That makes the math involved in selecting which character to render a lot easier.&lt;br /&gt;
&lt;br /&gt;
We want to avoid if statements as much as possible when programming, they make our code unpredictable. It is better to use weighted math when possible to avoid branching conditions. This is a perfect example of when to use this. We have two font sizes we want to choose from, and how we choose them is by altering the vertical axis of our texture mapping coordinate by 16 pixels. Either our texture mapping coordinate will be X, or it’ll be X + 16. We can think of that as X + (0)*16, and X + (1)*16. By changing the variable from 0 to 1, our answer changes by 16 pixels each time, without needing an if branch. We can accomplish something like this in our code by using our SizeFlag in the parameters. Let’s create a final FontSize scaling factor:&lt;br /&gt;
        uint32_t Font_Scale = 8 * SizeFlag;&lt;br /&gt;
&lt;br /&gt;
This variable, Font_Scale, represents how many pixels downward our bottom UV coordinate is, from the top of our texture map. Our sizeFlag parameter can either be 1 or 2. If it’s 1, then we use 8 pixel tall fonts. If it’s 2, then we use 16 pixel tall fonts.&lt;br /&gt;
&lt;br /&gt;
After that, we create our texture mapping context header. This will use font_png exclusively, since it renders text, so we don’t need a variable for the texture enum:&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(font_png);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
&lt;br /&gt;
We can now start working on our vertices. We still use a temporary vertex, T_Vertex, to work on, and a pointer, Vertex_Ptr, to hold the mesh vertex we’re working on, as convinence labels for readability. We also introduce a couple of new variables. One is a uint8_t flag called Input_String_EOL. It is used to control the loop that we use to read the character array string containing our text to render. We also have a uint8_t variable called FontSelector. This variable chooses which vertical value to use for our uv texture map, to select between one of the four font types. Since each font has 2 sizes, and each font row is always 16 pixels tall, we can multiply our FontSelector_Input parameter, which goes from 0-3, by 2, so it skips both font lines. Lastly, we add the result of the SizeFlag parameter with modulus division by 2. This gives us the remainder of division. Our SizeFlag choices are 1 or 2, with 2 being big font (16) and 1 being small font (8). When we use the big font, we’re using the first line in our font atlus, when we use the small font, we’re using the second line. Thus, when we pass 2 by our SizeFlag parameter, we need it to turn into 0 for our Line Selector. And if we pass 1 by our SizeFlag parameter, we need it to turn into 1 for our Line Selector. Modulus division does this. 2%2 = 0, since we have a remainder of 0 when we do 2/2. Likewise, 2%1 = 1, because we have a remainder of 1 when we do 2/1. We add this modulus division to our FontSelector value, which shifts the row selected by 0 or 1.&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            uint8_t Input_String_EOL = 0;&lt;br /&gt;
            uint8_t FontSelector = 2*FontSelector_Input;&lt;br /&gt;
            FontSelector+=SizeFlag%2;&lt;br /&gt;
With our LineSelector determining which font row we’re using, we’re ready to start rendering the text. We’ll create a for-loop to iterate through the Input_String array, byte by byte:&lt;br /&gt;
&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
 	 }&lt;br /&gt;
&lt;br /&gt;
The condition for the loop to terminate is that Input_String_EOL is something other than 0, so that flag is our loop terminator. Input_String[Idx] is a byte containing a single character of our text string:&lt;br /&gt;
&lt;br /&gt;
 if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
 {&lt;br /&gt;
 	Input_String_EOL = 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The first condition to consider is if that character is ‘\0’. This is a special character called a “NULL Terminator.” It’s a character which means “nothing,” that is used to mark special conditions. When encountered in a C-Style String, it means that is the end of the String, called EOL. So we set our Input_String_EOL flag to 1 to end the loop.&lt;br /&gt;
&lt;br /&gt;
 else if(Input_String[Idx] &amp;lt; 33 || Input_String[Idx] &amp;gt; 122)&lt;br /&gt;
            {&lt;br /&gt;
                /* We only print the error if it&#039;s 31 or below, because 32 is space */&lt;br /&gt;
                if(Input_String[Idx] &amp;lt; 32)&lt;br /&gt;
                    printf(&amp;quot;Invalid Character to Render: %c\n&amp;quot;, Input_String[Idx]);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
The first if conditional is appended with an else if statement. This condition considers that our character that we’re examining isn’t EOL, but also isn’t valid. According to the ASCII map, the only inputs we are considering is 32 to 122, with 32 being a space character. We don’t render anything for space, so we check to make sure our value is between 33 and 122. If it’s not, skip rendering and give a small message letting us know we encountered an unknown character.&lt;br /&gt;
&lt;br /&gt;
 else /* Render the character to the screen as a quad */&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
We append one last else condition. This is what happens if this is a valid character between 33 and 122. We need to do some more math on it. Characters after the value of 96 are actually lower case characters, and our font set does not cover those. So we can subtract 32 from our value if it’s after 96, which will turn lower case characters into upper case characters:&lt;br /&gt;
&lt;br /&gt;
                int32_t CharIdx = (uint8_t)Input_String[Idx];&lt;br /&gt;
                if(Input_String[Idx] &amp;gt; 96)&lt;br /&gt;
                {&lt;br /&gt;
                    CharIdx = CharIdx - 32;&lt;br /&gt;
                }&lt;br /&gt;
This ensures our index is now between 33 and 96. We want to turn this into an index from the range of 0-63, with each number being a horizontal cell index in our font texture. 64 x 16 = 1024:&lt;br /&gt;
CharIdx = CharIdx - 33;     /* Turn our CharIdx into a index for our array, we use 33 to turn space into -1 */&lt;br /&gt;
&lt;br /&gt;
With our Index now correctly configured, we can begin drawing the character. We need to call to get a vertex from our quad mesh, and we need to do it for 4 times as this is a quad. m_Meshes.Get(e_Quad)→m_VtxCount returns 4 programmatically:&lt;br /&gt;
&lt;br /&gt;
 for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now we’re ready to prime and submit our vertex. We use Vertex_Ptr to hold our vertex in our Quad Mesh:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + (Idx * Font_Scale)  + (Vertex_ptr-&amp;gt;x * Font_Scale);&lt;br /&gt;
                    T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                    &lt;br /&gt;
The main bit of this text rendering algorithm comes from how we set T_Vertex.x and T_Vertex.y, as well as T_Vertex.u and T_Vertex.v.&lt;br /&gt;
&lt;br /&gt;
T_Vertex.x is what determines the horizontal position of the quad being drawn. We start with our base X_In parameter, which becomes the origin of our Text Renderer. We add to this X_In origin the result of multiplication of the Index by the Font_Scale. Font_Scale will be either 8 or 16, and the Idx is choosing how many of these 8 or 16 pixel steps to move over. This makes the spot where we render our next character quad to shift over so we’re not rendering on top of ourselves.&lt;br /&gt;
&lt;br /&gt;
This same formula will be run on all 4 vertices of the quad. 2 of the vertices are on the left side of the edge of the quad, which is equal to our origin at X_Int. However, the other 2 vertices are on the right side of the quad, which is Font_Scale pixels to the right (either 8 or 16). When we made our Quad Mesh, the vertices on the left had a 0 in their x variable, and the vertices on the right had a 1. We can use this variable, Vertex_ptr-&amp;gt;x, as an on/off switch for our Font_Scale variable. This creates the XY coordinates for the quad that will make up our text character on screen, next we need to select it from the texture.&lt;br /&gt;
&lt;br /&gt;
When we do texture mapping, we are assigning an X,Y coordinate to each vertex that tells it where that corner should map to on our texture. Because X,Y are already used in our vertex to describe the position, we use UV instead. Anytime we see UV, we are likely talking about texture coordinates. In addition to knowing their use intuitively, the choice of UV also tells us that our values are normalized. Recall that normalizing a value restricts it between a range of 0.00 to 1.00. This turns our value into a percentage. That means when we describe our texture mapping coordinates, we do not do so in terms of pixel values. Rather, we describe our coordinates as “percentage to the right of our texture” and “percentage to the bottom of our texture.”&lt;br /&gt;
&lt;br /&gt;
You might think this method of storing coordinates is silly, but it’s very useful for textures. This is because we don’t always use the same size for our texture. A method to reduce computation for texture scaling is mipmapping, which involves creating the same texture multiple times in memory at different pre-scaled resolutions. If we described our texture mapping in terms of pixel coordinates, this wouldn’t work. If our texture at full resolution is 640 pixels horizontally, and we are at 50% mipmap level, and we tell our vertex to map to texel 640, it wouldn’t know what to do. At 50% mipmap level, our horizontal span is only 320. By describing our coordinate as a percentage, it remains the same no matter what size the texture.&lt;br /&gt;
&lt;br /&gt;
For example, if our right edge corner of our quad needs to map to the far right edge of the texture, we can say it’s 100% to the right. That way, if we are using 100% mipmap level, that’s pixel 640. And if we are using 50% mipmap level, then that’s pixel 320. Using UV coordinates as percentages, and thus describing them as normalized floats, keeps everything working as intended.&lt;br /&gt;
&lt;br /&gt;
Luckily the formula to translate from pixel space to normalized percentage is easy. U = X/Width, and V= Y/Height. To give an example, if we wanted to get a texel on the far right edge of a 640 pixel texture, then U = 640/640 = 1 = 100%. If we wanted to get a texel on the dead center of the texture, then U = 320/640 = .5 = 50%. This works for the V coordinate as well. We are doing exactly this in our T_Vertex.u calculation, just with more variables worked in:&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
                    T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
                    T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                    T_vertex.oargb = Vertex_ptr→oargb;&lt;br /&gt;
&lt;br /&gt;
The left edge of our texture map moves over by 16 pixels times our character index. This selects the character on the texture map. Our vertex was created with UV coordinates that change between 0 and 1, just like our position coordinates, so we can use them as a flag for turning off an offset in our calculation. In this case, the UV flag adds our Font_Scale variable (8 or 16 pixels). We then divide all of this by 1024.0f, our font.png width. That gives us the left and right edges of our texture map.&lt;br /&gt;
&lt;br /&gt;
We do the same for V using the Y coordinates. Instead of 1024.0f as our width, we use 128.0f as our height. &lt;br /&gt;
&lt;br /&gt;
With our Vertices calculated correctly for the text, we can submit them as we finish each loop:&lt;br /&gt;
&lt;br /&gt;
 /* Submit data */&lt;br /&gt;
                    pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
Everytime we submit a quad, we need to increment RenderDepth so we avoid z-fighting:&lt;br /&gt;
&lt;br /&gt;
 RenderDepth += 0.1;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
   } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
&lt;br /&gt;
We attach an else condition at the end of our close braces. At the very beginning of this function, we checked if we were on the PVR_LIST_TR_POLY bin list. If we’re not, we print a little error:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
        if(m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            printf(&amp;quot;Could not render text, font texture format is not PVR_LIST_TR_POLY\n&amp;quot;);&lt;br /&gt;
            m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
With all this done, let’s draw some text to the screen. In our gamestate.cpp render() function:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY;&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                SubmitText(&amp;quot;Hello World!!&amp;quot;, FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
	     OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see “HELLO WORLD!” rendered over the background!&lt;br /&gt;
&lt;br /&gt;
We can do other things with our SubmitText function. It can take a std::string if we use the c_str() function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Hello World!!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
We can also use variables in our string, with the built-in to_string function from &amp;lt;string&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Counter: &amp;quot;;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                Test += std::to_string(a);&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
You can use to_string to directly print a variable in our SubmitText function by using c_str() as well:&lt;br /&gt;
&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(std::to_string(a).c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
The 8x8 font actually looks pretty small on a 640x480 resolution, it was made for a 320x240 resolution in mind. The Dreamcast supports 320x240, but it’s sort of a hack. We can fake a 320x240 resolution by applying a scaling factor to all of our video functions. Let’s do that, in our gamestate class in gamestate.h, add the following private variable:&lt;br /&gt;
&lt;br /&gt;
    uint32_t VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will scale everything by a factor. We’ll set it to 2 to start in our constructor:&lt;br /&gt;
&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
    PrevControllerState.buttons = 0;&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    VideoScale = 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now, in our SubmitText function, let’s apply the scale:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
 T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
 T_vertex.x = X_In + (Idx * Font_Scale * VideoScale)  + (Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale;&lt;br /&gt;
 T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale * VideoScale);&lt;br /&gt;
 T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
 T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
 T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
 T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
&lt;br /&gt;
With our VideoScale set to 2, our 640x480 screen is treated like a 320x240 screen, or rather our text is rendered at double resolution!&lt;br /&gt;
&lt;br /&gt;
It would be very useful if our text rendering code could handle carriage returns. These are characters which starts a new line. We could pass a parameter to indicate the number of NewLines to start rendering at, and every time we encounter a ‘\n’ character we could add to it. Let’s build this out. In our Gamestate.h header, let’s clone our SubmitText function to overload it with an extra parameter for new lines:&lt;br /&gt;
&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In);&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In, uint32_t NewLines);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
    float VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
We need to create these functions. We’ll turn our existing function into the new function with the added parameter, then create a version of the original that calls our new function with new lines set to 0:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
    SubmitText(Input_String, FontSelector_Input, SizeFlag, X_In, Y_In, 0);&lt;br /&gt;
 }&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In, uint32_t NewLines)&lt;br /&gt;
 {&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
We are going to have a new variable called X_Position in our function to keep track of where we are drawing, so when we do a newline, we start at the beginning of the line. Previously we were using Idx as our value for the x position, but that wouldn’t reset with a new line character:&lt;br /&gt;
&lt;br /&gt;
      uint32_t X_Position = 0;&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
            if(Input_String[Idx] == &#039;\n&#039;)&lt;br /&gt;
            {&lt;br /&gt;
                NewLines++;&lt;br /&gt;
                X_Position = (-1);&lt;br /&gt;
            } else if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
We modify our if condition to add a check before our NULL Terminator check. This time, we’re looking for ‘\n’, which is the new line character. If we encounter it, increase our NewLines counter and reset our X_Position to -1. We set it to -1 instead of 0, because at the end of our loop we increase X_Position:&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
            X_Position++;&lt;br /&gt;
        }&lt;br /&gt;
    } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
Now, we need to change our vertex setting code to use X_Position  for the character position:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + ((X_Position * Font_Scale) * VideoScale)  + ((Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.y = Y_In + ((NewLines * Font_Scale) * VideoScale) + ((Vertex_ptr-&amp;gt;y * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
&lt;br /&gt;
With all this, we can now render newlines. Let’s test it in our Render function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
            std::string Test = &amp;quot;Hello World!! My name is gabriel\n&amp;quot;&lt;br /&gt;
                               &amp;quot;and I am typing this on my Sega \n&amp;quot;&lt;br /&gt;
                               &amp;quot;Dreamcast! \n\n&amp;quot;&lt;br /&gt;
                               &amp;quot;My email is support@aol.com!&amp;quot;;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_BIG, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
Every time we type \n, we get a new line in our text renderer!&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3738</id>
		<title>Text Rendering</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Text_Rendering&amp;diff=3738"/>
		<updated>2025-04-05T14:56:59Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Created page with &amp;quot;Now that we can display our font texture with transparency correctly, let’s build our function to render text. To do this, we’ll have to manipulate the UV coordinates of the texture we render with.  We start by making a clone of our SubmitQuad function, which we’ll call SubmitText. This will take some different parameters. First, it’ll take a const char* Input string. This is a c-style string, which is just an array of bytes on the stack. We want to take a font c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Now that we can display our font texture with transparency correctly, let’s build our function to render text. To do this, we’ll have to manipulate the UV coordinates of the texture we render with.&lt;br /&gt;
&lt;br /&gt;
We start by making a clone of our SubmitQuad function, which we’ll call SubmitText. This will take some different parameters. First, it’ll take a const char* Input string. This is a c-style string, which is just an array of bytes on the stack. We want to take a font color, since our font.png texture has 4 different font colors. Each font in our texture atlus has 2 sizes, so we’ll take a flag to switch between them. Finally, we’ll take an X and Y coordinate to place the text on screen. Our Function should look like this:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
			/* Function code in here */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Don’t forget to add this function declaration in Gamestate.h. This function is only for rendering text, so we can assume some things about it that we didn’t have to assume in the Quad function. We don’t want our text to have an opaque background, only transparent, so we’ll add a check to ensure we’re in the PVR_LIST_TR_POLY list:&lt;br /&gt;
&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
		/* Transparent Polygon Bin code in here */&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Our font atlus follows some rules that makes it organized well for our task. I drew the font so that every cell is 16x16 pixels big on the texture. There is an 8x8 font included on every other row, but they stick to the 16x16 grid. When the font is 8x8, it simply is stuck in the upper left corner of the 16x16 pixel grid. That makes the math involved in selecting which character to render a lot easier.&lt;br /&gt;
&lt;br /&gt;
We want to avoid if statements as much as possible when programming, they make our code unpredictable. It is better to use weighted math when possible to avoid branching conditions. This is a perfect example of when to use this. We have two font sizes we want to choose from, and how we choose them is by altering the vertical axis of our texture mapping coordinate by 16 pixels. Either our texture mapping coordinate will be X, or it’ll be X + 16. We can think of that as X + (0)*16, and X + (1)*16. By changing the variable from 0 to 1, our answer changes by 16 pixels each time, without needing an if branch. We can accomplish something like this in our code by using our SizeFlag in the parameters. Let’s create a final FontSize scaling factor:&lt;br /&gt;
        uint32_t Font_Scale = 8 * SizeFlag;&lt;br /&gt;
&lt;br /&gt;
This variable, Font_Scale, represents how many pixels downward our bottom UV coordinate is, from the top of our texture map. Our sizeFlag parameter can either be 1 or 2. If it’s 1, then we use 8 pixel tall fonts. If it’s 2, then we use 16 pixel tall fonts.&lt;br /&gt;
&lt;br /&gt;
After that, we create our texture mapping context header. This will use font_png exclusively, since it renders text, so we don’t need a variable for the texture enum:&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(font_png);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
&lt;br /&gt;
We can now start working on our vertices. We still use a temporary vertex, T_Vertex, to work on, and a pointer, Vertex_Ptr, to hold the mesh vertex we’re working on, as convinence labels for readability. We also introduce a couple of new variables. One is a uint8_t flag called Input_String_EOL. It is used to control the loop that we use to read the character array string containing our text to render. We also have a uint8_t variable called FontSelector. This variable chooses which vertical value to use for our uv texture map, to select between one of the four font types. Since each font has 2 sizes, and each font row is always 16 pixels tall, we can multiply our FontSelector_Input parameter, which goes from 0-3, by 2, so it skips both font lines. Lastly, we add the result of the SizeFlag parameter with modulus division by 2. This gives us the remainder of division. Our SizeFlag choices are 1 or 2, with 2 being big font (16) and 1 being small font (8). When we use the big font, we’re using the first line in our font atlus, when we use the small font, we’re using the second line. Thus, when we pass 2 by our SizeFlag parameter, we need it to turn into 0 for our Line Selector. And if we pass 1 by our SizeFlag parameter, we need it to turn into 1 for our Line Selector. Modulus division does this. 2%2 = 0, since we have a remainder of 0 when we do 2/2. Likewise, 2%1 = 1, because we have a remainder of 1 when we do 2/1. We add this modulus division to our FontSelector value, which shifts the row selected by 0 or 1.&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            uint8_t Input_String_EOL = 0;&lt;br /&gt;
            uint8_t FontSelector = 2*FontSelector_Input;&lt;br /&gt;
            FontSelector+=SizeFlag%2;&lt;br /&gt;
With our LineSelector determining which font row we’re using, we’re ready to start rendering the text. We’ll create a for-loop to iterate through the Input_String array, byte by byte:&lt;br /&gt;
&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
 	 }&lt;br /&gt;
&lt;br /&gt;
The condition for the loop to terminate is that Input_String_EOL is something other than 0, so that flag is our loop terminator. Input_String[Idx] is a byte containing a single character of our text string:&lt;br /&gt;
&lt;br /&gt;
 if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
 {&lt;br /&gt;
 	Input_String_EOL = 1;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
The first condition to consider is if that character is ‘\0’. This is a special character called a “NULL Terminator.” It’s a character which means “nothing,” that is used to mark special conditions. When encountered in a C-Style String, it means that is the end of the String, called EOL. So we set our Input_String_EOL flag to 1 to end the loop.&lt;br /&gt;
&lt;br /&gt;
 else if(Input_String[Idx] &amp;lt; 33 || Input_String[Idx] &amp;gt; 122)&lt;br /&gt;
            {&lt;br /&gt;
                /* We only print the error if it&#039;s 31 or below, because 32 is space */&lt;br /&gt;
                if(Input_String[Idx] &amp;lt; 32)&lt;br /&gt;
                    printf(&amp;quot;Invalid Character to Render: %c\n&amp;quot;, Input_String[Idx]);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
The first if conditional is appended with an else if statement. This condition considers that our character that we’re examining isn’t EOL, but also isn’t valid. According to the ASCII map, the only inputs we are considering is 32 to 122, with 32 being a space character. We don’t render anything for space, so we check to make sure our value is between 33 and 122. If it’s not, skip rendering and give a small message letting us know we encountered an unknown character.&lt;br /&gt;
&lt;br /&gt;
 else /* Render the character to the screen as a quad */&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
We append one last else condition. This is what happens if this is a valid character between 33 and 122. We need to do some more math on it. Characters after the value of 96 are actually lower case characters, and our font set does not cover those. So we can subtract 32 from our value if it’s after 96, which will turn lower case characters into upper case characters:&lt;br /&gt;
&lt;br /&gt;
                int32_t CharIdx = (uint8_t)Input_String[Idx];&lt;br /&gt;
                if(Input_String[Idx] &amp;gt; 96)&lt;br /&gt;
                {&lt;br /&gt;
                    CharIdx = CharIdx - 32;&lt;br /&gt;
                }&lt;br /&gt;
This ensures our index is now between 33 and 96. We want to turn this into an index from the range of 0-63, with each number being a horizontal cell index in our font texture. 64 x 16 = 1024:&lt;br /&gt;
CharIdx = CharIdx - 33;     /* Turn our CharIdx into a index for our array, we use 33 to turn space into -1 */&lt;br /&gt;
&lt;br /&gt;
With our Index now correctly configured, we can begin drawing the character. We need to call to get a vertex from our quad mesh, and we need to do it for 4 times as this is a quad. m_Meshes.Get(e_Quad)→m_VtxCount returns 4 programmatically:&lt;br /&gt;
&lt;br /&gt;
 for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
 {&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now we’re ready to prime and submit our vertex. We use Vertex_Ptr to hold our vertex in our Quad Mesh:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + (Idx * Font_Scale)  + (Vertex_ptr-&amp;gt;x * Font_Scale);&lt;br /&gt;
                    T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                    &lt;br /&gt;
The main bit of this text rendering algorithm comes from how we set T_Vertex.x and T_Vertex.y, as well as T_Vertex.u and T_Vertex.v.&lt;br /&gt;
&lt;br /&gt;
T_Vertex.x is what determines the horizontal position of the quad being drawn. We start with our base X_In parameter, which becomes the origin of our Text Renderer. We add to this X_In origin the result of multiplication of the Index by the Font_Scale. Font_Scale will be either 8 or 16, and the Idx is choosing how many of these 8 or 16 pixel steps to move over. This makes the spot where we render our next character quad to shift over so we’re not rendering on top of ourselves.&lt;br /&gt;
&lt;br /&gt;
This same formula will be run on all 4 vertices of the quad. 2 of the vertices are on the left side of the edge of the quad, which is equal to our origin at X_Int. However, the other 2 vertices are on the right side of the quad, which is Font_Scale pixels to the right (either 8 or 16). When we made our Quad Mesh, the vertices on the left had a 0 in their x variable, and the vertices on the right had a 1. We can use this variable, Vertex_ptr-&amp;gt;x, as an on/off switch for our Font_Scale variable. This creates the XY coordinates for the quad that will make up our text character on screen, next we need to select it from the texture.&lt;br /&gt;
&lt;br /&gt;
When we do texture mapping, we are assigning an X,Y coordinate to each vertex that tells it where that corner should map to on our texture. Because X,Y are already used in our vertex to describe the position, we use UV instead. Anytime we see UV, we are likely talking about texture coordinates. In addition to knowing their use intuitively, the choice of UV also tells us that our values are normalized. Recall that normalizing a value restricts it between a range of 0.00 to 1.00. This turns our value into a percentage. That means when we describe our texture mapping coordinates, we do not do so in terms of pixel values. Rather, we describe our coordinates as “percentage to the right of our texture” and “percentage to the bottom of our texture.”&lt;br /&gt;
&lt;br /&gt;
You might think this method of storing coordinates is silly, but it’s very useful for textures. This is because we don’t always use the same size for our texture. A method to reduce computation for texture scaling is mipmapping, which involves creating the same texture multiple times in memory at different pre-scaled resolutions. If we described our texture mapping in terms of pixel coordinates, this wouldn’t work. If our texture at full resolution is 640 pixels horizontally, and we are at 50% mipmap level, and we tell our vertex to map to texel 640, it wouldn’t know what to do. At 50% mipmap level, our horizontal span is only 320. By describing our coordinate as a percentage, it remains the same no matter what size the texture.&lt;br /&gt;
&lt;br /&gt;
For example, if our right edge corner of our quad needs to map to the far right edge of the texture, we can say it’s 100% to the right. That way, if we are using 100% mipmap level, that’s pixel 640. And if we are using 50% mipmap level, then that’s pixel 320. Using UV coordinates as percentages, and thus describing them as normalized floats, keeps everything working as intended.&lt;br /&gt;
&lt;br /&gt;
Luckily the formula to translate from pixel space to normalized percentage is easy. U = X/Width, and V= Y/Height. To give an example, if we wanted to get a texel on the far right edge of a 640 pixel texture, then U = 640/640 = 1 = 100%. If we wanted to get a texel on the dead center of the texture, then U = 320/640 = .5 = 50%. This works for the V coordinate as well. We are doing exactly this in our T_Vertex.u calculation, just with more variables worked in:&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
                    T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
                    T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                    T_vertex.oargb = Vertex_ptr→oargb;&lt;br /&gt;
&lt;br /&gt;
The left edge of our texture map moves over by 16 pixels times our character index. This selects the character on the texture map. Our vertex was created with UV coordinates that change between 0 and 1, just like our position coordinates, so we can use them as a flag for turning off an offset in our calculation. In this case, the UV flag adds our Font_Scale variable (8 or 16 pixels). We then divide all of this by 1024.0f, our font.png width. That gives us the left and right edges of our texture map.&lt;br /&gt;
&lt;br /&gt;
We do the same for V using the Y coordinates. Instead of 1024.0f as our width, we use 128.0f as our height. &lt;br /&gt;
&lt;br /&gt;
With our Vertices calculated correctly for the text, we can submit them as we finish each loop:&lt;br /&gt;
&lt;br /&gt;
 /* Submit data */&lt;br /&gt;
                    pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
Everytime we submit a quad, we need to increment RenderDepth so we avoid z-fighting:&lt;br /&gt;
&lt;br /&gt;
 RenderDepth += 0.1;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
   } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
&lt;br /&gt;
We attach an else condition at the end of our close braces. At the very beginning of this function, we checked if we were on the PVR_LIST_TR_POLY bin list. If we’re not, we print a little error:&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
        if(m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            printf(&amp;quot;Could not render text, font texture format is not PVR_LIST_TR_POLY\n&amp;quot;);&lt;br /&gt;
            m_Textures.GetTexture(font_png)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
With all this done, let’s draw some text to the screen. In our gamestate.cpp render() function:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY;&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                SubmitText(&amp;quot;Hello World!!&amp;quot;, FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
	     OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see “HELLO WORLD!” rendered over the background!&lt;br /&gt;
&lt;br /&gt;
We can do other things with our SubmitText function. It can take a std::string if we use the c_str() function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Hello World!!&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
We can also use variables in our string, with the built-in to_string function from &amp;lt;string&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                std::string Test = &amp;quot;Counter: &amp;quot;;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                Test += std::to_string(a);&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
You can use to_string to directly print a variable in our SubmitText function by using c_str() as well:&lt;br /&gt;
&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
                static int a = 0;&lt;br /&gt;
                a++;&lt;br /&gt;
                SubmitText(std::to_string(a).c_str(), FONT_BLUE, FONT_SMALL, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
The 8x8 font actually looks pretty small on a 640x480 resolution, it was made for a 320x240 resolution in mind. The Dreamcast supports 320x240, but it’s sort of a hack. We can fake a 320x240 resolution by applying a scaling factor to all of our video functions. Let’s do that, in our gamestate class in gamestate.h, add the following private variable:&lt;br /&gt;
&lt;br /&gt;
    uint32_t VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will scale everything by a factor. We’ll set it to 2 to start in our constructor:&lt;br /&gt;
&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
    PrevControllerState.buttons = 0;&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    VideoScale = 2;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now, in our SubmitText function, let’s apply the scale:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
 T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
 T_vertex.x = X_In + (Idx * Font_Scale * VideoScale)  + (Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale;&lt;br /&gt;
 T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * Font_Scale * VideoScale);&lt;br /&gt;
 T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
 T_vertex.u = ((16.0f * (float)CharIdx) + (Vertex_ptr-&amp;gt;u * Font_Scale))/1024.0f;&lt;br /&gt;
 T_vertex.v = ((16.0f * (float)FontSelector) + (Vertex_ptr-&amp;gt;v * Font_Scale))/128.0f;&lt;br /&gt;
 T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
 T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
&lt;br /&gt;
With our VideoScale set to 2, our 640x480 screen is treated like a 320x240 screen, or rather our text is rendered at double resolution!&lt;br /&gt;
&lt;br /&gt;
It would be very useful if our text rendering code could handle carriage returns. These are characters which starts a new line. We could pass a parameter to indicate the number of NewLines to start rendering at, and every time we encounter a ‘\n’ character we could add to it. Let’s build this out. In our Gamestate.h header, let’s clone our SubmitText function to overload it with an extra parameter for new lines:&lt;br /&gt;
&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In);&lt;br /&gt;
    void SubmitText(const char* Input_String, uint8_t FontColor, uint8_t Small, uint32_t X_In, uint32_t Y_In, uint32_t NewLines);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
    float VideoScale;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
We need to create these functions. We’ll turn our existing function into the new function with the added parameter, then create a version of the original that calls our new function with new lines set to 0:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In)&lt;br /&gt;
 {&lt;br /&gt;
    SubmitText(Input_String, FontSelector_Input, SizeFlag, X_In, Y_In, 0);&lt;br /&gt;
 }&lt;br /&gt;
 void GameState::SubmitText(const char* Input_String, uint8_t FontSelector_Input, uint8_t SizeFlag, uint32_t X_In, uint32_t Y_In, uint32_t NewLines)&lt;br /&gt;
 {&lt;br /&gt;
    if(OpenPolyList == PVR_LIST_TR_POLY)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
We are going to have a new variable called X_Position in our function to keep track of where we are drawing, so when we do a newline, we start at the beginning of the line. Previously we were using Idx as our value for the x position, but that wouldn’t reset with a new line character:&lt;br /&gt;
&lt;br /&gt;
      uint32_t X_Position = 0;&lt;br /&gt;
        for(int Idx = 0; !Input_String_EOL; Idx++)&lt;br /&gt;
        {&lt;br /&gt;
            if(Input_String[Idx] == &#039;\n&#039;)&lt;br /&gt;
            {&lt;br /&gt;
                NewLines++;&lt;br /&gt;
                X_Position = (-1);&lt;br /&gt;
            } else if(Input_String[Idx] == &#039;\0&#039;)&lt;br /&gt;
            {&lt;br /&gt;
&lt;br /&gt;
We modify our if condition to add a check before our NULL Terminator check. This time, we’re looking for ‘\n’, which is the new line character. If we encounter it, increase our NewLines counter and reset our X_Position to -1. We set it to -1 instead of 0, because at the end of our loop we increase X_Position:&lt;br /&gt;
&lt;br /&gt;
            }&lt;br /&gt;
            X_Position++;&lt;br /&gt;
        }&lt;br /&gt;
    } else /* if(OpenPolyList != PVR_LIST_TR_POLY) */&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
Now, we need to change our vertex setting code to use X_Position  for the character position:&lt;br /&gt;
&lt;br /&gt;
 /* Map all the information */&lt;br /&gt;
                    T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                    T_vertex.x = X_In + ((X_Position * Font_Scale) * VideoScale)  + ((Vertex_ptr-&amp;gt;x * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.y = Y_In + ((NewLines * Font_Scale) * VideoScale) + ((Vertex_ptr-&amp;gt;y * Font_Scale) * VideoScale);&lt;br /&gt;
                    T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
&lt;br /&gt;
With all this, we can now render newlines. Let’s test it in our Render function:&lt;br /&gt;
&lt;br /&gt;
 /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY;&lt;br /&gt;
            std::string Test = &amp;quot;Hello World!! My name is gabriel\n&amp;quot;&lt;br /&gt;
                               &amp;quot;and I am typing this on my Sega \n&amp;quot;&lt;br /&gt;
                               &amp;quot;Dreamcast! \n\n&amp;quot;&lt;br /&gt;
                               &amp;quot;My email is support@aol.com!&amp;quot;;&lt;br /&gt;
                SubmitText(Test.c_str(), FONT_BLUE, FONT_BIG, 15, 15);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
Every time we type \n, we get a new line in our text renderer!&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3737</id>
		<title>Dreamcast Tutorial</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3737"/>
		<updated>2025-04-05T14:54:55Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While many resources exist to explain individual parts of developing games and applications for the Dreamcast, there are not many comprehensive tutorials that detail the entire process. The following tutorial has been created to more thoroughly explain Dreamcast development topics towards a goal of creating fully featured applications. It is meant to be a full tutorial for beginners, starting from bare text files. This is a table of contents for topics the tutorial covers, in order.&lt;br /&gt;
&lt;br /&gt;
=== First Steps ===&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
&lt;br /&gt;
=== Texturing ===&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Transparent Textures]]&lt;br /&gt;
&lt;br /&gt;
=== Systems === &lt;br /&gt;
* [[Text Rendering]]&lt;br /&gt;
* [[Event Handling]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3736</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3736"/>
		<updated>2025-04-05T14:54:02Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
** [[Dreamcast Tutorial]]&lt;br /&gt;
*** [[Makefile]]&lt;br /&gt;
*** [[Main.cpp]]&lt;br /&gt;
*** [[Adding a Romdisk]]&lt;br /&gt;
*** [[Drawing a Texture]]&lt;br /&gt;
*** [[Textures and Meshes]]&lt;br /&gt;
*** [[Transparent Textures]]&lt;br /&gt;
*** [[Event Handling]]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3735</id>
		<title>Transparent Textures</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3735"/>
		<updated>2025-04-05T14:53:32Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Up till now, we’ve been relying on our attached console to have our dreamcast talk back to us. Now that we can map textures to the screen, let’s use that to create a function that can print text through the Dreamcast. We will learn how to use translucent textures in the process as well.&lt;br /&gt;
&lt;br /&gt;
Our font will take the form of a Texture Atlus. A texture atlus is a giant texture with lots of smaller textures in it. You select which texture you use by changing the UV coordinates of the vertices. &lt;br /&gt;
&lt;br /&gt;
The general idea behind our text rendering code will rely on how ASCII works. Our text will be a c-style string, which is an array of bytes, where each byte is a single character. These bytes map to characters using an agreed-upon code called ASCII. We will take the numeric value of the characters in our C-style string and map them to positions on our font. &lt;br /&gt;
&lt;br /&gt;
Our font will come in two sizes – 16x16 pixel ‘Large’ font, and 8x8 pixel ‘small’ font. We will map all characters A through Z, in caps, plus 0-9, plus the symbols mapped to 0-9, as well as a few punctuation marks and brackets. We will draw the fonts in a row in a png. Calculated out, our font will be 1024 pixels wide, which is the maximum amount the Dreamcast can have. Each font character needs to be at least 16x16 pixels big. I settled on my final font texture size being 1024x128 pixels big. The dimensions of the texture need to be a power of 2. 128 pixels big gives me eight rows of 16 pixel tall cells for font characters, where each row is a different font. &lt;br /&gt;
&lt;br /&gt;
By looking up the ASCII character codes, we can find the order our characters come in. We are mapping 64 characters, from ASCII code 32 to 96.&lt;br /&gt;
&lt;br /&gt;
I have provided a sample font.png, you can use it or make your own. The 8x8 fonts map to the upper left corner of a 16x16 grid cell. When you have your font made, place it in our romdisk folder so we can use it.&lt;br /&gt;
&lt;br /&gt;
Now let’s try drawing our font texture first. In our Texture_manager constructor, let’s have it build our font texture:&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, &amp;amp;TempTxr, 1024, 128, PNG_NO_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
    Textures[font_png] = TempTxr;&lt;br /&gt;
&lt;br /&gt;
Make sure we add font_png to our TextureEnums.h:&lt;br /&gt;
 #ifndef TEXTUREENUMS_H&lt;br /&gt;
 #define TEXTUREENUMS_H&lt;br /&gt;
 enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    TX_NULL&lt;br /&gt;
 };&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now in our GameState.Render() function, let’s submit a quad to draw with font_png. Our Font texture size is 1024x128:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Let’s run it and see if it works. We should see our background with our font texture drawn in front of it. It is much larger than the screen, so it goes to the right. Currently, we are drawing the font with no transparency, let’s change that. To do that, we will need to change our definition in texture_manager constructor:&lt;br /&gt;
 /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
We need to edit our font.png texture to have transparent pixels. Open it up in gimp, and create a new layer with a transparent background. Put it below our font.png layer. Select our font.png layer to work in. Now, on the menu bar in gimp, click “select” -&amp;gt; “By Color” and click on the pink color in the font image. Press delete, this will turn the pixels that used to be pink into transparent pixels.&lt;br /&gt;
&lt;br /&gt;
Now, we need to make sure we have 16-bit precision. Click Image-&amp;gt; Precision -&amp;gt; 16 bit integer. Now we need to export our image. Click File -&amp;gt; Export As, and in the dialog box, name it font_transparent.png in our romdisk folder. In the png export dialog, make sure “save color values from transparent pixels” is checked. &lt;br /&gt;
&lt;br /&gt;
We need to add a new value for our new texture in our TextureEnum.h file:&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTUREENUMS_H&lt;br /&gt;
 #define TEXTUREENUMS_H&lt;br /&gt;
 enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    font_transparent_png,&lt;br /&gt;
    TX_NULL&lt;br /&gt;
 };&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now, we need to make our texture_manager() constructor call our new transparent font texture:&lt;br /&gt;
&lt;br /&gt;
 texture_manager::texture_manager()&lt;br /&gt;
 {&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
 &lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
 &lt;br /&gt;
 /* Setup font_transparent.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font_transparent.png&amp;quot;, font_transparent_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Since this png has transparent pixels, we change our flag to PNG_FULL_ALPHA. This is a font texture, so we don’t really want any filtering, so we use PVR_FILTER_NONE. PNG_FULL_ALPHA means it needs to be drawn in our Translucent poly bin, currently we only draw in our opaque one. Let’s change it so it draws with the right bin, to do that we need to change our submission code:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
We now have two render lists. We first open our PVR_LIST_OP_POLY bin for Opaque polygons, then submit our quad for the background_png texture. Once we’re done submitting it, we close our PVR_LIST_OP_POLY bin, then open our PVR_LIST_TR_POLY bin list. This list holds vertices for transparent polygons. We need to change our ContextCompile code in our Texture_manager.cpp class to use the right Poly list when compiling the texture header:&lt;br /&gt;
&lt;br /&gt;
 void CompileContext(char* Path, TextureEnum TxrID, Texture_t* TempTxr, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
 {&lt;br /&gt;
    TempTxr-&amp;gt;Width = W;&lt;br /&gt;
    TempTxr-&amp;gt;Height = H;&lt;br /&gt;
    TempTxr-&amp;gt;TextureID = TxrID;&lt;br /&gt;
    TempTxr-&amp;gt;m_Ptr = pvr_mem_malloc(W * H * 2);&lt;br /&gt;
    png_to_texture(Path, TempTxr-&amp;gt;m_Ptr, PngMode);&lt;br /&gt;
    /* Set our Texture Type */&lt;br /&gt;
    uint32_t Texture_Fmt;&lt;br /&gt;
    pvr_list_t Poly_List;&lt;br /&gt;
    switch(PngMode)&lt;br /&gt;
    {&lt;br /&gt;
        /* Our PNG has 4-bit alpha channel, Translucent */&lt;br /&gt;
        case PNG_FULL_ALPHA:&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_ARGB4444;&lt;br /&gt;
            Poly_List = PVR_LIST_TR_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
        /* Our PNG has 1-bit alpha channel, Punch-thru */&lt;br /&gt;
        case PNG_MASK_ALPHA:&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_ARGB1555;&lt;br /&gt;
            Poly_List = PVR_LIST_PT_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
        /* Our PNG has no alpha channel */&lt;br /&gt;
        default:   /* PNG_NO_ALPHA, Opaque */&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_RGB565;&lt;br /&gt;
            Poly_List = PVR_LIST_OP_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
    pvr_poly_cxt_txr(&amp;amp;TempTxr-&amp;gt;m_Context,        /* Dest Context to write to */&lt;br /&gt;
                       Poly_List,        /* Polygon Bin Type */&lt;br /&gt;
                       Texture_Fmt,       /* Texture Format */&lt;br /&gt;
                       W,                     /* Texture Width */&lt;br /&gt;
                       H,                     /* Texture Height */&lt;br /&gt;
                       TempTxr-&amp;gt;m_Ptr,                /* Texture Pointer */&lt;br /&gt;
                       Filtering);    /* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;TempTxr-&amp;gt;m_Header, &amp;amp;TempTxr→m_Context);&lt;br /&gt;
    Textures[TxrID] = TempTxr;&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
We use a variable called Poly_list of type pvr_list_t. We set it to PVR_LIST_TR_POLY if we have PNG_FULL_ALPHA using PVR_TXRFMT_ARGB4444. We use PVR_LIST_PT_POLY if we have PNG_MASK_ALPHA using PVR_TXRFMT_ARGB1555. We use PVR_LIST_OP_POLY if we have PNG_NO_ALPHA using PVR_TXR_FMT_RGB565. We substitute this variable in our pvr_poly_cxt_txr function. Now, when we render our font texture, our transparent pixels will actually be transparent.&lt;br /&gt;
&lt;br /&gt;
Let’s add a guard so our Render() function won’t draw a mesh with vertices in the wrong list, just in case. In our gamestate.h header file, let’s add a new private variable called OpenPolyList of type pvr_list_t:&lt;br /&gt;
&lt;br /&gt;
 private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum Tex_In, MeshEnum Mesh_In);&lt;br /&gt;
    void SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will hold a state indicating when PVR poly bin we are submitting to. Let’s change our Render code to indicate this:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
    &lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
                        OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now, when we open a list, it’ll set OpenPolyList, and when we close it, we’ll clear it with 0. Our SubmitQuad function can now check if the OpenPolyList matches the Context in our Texture:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In)&lt;br /&gt;
 {&lt;br /&gt;
    if(OpenPolyList == m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type)&lt;br /&gt;
    {&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
            {&lt;br /&gt;
                /* Get the vertex */&lt;br /&gt;
                Vertex_ptr = m_Meshes.Get(e_Quad)-&amp;gt;GetVertex(i);&lt;br /&gt;
                /* Map all the information */&lt;br /&gt;
                T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                T_vertex.x = X_In + (Vertex_ptr-&amp;gt;x * W_In);&lt;br /&gt;
                T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * H_In);&lt;br /&gt;
                T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
                T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
                T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
                /* Submit data */&lt;br /&gt;
                pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
            }&lt;br /&gt;
            RenderDepth += 0.1;&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our Texture now won’t draw if it’s in the wrong bin. Let’s test this by intentionally putting our font texture in the opaque bin despite it being a transparent texture:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
    &lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
                SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY&lt;br /&gt;
                //SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
If we do this, then our font_png quad won’t render, and our console will output an error message letting us know. Let’s create a second font texture, this time fully transparent. In our texture_manager constructor:&lt;br /&gt;
&lt;br /&gt;
 texture_manager::texture_manager()&lt;br /&gt;
 {&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
 &lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
    &lt;br /&gt;
    /* Setup font_transparent.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font_transparent.png&amp;quot;, font_transparent_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
make sure we have a TextureEnum for font_transparent_png:&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTUREENUMS_H&lt;br /&gt;
 #define TEXTUREENUMS_H&lt;br /&gt;
 enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    font_transparent_png,&lt;br /&gt;
    TX_NULL&lt;br /&gt;
 };&lt;br /&gt;
 const char* GetTextureEnumString(TextureEnum In)&lt;br /&gt;
 {&lt;br /&gt;
    std::string TxEnum;&lt;br /&gt;
    switch(In)&lt;br /&gt;
    {&lt;br /&gt;
        case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
        case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
        case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
    return TxEnum.c_str();&lt;br /&gt;
 }&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
Let’s have SubmitQuads print out an error if we submit a vertex to the wrong bin list. We want it to be able to tell us which texture we called that was incompatible, along with the format of the texture and the OpenPolyList we are working on. We already have a function to turn our TextureEnums into a string, let’s create a quick function to turn our PolyBinList into a string. In TextureEnums.h, add:&lt;br /&gt;
&lt;br /&gt;
 #ifdef TEXTUREENUMS_CPP&lt;br /&gt;
    const char* GetTextureString(TextureEnum In)&lt;br /&gt;
    {&lt;br /&gt;
        std::string TxEnum;&lt;br /&gt;
        switch(In)&lt;br /&gt;
        {&lt;br /&gt;
            case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
    return TxEnum.c_str();&lt;br /&gt;
    }&lt;br /&gt;
    const char* GetPolyBinString(pvr_list_t Input)&lt;br /&gt;
    {&lt;br /&gt;
        std::string TxFmt;&lt;br /&gt;
        switch(Input)&lt;br /&gt;
        {&lt;br /&gt;
            case PVR_LIST_OP_MOD : TxFmt = &amp;quot;Opaque Modifier&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_TR_POLY: TxFmt = &amp;quot;Transparent&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_TR_MOD : TxFmt = &amp;quot;Transparent Modifier&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_PT_POLY: TxFmt = &amp;quot;Punch-Thru&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_OP_POLY: TxFmt = &amp;quot;Opaque&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        return TxFmt.c_str();&lt;br /&gt;
    }&lt;br /&gt;
 #else&lt;br /&gt;
    extern const char* GetTextureString(TextureEnum In);&lt;br /&gt;
    extern const char* GetPolyBinString(pvr_list_t Input);&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
We now have a function called GetPolyBinString which can turn a pvr_list_t into a string to print out. Now, let’s create a string to print out our error in our submitquad function. We need to store a flag in our Texture file to let us know if the error has been printed once before, otherwise our error will print out every loop when we render. We’ll call this Warning in our texture_t struct in texture.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef TEXTURE_H&lt;br /&gt;
 #define TEXTURE_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
    typedef struct _Texture_t&lt;br /&gt;
    {&lt;br /&gt;
        pvr_ptr_t m_Ptr;                  /* Pointer to VRAM */&lt;br /&gt;
        pvr_poly_cxt_t m_Context;       /* Texture Context settings */&lt;br /&gt;
        pvr_poly_hdr_t m_Header;         /* Texture PVR Header */&lt;br /&gt;
        uint32_t Width;                 /* Texture Width */&lt;br /&gt;
        uint32_t Height;                /* Texture Height */&lt;br /&gt;
        TextureEnum TextureID;&lt;br /&gt;
        uint8_t RenderWarning;                /* Flag letting us know if an error msg has printed once */&lt;br /&gt;
    } Texture_t;&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now let’s set it so our Texture_t has a warning of 0 when created in our Texture_manager compilerContext function:&lt;br /&gt;
&lt;br /&gt;
 void texture_manager::CompileContext(char* Path, TextureEnum TxrID, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
 {&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    TempTxr.RenderWarning = 0;&lt;br /&gt;
&lt;br /&gt;
Now, when we print our error when Rendering, we check if RenderWarning is 0 or not, and set it after printing the error, add this in our gamestate::SubmitQuad function:&lt;br /&gt;
&lt;br /&gt;
 else&lt;br /&gt;
    {&lt;br /&gt;
        if(m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            std::string Txr = GetPolyBinType(m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type);&lt;br /&gt;
            std::string Ply = GetPolyBinType(OpenPolyList);&lt;br /&gt;
            std::string TxrID = GetTextureEnumString(m_Textures.GetTexture(Tex_In)-&amp;gt;TextureID);&lt;br /&gt;
            printf(&amp;quot;Could not render %s, incorrect Texture Format for this Polygon Bin. Format: %s, Bin: %s\n&amp;quot;, TxrID.c_str(), Txr.c_str(), Ply.c_str());&lt;br /&gt;
            m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Now let’s modify the SubmitQuad function in gamestate.cpp:&lt;br /&gt;
&lt;br /&gt;
 else&lt;br /&gt;
    {&lt;br /&gt;
        if(m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            std::string Txr = GetPolyBinString(m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type);&lt;br /&gt;
            std::string Ply = GetPolyBinString(OpenPolyList);&lt;br /&gt;
            std::string TxrID = GetTextureString(m_Textures.GetTexture(Tex_In)-&amp;gt;TextureID);&lt;br /&gt;
            printf(&amp;quot;Could not render %s, incorrect Texture Format for this Polygon Bin. Format: %s, Bin: %s\n&amp;quot;, TxrID.c_str(), Txr.c_str(), Ply.c_str());&lt;br /&gt;
            m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see an error message telling us we used the wrong texture in the wrong list.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3734</id>
		<title>Transparent Textures</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Transparent_Textures&amp;diff=3734"/>
		<updated>2025-04-05T14:50:40Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Created page with &amp;quot; font. We will map all characters A through Z, in caps, plus 0-9, plus the symbols mapped to 0-9, as well as a few punctuation marks and brackets. We will draw the fonts in a row in a png. Calculated out, our font will be 1024 pixels wide, which is the maximum amount the Dreamcast can have. Each font character needs to be at least 16x16 pixels big. I settled on my final font texture size being 1024x128 pixels big. The dimensions of the texture need to be a power of 2. 12...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; font. We will map all characters A through Z, in caps, plus 0-9, plus the symbols mapped to 0-9, as well as a few punctuation marks and brackets. We will draw the fonts in a row in a png. Calculated out, our font will be 1024 pixels wide, which is the maximum amount the Dreamcast can have. Each font character needs to be at least 16x16 pixels big. I settled on my final font texture size being 1024x128 pixels big. The dimensions of the texture need to be a power of 2. 128 pixels big gives me eight rows of 16 pixel tall cells for font characters, where each row is a different font. &lt;br /&gt;
&lt;br /&gt;
By looking up the ASCII character codes, we can find the order our characters come in. We are mapping 64 characters, from ASCII code 32 to 96.&lt;br /&gt;
&lt;br /&gt;
I have provided a sample font.png, you can use it or make your own. The 8x8 fonts map to the upper left corner of a 16x16 grid cell. When you have your font made, place it in our romdisk folder so we can use it.&lt;br /&gt;
&lt;br /&gt;
Now let’s try drawing our font texture first. In our Texture_manager constructor, let’s have it build our font texture:&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, &amp;amp;TempTxr, 1024, 128, PNG_NO_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
    Textures[font_png] = TempTxr;&lt;br /&gt;
&lt;br /&gt;
Make sure we add font_png to our TextureEnums.h:&lt;br /&gt;
#ifndef TEXTUREENUMS_H&lt;br /&gt;
#define TEXTUREENUMS_H&lt;br /&gt;
enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    TX_NULL&lt;br /&gt;
};&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now in our GameState.Render() function, let’s submit a quad to draw with font_png. Our Font texture size is 1024x128:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Let’s run it and see if it works. We should see our background with our font texture drawn in front of it. It is much larger than the screen, so it goes to the right. Currently, we are drawing the font with no transparency, let’s change that. To do that, we will need to change our definition in texture_manager constructor:&lt;br /&gt;
/* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
We need to edit our font.png texture to have transparent pixels. Open it up in gimp, and create a new layer with a transparent background. Put it below our font.png layer. Select our font.png layer to work in. Now, on the menu bar in gimp, click “select” -&amp;gt; “By Color” and click on the pink color in the font image. Press delete, this will turn the pixels that used to be pink into transparent pixels.&lt;br /&gt;
&lt;br /&gt;
Now, we need to make sure we have 16-bit precision. Click Image-&amp;gt; Precision -&amp;gt; 16 bit integer. Now we need to export our image. Click File -&amp;gt; Export As, and in the dialog box, name it font_transparent.png in our romdisk folder. In the png export dialog, make sure “save color values from transparent pixels” is checked. &lt;br /&gt;
&lt;br /&gt;
We need to add a new value for our new texture in our TextureEnum.h file:&lt;br /&gt;
&lt;br /&gt;
#ifndef TEXTUREENUMS_H&lt;br /&gt;
#define TEXTUREENUMS_H&lt;br /&gt;
enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    font_transparent_png,&lt;br /&gt;
    TX_NULL&lt;br /&gt;
};&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now, we need to make our texture_manager() constructor call our new transparent font texture:&lt;br /&gt;
&lt;br /&gt;
texture_manager::texture_manager()&lt;br /&gt;
{&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
&lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
/* Setup font_transparent.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font_transparent.png&amp;quot;, font_transparent_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Since this png has transparent pixels, we change our flag to PNG_FULL_ALPHA. This is a font texture, so we don’t really want any filtering, so we use PVR_FILTER_NONE. PNG_FULL_ALPHA means it needs to be drawn in our Translucent poly bin, currently we only draw in our opaque one. Let’s change it so it draws with the right bin, to do that we need to change our submission code:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
We now have two render lists. We first open our PVR_LIST_OP_POLY bin for Opaque polygons, then submit our quad for the background_png texture. Once we’re done submitting it, we close our PVR_LIST_OP_POLY bin, then open our PVR_LIST_TR_POLY bin list. This list holds vertices for transparent polygons. We need to change our ContextCompile code in our Texture_manager.cpp class to use the right Poly list when compiling the texture header:&lt;br /&gt;
&lt;br /&gt;
void CompileContext(char* Path, TextureEnum TxrID, Texture_t* TempTxr, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
{&lt;br /&gt;
    TempTxr-&amp;gt;Width = W;&lt;br /&gt;
    TempTxr-&amp;gt;Height = H;&lt;br /&gt;
    TempTxr-&amp;gt;TextureID = TxrID;&lt;br /&gt;
    TempTxr-&amp;gt;m_Ptr = pvr_mem_malloc(W * H * 2);&lt;br /&gt;
    png_to_texture(Path, TempTxr-&amp;gt;m_Ptr, PngMode);&lt;br /&gt;
    /* Set our Texture Type */&lt;br /&gt;
    uint32_t Texture_Fmt;&lt;br /&gt;
    pvr_list_t Poly_List;&lt;br /&gt;
    switch(PngMode)&lt;br /&gt;
    {&lt;br /&gt;
        /* Our PNG has 4-bit alpha channel, Translucent */&lt;br /&gt;
        case PNG_FULL_ALPHA:&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_ARGB4444;&lt;br /&gt;
            Poly_List = PVR_LIST_TR_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
        /* Our PNG has 1-bit alpha channel, Punch-thru */&lt;br /&gt;
        case PNG_MASK_ALPHA:&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_ARGB1555;&lt;br /&gt;
            Poly_List = PVR_LIST_PT_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
        /* Our PNG has no alpha channel */&lt;br /&gt;
        default:   /* PNG_NO_ALPHA, Opaque */&lt;br /&gt;
        {&lt;br /&gt;
            Texture_Fmt = PVR_TXRFMT_RGB565;&lt;br /&gt;
            Poly_List = PVR_LIST_OP_POLY;&lt;br /&gt;
        }&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
    pvr_poly_cxt_txr(&amp;amp;TempTxr-&amp;gt;m_Context,        /* Dest Context to write to */&lt;br /&gt;
                       Poly_List,        /* Polygon Bin Type */&lt;br /&gt;
                       Texture_Fmt,       /* Texture Format */&lt;br /&gt;
                       W,                     /* Texture Width */&lt;br /&gt;
                       H,                     /* Texture Height */&lt;br /&gt;
                       TempTxr-&amp;gt;m_Ptr,                /* Texture Pointer */&lt;br /&gt;
                       Filtering);    /* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;TempTxr-&amp;gt;m_Header, &amp;amp;TempTxr→m_Context);&lt;br /&gt;
    Textures[TxrID] = TempTxr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We use a variable called Poly_list of type pvr_list_t. We set it to PVR_LIST_TR_POLY if we have PNG_FULL_ALPHA using PVR_TXRFMT_ARGB4444. We use PVR_LIST_PT_POLY if we have PNG_MASK_ALPHA using PVR_TXRFMT_ARGB1555. We use PVR_LIST_OP_POLY if we have PNG_NO_ALPHA using PVR_TXR_FMT_RGB565. We substitute this variable in our pvr_poly_cxt_txr function. Now, when we render our font texture, our transparent pixels will actually be transparent.&lt;br /&gt;
&lt;br /&gt;
Let’s add a guard so our Render() function won’t draw a mesh with vertices in the wrong list, just in case. In our gamestate.h header file, let’s add a new private variable called OpenPolyList of type pvr_list_t:&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum Tex_In, MeshEnum Mesh_In);&lt;br /&gt;
    void SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
    pvr_list_t OpenPolyList;&lt;br /&gt;
};&lt;br /&gt;
#endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
This variable will hold a state indicating when PVR poly bin we are submitting to. Let’s change our Render code to indicate this:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
    &lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY&lt;br /&gt;
            SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
                        OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Now, when we open a list, it’ll set OpenPolyList, and when we close it, we’ll clear it with 0. Our SubmitQuad function can now check if the OpenPolyList matches the Context in our Texture:&lt;br /&gt;
&lt;br /&gt;
void GameState::SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In)&lt;br /&gt;
{&lt;br /&gt;
    if(OpenPolyList == m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type)&lt;br /&gt;
    {&lt;br /&gt;
        /* Texture Mapping */&lt;br /&gt;
            Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
            pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        /* Vertex Submission */&lt;br /&gt;
            pvr_vertex_t  T_vertex;&lt;br /&gt;
            pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
            for(int i = 0; i &amp;lt; m_Meshes.Get(e_Quad)-&amp;gt;m_VtxCount; i++)&lt;br /&gt;
            {&lt;br /&gt;
                /* Get the vertex */&lt;br /&gt;
                Vertex_ptr = m_Meshes.Get(e_Quad)-&amp;gt;GetVertex(i);&lt;br /&gt;
                /* Map all the information */&lt;br /&gt;
                T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
                T_vertex.x = X_In + (Vertex_ptr-&amp;gt;x * W_In);&lt;br /&gt;
                T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * H_In);&lt;br /&gt;
                T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
                T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
                T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
                T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
                T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
                /* Submit data */&lt;br /&gt;
                pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
            }&lt;br /&gt;
            RenderDepth += 0.1;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our Texture now won’t draw if it’s in the wrong bin. Let’s test this by intentionally putting our font texture in the opaque bin despite it being a transparent texture:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
    &lt;br /&gt;
        /* Opaque Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_OP_POLY&lt;br /&gt;
                SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
                SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
        /* Translucent Polygons */&lt;br /&gt;
        pvr_list_begin(PVR_LIST_TR_POLY);&lt;br /&gt;
            OpenPolyList = PVR_LIST_TR_POLY&lt;br /&gt;
                //SubmitQuad(font_png, 0, 0, 1024, 128);&lt;br /&gt;
            OpenPolyList = 0;&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        &lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
If we do this, then our font_png quad won’t render, and our console will output an error message letting us know. Let’s create a second font texture, this time fully transparent. In our texture_manager constructor:&lt;br /&gt;
&lt;br /&gt;
texture_manager::texture_manager()&lt;br /&gt;
{&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
&lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
    &lt;br /&gt;
    /* Setup font_transparent.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font_transparent.png&amp;quot;, font_transparent_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make sure we have a TextureEnum for font_transparent_png:&lt;br /&gt;
&lt;br /&gt;
#ifndef TEXTUREENUMS_H&lt;br /&gt;
#define TEXTUREENUMS_H&lt;br /&gt;
enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    font_transparent_png,&lt;br /&gt;
    TX_NULL&lt;br /&gt;
};&lt;br /&gt;
const char* GetTextureEnumString(TextureEnum In)&lt;br /&gt;
{&lt;br /&gt;
    std::string TxEnum;&lt;br /&gt;
    switch(In)&lt;br /&gt;
    {&lt;br /&gt;
        case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
        case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
        case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
    return TxEnum.c_str();&lt;br /&gt;
}&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
Let’s have SubmitQuads print out an error if we submit a vertex to the wrong bin list. We want it to be able to tell us which texture we called that was incompatible, along with the format of the texture and the OpenPolyList we are working on. We already have a function to turn our TextureEnums into a string, let’s create a quick function to turn our PolyBinList into a string. In TextureEnums.h, add:&lt;br /&gt;
&lt;br /&gt;
#ifdef TEXTUREENUMS_CPP&lt;br /&gt;
    const char* GetTextureString(TextureEnum In)&lt;br /&gt;
    {&lt;br /&gt;
        std::string TxEnum;&lt;br /&gt;
        switch(In)&lt;br /&gt;
        {&lt;br /&gt;
            case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
    return TxEnum.c_str();&lt;br /&gt;
    }&lt;br /&gt;
    const char* GetPolyBinString(pvr_list_t Input)&lt;br /&gt;
    {&lt;br /&gt;
        std::string TxFmt;&lt;br /&gt;
        switch(Input)&lt;br /&gt;
        {&lt;br /&gt;
            case PVR_LIST_OP_MOD : TxFmt = &amp;quot;Opaque Modifier&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_TR_POLY: TxFmt = &amp;quot;Transparent&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_TR_MOD : TxFmt = &amp;quot;Transparent Modifier&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_PT_POLY: TxFmt = &amp;quot;Punch-Thru&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case PVR_LIST_OP_POLY: TxFmt = &amp;quot;Opaque&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        return TxFmt.c_str();&lt;br /&gt;
    }&lt;br /&gt;
#else&lt;br /&gt;
    extern const char* GetTextureString(TextureEnum In);&lt;br /&gt;
    extern const char* GetPolyBinString(pvr_list_t Input);&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
We now have a function called GetPolyBinString which can turn a pvr_list_t into a string to print out. Now, let’s create a string to print out our error in our submitquad function. We need to store a flag in our Texture file to let us know if the error has been printed once before, otherwise our error will print out every loop when we render. We’ll call this Warning in our texture_t struct in texture.h:&lt;br /&gt;
&lt;br /&gt;
#ifndef TEXTURE_H&lt;br /&gt;
#define TEXTURE_H&lt;br /&gt;
#include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
    typedef struct _Texture_t&lt;br /&gt;
    {&lt;br /&gt;
        pvr_ptr_t m_Ptr;                  /* Pointer to VRAM */&lt;br /&gt;
        pvr_poly_cxt_t m_Context;       /* Texture Context settings */&lt;br /&gt;
        pvr_poly_hdr_t m_Header;         /* Texture PVR Header */&lt;br /&gt;
        uint32_t Width;                 /* Texture Width */&lt;br /&gt;
        uint32_t Height;                /* Texture Height */&lt;br /&gt;
        TextureEnum TextureID;&lt;br /&gt;
        uint8_t RenderWarning;                /* Flag letting us know if an error msg has printed once */&lt;br /&gt;
    } Texture_t;&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
Now let’s set it so our Texture_t has a warning of 0 when created in our Texture_manager compilerContext function:&lt;br /&gt;
&lt;br /&gt;
void texture_manager::CompileContext(char* Path, TextureEnum TxrID, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
{&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    TempTxr.RenderWarning = 0;&lt;br /&gt;
&lt;br /&gt;
Now, when we print our error when Rendering, we check if RenderWarning is 0 or not, and set it after printing the error, add this in our gamestate::SubmitQuad function:&lt;br /&gt;
&lt;br /&gt;
else&lt;br /&gt;
    {&lt;br /&gt;
        if(m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            std::string Txr = GetPolyBinType(m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type);&lt;br /&gt;
            std::string Ply = GetPolyBinType(OpenPolyList);&lt;br /&gt;
            std::string TxrID = GetTextureEnumString(m_Textures.GetTexture(Tex_In)-&amp;gt;TextureID);&lt;br /&gt;
            printf(&amp;quot;Could not render %s, incorrect Texture Format for this Polygon Bin. Format: %s, Bin: %s\n&amp;quot;, TxrID.c_str(), Txr.c_str(), Ply.c_str());&lt;br /&gt;
            m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Now let’s modify the SubmitQuad function in gamestate.cpp:&lt;br /&gt;
&lt;br /&gt;
else&lt;br /&gt;
    {&lt;br /&gt;
        if(m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning == 0)&lt;br /&gt;
        {&lt;br /&gt;
            std::string Txr = GetPolyBinString(m_Textures.GetTexture(Tex_In)-&amp;gt;m_Context.list_type);&lt;br /&gt;
            std::string Ply = GetPolyBinString(OpenPolyList);&lt;br /&gt;
            std::string TxrID = GetTextureString(m_Textures.GetTexture(Tex_In)-&amp;gt;TextureID);&lt;br /&gt;
            printf(&amp;quot;Could not render %s, incorrect Texture Format for this Polygon Bin. Format: %s, Bin: %s\n&amp;quot;, TxrID.c_str(), Txr.c_str(), Ply.c_str());&lt;br /&gt;
            m_Textures.GetTexture(Tex_In)-&amp;gt;RenderWarning++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Run our program, and we should see an error message telling us we used the wrong texture in the wrong list.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3733</id>
		<title>Dreamcast Tutorial</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3733"/>
		<updated>2025-04-05T14:50:36Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While many resources exist to explain individual parts of developing games and applications for the Dreamcast, there are not many comprehensive tutorials that detail the entire process. The following tutorial has been created to more thoroughly explain Dreamcast development topics towards a goal of creating fully featured applications. It is meant to be a full tutorial for beginners, starting from bare text files. This is a table of contents for topics the tutorial covers, in order.&lt;br /&gt;
&lt;br /&gt;
=== First Steps ===&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
&lt;br /&gt;
=== Texturing ===&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Transparent Textures]]&lt;br /&gt;
&lt;br /&gt;
=== Systems ===&lt;br /&gt;
* [[Event Handling]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3732</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3732"/>
		<updated>2025-04-05T14:48:25Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
** [[Dreamcast Tutorial]]&lt;br /&gt;
*** [[Makefile]]&lt;br /&gt;
*** [[Main.cpp]]&lt;br /&gt;
*** [[Adding a Romdisk]]&lt;br /&gt;
*** [[Drawing a Texture]]&lt;br /&gt;
*** [[Textures and Meshes]]&lt;br /&gt;
*** [[Event Handling]]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3731</id>
		<title>Dreamcast Tutorial</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3731"/>
		<updated>2025-04-05T14:47:43Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While many resources exist to explain individual parts of developing games and applications for the Dreamcast, there are not many comprehensive tutorials that detail the entire process. The following tutorial has been created to more thoroughly explain Dreamcast development topics towards a goal of creating fully featured applications. It is meant to be a full tutorial for beginners, starting from bare text files. This is a table of contents for topics the tutorial covers, in order.&lt;br /&gt;
&lt;br /&gt;
=== First Steps ===&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
&lt;br /&gt;
=== Texturing ===&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
&lt;br /&gt;
=== Systems ===&lt;br /&gt;
* [[Event Handling]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3730</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3730"/>
		<updated>2025-04-05T14:46:56Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
** [[Dreamcast Tutorial]]&lt;br /&gt;
*** [[Makefile]]&lt;br /&gt;
*** [[Main.cpp]]&lt;br /&gt;
*** [[Adding a Romdisk]]&lt;br /&gt;
*** [[Drawing a Texture]]&lt;br /&gt;
*** [[Event Handling]]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3729</id>
		<title>Textures and Meshes</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3729"/>
		<updated>2025-04-05T14:45:14Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At this point, since we’re going to be using multiple textures from now on, it makes sense to make a texture manager class. This will hold and store our Textures for us, so we can easily look through them and delete them if necessary. Begin by making a new class in our folder, “texture_manager.cpp” and “texture_manager.h”. Don’t forget to add “texture_manager.o” to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Our Texture_Manager class will need to see KOS to get internal dreamcast types, such as pvr_ptr. We will begin by adding our standard KOS headers, as well as our standard IO and int headers. We will be dealing with png files, so we need to include png/png.h. We will also need to access maps for our texture container, and since we will be dealing with c-strings, we should include cstring. Our Texture_manager.h should look like this:&lt;br /&gt;
 #ifndef TEXTURE_MANAGER_H&lt;br /&gt;
 #define TEXTURE_MANAGER_H&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 class texture_manager&lt;br /&gt;
 { &lt;br /&gt;
 public:&lt;br /&gt;
     texture_manager();&lt;br /&gt;
 };&lt;br /&gt;
 #endif // TEXTURE_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Internally, our class will need a map that pairs our texture ptrs and polygon contexts and other data objects to an enum. We will create and maintain an enum type that can be used to identify Textures as we use them in our source code. We will also need to create a Texture type that bundles the parts of a texture needed to render it together. Let’s create a new blank text file called Texture.h, and let’s create our TextureEnum and fill it with our background texture, and our font texture that we’ll use:&lt;br /&gt;
 #ifndef TEXTUREENUMS_H&lt;br /&gt;
 #define TEXTUREENUMS_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
     enum TextureEnum {&lt;br /&gt;
         Background_png = 0,&lt;br /&gt;
     };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We want a global function that can provide the name of the Enum as a string when called. We’ll do this with a little trick. In C, if you want to use a function that is in another translation unit object, you can do so by telling that source that, when linked, there is an “external” function in another object by that name. We do this with the Extern keyname. We need that function declaration to actually exist as compiled code somewhere, too. We can accomplish both the forward declaration and the extern declaration at the same time. To do this, we create a “TextureEnums.cpp”  file. This file defines a macro variable named TEXTUREENUM_CPP at the beginning of the file, and then undefs it at the end. This lets anything included within these brackets know they’re in that file. We can include our header within these brackets:&lt;br /&gt;
&lt;br /&gt;
 #define TEXTUREENUMS_CPP&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
 #undef TEXTUREENUMS_CPP /* TEXTUREENUMS_CPP */&lt;br /&gt;
&lt;br /&gt;
Because we defined TEXTUREENUMS_CPP, our header file can behave different depending on if it’s in TEXTUREENUMS_CPP or not:&lt;br /&gt;
 #ifdef TEXTUREENUMS_CPP&lt;br /&gt;
     const char* GetTextureString(TextureEnum In)&lt;br /&gt;
     {&lt;br /&gt;
         std::string TxEnum;&lt;br /&gt;
         switch(In)&lt;br /&gt;
         {&lt;br /&gt;
             case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
             case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
             case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
         }&lt;br /&gt;
     return TxEnum.c_str();&lt;br /&gt;
     }&lt;br /&gt;
 #else&lt;br /&gt;
     extern const char* GetTextureString(TextureEnum In);&lt;br /&gt;
 #endif&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
 &lt;br /&gt;
This will define the function in TextureEnums.cpp, but in every other file, it’ll instead forward declare the external function. This function lets us map a const c-string return to a TextureEnum. Whenever we add a new TextureEnum, we should modify this part of the code to update the strings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let’s create our Texture container. When we rendered our texture in Main.cpp, every Texture needed a pvr_ptr, which pointed to the texture in VRAM. Each also needed a pvr_poly_ctx_t, which holds their polygon context for the texture. We can also store our pvr_ply_hdr_t which is our context compiled into a PVR object. It would be wise to also store the width and height of the Texture. We will also store our TextureEnum as TextureID, so our Texture can be reflexive, meaning it can identify itself. Our Texture container should be the following:&lt;br /&gt;
 #ifndef TEXTURE_H&lt;br /&gt;
 #define TEXTURE_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     typedef struct _Texture_t&lt;br /&gt;
     {&lt;br /&gt;
         pvr_ptr m_Ptr;                  /* Pointer to VRAM */&lt;br /&gt;
         pvr_poly_ctx_t m_Context;       /* Texture Context settings */&lt;br /&gt;
         pvr_ply_hdr_t m_Header;         /* Texture PVR Header */&lt;br /&gt;
         uint32_t Width;                 /* Texture Width */&lt;br /&gt;
         uint32_t Height;                /* Texture Height */&lt;br /&gt;
         TextureEnum TextureID;&lt;br /&gt;
     } Texture_t;&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, include this file in our Texture_Manager.h:&lt;br /&gt;
 #ifndef TEXTURE_MANAGER_H&lt;br /&gt;
 #define TEXTURE_MANAGER_H&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now in our class, let’s use a map container to hold our Texture_t. A map container lets you pair a value, our Texture_t, with a key, in this case a TextureEnum value. This will be our internal storage, so we’ll make it private:&lt;br /&gt;
private:&lt;br /&gt;
     std::map&amp;lt;TextureEnum, Texture_t&amp;gt; Textures;&lt;br /&gt;
&lt;br /&gt;
Now, let’s create a function to get a texture_t pointer from our internal texture map:&lt;br /&gt;
public:&lt;br /&gt;
     texture_manager();&lt;br /&gt;
     Texture_t* GetTexture(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Let’s fill our these functions in our texture_manager.cpp. Our constructor will load our Textures into Map and assign them to our Enums:&lt;br /&gt;
 texture_manager::texture_manager()&lt;br /&gt;
 {&lt;br /&gt;
     Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                             reuse to build out our Texture map */&lt;br /&gt;
     /* Setup background.png */&lt;br /&gt;
     CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, &amp;amp;TempTxr, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
     Textures[background_png] = TempTxr;&lt;br /&gt;
     /* Setup background.png */&lt;br /&gt;
     CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, &amp;amp;TempTxr, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
     Textures[font_png] = TempTxr;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our GetTexture Function returns a pointer to the Texture according to the TextureEnum passed to it:&lt;br /&gt;
&lt;br /&gt;
 Texture_t *texture_manager::GetTexture(TextureEnum In)&lt;br /&gt;
 {&lt;br /&gt;
     return &amp;amp;Textures[In];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We need to move our Render function to our GameState. In gamestate.h change the headers to:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and in the class, under public, add:&lt;br /&gt;
 public:&lt;br /&gt;
     GameState();&lt;br /&gt;
     ~GameState();&lt;br /&gt;
     void HandleEvents();&lt;br /&gt;
     void Render();&lt;br /&gt;
     uint32_t Done;                /* Is the game finished running? */   &lt;br /&gt;
     std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
     const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
     void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
&lt;br /&gt;
Under Private, we need to add our Texture manager object and a function to make our GameState submit polygons to the Dreamcast PVR. Make our Private section look like this:&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Our Gamestate now holds our Textures and can draw to the screen. It loads textures into it’s texture atlus at object creation. Lets build out the Render() function in gamestate.cpp:&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitPolygon(background_png);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is our Draw function from Main.cpp transplanted over to the Gamestate class. It calls a new function called SubmitPolygon, which we’ll create next.&lt;br /&gt;
 void GameState::SubmitPolygon(TextureEnum In)&lt;br /&gt;
 {&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(In);&lt;br /&gt;
        pvr_vertex_t vert;&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
        vert.oargb = 0;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is a function that submits vertices that fill the screen and have it draw a Texture specified by the input parameter. Our Gamestate object now can create and manage textures, as well as submit them to the PVR to draw. Let’s modify our Main.cpp to accommodate these changes. Firstly, we can remove the draw_back() and DrawFrame() functions from Main.cpp, as those are handled by our render() and submit_polygon() functions in gamestate. We can also remove “pvr_ptr_t back_tex” from the top of the file. We can remove the textures_init() function, as this is now handled by the gamestate.texture constructor.  &lt;br /&gt;
&lt;br /&gt;
This leaves our Main.cpp looking very bare-bones, which is what we want. Our Main.cpp should create an instance of our game object, then run it in a loop. This is our new Main.cpp:&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;maple_events.h&amp;quot;&lt;br /&gt;
 /*** C Library forward declarations ***/&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif&lt;br /&gt;
     #include &amp;lt;zlib/zlib.h&amp;gt;                  /* Z-Lib library, used to decompress gzip files */&lt;br /&gt;
     extern int zlib_getlength(char*);&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 }&lt;br /&gt;
 #endif&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
     /* init systems  */&lt;br /&gt;
     gdb_init();&lt;br /&gt;
     pvr_init_defaults();&lt;br /&gt;
     GameState Game;&lt;br /&gt;
     MapleEvents Maple;&lt;br /&gt;
     /* Game Loop */&lt;br /&gt;
     while(!Game.Done)&lt;br /&gt;
     {    &lt;br /&gt;
         Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
         Game.HandleEvents();&lt;br /&gt;
         Game.Render();&lt;br /&gt;
     }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our game now handles inputs and can quit by pressing start. Run it and we should see our texture drawn to the screen. We now have our Texture rendering system in place, but our rendering code still manually hardcodes our vertex and their positiions. Just as we broke our textures out into a texture type and manager, so should we break out our vertex mesh shapes. Let’s start doing that by creating a mesh manager class, in the same style as our texture manager class. Create two blank text files called mesh_manager.cpp and mesh_manager.h. Inside mesh_manager.h, put the following:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MESH_MANAGER_H&lt;br /&gt;
 #define MESH_MANAGER_H&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class mesh_manager&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
     mesh_manager();&lt;br /&gt;
 &lt;br /&gt;
 };&lt;br /&gt;
 #endif // MESH_MANAGER_H&lt;br /&gt;
 &lt;br /&gt;
That is our standard class declaration. Now, just as we needed to create a texture_t type to hold all the information we need about a texture object for our texture manager, so will we create a pool of vertices that make up a mesh for our mesh manager to take care of. Let’s start by creating a mesh class. Create a blank text file for mesh.cpp and mesh.h. Inside of mesh.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MESH_H&lt;br /&gt;
 #define MESH_H&lt;br /&gt;
 #include &amp;quot;Texture.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;cstring&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdio.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 class Mesh&lt;br /&gt;
 {&lt;br /&gt;
     public:&lt;br /&gt;
         Mesh();&lt;br /&gt;
     private:&lt;br /&gt;
         pvr_vertex_t* VertexArray;         /* pointer to our vertex pool that makes up this mesh */&lt;br /&gt;
 };&lt;br /&gt;
 #endif&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We are going to need to know our texture enums to map to our mesh so we need Texture.h. We also will need our standard IO and integer types.&lt;br /&gt;
&lt;br /&gt;
We have a public constructor and a private pvr_vertex_t* pointer called verts. We will allocate a pool on the heap in our class, and this will be the head of the array of vertices. &lt;br /&gt;
&lt;br /&gt;
We are going to need to keep some other information about our Mesh. We want to know how many vertices are in our verts array, and we want to know the size of our array that we’ve allocated, so we don’t write outside our boundry. We’ll need a MeshEnum variable so the Mesh will be reflexive of it’s own type. Let’s add all this under public, as other parts of our program might need to change those variables:&lt;br /&gt;
&lt;br /&gt;
        uint32_t m_VtxCount;           /* number of vertices in this mesh */&lt;br /&gt;
        uint32_t m_Size;              /* Amount of Space allocated */&lt;br /&gt;
        MeshEnum e_MeshID;             /* My own Mesh type */&lt;br /&gt;
&lt;br /&gt;
We need some functions to allocate and get and set data in our vertex array. Let’s create a public Allocate function, along with public GetVertex and SetVertex:&lt;br /&gt;
&lt;br /&gt;
        pvr_vertex_t* GetVertex(uint32_t Idx);&lt;br /&gt;
        void SetVertex(pvr_vertex_t Input, uint32_t Idx);&lt;br /&gt;
        void AllocateVertexArray(uint32_t Count);&lt;br /&gt;
&lt;br /&gt;
SetVertex will change an already existing member of our Array. Let’s use another function, AddVertex, to actually add a new vertex to the array:&lt;br /&gt;
        void AddVertex(pvr_vertex_t Input)&lt;br /&gt;
&lt;br /&gt;
The way our Mesh will work is that we’ll allocate space for X number of vertices. A variable in our container will keep track of how many vertices have actually been written to the array. We’ll call this variable Vtx_Idx, and keep it in private:&lt;br /&gt;
        uint32_t Vtx_Idx;&lt;br /&gt;
When our Mesh object is created, this Vtx_Idx will be set to 0. Every time AddVertex is called, this Vtx_Idx is increased. The value of Vtx_Idx is used to set and write the new vertex in the vertex array. That is where the name is derived from, “Vertex Index” which is the index we are writing at in the vertex array. This value also doubles as the number of vertices in the array. We will only allow a new vertex to be added to our mesh if Vtx_Idx is less than Size, which is how much we have allocated.&lt;br /&gt;
&lt;br /&gt;
Let’s start by filling our our constructor in Mesh.cpp:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
 Mesh_t::Mesh_t()&lt;br /&gt;
 {&lt;br /&gt;
         ptr_VertexArray = NULL;&lt;br /&gt;
         m_VtxCount = 0;&lt;br /&gt;
         Vtx_Idx = 0;&lt;br /&gt;
         e_MeshID = MESH_NULL;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We set our verts pointer to NULL, and then set our idx and num_vtx counters to 0. We set our Texture enum to TX_NULL, our special enum value for no-texture.&lt;br /&gt;
&lt;br /&gt;
Let’s next set up our getter, setter, and adder:&lt;br /&gt;
 &lt;br /&gt;
        pvr_vertex_t* Mesh::GetVertex(uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if( m_VtxCount &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
                {&lt;br /&gt;
                    return verts[Idx];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return NULL;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        void Mesh::SetVertex(pvr_vertex_t Input, uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
            {&lt;br /&gt;
                verts[Idx] = Input;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        void Mesh::AddVertex(pvr_vertex_t Input)&lt;br /&gt;
        {&lt;br /&gt;
            verts[Vtx_Idx] = Input;&lt;br /&gt;
            Vtx_Idx++;    &lt;br /&gt;
 	     m_VtxCount = Vtx_Idx;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Our Getter has a guard check to make sure we have a vertex added to the array, and that the asked index is less than the number of submitted vertices. The Setter has the same guard. The Add Vertex function adds to the map, the convention is to use the numeric variable Vtx_Idx as the input for the key via the brackets. You set the value with the equal sign. This creates a key-value pair in the map container. We then increase the Vtx_Idx counter, so it points to the next empty space in the Vertex array. m_VtxCount is set to reflect Vtx_Idx, because m_VtxCount is public-facing.&lt;br /&gt;
&lt;br /&gt;
Now let’s write a function to allocate our Vertex array:&lt;br /&gt;
&lt;br /&gt;
 void Mesh::AllocateVertexArray(uint32_t Count)&lt;br /&gt;
 {&lt;br /&gt;
    VertexArray = (pvr_vertex_t*)malloc(Count * sizeof(pvr_vertex_t))&lt;br /&gt;
    m_Size = Count;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This calls malloc, the function in c and c++ that reserves space. It takes in a number representing the number of bytes to reserve. We take in a number called count as a function parameter, and use that number times the dize of the pvr_vertex_t type, to figure out how many bytes we need to store our data. This allocated memory is pointed to using our VertexArray pointer. Our mesh m_Size member is set to Count, the number of pvr_vertex_t elements we have allocated space for.&lt;br /&gt;
&lt;br /&gt;
With this, we have our Mesh object. A mesh is any array of Vertices we want to group together under one texture to render. When we rendered our texture to the screen before, the full screen image, we used 4 vertices in a strip of 2 polygon triangles to draw it. Those 4 vertices are our mesh, we could call that a Quad Mesh. In fact, let’s do just that. We’ll keep an enum of our Meshes, just like we do with our Textures. Let’s create a blank header file called MeshEnums.h and add the following:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MESHENUMS_H&lt;br /&gt;
 #define MESHENUMS_H&lt;br /&gt;
 enum MeshEnum {&lt;br /&gt;
    e_Quad = 0,&lt;br /&gt;
    MESH_NULL&lt;br /&gt;
 };&lt;br /&gt;
 #endif // MESHENUMS_H&lt;br /&gt;
&lt;br /&gt;
This sets us up with an enum type, MeshEnum, which we can use to distinguish between mesh objects we define. We already have a type called Quad in our list, let’s build it out. We will create it in our Mesh_Manager then have it ready for when we need to call it. Let’s add our MeshEnums.h file to our Mesh_Manager.h header file:&lt;br /&gt;
 #ifndef MESH_MANAGER_H&lt;br /&gt;
 #define MESH_MANAGER_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;MeshEnums.h&amp;quot;&lt;br /&gt;
 class mesh_manager&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    mesh_manager();&lt;br /&gt;
 private:&lt;br /&gt;
    std::map&amp;lt;MeshEnum, Mesh_t&amp;gt; Meshes;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // MESH_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Mesh_Manager constructor make our quad mesh for us, as a default one when our program begins. That way we can always have it on hand to easily render textures to the screen. Let’s allocate some vertex space and create our mesh object in the constructor in mesh_manager.cpp:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
 mesh_manager::mesh_manager()&lt;br /&gt;
 {&lt;br /&gt;
    Mesh_t T_Mesh;                   /* A temporary Mesh_t object we will fill out to add to our mesh vector */&lt;br /&gt;
    pvr_vertex_t T_Vertex;      /* A temporary vertex object, we will fill out to add to our T Mesh&#039;s vertex array */&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.AllocateVertexArray(4);   /* We can hold 4 vertices in this mesh */&lt;br /&gt;
    T_Vertex.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    T_Vertex.oargb = 0;&lt;br /&gt;
    T_Vertex.flags = PVR_CMD_VERTEX;&lt;br /&gt;
    &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We begin by creating a temporary T_Mesh object of Mesh_t type. This is the object we will interact with and configure, which will be submitted to the Mesh vector in our manager. We next create a temporary T_Vertex object, of pvr_vertex_t type. This is the vertex object that we will configure, which will be uploaded to the T_Mesh vertex array.&lt;br /&gt;
&lt;br /&gt;
We begin by allocating 4 vertices in T_Mesh. Next, we configure our argb and oargb values in our T_Vertex, and set a flag indicating this is a PVR_CMD_VERTEX. That means this is just one in a strip of vertices, not the end of the strip.&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
&lt;br /&gt;
Our next step is to set the XYZ position and the UV coordinates of the vertex. This is the upper left corner of the quad. We use 1.0 as the constant Z value. After we set the vertex position and uv coordinates, we push it onto our T_Mesh Vertex Array. We can then do the same for the other 3 vertices:&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Vertex.T_Mesh.AddVertex = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.e_MeshID = e_Quad;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A few things to note here. In our previous example where we drew the background texture to the screen, our vertex positions spanned from 0 to 640 in the X range, and 0 to 480 in the Y range. Yet in this mesh, our vertex spans from 0 to 1 in both ranges. This is because this will be a generic mesh. We will create a transformation matrix that will allow us to resize the mesh on the fly when we need it, that way we can reuse this mesh to draw any quad shape we want to the screen.&lt;br /&gt;
&lt;br /&gt;
The second thing to note is that in the final vertex, we change the flag to PVR_CMD_VERTEX_EOL. This is a command to tell the PVR that this vertex is the tail end of the vertex chain, meaning this group of 4 Vertices are grouped as one Vertex Strip.&lt;br /&gt;
&lt;br /&gt;
Finally, we set the enum inside this Mesh object to e_Quad, so our object can self-identify. With all this done, we are ready to add this to our Mesh_Manager object:&lt;br /&gt;
&lt;br /&gt;
    Meshes[e_Quad] = T_Mesh;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This creates a hash item in our Meshes Map for e_Quad, which contains a copy of our T_Mesh object. We now have a Mesh in our Mesh_Manager object that we can easily call to draw quads with. Let’s put an instance of our Mesh_Manager in our Gamestate class. First, we need to add our header to gamestate.h:&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Next, in gamestate.h, inside the class Gamestate {} declaration, add this under private:&lt;br /&gt;
&lt;br /&gt;
 private:&lt;br /&gt;
     cont_state_t PrevControllerState;&lt;br /&gt;
     &lt;br /&gt;
     texture_manager m_Textures;&lt;br /&gt;
     void SubmitPolygon(TextureEnum In);&lt;br /&gt;
     mesh_manager m_Meshes;&lt;br /&gt;
 };&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Now let’s try using our mesh object from our mesh manager. In Gamestate.cpp, in the SubmitPolygon function, let’s have it call and use our Mesh_Manager:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitPolygon(TextureEnum Tex_In, MeshEnum Mesh_In)&lt;br /&gt;
 {&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[Mesh_In].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[Mesh_In].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = Vertex_ptr-&amp;gt;x;&lt;br /&gt;
            T_vertex.y = Vertex_ptr-&amp;gt;y;&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is basically the same logic as before, only now the vertex is being submitted in a loop. We set the for-loop to repeat for as many vertices are in our mesh, as called by m_Meshes.Meshes[Mesh_In].m_VtxCount. A temporary vertex T_Vertex is then mapped to the current vertex in the Vertex Array for that mesh, and then T_Vertex is submitted to the dreamcast PVR to render. We can select which Mesh to render when using the function by using a Mesh_In enum, which is set as a second parameter for “Submit Polygon.” There is one problem, however: Our XY positions for the corners of our quad are 1 pixel big. We need to do math on them to make them resize the way we want it. Let’s clone our SubmitPolygon function, and make a “SubmitQuad” function:&lt;br /&gt;
&lt;br /&gt;
 void GameState::SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In)&lt;br /&gt;
 {&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        &lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[e_Quad].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[e_Quad].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = X_In + (Vertex_ptr-&amp;gt;x * W_In);&lt;br /&gt;
            T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * H_In);&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
            RenderDepth += 0.01;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to the old SubmitPolygon function, but the x and y positions ot T_Vertex are altered before drawing. This function is only for drawing Quads, so we don’t need it to take in a MeshEnum parameter, we already know it’ll use the e_Quad value. Instead, we take in an X, Y, W, and H parameter. This is the position and dimensions of the Quad we are drawing.  When we submit our vertices, we do some math to change the value of T_Vertex before it’s submitted.&lt;br /&gt;
&lt;br /&gt;
We are using a new variable called RenderDepth and adding it to the Z position in the Vertex. This is because rendering two Quads in the same position causes Z-Fighting, so we need to offset every call to this Quad function by a small amount each time. Let’s create this variable in Gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
    &lt;br /&gt;
    float Render_Depth;&lt;br /&gt;
&lt;br /&gt;
Every time we call the Render function in Gamestate, we need to reset our Render_Depth:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    static uint8_t Timer = 0;&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
        Timer++;&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            if(Timer &amp;amp; 1)&lt;br /&gt;
            {&lt;br /&gt;
                SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
                SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            }&lt;br /&gt;
            SubmitQuad(background_png, 200, 20, 150, 150);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
First, we add our X_In and Y_In positions to our X and Y vertex positions respectively. This lets us scroll the quad with those two values. The Vertex X and Y positions are also added the Width and Height values provided, but only when the Vertex X and Y are 1 and not 0. This is why we set our Vertex positions to 1 instead of 640 and 480 in our mesh constructor, so they can be used as toggles for these additional height and width calculations. &lt;br /&gt;
&lt;br /&gt;
Don’t forget to add a declaration for our SubmitQuad function in our gamestate header. We have also changed our SubmitPolygon function to take in a MeshEnum parameter so we can choose which mesh to render, so let’s make these changes:&lt;br /&gt;
&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
 private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    &lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
    void SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
We also need to add our new source files to our Makefile under $(OBJS):&lt;br /&gt;
OBJS = game.o romdisk.o gamestate.o maple_events.o texture_manager.o mesh.o mesh_manager.o &lt;br /&gt;
&lt;br /&gt;
With these changes set, we can now tell our program to draw a texture anywhere in any size on the screen, just by referring to the TextureEnum. Let’s do so in our Gamestate class. In our Render function, let’s call our SubmitQuad function instead. Let’s use custom X,Y,W, and H settings:&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Let’s run and see what happens! We can now draw textures to the screen in any position or shape we want! Let’s go crazy and do it multiple times!&lt;br /&gt;
&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
            SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            SubmitQuad(background_png, 200, 300, 950, 950);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We now have a pretty good base tool which we can modify to start rendering text. These mesh and texture classes and their respective managers will pay off greatly down the line. Just remember that for each mesh and texture we create, we need to modify their Enum header files to indicate their creation and enable their usage.&lt;br /&gt;
&lt;br /&gt;
Let’s have our Texture_manager load our font texture. First, we need to create an entry in our TextureEnum.h:&lt;br /&gt;
&lt;br /&gt;
 enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    TX_NULL&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Let’s create a function to compile our Texture context for us:&lt;br /&gt;
 void CompileContext(char* Path, TextureEnum TxrID, Texture_t* TempTxr, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
 {&lt;br /&gt;
 TempTxr.Width = W;&lt;br /&gt;
    TempTxr.Height = H;&lt;br /&gt;
    TempTxr.TextureID = TxrID;&lt;br /&gt;
    TempTxr.m_Ptr = pvr_mem_malloc(W * H * 2);&lt;br /&gt;
    png_to_texture(Path, TempTxr.m_Ptr, PngMode);&lt;br /&gt;
    /* Set our Texture Type */&lt;br /&gt;
 &lt;br /&gt;
     pvr_poly_cxt_txr(&amp;amp;TempTxr-&amp;gt;m_Context,        /* Dest Context to write to */&lt;br /&gt;
                       PVR_LIST_OP_POLY,        /* Polygon Bin Type */&lt;br /&gt;
                       PVR_TXRFMT_RGB565,       /* Texture Format */&lt;br /&gt;
                       W,                     /* Texture Width */&lt;br /&gt;
                       H,                     /* Texture Height */&lt;br /&gt;
                       TempTxr-&amp;gt;m_Ptr,                /* Texture Pointer */&lt;br /&gt;
                       Filtering);    /* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;TempTxr.m_Header, &amp;amp;TempTxr.m_Context);&lt;br /&gt;
    Textures[TxrID] = TempTxr;&lt;br /&gt;
 }&lt;br /&gt;
This is the same code we used to compile our Texture Context before. We set the dest, set the polygon list to use, set the texture format, set width, height, a texture pointer, and a filter flag. &lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Texture_manager constructor create a font texture for us:&lt;br /&gt;
&lt;br /&gt;
 texture_manager::texture_manager()&lt;br /&gt;
 {&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
 &lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3728</id>
		<title>Textures and Meshes</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3728"/>
		<updated>2025-04-05T14:41:57Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At this point, since we’re going to be using multiple textures from now on, it makes sense to make a texture manager class. This will hold and store our Textures for us, so we can easily look through them and delete them if necessary. Begin by making a new class in our folder, “texture_manager.cpp” and “texture_manager.h”. Don’t forget to add “texture_manager.o” to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Our Texture_Manager class will need to see KOS to get internal dreamcast types, such as pvr_ptr. We will begin by adding our standard KOS headers, as well as our standard IO and int headers. We will be dealing with png files, so we need to include png/png.h. We will also need to access maps for our texture container, and since we will be dealing with c-strings, we should include cstring. Our Texture_manager.h should look like this:&lt;br /&gt;
 #ifndef TEXTURE_MANAGER_H&lt;br /&gt;
 #define TEXTURE_MANAGER_H&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 class texture_manager&lt;br /&gt;
 { &lt;br /&gt;
 public:&lt;br /&gt;
     texture_manager();&lt;br /&gt;
 };&lt;br /&gt;
 #endif // TEXTURE_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Internally, our class will need a map that pairs our texture ptrs and polygon contexts and other data objects to an enum. We will create and maintain an enum type that can be used to identify Textures as we use them in our source code. We will also need to create a Texture type that bundles the parts of a texture needed to render it together. Let’s create a new blank text file called Texture.h, and let’s create our TextureEnum and fill it with our background texture, and our font texture that we’ll use:&lt;br /&gt;
 #ifndef TEXTUREENUMS_H&lt;br /&gt;
 #define TEXTUREENUMS_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
     enum TextureEnum {&lt;br /&gt;
         Background_png = 0,&lt;br /&gt;
     };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We want a global function that can provide the name of the Enum as a string when called. We’ll do this with a little trick. In C, if you want to use a function that is in another translation unit object, you can do so by telling that source that, when linked, there is an “external” function in another object by that name. We do this with the Extern keyname. We need that function declaration to actually exist as compiled code somewhere, too. We can accomplish both the forward declaration and the extern declaration at the same time. To do this, we create a “TextureEnums.cpp”  file. This file defines a macro variable named TEXTUREENUM_CPP at the beginning of the file, and then undefs it at the end. This lets anything included within these brackets know they’re in that file. We can include our header within these brackets:&lt;br /&gt;
&lt;br /&gt;
 #define TEXTUREENUMS_CPP&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
 #undef TEXTUREENUMS_CPP /* TEXTUREENUMS_CPP */&lt;br /&gt;
&lt;br /&gt;
Because we defined TEXTUREENUMS_CPP, our header file can behave different depending on if it’s in TEXTUREENUMS_CPP or not:&lt;br /&gt;
 #ifdef TEXTUREENUMS_CPP&lt;br /&gt;
     const char* GetTextureString(TextureEnum In)&lt;br /&gt;
     {&lt;br /&gt;
         std::string TxEnum;&lt;br /&gt;
         switch(In)&lt;br /&gt;
         {&lt;br /&gt;
             case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
             case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
             case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
             break;&lt;br /&gt;
         }&lt;br /&gt;
     return TxEnum.c_str();&lt;br /&gt;
     }&lt;br /&gt;
 #else&lt;br /&gt;
     extern const char* GetTextureString(TextureEnum In);&lt;br /&gt;
 #endif&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
 &lt;br /&gt;
This will define the function in TextureEnums.cpp, but in every other file, it’ll instead forward declare the external function. This function lets us map a const c-string return to a TextureEnum. Whenever we add a new TextureEnum, we should modify this part of the code to update the strings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let’s create our Texture container. When we rendered our texture in Main.cpp, every Texture needed a pvr_ptr, which pointed to the texture in VRAM. Each also needed a pvr_poly_ctx_t, which holds their polygon context for the texture. We can also store our pvr_ply_hdr_t which is our context compiled into a PVR object. It would be wise to also store the width and height of the Texture. We will also store our TextureEnum as TextureID, so our Texture can be reflexive, meaning it can identify itself. Our Texture container should be the following:&lt;br /&gt;
 #ifndef TEXTURE_H&lt;br /&gt;
 #define TEXTURE_H&lt;br /&gt;
 #include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
     typedef struct _Texture_t&lt;br /&gt;
     {&lt;br /&gt;
         pvr_ptr m_Ptr;                  /* Pointer to VRAM */&lt;br /&gt;
         pvr_poly_ctx_t m_Context;       /* Texture Context settings */&lt;br /&gt;
         pvr_ply_hdr_t m_Header;         /* Texture PVR Header */&lt;br /&gt;
         uint32_t Width;                 /* Texture Width */&lt;br /&gt;
         uint32_t Height;                /* Texture Height */&lt;br /&gt;
         TextureEnum TextureID;&lt;br /&gt;
     } Texture_t;&lt;br /&gt;
 #endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, include this file in our Texture_Manager.h:&lt;br /&gt;
 #ifndef TEXTURE_MANAGER_H&lt;br /&gt;
 #define TEXTURE_MANAGER_H&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 #include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now in our class, let’s use a map container to hold our Texture_t. A map container lets you pair a value, our Texture_t, with a key, in this case a TextureEnum value. This will be our internal storage, so we’ll make it private:&lt;br /&gt;
private:&lt;br /&gt;
     std::map&amp;lt;TextureEnum, Texture_t&amp;gt; Textures;&lt;br /&gt;
&lt;br /&gt;
Now, let’s create a function to get a texture_t pointer from our internal texture map:&lt;br /&gt;
public:&lt;br /&gt;
     texture_manager();&lt;br /&gt;
     Texture_t* GetTexture(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Let’s fill our these functions in our texture_manager.cpp. Our constructor will load our Textures into Map and assign them to our Enums:&lt;br /&gt;
 texture_manager::texture_manager()&lt;br /&gt;
 {&lt;br /&gt;
     Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                             reuse to build out our Texture map */&lt;br /&gt;
     /* Setup background.png */&lt;br /&gt;
     CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, &amp;amp;TempTxr, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
     Textures[background_png] = TempTxr;&lt;br /&gt;
     /* Setup background.png */&lt;br /&gt;
     CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, &amp;amp;TempTxr, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
     Textures[font_png] = TempTxr;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our GetTexture Function returns a pointer to the Texture according to the TextureEnum passed to it:&lt;br /&gt;
&lt;br /&gt;
 Texture_t *texture_manager::GetTexture(TextureEnum In)&lt;br /&gt;
 {&lt;br /&gt;
     return &amp;amp;Textures[In];&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We need to move our Render function to our GameState. In gamestate.h change the headers to:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and in the class, under public, add:&lt;br /&gt;
 public:&lt;br /&gt;
     GameState();&lt;br /&gt;
     ~GameState();&lt;br /&gt;
     void HandleEvents();&lt;br /&gt;
     void Render();&lt;br /&gt;
     uint32_t Done;                /* Is the game finished running? */   &lt;br /&gt;
     std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
     const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
     void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
&lt;br /&gt;
Under Private, we need to add our Texture manager object and a function to make our GameState submit polygons to the Dreamcast PVR. Make our Private section look like this:&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Our Gamestate now holds our Textures and can draw to the screen. It loads textures into it’s texture atlus at object creation. Lets build out the Render() function in gamestate.cpp:&lt;br /&gt;
 void GameState::Render()&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitPolygon(background_png);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is our Draw function from Main.cpp transplanted over to the Gamestate class. It calls a new function called SubmitPolygon, which we’ll create next.&lt;br /&gt;
 void GameState::SubmitPolygon(TextureEnum In)&lt;br /&gt;
 {&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(In);&lt;br /&gt;
        pvr_vertex_t vert;&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
        vert.oargb = 0;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This is a function that submits vertices that fill the screen and have it draw a Texture specified by the input parameter. Our Gamestate object now can create and manage textures, as well as submit them to the PVR to draw. Let’s modify our Main.cpp to accommodate these changes. Firstly, we can remove the draw_back() and DrawFrame() functions from Main.cpp, as those are handled by our render() and submit_polygon() functions in gamestate. We can also remove “pvr_ptr_t back_tex” from the top of the file. We can remove the textures_init() function, as this is now handled by the gamestate.texture constructor.  &lt;br /&gt;
&lt;br /&gt;
This leaves our Main.cpp looking very bare-bones, which is what we want. Our Main.cpp should create an instance of our game object, then run it in a loop. This is our new Main.cpp:&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;maple_events.h&amp;quot;&lt;br /&gt;
 /*** C Library forward declarations ***/&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 extern &amp;quot;C&amp;quot; {&lt;br /&gt;
 #endif&lt;br /&gt;
     #include &amp;lt;zlib/zlib.h&amp;gt;                  /* Z-Lib library, used to decompress gzip files */&lt;br /&gt;
     extern int zlib_getlength(char*);&lt;br /&gt;
 #ifdef __cplusplus&lt;br /&gt;
 }&lt;br /&gt;
 #endif&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
     /* init systems  */&lt;br /&gt;
     gdb_init();&lt;br /&gt;
     pvr_init_defaults();&lt;br /&gt;
     GameState Game;&lt;br /&gt;
     MapleEvents Maple;&lt;br /&gt;
     /* Game Loop */&lt;br /&gt;
     while(!Game.Done)&lt;br /&gt;
     {    &lt;br /&gt;
         Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
         Game.HandleEvents();&lt;br /&gt;
         Game.Render();&lt;br /&gt;
     }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our game now handles inputs and can quit by pressing start. Run it and we should see our texture drawn to the screen. We now have our Texture rendering system in place, but our rendering code still manually hardcodes our vertex and their positiions. Just as we broke our textures out into a texture type and manager, so should we break out our vertex mesh shapes. Let’s start doing that by creating a mesh manager class, in the same style as our texture manager class. Create two blank text files called mesh_manager.cpp and mesh_manager.h. Inside mesh_manager.h, put the following:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MESH_MANAGER_H&lt;br /&gt;
 #define MESH_MANAGER_H&lt;br /&gt;
 &lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 #include &amp;lt;map&amp;gt;&lt;br /&gt;
 #include &amp;lt;cstring&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class mesh_manager&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
     mesh_manager();&lt;br /&gt;
 &lt;br /&gt;
 };&lt;br /&gt;
 #endif // MESH_MANAGER_H&lt;br /&gt;
 &lt;br /&gt;
That is our standard class declaration. Now, just as we needed to create a texture_t type to hold all the information we need about a texture object for our texture manager, so will we create a pool of vertices that make up a mesh for our mesh manager to take care of. Let’s start by creating a mesh class. Create a blank text file for mesh.cpp and mesh.h. Inside of mesh.h:&lt;br /&gt;
&lt;br /&gt;
#ifndef MESH_H&lt;br /&gt;
#define MESH_H&lt;br /&gt;
#include &amp;quot;Texture.h&amp;quot;&lt;br /&gt;
#include &amp;quot;cstring&amp;quot;&lt;br /&gt;
#include &amp;quot;stdio.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
class Mesh&lt;br /&gt;
{&lt;br /&gt;
    public:&lt;br /&gt;
        Mesh();&lt;br /&gt;
    private:&lt;br /&gt;
        pvr_vertex_t* VertexArray;         /* pointer to our vertex pool that makes up this mesh */&lt;br /&gt;
};&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We are going to need to know our texture enums to map to our mesh so we need Texture.h. We also will need our standard IO and integer types.&lt;br /&gt;
&lt;br /&gt;
We have a public constructor and a private pvr_vertex_t* pointer called verts. We will allocate a pool on the heap in our class, and this will be the head of the array of vertices. &lt;br /&gt;
&lt;br /&gt;
We are going to need to keep some other information about our Mesh. We want to know how many vertices are in our verts array, and we want to know the size of our array that we’ve allocated, so we don’t write outside our boundry. We’ll need a MeshEnum variable so the Mesh will be reflexive of it’s own type. Let’s add all this under public, as other parts of our program might need to change those variables:&lt;br /&gt;
        uint32_t m_VtxCount;           /* number of vertices in this mesh */&lt;br /&gt;
        uint32_t m_Size;              /* Amount of Space allocated */&lt;br /&gt;
        MeshEnum e_MeshID;             /* My own Mesh type */&lt;br /&gt;
&lt;br /&gt;
We need some functions to allocate and get and set data in our vertex array. Let’s create a public Allocate function, along with public GetVertex and SetVertex:&lt;br /&gt;
&lt;br /&gt;
        pvr_vertex_t* GetVertex(uint32_t Idx);&lt;br /&gt;
        void SetVertex(pvr_vertex_t Input, uint32_t Idx);&lt;br /&gt;
        void AllocateVertexArray(uint32_t Count);&lt;br /&gt;
&lt;br /&gt;
SetVertex will change an already existing member of our Array. Let’s use another function, AddVertex, to actually add a new vertex to the array:&lt;br /&gt;
        void AddVertex(pvr_vertex_t Input)&lt;br /&gt;
&lt;br /&gt;
The way our Mesh will work is that we’ll allocate space for X number of vertices. A variable in our container will keep track of how many vertices have actually been written to the array. We’ll call this variable Vtx_Idx, and keep it in private:&lt;br /&gt;
        uint32_t Vtx_Idx;&lt;br /&gt;
When our Mesh object is created, this Vtx_Idx will be set to 0. Every time AddVertex is called, this Vtx_Idx is increased. The value of Vtx_Idx is used to set and write the new vertex in the vertex array. That is where the name is derived from, “Vertex Index” which is the index we are writing at in the vertex array. This value also doubles as the number of vertices in the array. We will only allow a new vertex to be added to our mesh if Vtx_Idx is less than Size, which is how much we have allocated.&lt;br /&gt;
&lt;br /&gt;
Let’s start by filling our our constructor in Mesh.cpp:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
Mesh_t::Mesh_t()&lt;br /&gt;
{&lt;br /&gt;
        ptr_VertexArray = NULL;&lt;br /&gt;
        m_VtxCount = 0;&lt;br /&gt;
        Vtx_Idx = 0;&lt;br /&gt;
        e_MeshID = MESH_NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We set our verts pointer to NULL, and then set our idx and num_vtx counters to 0. We set our Texture enum to TX_NULL, our special enum value for no-texture.&lt;br /&gt;
&lt;br /&gt;
Let’s next set up our getter, setter, and adder:&lt;br /&gt;
&lt;br /&gt;
        pvr_vertex_t* Mesh::GetVertex(uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if( m_VtxCount &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
                {&lt;br /&gt;
                    return verts[Idx];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return NULL;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        void Mesh::SetVertex(pvr_vertex_t Input, uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
            {&lt;br /&gt;
                verts[Idx] = Input;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        void Mesh::AddVertex(pvr_vertex_t Input)&lt;br /&gt;
        {&lt;br /&gt;
            verts[Vtx_Idx] = Input;&lt;br /&gt;
            Vtx_Idx++;    &lt;br /&gt;
	     m_VtxCount = Vtx_Idx;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Our Getter has a guard check to make sure we have a vertex added to the array, and that the asked index is less than the number of submitted vertices. The Setter has the same guard. The Add Vertex function adds to the map, the convention is to use the numeric variable Vtx_Idx as the input for the key via the brackets. You set the value with the equal sign. This creates a key-value pair in the map container. We then increase the Vtx_Idx counter, so it points to the next empty space in the Vertex array. m_VtxCount is set to reflect Vtx_Idx, because m_VtxCount is public-facing.&lt;br /&gt;
&lt;br /&gt;
Now let’s write a function to allocate our Vertex array:&lt;br /&gt;
&lt;br /&gt;
void Mesh::AllocateVertexArray(uint32_t Count)&lt;br /&gt;
{&lt;br /&gt;
    VertexArray = (pvr_vertex_t*)malloc(Count * sizeof(pvr_vertex_t))&lt;br /&gt;
    m_Size = Count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This calls malloc, the function in c and c++ that reserves space. It takes in a number representing the number of bytes to reserve. We take in a number called count as a function parameter, and use that number times the dize of the pvr_vertex_t type, to figure out how many bytes we need to store our data. This allocated memory is pointed to using our VertexArray pointer. Our mesh m_Size member is set to Count, the number of pvr_vertex_t elements we have allocated space for.&lt;br /&gt;
&lt;br /&gt;
With this, we have our Mesh object. A mesh is any array of Vertices we want to group together under one texture to render. When we rendered our texture to the screen before, the full screen image, we used 4 vertices in a strip of 2 polygon triangles to draw it. Those 4 vertices are our mesh, we could call that a Quad Mesh. In fact, let’s do just that. We’ll keep an enum of our Meshes, just like we do with our Textures. Let’s create a blank header file called MeshEnums.h and add the following:&lt;br /&gt;
&lt;br /&gt;
#ifndef MESHENUMS_H&lt;br /&gt;
#define MESHENUMS_H&lt;br /&gt;
enum MeshEnum {&lt;br /&gt;
    e_Quad = 0,&lt;br /&gt;
    MESH_NULL&lt;br /&gt;
};&lt;br /&gt;
#endif // MESHENUMS_H&lt;br /&gt;
&lt;br /&gt;
This sets us up with an enum type, MeshEnum, which we can use to distinguish between mesh objects we define. We already have a type called Quad in our list, let’s build it out. We will create it in our Mesh_Manager then have it ready for when we need to call it. Let’s add our MeshEnums.h file to our Mesh_Manager.h header file:&lt;br /&gt;
#ifndef MESH_MANAGER_H&lt;br /&gt;
#define MESH_MANAGER_H&lt;br /&gt;
#include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MeshEnums.h&amp;quot;&lt;br /&gt;
class mesh_manager&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    mesh_manager();&lt;br /&gt;
private:&lt;br /&gt;
    std::map&amp;lt;MeshEnum, Mesh_t&amp;gt; Meshes;&lt;br /&gt;
};&lt;br /&gt;
#endif // MESH_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Mesh_Manager constructor make our quad mesh for us, as a default one when our program begins. That way we can always have it on hand to easily render textures to the screen. Let’s allocate some vertex space and create our mesh object in the constructor in mesh_manager.cpp:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
mesh_manager::mesh_manager()&lt;br /&gt;
{&lt;br /&gt;
    Mesh_t T_Mesh;                   /* A temporary Mesh_t object we will fill out to add to our mesh vector */&lt;br /&gt;
    pvr_vertex_t T_Vertex;      /* A temporary vertex object, we will fill out to add to our T Mesh&#039;s vertex array */&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.AllocateVertexArray(4);   /* We can hold 4 vertices in this mesh */&lt;br /&gt;
    T_Vertex.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    T_Vertex.oargb = 0;&lt;br /&gt;
    T_Vertex.flags = PVR_CMD_VERTEX;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We begin by creating a temporary T_Mesh object of Mesh_t type. This is the object we will interact with and configure, which will be submitted to the Mesh vector in our manager. We next create a temporary T_Vertex object, of pvr_vertex_t type. This is the vertex object that we will configure, which will be uploaded to the T_Mesh vertex array.&lt;br /&gt;
&lt;br /&gt;
We begin by allocating 4 vertices in T_Mesh. Next, we configure our argb and oargb values in our T_Vertex, and set a flag indicating this is a PVR_CMD_VERTEX. That means this is just one in a strip of vertices, not the end of the strip.&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
&lt;br /&gt;
Our next step is to set the XYZ position and the UV coordinates of the vertex. This is the upper left corner of the quad. We use 1.0 as the constant Z value. After we set the vertex position and uv coordinates, we push it onto our T_Mesh Vertex Array. We can then do the same for the other 3 vertices:&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Vertex.T_Mesh.AddVertex = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.e_MeshID = e_Quad;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A few things to note here. In our previous example where we drew the background texture to the screen, our vertex positions spanned from 0 to 640 in the X range, and 0 to 480 in the Y range. Yet in this mesh, our vertex spans from 0 to 1 in both ranges. This is because this will be a generic mesh. We will create a transformation matrix that will allow us to resize the mesh on the fly when we need it, that way we can reuse this mesh to draw any quad shape we want to the screen.&lt;br /&gt;
&lt;br /&gt;
The second thing to note is that in the final vertex, we change the flag to PVR_CMD_VERTEX_EOL. This is a command to tell the PVR that this vertex is the tail end of the vertex chain, meaning this group of 4 Vertices are grouped as one Vertex Strip.&lt;br /&gt;
&lt;br /&gt;
Finally, we set the enum inside this Mesh object to e_Quad, so our object can self-identify. With all this done, we are ready to add this to our Mesh_Manager object:&lt;br /&gt;
&lt;br /&gt;
    Meshes[e_Quad] = T_Mesh;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This creates a hash item in our Meshes Map for e_Quad, which contains a copy of our T_Mesh object. We now have a Mesh in our Mesh_Manager object that we can easily call to draw quads with. Let’s put an instance of our Mesh_Manager in our Gamestate class. First, we need to add our header to gamestate.h:&lt;br /&gt;
#ifndef GAMESTATE_H&lt;br /&gt;
#define GAMESTATE_H&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
#include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Next, in gamestate.h, inside the class Gamestate {} declaration, add this under private:&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    &lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
};&lt;br /&gt;
#endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Now let’s try using our mesh object from our mesh manager. In Gamestate.cpp, in the SubmitPolygon function, let’s have it call and use our Mesh_Manager:&lt;br /&gt;
&lt;br /&gt;
void GameState::SubmitPolygon(TextureEnum Tex_In, MeshEnum Mesh_In)&lt;br /&gt;
{&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[Mesh_In].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[Mesh_In].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = Vertex_ptr-&amp;gt;x;&lt;br /&gt;
            T_vertex.y = Vertex_ptr-&amp;gt;y;&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This is basically the same logic as before, only now the vertex is being submitted in a loop. We set the for-loop to repeat for as many vertices are in our mesh, as called by m_Meshes.Meshes[Mesh_In].m_VtxCount. A temporary vertex T_Vertex is then mapped to the current vertex in the Vertex Array for that mesh, and then T_Vertex is submitted to the dreamcast PVR to render. We can select which Mesh to render when using the function by using a Mesh_In enum, which is set as a second parameter for “Submit Polygon.” There is one problem, however: Our XY positions for the corners of our quad are 1 pixel big. We need to do math on them to make them resize the way we want it. Let’s clone our SubmitPolygon function, and make a “SubmitQuad” function:&lt;br /&gt;
&lt;br /&gt;
void GameState::SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In)&lt;br /&gt;
{&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        &lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[e_Quad].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[e_Quad].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = X_In + (Vertex_ptr-&amp;gt;x * W_In);&lt;br /&gt;
            T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * H_In);&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
            RenderDepth += 0.01;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to the old SubmitPolygon function, but the x and y positions ot T_Vertex are altered before drawing. This function is only for drawing Quads, so we don’t need it to take in a MeshEnum parameter, we already know it’ll use the e_Quad value. Instead, we take in an X, Y, W, and H parameter. This is the position and dimensions of the Quad we are drawing.  When we submit our vertices, we do some math to change the value of T_Vertex before it’s submitted.&lt;br /&gt;
&lt;br /&gt;
We are using a new variable called RenderDepth and adding it to the Z position in the Vertex. This is because rendering two Quads in the same position causes Z-Fighting, so we need to offset every call to this Quad function by a small amount each time. Let’s create this variable in Gamestate.h:&lt;br /&gt;
&lt;br /&gt;
class GameState&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
    &lt;br /&gt;
    float Render_Depth;&lt;br /&gt;
&lt;br /&gt;
Every time we call the Render function in Gamestate, we need to reset our Render_Depth:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    static uint8_t Timer = 0;&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
        Timer++;&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            if(Timer &amp;amp; 1)&lt;br /&gt;
            {&lt;br /&gt;
                SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
                SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            }&lt;br /&gt;
            SubmitQuad(background_png, 200, 20, 150, 150);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
First, we add our X_In and Y_In positions to our X and Y vertex positions respectively. This lets us scroll the quad with those two values. The Vertex X and Y positions are also added the Width and Height values provided, but only when the Vertex X and Y are 1 and not 0. This is why we set our Vertex positions to 1 instead of 640 and 480 in our mesh constructor, so they can be used as toggles for these additional height and width calculations. &lt;br /&gt;
&lt;br /&gt;
Don’t forget to add a declaration for our SubmitQuad function in our gamestate header. We have also changed our SubmitPolygon function to take in a MeshEnum parameter so we can choose which mesh to render, so let’s make these changes:&lt;br /&gt;
&lt;br /&gt;
class GameState&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    &lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
    void SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
We also need to add our new source files to our Makefile under $(OBJS):&lt;br /&gt;
OBJS = game.o romdisk.o gamestate.o maple_events.o texture_manager.o mesh.o mesh_manager.o &lt;br /&gt;
&lt;br /&gt;
With these changes set, we can now tell our program to draw a texture anywhere in any size on the screen, just by referring to the TextureEnum. Let’s do so in our Gamestate class. In our Render function, let’s call our SubmitQuad function instead. Let’s use custom X,Y,W, and H settings:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Let’s run and see what happens! We can now draw textures to the screen in any position or shape we want! Let’s go crazy and do it multiple times!&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
            SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            SubmitQuad(background_png, 200, 300, 950, 950);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We now have a pretty good base tool which we can modify to start rendering text. These mesh and texture classes and their respective managers will pay off greatly down the line. Just remember that for each mesh and texture we create, we need to modify their Enum header files to indicate their creation and enable their usage.&lt;br /&gt;
&lt;br /&gt;
Let’s have our Texture_manager load our font texture. First, we need to create an entry in our TextureEnum.h:&lt;br /&gt;
&lt;br /&gt;
enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    TX_NULL&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Let’s create a function to compile our Texture context for us:&lt;br /&gt;
void CompileContext(char* Path, TextureEnum TxrID, Texture_t* TempTxr, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
{&lt;br /&gt;
TempTxr.Width = W;&lt;br /&gt;
    TempTxr.Height = H;&lt;br /&gt;
    TempTxr.TextureID = TxrID;&lt;br /&gt;
    TempTxr.m_Ptr = pvr_mem_malloc(W * H * 2);&lt;br /&gt;
    png_to_texture(Path, TempTxr.m_Ptr, PngMode);&lt;br /&gt;
    /* Set our Texture Type */&lt;br /&gt;
&lt;br /&gt;
     pvr_poly_cxt_txr(&amp;amp;TempTxr-&amp;gt;m_Context,        /* Dest Context to write to */&lt;br /&gt;
                       PVR_LIST_OP_POLY,        /* Polygon Bin Type */&lt;br /&gt;
                       PVR_TXRFMT_RGB565,       /* Texture Format */&lt;br /&gt;
                       W,                     /* Texture Width */&lt;br /&gt;
                       H,                     /* Texture Height */&lt;br /&gt;
                       TempTxr-&amp;gt;m_Ptr,                /* Texture Pointer */&lt;br /&gt;
                       Filtering);    /* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;TempTxr.m_Header, &amp;amp;TempTxr.m_Context);&lt;br /&gt;
    Textures[TxrID] = TempTxr;&lt;br /&gt;
}&lt;br /&gt;
This is the same code we used to compile our Texture Context before. We set the dest, set the polygon list to use, set the texture format, set width, height, a texture pointer, and a filter flag. &lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Texture_manager constructor create a font texture for us:&lt;br /&gt;
&lt;br /&gt;
texture_manager::texture_manager()&lt;br /&gt;
{&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3727</id>
		<title>Textures and Meshes</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Textures_and_Meshes&amp;diff=3727"/>
		<updated>2025-04-05T14:39:57Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Created page with &amp;quot;At this point, since we’re going to be using multiple textures from now on, it makes sense to make a texture manager class. This will hold and store our Textures for us, so we can easily look through them and delete them if necessary. Begin by making a new class in our folder, “texture_manager.cpp” and “texture_manager.h”. Don’t forget to add “texture_manager.o” to $(OBJS) in our Makefile.  Our Texture_Manager class will need to see KOS to get internal dr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At this point, since we’re going to be using multiple textures from now on, it makes sense to make a texture manager class. This will hold and store our Textures for us, so we can easily look through them and delete them if necessary. Begin by making a new class in our folder, “texture_manager.cpp” and “texture_manager.h”. Don’t forget to add “texture_manager.o” to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Our Texture_Manager class will need to see KOS to get internal dreamcast types, such as pvr_ptr. We will begin by adding our standard KOS headers, as well as our standard IO and int headers. We will be dealing with png files, so we need to include png/png.h. We will also need to access maps for our texture container, and since we will be dealing with c-strings, we should include cstring. Our Texture_manager.h should look like this:&lt;br /&gt;
#ifndef TEXTURE_MANAGER_H&lt;br /&gt;
#define TEXTURE_MANAGER_H&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;lt;cstring&amp;gt;&lt;br /&gt;
class texture_manager&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    texture_manager();&lt;br /&gt;
};&lt;br /&gt;
#endif // TEXTURE_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Internally, our class will need a map that pairs our texture ptrs and polygon contexts and other data objects to an enum. We will create and maintain an enum type that can be used to identify Textures as we use them in our source code. We will also need to create a Texture type that bundles the parts of a texture needed to render it together. Let’s create a new blank text file called Texture.h, and let’s create our TextureEnum and fill it with our background texture, and our font texture that we’ll use:&lt;br /&gt;
#ifndef TEXTUREENUMS_H&lt;br /&gt;
#define TEXTUREENUMS_H&lt;br /&gt;
#include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
    enum TextureEnum {&lt;br /&gt;
        Background_png = 0,&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We want a global function that can provide the name of the Enum as a string when called. We’ll do this with a little trick. In C, if you want to use a function that is in another translation unit object, you can do so by telling that source that, when linked, there is an “external” function in another object by that name. We do this with the Extern keyname. We need that function declaration to actually exist as compiled code somewhere, too. We can accomplish both the forward declaration and the extern declaration at the same time. To do this, we create a “TextureEnums.cpp”  file. This file defines a macro variable named TEXTUREENUM_CPP at the beginning of the file, and then undefs it at the end. This lets anything included within these brackets know they’re in that file. We can include our header within these brackets:&lt;br /&gt;
&lt;br /&gt;
#define TEXTUREENUMS_CPP&lt;br /&gt;
#include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
#undef TEXTUREENUMS_CPP /* TEXTUREENUMS_CPP */&lt;br /&gt;
Because we defined TEXTUREENUMS_CPP, our header file can behave different depending on if it’s in TEXTUREENUMS_CPP or not:&lt;br /&gt;
&lt;br /&gt;
#ifdef TEXTUREENUMS_CPP&lt;br /&gt;
    const char* GetTextureString(TextureEnum In)&lt;br /&gt;
    {&lt;br /&gt;
        std::string TxEnum;&lt;br /&gt;
        switch(In)&lt;br /&gt;
        {&lt;br /&gt;
            case background_png : TxEnum = &amp;quot;background_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_png: TxEnum = &amp;quot;font_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
            case font_transparent_png : TxEnum = &amp;quot;font_transparent_png&amp;quot;;&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
    return TxEnum.c_str();&lt;br /&gt;
    }&lt;br /&gt;
#else&lt;br /&gt;
    extern const char* GetTextureString(TextureEnum In);&lt;br /&gt;
#endif&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
This will define the function in TextureEnums.cpp, but in every other file, it’ll instead forward declare the external function. This function lets us map a const c-string return to a TextureEnum. Whenever we add a new TextureEnum, we should modify this part of the code to update the strings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let’s create our Texture container. When we rendered our texture in Main.cpp, every Texture needed a pvr_ptr, which pointed to the texture in VRAM. Each also needed a pvr_poly_ctx_t, which holds their polygon context for the texture. We can also store our pvr_ply_hdr_t which is our context compiled into a PVR object. It would be wise to also store the width and height of the Texture. We will also store our TextureEnum as TextureID, so our Texture can be reflexive, meaning it can identify itself. Our Texture container should be the following:&lt;br /&gt;
#ifndef TEXTURE_H&lt;br /&gt;
#define TEXTURE_H&lt;br /&gt;
#include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    typedef struct _Texture_t&lt;br /&gt;
    {&lt;br /&gt;
        pvr_ptr m_Ptr;                  /* Pointer to VRAM */&lt;br /&gt;
        pvr_poly_ctx_t m_Context;       /* Texture Context settings */&lt;br /&gt;
        pvr_ply_hdr_t m_Header;         /* Texture PVR Header */&lt;br /&gt;
        uint32_t Width;                 /* Texture Width */&lt;br /&gt;
        uint32_t Height;                /* Texture Height */&lt;br /&gt;
        TextureEnum TextureID;&lt;br /&gt;
    } Texture_t;&lt;br /&gt;
#endif // TEXTUREENUMS_H&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, include this file in our Texture_Manager.h:&lt;br /&gt;
#ifndef TEXTURE_MANAGER_H&lt;br /&gt;
#define TEXTURE_MANAGER_H&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;lt;cstring&amp;gt;&lt;br /&gt;
#include &amp;quot;TextureEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now in our class, let’s use a map container to hold our Texture_t. A map container lets you pair a value, our Texture_t, with a key, in this case a TextureEnum value. This will be our internal storage, so we’ll make it private:&lt;br /&gt;
private:&lt;br /&gt;
    std::map&amp;lt;TextureEnum, Texture_t&amp;gt; Textures;&lt;br /&gt;
&lt;br /&gt;
Now, let’s create a function to get a texture_t pointer from our internal texture map:&lt;br /&gt;
public:&lt;br /&gt;
    texture_manager();&lt;br /&gt;
    Texture_t* GetTexture(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Let’s fill our these functions in our texture_manager.cpp. Our constructor will load our Textures into Map and assign them to our Enums:&lt;br /&gt;
texture_manager::texture_manager()&lt;br /&gt;
{&lt;br /&gt;
    Texture_t TempTxr;  /* This is a dummy Texture_t object we&lt;br /&gt;
                            reuse to build out our Texture map */&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, &amp;amp;TempTxr, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
    Textures[background_png] = TempTxr;&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, &amp;amp;TempTxr, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
    Textures[font_png] = TempTxr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our GetTexture Function returns a pointer to the Texture according to the TextureEnum passed to it:&lt;br /&gt;
&lt;br /&gt;
Texture_t *texture_manager::GetTexture(TextureEnum In)&lt;br /&gt;
{&lt;br /&gt;
    return &amp;amp;Textures[In];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We need to move our Render function to our GameState. In gamestate.h change the headers to:&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
and in the class, under public, add:&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    uint32_t Done;                /* Is the game finished running? */   &lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
&lt;br /&gt;
Under Private, we need to add our Texture manager object and a function to make our GameState submit polygons to the Dreamcast PVR. Make our Private section look like this:&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
&lt;br /&gt;
Our Gamestate now holds our Textures and can draw to the screen. It loads textures into it’s texture atlus at object creation. Lets build out the Render() function in gamestate.cpp:&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitPolygon(background_png);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This is our Draw function from Main.cpp transplanted over to the Gamestate class. It calls a new function called SubmitPolygon, which we’ll create next.&lt;br /&gt;
void GameState::SubmitPolygon(TextureEnum In)&lt;br /&gt;
{&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(In);&lt;br /&gt;
        pvr_vertex_t vert;&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
        vert.oargb = 0;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 0.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 0.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 0.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 0.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
        vert.x = 640.0f;&lt;br /&gt;
        vert.y = 480.0f;&lt;br /&gt;
        vert.z = 1.0f;&lt;br /&gt;
        vert.u = 1.0f;&lt;br /&gt;
        vert.v = 1.0f;&lt;br /&gt;
        vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
        pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This is a function that submits vertices that fill the screen and have it draw a Texture specified by the input parameter. Our Gamestate object now can create and manage textures, as well as submit them to the PVR to draw. Let’s modify our Main.cpp to accommodate these changes. Firstly, we can remove the draw_back() and DrawFrame() functions from Main.cpp, as those are handled by our render() and submit_polygon() functions in gamestate. We can also remove “pvr_ptr_t back_tex” from the top of the file. We can remove the textures_init() function, as this is now handled by the gamestate.texture constructor.  &lt;br /&gt;
&lt;br /&gt;
This leaves our Main.cpp looking very bare-bones, which is what we want. Our Main.cpp should create an instance of our game object, then run it in a loop. This is our new Main.cpp:&lt;br /&gt;
#include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
#include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
#include &amp;quot;maple_events.h&amp;quot;&lt;br /&gt;
/*** C Library forward declarations ***/&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
extern &amp;quot;C&amp;quot; {&lt;br /&gt;
#endif&lt;br /&gt;
    #include &amp;lt;zlib/zlib.h&amp;gt;                  /* Z-Lib library, used to decompress gzip files */&lt;br /&gt;
    extern int zlib_getlength(char*);&lt;br /&gt;
#ifdef __cplusplus&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Game.Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Our game now handles inputs and can quit by pressing start. Run it and we should see our texture drawn to the screen. We now have our Texture rendering system in place, but our rendering code still manually hardcodes our vertex and their positiions. Just as we broke our textures out into a texture type and manager, so should we break out our vertex mesh shapes. Let’s start doing that by creating a mesh manager class, in the same style as our texture manager class. Create two blank text files called mesh_manager.cpp and mesh_manager.h. Inside mesh_manager.h, put the following:&lt;br /&gt;
&lt;br /&gt;
#ifndef MESH_MANAGER_H&lt;br /&gt;
#define MESH_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;lt;cstring&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class mesh_manager&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    mesh_manager();&lt;br /&gt;
&lt;br /&gt;
};&lt;br /&gt;
#endif // MESH_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
That is our standard class declaration. Now, just as we needed to create a texture_t type to hold all the information we need about a texture object for our texture manager, so will we create a pool of vertices that make up a mesh for our mesh manager to take care of. Let’s start by creating a mesh class. Create a blank text file for mesh.cpp and mesh.h. Inside of mesh.h:&lt;br /&gt;
&lt;br /&gt;
#ifndef MESH_H&lt;br /&gt;
#define MESH_H&lt;br /&gt;
#include &amp;quot;Texture.h&amp;quot;&lt;br /&gt;
#include &amp;quot;cstring&amp;quot;&lt;br /&gt;
#include &amp;quot;stdio.h&amp;quot;&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
class Mesh&lt;br /&gt;
{&lt;br /&gt;
    public:&lt;br /&gt;
        Mesh();&lt;br /&gt;
    private:&lt;br /&gt;
        pvr_vertex_t* VertexArray;         /* pointer to our vertex pool that makes up this mesh */&lt;br /&gt;
};&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We are going to need to know our texture enums to map to our mesh so we need Texture.h. We also will need our standard IO and integer types.&lt;br /&gt;
&lt;br /&gt;
We have a public constructor and a private pvr_vertex_t* pointer called verts. We will allocate a pool on the heap in our class, and this will be the head of the array of vertices. &lt;br /&gt;
&lt;br /&gt;
We are going to need to keep some other information about our Mesh. We want to know how many vertices are in our verts array, and we want to know the size of our array that we’ve allocated, so we don’t write outside our boundry. We’ll need a MeshEnum variable so the Mesh will be reflexive of it’s own type. Let’s add all this under public, as other parts of our program might need to change those variables:&lt;br /&gt;
        uint32_t m_VtxCount;           /* number of vertices in this mesh */&lt;br /&gt;
        uint32_t m_Size;              /* Amount of Space allocated */&lt;br /&gt;
        MeshEnum e_MeshID;             /* My own Mesh type */&lt;br /&gt;
&lt;br /&gt;
We need some functions to allocate and get and set data in our vertex array. Let’s create a public Allocate function, along with public GetVertex and SetVertex:&lt;br /&gt;
&lt;br /&gt;
        pvr_vertex_t* GetVertex(uint32_t Idx);&lt;br /&gt;
        void SetVertex(pvr_vertex_t Input, uint32_t Idx);&lt;br /&gt;
        void AllocateVertexArray(uint32_t Count);&lt;br /&gt;
&lt;br /&gt;
SetVertex will change an already existing member of our Array. Let’s use another function, AddVertex, to actually add a new vertex to the array:&lt;br /&gt;
        void AddVertex(pvr_vertex_t Input)&lt;br /&gt;
&lt;br /&gt;
The way our Mesh will work is that we’ll allocate space for X number of vertices. A variable in our container will keep track of how many vertices have actually been written to the array. We’ll call this variable Vtx_Idx, and keep it in private:&lt;br /&gt;
        uint32_t Vtx_Idx;&lt;br /&gt;
When our Mesh object is created, this Vtx_Idx will be set to 0. Every time AddVertex is called, this Vtx_Idx is increased. The value of Vtx_Idx is used to set and write the new vertex in the vertex array. That is where the name is derived from, “Vertex Index” which is the index we are writing at in the vertex array. This value also doubles as the number of vertices in the array. We will only allow a new vertex to be added to our mesh if Vtx_Idx is less than Size, which is how much we have allocated.&lt;br /&gt;
&lt;br /&gt;
Let’s start by filling our our constructor in Mesh.cpp:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
Mesh_t::Mesh_t()&lt;br /&gt;
{&lt;br /&gt;
        ptr_VertexArray = NULL;&lt;br /&gt;
        m_VtxCount = 0;&lt;br /&gt;
        Vtx_Idx = 0;&lt;br /&gt;
        e_MeshID = MESH_NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We set our verts pointer to NULL, and then set our idx and num_vtx counters to 0. We set our Texture enum to TX_NULL, our special enum value for no-texture.&lt;br /&gt;
&lt;br /&gt;
Let’s next set up our getter, setter, and adder:&lt;br /&gt;
&lt;br /&gt;
        pvr_vertex_t* Mesh::GetVertex(uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if( m_VtxCount &amp;gt; 0)&lt;br /&gt;
            {&lt;br /&gt;
                if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
                {&lt;br /&gt;
                    return verts[Idx];&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return NULL;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        void Mesh::SetVertex(pvr_vertex_t Input, uint32_t Idx)&lt;br /&gt;
        {&lt;br /&gt;
            if(Idx &amp;lt; m_VtxCount)&lt;br /&gt;
            {&lt;br /&gt;
                verts[Idx] = Input;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        void Mesh::AddVertex(pvr_vertex_t Input)&lt;br /&gt;
        {&lt;br /&gt;
            verts[Vtx_Idx] = Input;&lt;br /&gt;
            Vtx_Idx++;    &lt;br /&gt;
	     m_VtxCount = Vtx_Idx;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
Our Getter has a guard check to make sure we have a vertex added to the array, and that the asked index is less than the number of submitted vertices. The Setter has the same guard. The Add Vertex function adds to the map, the convention is to use the numeric variable Vtx_Idx as the input for the key via the brackets. You set the value with the equal sign. This creates a key-value pair in the map container. We then increase the Vtx_Idx counter, so it points to the next empty space in the Vertex array. m_VtxCount is set to reflect Vtx_Idx, because m_VtxCount is public-facing.&lt;br /&gt;
&lt;br /&gt;
Now let’s write a function to allocate our Vertex array:&lt;br /&gt;
&lt;br /&gt;
void Mesh::AllocateVertexArray(uint32_t Count)&lt;br /&gt;
{&lt;br /&gt;
    VertexArray = (pvr_vertex_t*)malloc(Count * sizeof(pvr_vertex_t))&lt;br /&gt;
    m_Size = Count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This calls malloc, the function in c and c++ that reserves space. It takes in a number representing the number of bytes to reserve. We take in a number called count as a function parameter, and use that number times the dize of the pvr_vertex_t type, to figure out how many bytes we need to store our data. This allocated memory is pointed to using our VertexArray pointer. Our mesh m_Size member is set to Count, the number of pvr_vertex_t elements we have allocated space for.&lt;br /&gt;
&lt;br /&gt;
With this, we have our Mesh object. A mesh is any array of Vertices we want to group together under one texture to render. When we rendered our texture to the screen before, the full screen image, we used 4 vertices in a strip of 2 polygon triangles to draw it. Those 4 vertices are our mesh, we could call that a Quad Mesh. In fact, let’s do just that. We’ll keep an enum of our Meshes, just like we do with our Textures. Let’s create a blank header file called MeshEnums.h and add the following:&lt;br /&gt;
&lt;br /&gt;
#ifndef MESHENUMS_H&lt;br /&gt;
#define MESHENUMS_H&lt;br /&gt;
enum MeshEnum {&lt;br /&gt;
    e_Quad = 0,&lt;br /&gt;
    MESH_NULL&lt;br /&gt;
};&lt;br /&gt;
#endif // MESHENUMS_H&lt;br /&gt;
&lt;br /&gt;
This sets us up with an enum type, MeshEnum, which we can use to distinguish between mesh objects we define. We already have a type called Quad in our list, let’s build it out. We will create it in our Mesh_Manager then have it ready for when we need to call it. Let’s add our MeshEnums.h file to our Mesh_Manager.h header file:&lt;br /&gt;
#ifndef MESH_MANAGER_H&lt;br /&gt;
#define MESH_MANAGER_H&lt;br /&gt;
#include &amp;quot;kos.h&amp;quot;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
#include &amp;lt;map&amp;gt;&lt;br /&gt;
#include &amp;quot;mesh.h&amp;quot;&lt;br /&gt;
#include &amp;quot;MeshEnums.h&amp;quot;&lt;br /&gt;
class mesh_manager&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    mesh_manager();&lt;br /&gt;
private:&lt;br /&gt;
    std::map&amp;lt;MeshEnum, Mesh_t&amp;gt; Meshes;&lt;br /&gt;
};&lt;br /&gt;
#endif // MESH_MANAGER_H&lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Mesh_Manager constructor make our quad mesh for us, as a default one when our program begins. That way we can always have it on hand to easily render textures to the screen. Let’s allocate some vertex space and create our mesh object in the constructor in mesh_manager.cpp:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
mesh_manager::mesh_manager()&lt;br /&gt;
{&lt;br /&gt;
    Mesh_t T_Mesh;                   /* A temporary Mesh_t object we will fill out to add to our mesh vector */&lt;br /&gt;
    pvr_vertex_t T_Vertex;      /* A temporary vertex object, we will fill out to add to our T Mesh&#039;s vertex array */&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.AllocateVertexArray(4);   /* We can hold 4 vertices in this mesh */&lt;br /&gt;
    T_Vertex.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    T_Vertex.oargb = 0;&lt;br /&gt;
    T_Vertex.flags = PVR_CMD_VERTEX;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We begin by creating a temporary T_Mesh object of Mesh_t type. This is the object we will interact with and configure, which will be submitted to the Mesh vector in our manager. We next create a temporary T_Vertex object, of pvr_vertex_t type. This is the vertex object that we will configure, which will be uploaded to the T_Mesh vertex array.&lt;br /&gt;
&lt;br /&gt;
We begin by allocating 4 vertices in T_Mesh. Next, we configure our argb and oargb values in our T_Vertex, and set a flag indicating this is a PVR_CMD_VERTEX. That means this is just one in a strip of vertices, not the end of the strip.&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
&lt;br /&gt;
Our next step is to set the XYZ position and the UV coordinates of the vertex. This is the upper left corner of the quad. We use 1.0 as the constant Z value. After we set the vertex position and uv coordinates, we push it onto our T_Mesh Vertex Array. We can then do the same for the other 3 vertices:&lt;br /&gt;
&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 0.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 0.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 0.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 0.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    T_Vertex.x = 1.0f;&lt;br /&gt;
    T_Vertex.y = 1.0f;&lt;br /&gt;
    T_Vertex.z = 1.0f;&lt;br /&gt;
    T_Vertex.u = 1.0f;&lt;br /&gt;
    T_Vertex.v = 1.0f;&lt;br /&gt;
    T_Vertex.T_Mesh.AddVertex = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    T_Mesh.AddVertex(T_Vertex);&lt;br /&gt;
    &lt;br /&gt;
    T_Mesh.e_MeshID = e_Quad;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A few things to note here. In our previous example where we drew the background texture to the screen, our vertex positions spanned from 0 to 640 in the X range, and 0 to 480 in the Y range. Yet in this mesh, our vertex spans from 0 to 1 in both ranges. This is because this will be a generic mesh. We will create a transformation matrix that will allow us to resize the mesh on the fly when we need it, that way we can reuse this mesh to draw any quad shape we want to the screen.&lt;br /&gt;
&lt;br /&gt;
The second thing to note is that in the final vertex, we change the flag to PVR_CMD_VERTEX_EOL. This is a command to tell the PVR that this vertex is the tail end of the vertex chain, meaning this group of 4 Vertices are grouped as one Vertex Strip.&lt;br /&gt;
&lt;br /&gt;
Finally, we set the enum inside this Mesh object to e_Quad, so our object can self-identify. With all this done, we are ready to add this to our Mesh_Manager object:&lt;br /&gt;
&lt;br /&gt;
    Meshes[e_Quad] = T_Mesh;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This creates a hash item in our Meshes Map for e_Quad, which contains a copy of our T_Mesh object. We now have a Mesh in our Mesh_Manager object that we can easily call to draw quads with. Let’s put an instance of our Mesh_Manager in our Gamestate class. First, we need to add our header to gamestate.h:&lt;br /&gt;
#ifndef GAMESTATE_H&lt;br /&gt;
#define GAMESTATE_H&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;quot;texture_manager.h&amp;quot;&lt;br /&gt;
#include &amp;quot;mesh_manager.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Next, in gamestate.h, inside the class Gamestate {} declaration, add this under private:&lt;br /&gt;
&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    &lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
};&lt;br /&gt;
#endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Now let’s try using our mesh object from our mesh manager. In Gamestate.cpp, in the SubmitPolygon function, let’s have it call and use our Mesh_Manager:&lt;br /&gt;
&lt;br /&gt;
void GameState::SubmitPolygon(TextureEnum Tex_In, MeshEnum Mesh_In)&lt;br /&gt;
{&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[Mesh_In].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[Mesh_In].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = Vertex_ptr-&amp;gt;x;&lt;br /&gt;
            T_vertex.y = Vertex_ptr-&amp;gt;y;&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This is basically the same logic as before, only now the vertex is being submitted in a loop. We set the for-loop to repeat for as many vertices are in our mesh, as called by m_Meshes.Meshes[Mesh_In].m_VtxCount. A temporary vertex T_Vertex is then mapped to the current vertex in the Vertex Array for that mesh, and then T_Vertex is submitted to the dreamcast PVR to render. We can select which Mesh to render when using the function by using a Mesh_In enum, which is set as a second parameter for “Submit Polygon.” There is one problem, however: Our XY positions for the corners of our quad are 1 pixel big. We need to do math on them to make them resize the way we want it. Let’s clone our SubmitPolygon function, and make a “SubmitQuad” function:&lt;br /&gt;
&lt;br /&gt;
void GameState::SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In)&lt;br /&gt;
{&lt;br /&gt;
    /* Texture Mapping */&lt;br /&gt;
        Texture_t* Texture = m_Textures.GetTexture(Tex_In);&lt;br /&gt;
        pvr_prim(&amp;amp;Texture-&amp;gt;m_Header, sizeof(Texture-&amp;gt;m_Header));&lt;br /&gt;
        &lt;br /&gt;
    /* Vertex Submission */        &lt;br /&gt;
        pvr_vertex_t  T_vertex;&lt;br /&gt;
        pvr_vertex_t* Vertex_ptr;&lt;br /&gt;
        &lt;br /&gt;
        for(int i = 0; i &amp;lt; m_Meshes.Meshes[e_Quad].m_VtxCount; i++)&lt;br /&gt;
        {&lt;br /&gt;
            /* Get the vertex */&lt;br /&gt;
            Vertex_ptr = m_Meshes.Meshes[e_Quad].GetVertex(i);&lt;br /&gt;
        &lt;br /&gt;
            /* Map all the information */&lt;br /&gt;
            T_vertex.flags = Vertex_ptr-&amp;gt;flags;&lt;br /&gt;
            T_vertex.x = X_In + (Vertex_ptr-&amp;gt;x * W_In);&lt;br /&gt;
            T_vertex.y = Y_In + (Vertex_ptr-&amp;gt;y * H_In);&lt;br /&gt;
            T_vertex.z = Vertex_ptr-&amp;gt;z + RenderDepth;&lt;br /&gt;
            T_vertex.u = Vertex_ptr-&amp;gt;u;&lt;br /&gt;
            T_vertex.v = Vertex_ptr-&amp;gt;v;&lt;br /&gt;
            T_vertex.argb = Vertex_ptr-&amp;gt;argb;&lt;br /&gt;
            T_vertex.oargb = Vertex_ptr-&amp;gt;oargb;&lt;br /&gt;
        &lt;br /&gt;
            /* Submit data */&lt;br /&gt;
            pvr_prim(&amp;amp;T_vertex, sizeof(T_vertex));&lt;br /&gt;
        }&lt;br /&gt;
            RenderDepth += 0.01;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to the old SubmitPolygon function, but the x and y positions ot T_Vertex are altered before drawing. This function is only for drawing Quads, so we don’t need it to take in a MeshEnum parameter, we already know it’ll use the e_Quad value. Instead, we take in an X, Y, W, and H parameter. This is the position and dimensions of the Quad we are drawing.  When we submit our vertices, we do some math to change the value of T_Vertex before it’s submitted.&lt;br /&gt;
&lt;br /&gt;
We are using a new variable called RenderDepth and adding it to the Z position in the Vertex. This is because rendering two Quads in the same position causes Z-Fighting, so we need to offset every call to this Quad function by a small amount each time. Let’s create this variable in Gamestate.h:&lt;br /&gt;
&lt;br /&gt;
class GameState&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
    &lt;br /&gt;
    float Render_Depth;&lt;br /&gt;
&lt;br /&gt;
Every time we call the Render function in Gamestate, we need to reset our Render_Depth:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    static uint8_t Timer = 0;&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
        Timer++;&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            if(Timer &amp;amp; 1)&lt;br /&gt;
            {&lt;br /&gt;
                SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
                SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            }&lt;br /&gt;
            SubmitQuad(background_png, 200, 20, 150, 150);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
First, we add our X_In and Y_In positions to our X and Y vertex positions respectively. This lets us scroll the quad with those two values. The Vertex X and Y positions are also added the Width and Height values provided, but only when the Vertex X and Y are 1 and not 0. This is why we set our Vertex positions to 1 instead of 640 and 480 in our mesh constructor, so they can be used as toggles for these additional height and width calculations. &lt;br /&gt;
&lt;br /&gt;
Don’t forget to add a declaration for our SubmitQuad function in our gamestate header. We have also changed our SubmitPolygon function to take in a MeshEnum parameter so we can choose which mesh to render, so let’s make these changes:&lt;br /&gt;
&lt;br /&gt;
class GameState&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
    ~GameState();&lt;br /&gt;
    void HandleControllerEvents();&lt;br /&gt;
    void Render();&lt;br /&gt;
    void ClearEvents();&lt;br /&gt;
    uint32_t Done;                                              /* Is the game finished running? */&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
    const cont_state_t &amp;amp;GetPrevController() const;&lt;br /&gt;
    void SetPrevControllerButtons(uint32_t In);&lt;br /&gt;
private:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
    &lt;br /&gt;
    texture_manager m_Textures;&lt;br /&gt;
    void SubmitPolygon(TextureEnum In);&lt;br /&gt;
    void SubmitQuad(TextureEnum Tex_In, uint32_t X_In, uint32_t Y_In, uint32_t W_In, uint32_t H_In);&lt;br /&gt;
    mesh_manager m_Meshes;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
We also need to add our new source files to our Makefile under $(OBJS):&lt;br /&gt;
OBJS = game.o romdisk.o gamestate.o maple_events.o texture_manager.o mesh.o mesh_manager.o &lt;br /&gt;
&lt;br /&gt;
With these changes set, we can now tell our program to draw a texture anywhere in any size on the screen, just by referring to the TextureEnum. Let’s do so in our Gamestate class. In our Render function, let’s call our SubmitQuad function instead. Let’s use custom X,Y,W, and H settings:&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Let’s run and see what happens! We can now draw textures to the screen in any position or shape we want! Let’s go crazy and do it multiple times!&lt;br /&gt;
&lt;br /&gt;
void GameState::Render()&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    RenderDepth = 0;&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            SubmitQuad(background_png, 0, 0, 640, 480);&lt;br /&gt;
            SubmitQuad(background_png, 20, 20, 200, 140);&lt;br /&gt;
            SubmitQuad(background_png, 500, 98, 90, 90);&lt;br /&gt;
            SubmitQuad(background_png, 200, 300, 950, 950);&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
        pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We now have a pretty good base tool which we can modify to start rendering text. These mesh and texture classes and their respective managers will pay off greatly down the line. Just remember that for each mesh and texture we create, we need to modify their Enum header files to indicate their creation and enable their usage.&lt;br /&gt;
&lt;br /&gt;
Let’s have our Texture_manager load our font texture. First, we need to create an entry in our TextureEnum.h:&lt;br /&gt;
&lt;br /&gt;
enum TextureEnum {&lt;br /&gt;
    background_png = 0,&lt;br /&gt;
    font_png,   /* = 1 */&lt;br /&gt;
    TX_NULL&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Let’s create a function to compile our Texture context for us:&lt;br /&gt;
void CompileContext(char* Path, TextureEnum TxrID, Texture_t* TempTxr, uint32_t W, uint32_t H, uint32_t PngMode, uint32_t Filtering)&lt;br /&gt;
{&lt;br /&gt;
TempTxr.Width = W;&lt;br /&gt;
    TempTxr.Height = H;&lt;br /&gt;
    TempTxr.TextureID = TxrID;&lt;br /&gt;
    TempTxr.m_Ptr = pvr_mem_malloc(W * H * 2);&lt;br /&gt;
    png_to_texture(Path, TempTxr.m_Ptr, PngMode);&lt;br /&gt;
    /* Set our Texture Type */&lt;br /&gt;
&lt;br /&gt;
     pvr_poly_cxt_txr(&amp;amp;TempTxr-&amp;gt;m_Context,        /* Dest Context to write to */&lt;br /&gt;
                       PVR_LIST_OP_POLY,        /* Polygon Bin Type */&lt;br /&gt;
                       PVR_TXRFMT_RGB565,       /* Texture Format */&lt;br /&gt;
                       W,                     /* Texture Width */&lt;br /&gt;
                       H,                     /* Texture Height */&lt;br /&gt;
                       TempTxr-&amp;gt;m_Ptr,                /* Texture Pointer */&lt;br /&gt;
                       Filtering);    /* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;TempTxr.m_Header, &amp;amp;TempTxr.m_Context);&lt;br /&gt;
    Textures[TxrID] = TempTxr;&lt;br /&gt;
}&lt;br /&gt;
This is the same code we used to compile our Texture Context before. We set the dest, set the polygon list to use, set the texture format, set width, height, a texture pointer, and a filter flag. &lt;br /&gt;
&lt;br /&gt;
Now, let’s have our Texture_manager constructor create a font texture for us:&lt;br /&gt;
&lt;br /&gt;
texture_manager::texture_manager()&lt;br /&gt;
{&lt;br /&gt;
    /* Setup background.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/background.png&amp;quot;, background_png, background_png, 512, 512, PNG_NO_ALPHA, PVR_FILTER_BILINEAR);&lt;br /&gt;
    /* Setup font.png */&lt;br /&gt;
    CompileContext(&amp;quot;/rd/font.png&amp;quot;, font_png, font_png, 1024, 128, PNG_FULL_ALPHA, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3726</id>
		<title>Dreamcast Tutorial</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Dreamcast_Tutorial&amp;diff=3726"/>
		<updated>2025-04-05T14:39:53Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;While many resources exist to explain individual parts of developing games and applications for the Dreamcast, there are not many comprehensive tutorials that detail the entire process. The following tutorial has been created to more thoroughly explain Dreamcast development topics towards a goal of creating fully featured applications. It is meant to be a full tutorial for beginners, starting from bare text files. This is a table of contents for topics the tutorial covers, in order.&lt;br /&gt;
&lt;br /&gt;
=== First Steps ===&lt;br /&gt;
* [[Makefile]]&lt;br /&gt;
* [[Main.cpp]]&lt;br /&gt;
&lt;br /&gt;
=== First Texture ===&lt;br /&gt;
* [[Adding a Romdisk]]&lt;br /&gt;
* [[Drawing a Texture]]&lt;br /&gt;
* [[Textures and Meshes]]&lt;br /&gt;
* [[Event Handling]]&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3725</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3725"/>
		<updated>2025-04-05T14:37:43Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
 	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
 	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
 		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
 									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3724</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3724"/>
		<updated>2025-04-05T14:36:57Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
 	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
 		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
 									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3723</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3723"/>
		<updated>2025-04-05T14:36:49Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
 		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
 									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3722</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3722"/>
		<updated>2025-04-05T14:36:09Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3721</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3721"/>
		<updated>2025-04-05T14:35:29Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a &lt;br /&gt;
 variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
 	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
 	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3720</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3720"/>
		<updated>2025-04-05T14:34:24Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a &lt;br /&gt;
 variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
    	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator&lt;br /&gt;
	so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3719</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3719"/>
		<updated>2025-04-05T14:32:31Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a &lt;br /&gt;
 variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
 	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
 		Event_It != ControllerEvents.end(); &lt;br /&gt;
 		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
 		uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
 				       &lt;br /&gt;
 		/*Erasing an element advances the iterator&lt;br /&gt;
 		so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
 	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
 	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator&lt;br /&gt;
	so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3718</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3718"/>
		<updated>2025-04-05T14:30:20Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a &lt;br /&gt;
 variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
		Event_It != ControllerEvents.end(); &lt;br /&gt;
		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
		uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
		/*Erasing an element advances the iterator&lt;br /&gt;
		so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator&lt;br /&gt;
	so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3717</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3717"/>
		<updated>2025-04-05T14:29:25Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMESTATE_H&lt;br /&gt;
 #define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
 #endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
 #include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
&lt;br /&gt;
 /* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
 class GameState&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    GameState();&lt;br /&gt;
 uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
 GameState::GameState()&lt;br /&gt;
 {&lt;br /&gt;
    Done = 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
&lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp. Begin in MapleEvents.h:&lt;br /&gt;
&lt;br /&gt;
 #ifndef MapleEvents_H&lt;br /&gt;
 #define MapleEvents_H&lt;br /&gt;
 #include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
 #include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
 #include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
 #include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
 #include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
 #include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
 /* Classes */&lt;br /&gt;
 #include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 #endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
 class MapleEvents&lt;br /&gt;
 {&lt;br /&gt;
 public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
 #include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
 MapleEvents::MapleEvents()&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
&lt;br /&gt;
 MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
 MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
 MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
 MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
 MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
 MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a &lt;br /&gt;
 variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
&lt;br /&gt;
 #ifndef GAMECONTROLLER_H&lt;br /&gt;
 #define GAMECONTROLLER_H&lt;br /&gt;
 enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
 };&lt;br /&gt;
 enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
 };&lt;br /&gt;
 typedef struct _Event_ControllerAction&lt;br /&gt;
 {&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
 } Event_ControllerAction;&lt;br /&gt;
 #endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
 #include &amp;lt;vector&amp;gt;&lt;br /&gt;
 #include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
 void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
 {&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
 Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
 /* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
 else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
 void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
 {&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
 /* This is the function which handles input */&lt;br /&gt;
 void HandleControllerEvents(GameState* GState)&lt;br /&gt;
 {   &lt;br /&gt;
	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
		Event_It != ControllerEvents.end(); &lt;br /&gt;
		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
		uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
		/*Erasing an element advances the iterator&lt;br /&gt;
		so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
 Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
 int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
 /* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
 /* 	Erasing an element advances the iterator&lt;br /&gt;
	so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
 switch(Event_It-&amp;gt;Button)&lt;br /&gt;
 {&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
 }&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
 switch(Event_It-&amp;gt;State)&lt;br /&gt;
 {&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
 case Released:&lt;br /&gt;
 {&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
 break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
 void GameState::ClearEvents()&lt;br /&gt;
 {&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
 /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3716</id>
		<title>Event Handling</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Event_Handling&amp;diff=3716"/>
		<updated>2025-04-05T14:26:05Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Created page with &amp;quot;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.  We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Events allow us to send automated messages from one part of our program to other parts. With a simple program like we have now, that’s not so important, but in more complex programs this becomes very important. We’ll create an event handler for Gamepad Input in this section, which will let us start writing code to control our program while it’s running.&lt;br /&gt;
&lt;br /&gt;
We need a central object for parts of our program to talk with. Using global variables is a bad idea on the Sega Dreamcast, the elf executable format has a section for global variables which makes accessing and reading them slow. Instead, we’ll create one object in our Main() function, then pass it around. This object will contain all the info we need to know about the game, we’ll call it a Game State. Let’s create our Game State class. Begin by making a new blank text file named gamestate.cpp. Be sure to add gamestate.o to $(OBJS) in our Makefile.&lt;br /&gt;
&lt;br /&gt;
Create a second blank text file and name it gamestate.h. This is our Header file for the gamestate, we can include it in other files which will make those files able to use it’s functions and interact with the object its class defines. Let’s create our class definition right now in gamestate.h:&lt;br /&gt;
#ifndef GAMESTATE_H&lt;br /&gt;
#define GAMESTATE_H&lt;br /&gt;
	//Game State Class stuff&lt;br /&gt;
#endif // GAMESTATE_H&lt;br /&gt;
&lt;br /&gt;
Begin with this ifdef. This is a header guard, it will ensure that we don’t redefine our class definition multiple times. When we include our header in other source files, the #include directive essentially copies and pastes the file into our source. Without these guards, our class definition would be copied multiple times. These guards look for a lock symbol, called GAMESTATE_H. If it doesn’t exist, as it would when this code is encountered for the first time, it’ll run the rest of the header. It begins by immediately defining GAMESTATE_H. This way, the next time this code is run, the preprocessor will skip copying it, preventing our redefinition error. You can do the same thing with #pragma once in c++ files, but this is the old school way that also works in C.&lt;br /&gt;
We need some header files in our gamestate.h so we can use certain calls in our class:&lt;br /&gt;
#include &amp;quot;stdint.h&amp;quot;&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We need to access KOS, along with standard integer types. Now we can begin to define our class:&lt;br /&gt;
/* This structure holds all the data about our global game state&lt;br /&gt;
 * we create this object once, and other objects check and interact&lt;br /&gt;
 * with it. This lets them communicate with each other. */&lt;br /&gt;
class GameState&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    GameState();&lt;br /&gt;
uint32_t Done;          /* Is the game finished running? */&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Basic stuff, we have a private variable called Done, which represents the state of our program running. It is proper form to make the variable private, and use functions to access it, but for something this simple, it’s just as valid to keep the variable public.&lt;br /&gt;
&lt;br /&gt;
We need to define our constructor in gamestate.cpp:&lt;br /&gt;
GameState::GameState()&lt;br /&gt;
{&lt;br /&gt;
    Done = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This function is run the first time our object is created. It will automatically set Done to 0, so our program  begins by running. We will create a GameState Object in main and begin using it to control our program loop. In Main.cpp, add our gamestate.h to our includes:&lt;br /&gt;
/* Classes */&lt;br /&gt;
#include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Now, in our Main function, create the GameState Object and make Done the condition in our While...Loop.&lt;br /&gt;
&lt;br /&gt;
	GameState Game;&lt;br /&gt;
    /* keep drawing frames until start is pressed */&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        DrawFrame();&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
If we want to end our program, all we have to do is change Game.Done to 1 and our loop will stop. We can pass our GameState object by reference using pointers to other classes to keep up with this “global” variable, without the penalty of defining it in global space! &lt;br /&gt;
Now that we have a GameState to keep track of information, let’s build an Event Handler Class. Make a new text file called MapleEvents.cpp, and MapleEvents.h. Be sure to add MapleEvents.o to $(OBJS), and also add MapleEvents.h to our header section of Main.cpp.&lt;br /&gt;
Begin in MapleEvents.h:&lt;br /&gt;
#ifndef MapleEvents_H&lt;br /&gt;
#define MapleEvents_H&lt;br /&gt;
#include &amp;lt;arch/gdb.h&amp;gt;           /* gdb debugger */&lt;br /&gt;
#include &amp;lt;kos.h&amp;gt;                /* KalistiOS Dreamcast SDK */&lt;br /&gt;
#include &amp;lt;kos/dbglog.h&amp;gt;         /* debug log */&lt;br /&gt;
#include &amp;lt;arch/timer.h&amp;gt;         /* used for timing functions related to framerate */&lt;br /&gt;
#include &amp;lt;arch/irq.h&amp;gt;           /* Interrupt request functions */&lt;br /&gt;
#include &amp;lt;png/png.h&amp;gt;            /* Library to load png files */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              /* Standard Input-Output */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;             /* Standard Integer types (uint_t, etc) */&lt;br /&gt;
/* Classes */&lt;br /&gt;
#include &amp;quot;gamestate.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#endif // MapleEvents_H&lt;br /&gt;
&lt;br /&gt;
Here we use Include Guards, and include the normal variety of KOS and standard headers. We also include our GameState class, so we can use and manipulate it if we want. Let’s create our MapleEvents class:&lt;br /&gt;
class MapleEvents&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
    MapleEvents();  &lt;br /&gt;
    void PollEvent(GameState* GState);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Aside from our constructor, we also have a function called PollEvent, and it takes a pointer of GameState type. This means we can pass our GameState to it, and it can manipulate it. Define the functions in MapleEvents.cpp:&lt;br /&gt;
#include &amp;quot;MapleEvents.h&amp;quot;&lt;br /&gt;
MapleEvents::MapleEvents()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Create a dummy constructor. Now let’s start building our PollEvent function, this is the function which will talk to MAPLE on the dreamcast and get a controller state back:&lt;br /&gt;
void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
{&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    &lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our function includes a pair of preprocessor macros that KOS provides, called MAPLE_FOREACH_BEGIN and MAPLE_FOREACH_END. These iterate through all the controllers in MAPLE and returns their state in an object. This object is of cont_state_t type. The MAPLE_FOREACH_BEGIN macro takes paramters. The first is the Function code, which tells MAPLE what to operate on. MAPLE_FUNC_CONTROLLER has us working on Dreamcast controllers. Other options available are:&lt;br /&gt;
MAPLE_FUNC_KEYBOARD: Poll the Dreamcast Keyboard&lt;br /&gt;
MAPLE_FUNC_LIGHTGUN: Poll a lightgun controllers&lt;br /&gt;
MAPLE_FUNC_MOUSE: Poll a Dreamcast Mouse&lt;br /&gt;
MAPLE_FUNC_MEMCARD: Interact with the Dreamcast VMU&lt;br /&gt;
MAPLE_FUNC_PURUPURU: Interact with the Dreamcast Jump Pack&lt;br /&gt;
MAPLE_FUNC_LCD: Interact with the VMU screen on the Dreamcast Controller&lt;br /&gt;
Our MAPLE_FOREACH_BEGIN macro creates a variable cont_state_t st which holds the polled controller info. This info comes in the form of a uint32_t number, which is interpreted as a bitfield. A 0 indicates a button is not being pressed, and a 1 indicates a button is currently being pressed. These are raw states, in that moment. This information isn’t too useful. If we see a 1 for a button, does that mean the button was just pressed? Is it being held down? If we see a 0, does that mean it was just released? We need more information, which means we need the last state to compare to. Our GameState object is perfect for holding this information in. In our GameState class, add a variable to hold our Previous Controller state:&lt;br /&gt;
    cont_state_t PrevControllerState;&lt;br /&gt;
&lt;br /&gt;
Now, when we poll our controller, we can compare the results to the last frame. This means every loop, we need to update the PrevControllerState with that frame’s information. Let’s do this in our PollEvent function. For readability reasons, let’s cache our Buttons into variables:&lt;br /&gt;
void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
{&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    &lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We get our PrevControllerState buttons into PrevButtons, and we get st-&amp;gt;buttons (the current polled controller state) into CurrButtons. At the end of the function, just before MAPLE_FOREACH_END(), we set our PrevControllerState.buttons variable in our GameState, which is located by the GState pointer.&lt;br /&gt;
&lt;br /&gt;
We can now compare button states with two samples. This lets us tell if we have just pressed, just released, or are holding down a button. All of these actions are Events. We need to create an enum type that can keep track of these actions. When we want to raise an event, we will push these enum actions onto a vector to store them. Let’s begin by defining our action events. We will do so in a new text file called EventEnums.h. This isn’t a cpp file, so it doesn’t become compiled into a translation unit object, so no EventEnums.o in our $(OBJS). In EventEnums.h, we can start building our event enum:&lt;br /&gt;
#ifndef GAMECONTROLLER_H&lt;br /&gt;
#define GAMECONTROLLER_H&lt;br /&gt;
enum Event_ControllerButton {&lt;br /&gt;
    Up = 0,&lt;br /&gt;
    Down = 1,&lt;br /&gt;
    Left = 2,&lt;br /&gt;
    Right = 3,&lt;br /&gt;
    A = 4,&lt;br /&gt;
    B = 5,&lt;br /&gt;
    C = 6,&lt;br /&gt;
    X = 7,&lt;br /&gt;
    Y = 8,&lt;br /&gt;
    Z = 9,&lt;br /&gt;
    Start = 10&lt;br /&gt;
};&lt;br /&gt;
enum Event_ControllerState {&lt;br /&gt;
    None = 0,&lt;br /&gt;
    Pressed = 1,&lt;br /&gt;
    Hold = 2,&lt;br /&gt;
    Released = 3&lt;br /&gt;
};&lt;br /&gt;
typedef struct _Event_ControllerAction&lt;br /&gt;
{&lt;br /&gt;
    Event_ControllerButton Button;&lt;br /&gt;
    Event_ControllerState State;&lt;br /&gt;
} Event_ControllerAction;&lt;br /&gt;
#endif // GAMECONTROLLER_H&lt;br /&gt;
&lt;br /&gt;
The idea is to have two different kinds of enums, which get paired together into a structure that represents the event. On one hand of the structure, we’ll have the Event_ControllerButton enum. It has fields for every digital button, Up,down,left,right, ABCXYZ and Start.&lt;br /&gt;
On the other hand of the event structure, we have the Event_ControllerState enum. This describes how the button behaved during the event: Just pressed down, being held down, or was just released.&lt;br /&gt;
With this ControllerAction event defined, we can start using it. Add our header to MapleEvents.h:&lt;br /&gt;
#include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
We need a place to hold our Events as we throw them. Our GameState can hold our events so they can be passed around various parts of our program. In our GameState.h class, add the following header:&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
#include &amp;quot;EventEnums.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
vectors are dynamic arrays in C++. We can create a vector container for our Event_ControllerAction in our GameState, which will let us store events as we throw them. The vector array will grow and shrink as we add or delete Events from it. Add this to the public section of our GameState class:&lt;br /&gt;
    std::vector&amp;lt;Event_ControllerAction&amp;gt; ControllerEvents;&lt;br /&gt;
&lt;br /&gt;
Now, let’s code the function analyze our controller state and throw events. We’ll create a helper function called QueueEvent to accomplish this:&lt;br /&gt;
void MapleEvents::QueueEvent(GameState* GState, uint32_t CONT_IN, uint32_t CurrButtons, uint32_t PrevButtons, Event_ControllerButton Button)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState pointer, so we can access and read and write to the ControllerEvents vector. It takes a uint32_t mask called CONT_IN. We can compare this mask to our buttons state to check individual bits. KOS provides macros for the correct bitfield locations for all the dreamcast controller buttons. This function also takes the current button state in CurrButtons, and the previous button state in PrevButtons. Finally, we set a Event_ControllerButton variable, this is what we will set in our Event structure if we send an event.&lt;br /&gt;
Inside our function, we begin by creating a temporary Event_ControllerAction called T:&lt;br /&gt;
Event_ControllerAction T;&lt;br /&gt;
    T.State = None;&lt;br /&gt;
&lt;br /&gt;
We will use T as a blank Event to configure before adding it to our event vector. Next, we’ll check the status of the Current button. The button being checked is determined by CONT_IN. The state in T begins as “None,” which we use as a flag to see if no event related to the CONT_IN button needs to be thrown. Let’s first begin by assuming the button is pressed down:&lt;br /&gt;
/* The current button is down */&lt;br /&gt;
    if((CurrButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        /* Was it down a frame before? */&lt;br /&gt;
        if(PrevButtons &amp;amp; CONT_IN)&lt;br /&gt;
        {&lt;br /&gt;
            /* It was down last frame, so it&#039;s being held */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Hold;&lt;br /&gt;
        } else&lt;br /&gt;
        {&lt;br /&gt;
            /* It wasn&#039;t down a frame before, so it&#039;s just been pressed */&lt;br /&gt;
            T.Button = Button;&lt;br /&gt;
            T.State = Pressed;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The logic is that if the button is pressed down, we will check what it was doing right before. If the button was being pressed down the frame before, then the button is currently being held. We set the State in T to “hold” and record Button we sent in the parameters in T.Button.&lt;br /&gt;
Otherwise, the button was not being pressed down the frame prior, which means this button has just been pressed. We set out state in T to “Pressed” and record the Button in T as well.&lt;br /&gt;
&lt;br /&gt;
That covers both events that can happen when the button is currently being pressed, but an event can arise if the button is not being pressed. This would happen if the button had been pressed down the frame before. If this discrepancy occurs, then the button has just been released. We can continue with our If statement by appending else to account for the button not being pressed:&lt;br /&gt;
else if(!(CurrButtons &amp;amp; CONT_IN) &amp;amp;&amp;amp; (PrevButtons &amp;amp; CONT_IN))&lt;br /&gt;
    {&lt;br /&gt;
        T.Button = Button;&lt;br /&gt;
        T.State = Released;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
In this case, we set the state in T to “released” and record the button. Now that we have found an event to throw, we can add it from our vector:&lt;br /&gt;
    if(T.State != None)&lt;br /&gt;
        GState-&amp;gt;ControllerEvents.push_back(T);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This comes at the end of our function. It first checks if our T.State is anything other than “None.” It will be something else if we threw an event. If so, add it to our ControllerEvents vector in our GameState. Push_Back() is a function that adds an element to the vector array, at the tail end.&lt;br /&gt;
With our QueueEvent helper function defined, we can start using it in our PollEvent function to check for individual button presses. Add the following to our function:&lt;br /&gt;
void MapleEvents::PollEvent(GameState* GState)&lt;br /&gt;
{&lt;br /&gt;
    MAPLE_FOREACH_BEGIN(MAPLE_FUNC_CONTROLLER, cont_state_t, st)&lt;br /&gt;
    uint32_t PrevButtons = GState-&amp;gt;PrevControllerState.buttons;&lt;br /&gt;
    uint32_t CurrButtons = st-&amp;gt;buttons;&lt;br /&gt;
    QueueEvent(GState, CONT_START, CurrButtons, PrevButtons, Start);&lt;br /&gt;
    QueueEvent(GState, CONT_A, CurrButtons, PrevButtons, A);&lt;br /&gt;
    QueueEvent(GState, CONT_B, CurrButtons, PrevButtons, B);&lt;br /&gt;
    QueueEvent(GState, CONT_C, CurrButtons, PrevButtons, C);&lt;br /&gt;
    QueueEvent(GState, CONT_X, CurrButtons, PrevButtons, X);&lt;br /&gt;
    QueueEvent(GState, CONT_Y, CurrButtons, PrevButtons, Y);&lt;br /&gt;
    QueueEvent(GState, CONT_Z, CurrButtons, PrevButtons, Z);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_UP, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_DOWN, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_LEFT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    QueueEvent(GState, CONT_DPAD_RIGHT, CurrButtons, PrevButtons, Up);&lt;br /&gt;
    GState-&amp;gt;PrevControllerState.buttons = CurrButtons;&lt;br /&gt;
    MAPLE_FOREACH_END()&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We use QueueEvent to check for every button on our Controller. It throws the appropriate events if so. If we run this PollEvent function once per frame, it means all the subsequent functions in the frame can read controller events in our GameState. When some other part of our program uses an Event, it deletes it from the Queue. We call this “consuming” the event. Various parts of our program can have MapleEventss which go through the ControllerEvent vector and check if they have matching mappings for various controller events. By consuming the events, it means the topmost running Program functions take the controller input first. This style of event handler lets events naturally flow to parts of the program which can consumer them as needed. At the very end of our frame, we need to make sure to clear the ControllerEvent vector just in case no part of our program consumed the event.&lt;br /&gt;
&lt;br /&gt;
Let’s demonstrate this by adding an MapleEvents to Main.cpp. Create the following function:&lt;br /&gt;
/* This is the function which handles input */&lt;br /&gt;
void HandleControllerEvents(GameState* GState)&lt;br /&gt;
{   &lt;br /&gt;
	static uint8_t Erased = 0;&lt;br /&gt;
    	for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); &lt;br /&gt;
		Event_It != ControllerEvents.end(); &lt;br /&gt;
		/* not advancing iterator in for-loop */)&lt;br /&gt;
    	{&lt;br /&gt;
		uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
		/*Erasing an element advances the iterator&lt;br /&gt;
		so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        	if(!Erased)&lt;br /&gt;
	        {&lt;br /&gt;
             		++Event_It;&lt;br /&gt;
	        }    &lt;br /&gt;
     	} /* End ControllerEvents Iterator */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
This function takes a GameState object via pointer. We create an iterator of type vector&amp;lt;Event_ControllerAction&amp;gt; called Event_It. This sounds scary and complex, but it’s actually very simple. The type inside the &amp;lt;&amp;gt; of the Vector in the declaration tells the Iterator how to set itself up. This allows the iterator to correctly navigate the vector array. We can use this iterator like an index into the vector which moves along a path. Our Iterator begins at the beginning of the vector, then moves to the back of the vector. &lt;br /&gt;
&lt;br /&gt;
Inside this loop as the iterator moves, we use the erase() command to delete the event from the vector. We need to call erase in a way that advances the iterator correctly, or else we’ll delete the element the iterator is pointing to and it’ll get lost. We use a flag called Erased to manage this. When an element is erased, this flag is set to 1. If we get to the end of the loop and we haven’t erased an element (and thus advanced the iterator), then we’ll manually advance it. This keeps things in a way so that the next loop will point to the correct spot.&lt;br /&gt;
&lt;br /&gt;
Now, in between the start of this iterator loop, and the iterator deletion, we can add the checks for button events. Lets make it so when the start button is released, our program quits. We can do that like so:&lt;br /&gt;
Event_ControllerButton ButtonInput = It-&amp;gt;Button;&lt;br /&gt;
        Event_ControllerState StateInput = It-&amp;gt;State;&lt;br /&gt;
        switch(ButtonInput)&lt;br /&gt;
        {&lt;br /&gt;
            case Start:&lt;br /&gt;
            {&lt;br /&gt;
                switch(StateInput)&lt;br /&gt;
                {&lt;br /&gt;
                    break;&lt;br /&gt;
                    case Released:&lt;br /&gt;
                    {&lt;br /&gt;
                        GState-&amp;gt;Done = 1;&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }; /* End Switch(Button) */&lt;br /&gt;
&lt;br /&gt;
We begin by using some convenience objects for readability. ButtonInput is the Button the event is for. StateInput is the condition of the button event. We begin with a switch statement fort he ButtonInput. This lets us use cases to select by button. Inside the Case for the start button, we can use a switch statement for StateInput to check for the button condition. Under case Released: we set Gstate-&amp;gt;Done = 1. This will cause the program to quit when this loop is finished. We need to include a break; command to get out of our switch statements.&lt;br /&gt;
&lt;br /&gt;
We can continue adding cases for other buttons with their own cases for their conditions to further map events to this part of our program. By mapping Case Start: case Released, this particular MapleEvents consumes the Start button if pressed. Now when we press start while our program is running, it’ll properly quit and reboot our dreamcast to dc-load-ip.&lt;br /&gt;
&lt;br /&gt;
Main in Main.cpp should now look like this:&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv) {&lt;br /&gt;
    /* init systems  */&lt;br /&gt;
    gdb_init();&lt;br /&gt;
    pvr_init_defaults();&lt;br /&gt;
    GameState Game;&lt;br /&gt;
    MapleEvents Maple;&lt;br /&gt;
    /* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {    &lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleEvents();&lt;br /&gt;
        Render();&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We have a function in our gamestate to let it handle the input events that are thrown by Maple when it calls PollControllers. We will call that function HandleEvents(). Let’s fill that out:&lt;br /&gt;
/* We are going to be possibly changing the vector as we iterate through it.&lt;br /&gt;
     * This means we will call the vector.erase() function, which automatically&lt;br /&gt;
     * returns the address of the next element in the vector, so our iterator&lt;br /&gt;
     * is not lost. This creates a conflict if we advance the iterator in the&lt;br /&gt;
     * for-loop declaration, so to solve this, we must manually advance the iterator&lt;br /&gt;
     * in the loop itself, and only advance it if we haven&#039;t erased an element. */&lt;br /&gt;
    &lt;br /&gt;
    for( std::vector&amp;lt;Event_ControllerAction&amp;gt;::iterator Event_It = ControllerEvents.begin(); Event_It != ControllerEvents.end(); /* not advancing iterator in for-loop */)&lt;br /&gt;
    {&lt;br /&gt;
	uint32_t Erased = 0;  /* flag we use to track if we erased an element or not */&lt;br /&gt;
				       &lt;br /&gt;
/* 	Erasing an element advances the iterator&lt;br /&gt;
	so if we didn&#039;t erase, advance it manually */&lt;br /&gt;
        if(!Erased)&lt;br /&gt;
        {&lt;br /&gt;
             ++Event_It;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
We state by creating an iterator called Event_It. This will walk through our ControllerEvents vector. After creating the iterator, we create a for loop that walks through the vector. It is possible we will be changing this vector as we iterate through it, and this causes a problem. If we advance the iterator through the for-loop declaration, then when we remove an element using vector.erase(), we’ll accidentally advance the iterator twice. This is because vector.erase() automatically advances the iterator when called. What we need to do is track if we call Vector.erase() during an iteration of a loop, and if we did not, then we’ll manually advance the iterator.&lt;br /&gt;
&lt;br /&gt;
To do that, we created a flag called Erased, and set it to 0 (false). At the bottom of our for-loop iteration, we set a condition: If Erased has been set to false (not 1), then advance the iterator with Event_It++. This accounts for if we remove an element while iterating.&lt;br /&gt;
&lt;br /&gt;
Next, inside our for-loop, we can create a switch statement to examine the Button input of our Event. This will let us isolate each case by button, like so:&lt;br /&gt;
switch(Event_It-&amp;gt;Button)&lt;br /&gt;
{&lt;br /&gt;
      case Start:&lt;br /&gt;
      {&lt;br /&gt;
		//Logic for Start Button in here.	&lt;br /&gt;
	} beak;&lt;br /&gt;
}&lt;br /&gt;
This first case is for how we should handle events from the start button. Inside this event case, we can create another switch statement for the StateInput from our event. The StateInput tells us what action the Button Event is throwing. We can do so like this:&lt;br /&gt;
switch(Event_It-&amp;gt;State)&lt;br /&gt;
{&lt;br /&gt;
     case Released:&lt;br /&gt;
     {&lt;br /&gt;
         //Released Code&lt;br /&gt;
     } break;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
When the Start button is Released, the following action is performed. In this case, we are setting Done to 1 (true). This will cause our Loop to end in the main() function, which will progress the program to the end, where it will quit. This maps Start to ending the program. Once we perform an action, it is customary for our Event handler to consume the event from the queue. We do that by deleting the iterator. Luckily, C++ provides a way to do this. Container types that impliment iterator, like vector does, have a function that can delete an iterator instance. It returns the address of the next element, which we can use to advance our iterator, so it isn’t lost when our object is deleted. We can do that like so:&lt;br /&gt;
case Released:&lt;br /&gt;
{&lt;br /&gt;
    Done = 1;     /* Set program to end */&lt;br /&gt;
    Erased = 1;   /* Set flag so we don&#039;t advance iterator twice */&lt;br /&gt;
    Event_It = ControllerEvents.erase(Event_It);   /* delete element &lt;br /&gt;
									and advance iterator once */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
If we have no other controller functions we want to map, we can ignore the rest. However, it’s proper form in a switch statement to cover all possible states. We can fill out the remaining states in our switch functions gracefully. In our switch(Event_It→State) condition:&lt;br /&gt;
   case Pressed:&lt;br /&gt;
   case Hold:&lt;br /&gt;
   case None:&lt;br /&gt;
break;&lt;br /&gt;
&lt;br /&gt;
and in our switch(Event_It-&amp;gt;Button) condition:&lt;br /&gt;
   case Up:&lt;br /&gt;
   case Down:&lt;br /&gt;
   case Left:&lt;br /&gt;
   case Right:&lt;br /&gt;
   case A:&lt;br /&gt;
   case B:&lt;br /&gt;
   case C:&lt;br /&gt;
   case X:&lt;br /&gt;
   case Y:&lt;br /&gt;
   case Z:&lt;br /&gt;
break;&lt;br /&gt;
&lt;br /&gt;
The purpose of this system isn’t obvious yet because our program is a monolith, but when we have multiple components that have their own event handlers, it’ll be useful. It lets events trickle down, so you have have context-sensitive inputs. We’ll show how this works later on. For now, at the very end of our loop, we need to empty our ControllerEvents vector, so the new frame begins fresh. We do that with our ClearEvents() function:&lt;br /&gt;
void GameState::ClearEvents()&lt;br /&gt;
{&lt;br /&gt;
    ControllerEvents.erase(ControllerEvents.begin(), ControllerEvents.end());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
We call this function at the end of our loop in Main.cpp:&lt;br /&gt;
&lt;br /&gt;
/* Game Loop */&lt;br /&gt;
    while(!Game.Done)&lt;br /&gt;
    {&lt;br /&gt;
        /* Input */&lt;br /&gt;
        Maple.PollControllers(&amp;amp;Game);&lt;br /&gt;
        Game.HandleControllerEvents();&lt;br /&gt;
        /* Rendering */&lt;br /&gt;
        Game.Render();&lt;br /&gt;
        /* Clean up */&lt;br /&gt;
        Game.ClearEvents();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With our MapleEvents written, we can now start manipulating the program to show how various parts of the PVR work. Let’s begin by exploring how translucent textures work.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3715</id>
		<title>DCWiki:Software</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=DCWiki:Software&amp;diff=3715"/>
		<updated>2025-04-05T14:25:33Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Software ==&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Dreamcast Games and Software&lt;br /&gt;
! style=&amp;quot;width: 50%&amp;quot;|Development and Technical&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
* Officially [[Licensed games and software|licensed games and software]]&lt;br /&gt;
* [[Online Services]]&lt;br /&gt;
* Commercially sold, independently developed [[Indie games|indie games]]&lt;br /&gt;
* 3rd-party [[Unlicensed software|unlicensed software]]&lt;br /&gt;
* [[Freeware homebrew games|Homebrew games and ports]] (freeware)&lt;br /&gt;
* [[Emulators on Dreamcast|Emulating other systems]] on your Dreamcast&lt;br /&gt;
* [[Media players]]&lt;br /&gt;
* [[Hardware Tests]]&lt;br /&gt;
* [[Other Dreamcast software]] (utilities and other miscellanea)&lt;br /&gt;
* [[VMU games]]&lt;br /&gt;
* [[Old tools]]&lt;br /&gt;
| style=&amp;quot;padding: 5px;vertical-align:top&amp;quot;|&lt;br /&gt;
{|&lt;br /&gt;
* [[Development]]&lt;br /&gt;
** [[Getting Started with Dreamcast development|Get Started]]&lt;br /&gt;
** [[Programming language support]]&lt;br /&gt;
** [[Engine &amp;amp; Library]]&lt;br /&gt;
** [[Tools and Utilities]]&lt;br /&gt;
** [https://kos-docs.dreamcast.wiki/ KallistiOS documentation]&lt;br /&gt;
** [https://sh4-sim.dreamcast.wiki/ SH4 Pipeline Simulator]&lt;br /&gt;
* [[Dreamcast emulators]]&lt;br /&gt;
* [[VMU emulators]]&lt;br /&gt;
* [[Boot process]]&lt;br /&gt;
* [[Memory map]], [[VRAM]]&lt;br /&gt;
* [[IP.BIN]], [[MR image]], [[Scrambling]]&lt;br /&gt;
* [[BIOS]]&lt;br /&gt;
* [[Useful programming tips]]&lt;br /&gt;
* [[NetBSD/Dreamcast]]&lt;br /&gt;
* [[Dreamcast Tutorial]]&lt;br /&gt;
** [[Makefile]]&lt;br /&gt;
** [[Main.cpp]]&lt;br /&gt;
** [[Adding a Romdisk]]&lt;br /&gt;
** [[Drawing a Texture]]&lt;br /&gt;
** [[Event Handling]]&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3714</id>
		<title>Drawing a Texture</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3714"/>
		<updated>2025-04-05T14:24:50Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The dreamcast does not draw like a modern GPU, it doesn’t have a GPU at all. It has a PVR Core which uses deferred rendering. The way this works is that a small amount of memory inside the Dreamcast VRAM is set aside to hold vertex data. Instead of rasterizing each polygon as they are sent to the dreamcast and immediately drawing it to the destination, the Dreamcast instead caches all polygons upfront. Once all the vertecies for the polygons in the scene are collected, it renders the output in steps, one 32x32 pixel tiles at a time. This has a bunch of really cool added benefits, notably that you do not have to sort polygons for transparancies to work. Overdraw is also generally not a thing, since only the exact amount of pixels needed for the destination are drawn. Every single pixel drawn is depth tested against all polygons around it during rasterization. This means pixel perfect z-buffers!&lt;br /&gt;
&lt;br /&gt;
=== Types of Polygons ===&lt;br /&gt;
&lt;br /&gt;
There are 5 types of polygons that are rendered. They are the Opaque Polygons, the Opaque Modifier Polygons, the Translucent polygons, the Translucent modifier polygons, and punch-thru polygons. Opaque Polygons are fully visible, no holes in it. If it is texture mapped, then the texture cannot have an alpha channel in it, it must be only RGB. Translucent Polygons are what we would think of as true-color 32-bit in modern computing. It means colors are represented as ARGB, providing an alpha channel. When used on a texture mapped polygon, the individual alpha channels of pixels in the texture determine the visibility. Instead of per-polygon transparency, the dreamcast does per-pixel! Pixels can be transparent in a range depending on the bitdepth. An offshoot of Translucent Polygons are Punch-Thru polygons. Data-wise, these are basically the same as a translucent polygon, except any value in the alpha channel besides 0 is treated as 100% transparent. That means pixels are either entirely visible, or entirely transparent. It is said to “punch-through” because the transparent pixels look like holes punched through the polygon.&lt;br /&gt;
&lt;br /&gt;
We need to determine how much VRAM space to reserve to hold references to these polygons. Since the output is divided into 32x32 tiles during render, every tile needs space to hold polygon references that keep track of which polygons reside in that tile. Polygon references in a tile are stored in a linked list known as the Object List. Nodes in the linked list can hold a set number of polygon references, and can point to each other for an arbitrary number of polygon references to be stored. These nodes are known as Object Pointer Blocks. We can set the size of each OPB for each polygon type with a KOS structure called pvr_init_params:&lt;br /&gt;
&lt;br /&gt;
 static pvr_init_params_t pvr_params = {&lt;br /&gt;
    /* OPB (Object Pointer Block) node: */&lt;br /&gt;
    {&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Opaque Poly OPB: 32 word (128 byte) length */&lt;br /&gt;
        PVR_BINSIZE_0, /* Disable Opaque Modifier Poly OPB  */&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Translucent Poly OPB: 32 word (128 byte) length  */&lt;br /&gt;
        PVR_BINSIZE_0, /* Disable Translucent Modifier Poly OPB  */&lt;br /&gt;
        PVR_BINSIZE_0  /* Disable Punch-thru Poly OPB*/},&lt;br /&gt;
    /* Vertex buffer size 512K */&lt;br /&gt;
    512 * 1024,&lt;br /&gt;
    /* DMA Enable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* FSAA Enable: Off*/&lt;br /&gt;
    0,&lt;br /&gt;
    /* Translucent Autosort Disable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* OPB Overflow count: Preallocates this many extra OPBs (sets of tile bins), allowing the PVR to use the extra space when there&#039;s too much geometry in the first OPB. */&lt;br /&gt;
    0&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
The available sizes for allocation for each bin are as follows:&lt;br /&gt;
 PVR_BINSIZE_0: 0-length, which disables the list&lt;br /&gt;
 PVR_BINSIZE_8: 8-word (32-byte) length&lt;br /&gt;
 PVR_BINSIZE_16: 16-word (64-byte) length&lt;br /&gt;
 PVR_BINSIZE_32: 32-word (128-byte) length&lt;br /&gt;
&lt;br /&gt;
The number of references that can be stored is equal to the binsize. I.e. PVR_BINSIZE_8 can store 8 polygon references in this OPB node. In the above example, we’re allocating 128-bytes to the Opaque Polygon bin, and 128-bytes to the Translucent Polygon bin. With our VRAM memory allocated for our OPBs, it’s time to create some textures. Let’s define some pointers to vram memory in our source code as global variables:&lt;br /&gt;
 pvr_ptr_t tex_blue;&lt;br /&gt;
 pvr_ptr_t back_tex;&lt;br /&gt;
&lt;br /&gt;
These pointers will hold the address of our textures in vram, making them our system handles for those textures. Let’s create a function that will let us allocate some memory for these textures in vram, then fill them up:&lt;br /&gt;
 void textures_init(void) {&lt;br /&gt;
    tex_blue = pvr_mem_malloc(128 * 128 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/blue.png&amp;quot;, tex_blue, PNG_FULL_ALPHA);&lt;br /&gt;
    back_tex = pvr_mem_malloc(512 * 512 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/background.png&amp;quot;, back_tex, PNG_NO_ALPHA);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our function begins by calling pvr_mem_malloc(). This function takes a number which represents how many bytes to allocate. We want enough room to hold all the pixels in our textures. Our Blue Texture is 128x128 pixels big, and the Dreamcast uses 16-bit color internally, despite supporting 24-bit color. 16-bits is the same as 2-bytes, which is where the 2 comes from in the above formula. Thus we need 2-bytes for each pixel, and there are 128x128 pixels. We can add the math into the parameters so it’s more readable. Pvr_mem_malloc returns the vram address where it allocated the space, which we save in our tex_blue pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We do the same with back_tex. This time, our background.png image is 512x512 pixels big. We adjust the parameter to account, and store the pointer in the appropriate pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We use each pointer to direct our png_to_texture function where to deposite the pixels it loads. png_to_texture opens a png file and returns the raw pixel data in a dreamcast pixel format. It takes a char* string that is the filepath to the png, along with a pvr_ptr that points to an allocated area of VRAM, and a flag. The flag determines how the function treats the png, and how it orders the data. There are 3 enums that an be set as the flag:&lt;br /&gt;
&lt;br /&gt;
 PNG_FULL_ALPHA: The png loaded has an alpha channel. It will be turned into ARGB4444.&lt;br /&gt;
 PNG_NO_ALPHA: The png loaded has no alpha channel. It will be turned into RGB565. &lt;br /&gt;
 PNG_MASK_ALPHA: The png loaded has an alpha channel, but will be a punch-thru texture. It will be turned into ARGB1555.&lt;br /&gt;
&lt;br /&gt;
We will need to know the pixel format of the texture in a moment, so take note of which flag you have set. We used FULL_ALPHA for the blue texture, and NO_ALPHA for the background texture.&lt;br /&gt;
&lt;br /&gt;
We need a function to call that will actually Submit vertices to the Dreamcast and command it to draw. We’ll call that function DrawFrame(), although that’s a misnomer. It’s actually just submitting frame data, and the frame is drawn later. Regardless of semantics, let’s create such a function:&lt;br /&gt;
 void DrawFrame(void)&lt;br /&gt;
 {&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        // Rendering code in here&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Our DrawFrame function begins with pvr_wait_ready(). This is a function that gets the PVR ready to accept vertices. This means doing some internal house keeping, as well as generally waiting for vblank to start a new frame. That means calling pvr_wait_ready(); ends the previous frame in a loop and waits for a new one to begin. If you call this twice in a loop, then your loop will run at 30 FPS. If you call it 3 times, your loop will run at 20 FPS. And so forth.&lt;br /&gt;
&lt;br /&gt;
After the PVR is ready, we have a pair of calls, pvr_scene_begin() and pvr_scene_end. Everything that goes in between these calls encapsulates a full frame of the scene being drawn. In between these calls, we can further breakdown which polygon bin we are going to be working on:&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            // Vertex code here for Opaque polygons&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
This is a pair of calls, pvr_list_begin(int) and pvr_list_finish(). pvr_list_begin takes an enum that tells it which list to bind. When a list is bound, all pvr functions will be directed towards that one. pvr_list_finish closes the bin for the scene, once a bin is closed it cannot be reopened until the next frame. In this example, we are opening the bin for opaque polygons, meaning any vertex we submit will go to that bin.&lt;br /&gt;
&lt;br /&gt;
Inside our Opaque Polygon list functions, we can create vertices and submit them. We can also create a command to let the PVR know which texture we want to use when texture mapping the polygon. We need to first create some variables:&lt;br /&gt;
    pvr_poly_cxt_t cxt;&lt;br /&gt;
    pvr_poly_hdr_t hdr;&lt;br /&gt;
    pvr_vertex_t vert;&lt;br /&gt;
&lt;br /&gt;
First, we need to create a variable to hold our polygon context. A context is an instance of the polygon parameter data, encapsulated into an object. This context is where we set which texture to draw with for the next polygon, along with the parameters for the texture. Once we have our polygon context defined, we can compile it into a pvr polygon header. A PVR Polygon Header is an object that represents a command to the PVR to setup the next polygon. It is the same size as an vertex, and thus behaves like one. You submit the polygon header the same way you submit a vertex. In fact, you can store a bunch of vertices into an array, and insert polygon headers into the array, and submit all the polygon data at once, which we’ll get into later. For now, let’s concentrate on submitting one vertex (or header) at a time.&lt;br /&gt;
&lt;br /&gt;
Our actual vertices will be stored in a structure called pvr_vertex_t. The Dreamcast and KOS have a number of predefined vertex types, which have more or less attributes depending on rendering mode. The more features a vertex or render mode has, the more space it consumes. Vertices are either 32-bytes big, or 64-bytes big. A special case is a Sprite object, which is 4 vertices squished together into one 64-byte object, meaning you can define a sprite in one vertex instead of needing 4 vertices. The types of vertices available are:&lt;br /&gt;
pvr_vertex_t: the generic, default vertex.&lt;br /&gt;
We are going with the default type. When we submit vertices to the PVR, we will use this variable and fill out the fields inside of it as needed.&lt;br /&gt;
&lt;br /&gt;
Let’s begin by creating our Polygon context. We want to draw the background texture to the entire screen. We can do that like so:&lt;br /&gt;
    pvr_poly_cxt_txr(	&amp;amp;cxt, 			/* Destination Context */&lt;br /&gt;
				PVR_LIST_OP_POLY, 	/* Flags */&lt;br /&gt;
				PVR_TXRFMT_RGB565, 	/* Texture Format */&lt;br /&gt;
				512, 				/* Texture Width */&lt;br /&gt;
				512, 				/* Texture Height */&lt;br /&gt;
				back_tex, 			/* TextureID */&lt;br /&gt;
			PVR_FILTER_BILINEAR);		/* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;hdr, &amp;amp;cxt);&lt;br /&gt;
    pvr_prim(&amp;amp;hdr, sizeof(hdr));&lt;br /&gt;
&lt;br /&gt;
We need to create a polygon context for our background texture. We fill in the appropriate fields: this is going to the opaque polygon bin, the texture has no alpha channel so it’s RGB565, the width and height are 512x512, the pointer to the texture in memory is back_tex, and we will be using bilinear filtering. With this context object created, we compile it into our header. PVR_prim() is a function that takes a vertex or header file, and send its data over to the VRAM polygon bin. It takes a second parameter with a size to know how many bytes to send to VRAM. We send our header that tells our PVR that the next polygon renders with the back_tex using bilinear filtering as an opaque polygon.&lt;br /&gt;
&lt;br /&gt;
Now, let’s set some general parameters for our vertices:&lt;br /&gt;
    vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    vert.oargb = 0;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
&lt;br /&gt;
Our vertex contains a field for an argb definition, to give the vertex a diffuse color. We set it to pure white, 1.0 (100%) in RGBA. Our vertex also has an offset argb value, this is for specular highlights. We’ll leave it set to 0, unused. We set a command in the flag field: PVR_CMD_VERTEX. This tells the PVR to begin taking in vertices for a polygon strip. When a command is given telling the PVR that it’s the EOL for the strip, it’ll end the polygon and move onto a new one.&lt;br /&gt;
&lt;br /&gt;
With our general parameters set, lets begin making the actual position data in the vertices and uploading them to VRAM:&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
each one of these sections is a single vertex. We are manually changing the XYZ coordinates of the vertex, along with the UV coordinates, before sending it to the PVR. This vertex is at 0,0,1.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
The next vertex resides at 640,0,1. Our two vertices so far have drawn a 640-pixel straight line from the left side of the screen to the right side, at Y position 0, which is the very top.&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
Our next vertex is at 0,480,1. This has shot back to the left side of the screen, then all the way down to the bottom row of pixels, Y at 480. This has formed a triangle between our previous 3 vertices. However, we have not given the command that this the end of line for the triangle strip, so we can submit another vertex.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
This final vertex is at 640,480,1. It’s at the very bottom right corner of the screen. Given the previous 3 vertices, this forms a second triangle, with the area of both filling the entire 640x480 screen. We pack a command into the flag of this final vertex, “PVR_CMD_VERTEX_EOL.” This tells the PVR that this strip of 4 vertices is a single long polygon that is finished. In the end, we wound up defining a screen-filling square and filled it with our back_tex.&lt;br /&gt;
Place this call within our Main() loop and run the program, and we should get the background texture filling our screen:&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        //Counter++;&lt;br /&gt;
        EvHandler.PollEvent(&amp;amp;Game);&lt;br /&gt;
        HandleInput(&amp;amp;Game);&lt;br /&gt;
        DrawFrame();    }&lt;br /&gt;
&lt;br /&gt;
We have successfully loaded and displayed a texture. We will come back shortly and continue learning how to use the PVR. However, our program currently has no way of responding, every time we want to make a change we have to turn off the dreamcast and wait for it to boot back up. Let’s give ourselves the ability to communicate with our program using our gamepads.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3713</id>
		<title>Drawing a Texture</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Drawing_a_Texture&amp;diff=3713"/>
		<updated>2025-04-05T14:14:49Z</updated>

		<summary type="html">&lt;p&gt;Cooljerk: Created page with &amp;quot;DRAWING A TEXTURE First, we need to talk about how the dreamcast draws. The dreamcast does not draw like a modern GPU, it doesn’t have a GPU at all. It has a PVR Core which uses deferred rendering. The way this works is that a small amount of memory inside the Dreamcast VRAM is set aside to hold vertex data. Instead of rasterizing each polygon as they are sent to the dreamcast and immediately drawing it to the destination, the Dreamcast instead caches all polygons upfr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DRAWING A TEXTURE&lt;br /&gt;
First, we need to talk about how the dreamcast draws. The dreamcast does not draw like a modern GPU, it doesn’t have a GPU at all. It has a PVR Core which uses deferred rendering. The way this works is that a small amount of memory inside the Dreamcast VRAM is set aside to hold vertex data. Instead of rasterizing each polygon as they are sent to the dreamcast and immediately drawing it to the destination, the Dreamcast instead caches all polygons upfront into these memory bins, which are known as Object Polygon Buffers, or OPBs for short. One all the vertecies for the polygons in the scene are collected, you tell the dreamcast that the scene is done and it renders. This has a bunch of really cool added benefits, notably that you do not have to sort polygons for transparancies to work. Overdraw is also generally not a thing, since only the exact amount of pixels needed for the destination are drawn. Every single pixel drawn is depth tested against all polygons around it during rasterization. This means pixel perfect z-buffers!&lt;br /&gt;
&lt;br /&gt;
There are 5 types of Object Polygon Buffers in VRAM, which determine attributes about the polygon rendered. They are the Opaque Polygon Bin, the Opaque Modifier Polygon Bin, the Translucent polygon bin, the Translucent modifier polygon bin, and the punch-thru polygon bin. The type of bin a vertex belongs to determines what kind of polygon it will be. Broadly, there are 3 types: Opaque, Translucent, and Punch-Thru. We’ll talk about modifier volumes later.&lt;br /&gt;
&lt;br /&gt;
Opaque Polygons are fully visible, no holes in it. If it is texture mapped, then the texture cannot have an alpha channel in it, it must be only RGB. &lt;br /&gt;
&lt;br /&gt;
Translucent Polygons are what we would think of as true-color 32-bit in modern computing. It means colors are represented as ARGB, providing an alpha channel. When used on a texture mapped polygon, the individual alpha channels of pixels in the texture determine the visibility. Instead of per-polygon transparency, the dreamcast does per-pixel! Pixels can be transparent in a range depending on the bitdepth. &lt;br /&gt;
&lt;br /&gt;
An offshoot of Translucent Polygons are Punch-Thru polygons. Data-wise, these are basically the same as a translucent polygon, except any value in the alpha channel besides 0 is treated as 100% transparent. That means pixels are either entirely visible, or entirely transparent. It is said to “punch-through” because the transparent pixels look like holes punched through the polygon.&lt;br /&gt;
&lt;br /&gt;
We need to determine how much VRAM space to give each one of these polygon bins. When we render our scene, we will send our vertices to one of these bins depending on how we want the resultant polygon to be drawn. We specify how much VRAM each bin gets in the pvr_init_params_t:&lt;br /&gt;
static pvr_init_params_t pvr_params = {&lt;br /&gt;
    /* OPB (Object Polygon Buffer) Bin allocation table: */&lt;br /&gt;
    {&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Opaque Poly Bin: 32 word (128 byte) length */&lt;br /&gt;
        PVR_BINSIZE_0, /* Enable Opaque Modifier Poly Bin: 32 word (128 byte) length  */&lt;br /&gt;
        PVR_BINSIZE_32, /* Enable Translucent Poly Bin: 32 word (128 byte) length  */&lt;br /&gt;
        PVR_BINSIZE_0, /* Enable Translucent Modifier Poly Bin: 32 word (128 byte) length  */&lt;br /&gt;
        PVR_BINSIZE_0  /* Enable Punch-thru Poly Bin: 32 word (128 byte) length  */},&lt;br /&gt;
    /* Vertex buffer size 512K */&lt;br /&gt;
    512 * 1024,&lt;br /&gt;
    /* DMA Enable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* FSAA Enable: Off*/&lt;br /&gt;
    0,&lt;br /&gt;
    /* Translucent Autosort Disable: Off */&lt;br /&gt;
    0,&lt;br /&gt;
    /* OPB Overflow count: Preallocates this many extra OPBs (sets of tile bins), allowing the PVR to use the extra space when there&#039;s too much geometry in the first OPB. */&lt;br /&gt;
    0&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
The available sizes for allocation for each bin are as follows:&lt;br /&gt;
PVR_BINSIZE_0: 0-length, which disables the list&lt;br /&gt;
PVR_BINSIZE_8: 8-word (32-byte) length&lt;br /&gt;
PVR_BINSIZE_16: 16-word (64-byte) length&lt;br /&gt;
PVR_BINSIZE_32: 32-word (128-byte) length&lt;br /&gt;
In the above example, we’re allocating 128-bytes to the Opaque Polygon bin, and 128-bytes to the Translucent Polygon bin. With our VRAM memory allocated for our OPBs, it’s time to create some textures. Let’s define some pointers to vram memory in our source code as global variables:&lt;br /&gt;
pvr_ptr_t tex_blue;&lt;br /&gt;
pvr_ptr_t back_tex;&lt;br /&gt;
&lt;br /&gt;
These pointers will hold the address of our textures in vram, making them our system handles for those textures. Let’s create a function that will let us allocate some memory for these textures in vram, then fill them up:&lt;br /&gt;
void textures_init(void) {&lt;br /&gt;
    tex_blue = pvr_mem_malloc(128 * 128 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/blue.png&amp;quot;, tex_blue, PNG_FULL_ALPHA);&lt;br /&gt;
    back_tex = pvr_mem_malloc(512 * 512 * 2);&lt;br /&gt;
    png_to_texture(&amp;quot;/rd/background.png&amp;quot;, back_tex, PNG_NO_ALPHA);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our function begins by calling pvr_mem_malloc(). This function takes a number which represents how many bytes to allocate. We want enough room to hold all the pixels in our textures. Our Blue Texture is 128x128 pixels big, and the Dreamcast uses 16-bit color internally, despite supporting 24-bit color. 16-bits is the same as 2-bytes, which is where the 2 comes from in the above formula. Thus we need 2-bytes for each pixel, and there are 128x128 pixels. We can add the math into the parameters so it’s more readable. Pvr_mem_malloc returns the vram address where it allocated the space, which we save in our tex_blue pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We do the same with back_tex. This time, our background.png image is 512x512 pixels big. We adjust the parameter to account, and store the pointer in the appropriate pvr_ptr.&lt;br /&gt;
&lt;br /&gt;
We use each pointer to direct our png_to_texture function where to deposite the pixels it loads. png_to_texture opens a png file and returns the raw pixel data in a dreamcast pixel format. It takes a char* string that is the filepath to the png, along with a pvr_ptr that points to an allocated area of VRAM, and a flag. The flag determines how the function treats the png, and how it orders the data. There are 3 enums that an be set as the flag:&lt;br /&gt;
PNG_FULL_ALPHA: The png loaded has an alpha channel. It will be turned into ARGB4444.&lt;br /&gt;
PNG_NO_ALPHA: The png loaded has no alpha channel. It will be turned into RGB565.&lt;br /&gt;
&lt;br /&gt;
PNG_MASK_ALPHA: The png loaded has an alpha channel, but will be a punch-thru texture. It will be turned into ARGB1555.&lt;br /&gt;
&lt;br /&gt;
We will need to know the pixel format of the texture in a moment, so take note of which flag you have set. We used FULL_ALPHA for the blue texture, and NO_ALPHA for the background texture.&lt;br /&gt;
&lt;br /&gt;
We need a function to call that will actually Submit vertices to the Dreamcast and command it to draw. We’ll call that function DrawFrame(), although that’s a misnomer. It’s actually just submitting frame data, and the frame is drawn later. Regardless of semantics, let’s create such a function:&lt;br /&gt;
void DrawFrame(void)&lt;br /&gt;
{&lt;br /&gt;
    pvr_wait_ready();&lt;br /&gt;
    pvr_scene_begin();&lt;br /&gt;
        // Rendering code in here&lt;br /&gt;
    pvr_scene_finish();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Our DrawFrame function begins with pvr_wait_ready(). This is a function that gets the PVR ready to accept vertices. This means doing some internal house keeping, as well as generally waiting for vblank to start a new frame. That means calling pvr_wait_ready(); ends the previous frame in a loop and waits for a new one to begin. If you call this twice in a loop, then your loop will run at 30 FPS. If you call it 3 times, your loop will run at 20 FPS. And so forth.&lt;br /&gt;
&lt;br /&gt;
After the PVR is ready, we have a pair of calls, pvr_scene_begin() and pvr_scene_end. Everything that goes in between these calls encapsulates a full frame of the scene being drawn. In between these calls, we can further breakdown which polygon bin we are going to be working on:&lt;br /&gt;
        pvr_list_begin(PVR_LIST_OP_POLY);&lt;br /&gt;
            // Vertex code here for Opaque polygons&lt;br /&gt;
        pvr_list_finish();&lt;br /&gt;
&lt;br /&gt;
This is a pair of calls, pvr_list_begin(int) and pvr_list_finish(). pvr_list_begin takes an enum that tells it which list to bind. When a list is bound, all pvr functions will be directed towards that one. pvr_list_finish closes the bin for the scene, once a bin is closed it cannot be reopened until the next frame. In this example, we are opening the bin for opaque polygons, meaning any vertex we submit will go to that bin.&lt;br /&gt;
&lt;br /&gt;
Inside our Opaque Polygon list functions, we can create vertices and submit them. We can also create a command to let the PVR know which texture we want to use when texture mapping the polygon. We need to first create some variables:&lt;br /&gt;
    pvr_poly_cxt_t cxt;&lt;br /&gt;
    pvr_poly_hdr_t hdr;&lt;br /&gt;
    pvr_vertex_t vert;&lt;br /&gt;
&lt;br /&gt;
First, we need to create a variable to hold our polygon context. A context is an instance of the polygon parameter data, encapsulated into an object. This context is where we set which texture to draw with for the next polygon, along with the parameters for the texture. Once we have our polygon context defined, we can compile it into a pvr polygon header. A PVR Polygon Header is an object that represents a command to the PVR to setup the next polygon. It is the same size as an vertex, and thus behaves like one. You submit the polygon header the same way you submit a vertex. In fact, you can store a bunch of vertices into an array, and insert polygon headers into the array, and submit all the polygon data at once, which we’ll get into later. For now, let’s concentrate on submitting one vertex (or header) at a time.&lt;br /&gt;
&lt;br /&gt;
Our actual vertices will be stored in a structure called pvr_vertex_t. The Dreamcast and KOS have a number of predefined vertex types, which have more or less attributes depending on rendering mode. The more features a vertex or render mode has, the more space it consumes. Vertices are either 32-bytes big, or 64-bytes big. A special case is a Sprite object, which is 4 vertices squished together into one 64-byte object, meaning you can define a sprite in one vertex instead of needing 4 vertices. The types of vertices available are:&lt;br /&gt;
pvr_vertex_t: the generic, default vertex.&lt;br /&gt;
We are going with the default type. When we submit vertices to the PVR, we will use this variable and fill out the fields inside of it as needed.&lt;br /&gt;
&lt;br /&gt;
Let’s begin by creating our Polygon context. We want to draw the background texture to the entire screen. We can do that like so:&lt;br /&gt;
    pvr_poly_cxt_txr(	&amp;amp;cxt, 			/* Destination Context */&lt;br /&gt;
				PVR_LIST_OP_POLY, 	/* Flags */&lt;br /&gt;
				PVR_TXRFMT_RGB565, 	/* Texture Format */&lt;br /&gt;
				512, 				/* Texture Width */&lt;br /&gt;
				512, 				/* Texture Height */&lt;br /&gt;
				back_tex, 			/* TextureID */&lt;br /&gt;
			PVR_FILTER_BILINEAR);		/* Filtering */&lt;br /&gt;
    pvr_poly_compile(&amp;amp;hdr, &amp;amp;cxt);&lt;br /&gt;
    pvr_prim(&amp;amp;hdr, sizeof(hdr));&lt;br /&gt;
&lt;br /&gt;
We need to create a polygon context for our background texture. We fill in the appropriate fields: this is going to the opaque polygon bin, the texture has no alpha channel so it’s RGB565, the width and height are 512x512, the pointer to the texture in memory is back_tex, and we will be using bilinear filtering. With this context object created, we compile it into our header. PVR_prim() is a function that takes a vertex or header file, and send its data over to the VRAM polygon bin. It takes a second parameter with a size to know how many bytes to send to VRAM. We send our header that tells our PVR that the next polygon renders with the back_tex using bilinear filtering as an opaque polygon.&lt;br /&gt;
&lt;br /&gt;
Now, let’s set some general parameters for our vertices:&lt;br /&gt;
    vert.argb = PVR_PACK_COLOR(1.0f, 1.0f, 1.0f, 1.0f);&lt;br /&gt;
    vert.oargb = 0;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX;&lt;br /&gt;
&lt;br /&gt;
Our vertex contains a field for an argb definition, to give the vertex a diffuse color. We set it to pure white, 1.0 (100%) in RGBA. Our vertex also has an offset argb value, this is for specular highlights. We’ll leave it set to 0, unused. We set a command in the flag field: PVR_CMD_VERTEX. This tells the PVR to begin taking in vertices for a polygon strip. When a command is given telling the PVR that it’s the EOL for the strip, it’ll end the polygon and move onto a new one.&lt;br /&gt;
&lt;br /&gt;
With our general parameters set, lets begin making the actual position data in the vertices and uploading them to VRAM:&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
each one of these sections is a single vertex. We are manually changing the XYZ coordinates of the vertex, along with the UV coordinates, before sending it to the PVR. This vertex is at 0,0,1.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 0.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 0.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
The next vertex resides at 640,0,1. Our two vertices so far have drawn a 640-pixel straight line from the left side of the screen to the right side, at Y position 0, which is the very top.&lt;br /&gt;
    vert.x = 0.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 0.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
Our next vertex is at 0,480,1. This has shot back to the left side of the screen, then all the way down to the bottom row of pixels, Y at 480. This has formed a triangle between our previous 3 vertices. However, we have not given the command that this the end of line for the triangle strip, so we can submit another vertex.&lt;br /&gt;
    vert.x = 640.0f;&lt;br /&gt;
    vert.y = 480.0f;&lt;br /&gt;
    vert.z = 1.0f;&lt;br /&gt;
    vert.u = 1.0f;&lt;br /&gt;
    vert.v = 1.0f;&lt;br /&gt;
    vert.flags = PVR_CMD_VERTEX_EOL;&lt;br /&gt;
    pvr_prim(&amp;amp;vert, sizeof(vert));&lt;br /&gt;
&lt;br /&gt;
This final vertex is at 640,480,1. It’s at the very bottom right corner of the screen. Given the previous 3 vertices, this forms a second triangle, with the area of both filling the entire 640x480 screen. We pack a command into the flag of this final vertex, “PVR_CMD_VERTEX_EOL.” This tells the PVR that this strip of 4 vertices is a single long polygon that is finished. In the end, we wound up defining a screen-filling square and filled it with our back_tex.&lt;br /&gt;
Place this call within our Main() loop and run the program, and we should get the background texture filling our screen:&lt;br /&gt;
    while(Game.Done == 0)&lt;br /&gt;
    {&lt;br /&gt;
        //Counter++;&lt;br /&gt;
        EvHandler.PollEvent(&amp;amp;Game);&lt;br /&gt;
        HandleInput(&amp;amp;Game);&lt;br /&gt;
        DrawFrame();    }&lt;br /&gt;
&lt;br /&gt;
We have successfully loaded and displayed a texture. We will come back shortly and continue learning how to use the PVR. However, our program currently has no way of responding, every time we want to make a change we have to turn off the dreamcast and wait for it to boot back up. Let’s give ourselves the ability to communicate with our program using our gamepads.&lt;/div&gt;</summary>
		<author><name>Cooljerk</name></author>
	</entry>
</feed>