Thursday, June 1, 2023

Sega Console Game Port

In 2017, we checked out devkitSMS Programming Setup to build code in C for the 8-bit Sega Master System. Then, in 2020, we checked out SGDK Programming Setup to build code in C for the 16-bit Sega Mega Drive.

Leveraging this knowledge, we would now like to port existing code built for the 8-bit Sega Master System, for example, Simpsons Trivia SMS to the 16-bit Mega Drive Simpsons Trivia MD and document the process.
 SEGA MASTER SYSTEM [256 x 192]  SEGA MEGA DRIVE [320 x 224]
Let's check it out!

Software
Follow most instructions from the previous post: this documents how to setup some pre-requisite software.

Here is a summary of some of the software to be installed:
 Name Version
 C IDE Editor Visual Studio 2015
 Emulators Fusion, Gens KMod
 
 Name Version
 Cross compiler GCC
 Make files Cygwin


Setup Project
Create folder C:\SimpsonsTriviaMD. Copy new SGDK custom library lib folder here. Create sub-folder: dev. Change directory to dev folder and create the following sub-folders as indicated per Usage: inc, out, res, src


Launch Visual Studio 2015. File | New | Project... | Visual C++ | Win32 | Win32 Project

 Name:  Game
 Location:  C:\SimpsonsTriviaMD\dev
 Create directory for solution  UNCHECKED
OK

 Application type:  Console application
 Additional options:  Empty project CHECKED
Finish

First, remove x64 build configuration! Right click Solution | Properties. Click Configuration Manager button. Click Active solution platform drop down | Edit. Click x64 option | Remove. Now will have only Win32 build.

Right click Project | Properties | Configuration Properties | General. Set Output and Intermediate directories:

 Output Directory:  $(SolutionDir)..\bin\$(ConfigurationName)
 Intermediate Directory:  $(SolutionDir)..\obj\$(ConfigurationName)

Right click Project | Properties | Configuration Properties | C++ | General. Set Additional Include Directories:

 Value:   $(SolutionDir)..\lib;$(ProjectDir)inc;$(ProjectDir)res;$(GDK_WIN)\inc;$(IncludePath)

Right click Project | Properties | Configuration Properties | Linker | General | Additional Library Directories:

 Value:   $(SolutionDir)..\lib

Right click Project | Properties | Configuration Properties | Linker | Input. Set the Additional Dependencies:

 Value:   _genesis.lib;%(AdditionalDependencies)

The final solution should look like this:


Setup Resources
Import all resources into your project as media files that your game will use such as images for background tiles + sprites, audio for music + sound effects etc. Clone the "Setup Project" folder and follow these steps:

Change directory to res folder under dev folder. Copy all resources here. Create corresponding *.res files. Next execute build.bat to compile all resources then generate all corresponding gfx and sfx header files.

Create folder gfx at same level as dev folder. Create sub folder res. Add dummy corresponding translation unit files under res sub folder. Repeat process with sfx folder. Import all translation units into Visual Studio.


Setup Folders
Larger game projects will require nested folders in the inc or src directories to organize engine and screen code etc. Clone the "Setup Resources" folder and add all necessary subfolders + then update the makefile.

Launch Visual Studio and include resource files as before. Next, scale out engine and screen code but now organize into subfolders. Create as New Filters under Visual Studio Header Files and Source Files solution:

Create corresponding engine and screen subfolders beneath inc folder under dev. Add header files. Create engine and screen subfolders beneath src folder under dev. Add all the corresponding translation unit code.

Right click Project | Properties | Configuration Properties | C++ | General. Set Additional Include Directories:

 Value:   $(SolutionDir)..\lib;$(ProjectDir)inc;$(ProjectDir)res;$(GDK_WIN)\inc;$(IncludePath);
 $(ProjectDir)inc\engine;$(ProjectDir)inc\object;$(ProjectDir)inc\screen

Customize the makefile.gen file to include the new subfolders accordingly. Copy %GDK_WIN%\makefile.gen to local dev folder. Update makefile: Add new $(wildcard $(SRC)/ and -I$(INCLUDE) entries per folder.

Update dev built.bat file to use new local custom makefile.gen instead of de-facto %GDK_WIN% version.
If you remove pre-build step to speed up makefile build then don't forget to create out subfolders manually.


Convert APIs
Finally, copy over all engine, object, screen etc. files from the Sega Master System code base into the Sega Mega Drive port. Convert all devkitSMS APIs to the SGDK equivalents. Allow for different screen resolution!

Here is quick cheat of devkitSMS to SGDK API conversions; of course not all APIs are one-to-one mapping:
   SEGA MASTER SYSTEM  SEGA MEGA DRIVE
 Audio  PSGPlay();
 PSGStop();
 PSGGetStatus();
 XGM_startPlayPCM();
 XGM_stopPlayPCM();
 XGM_isPlayingPCM();
 Dimensions  256 x 192 [32x24]
 320 x 224 [40x28]
 Font  SMS_setNextTileatXY();
 SMS_setTile();
 VDP_setMapEx();
 
 Graphics  SMS_loadPSGaidencompressedTiles();
 SMS_loadBGPalette();
 VDP_drawImageEx();
 VDP_setPalette();
 Hack  Address : 0x0050
 Address : 0x01E0
 Input  SMS_getKeysStatus();
 JOY_readJoypad();
 Random  rand();
 random();
 Sprites  SMS_addSprite();
 SMS_copySpritestoSAT();
 SPR_addSprite();
 SPR_update();


Summary
Repeat process with Skazka. In summary, the Master System to Mega Drive port should be fairly seemless J
 SEGA MASTER SYSTEM [256 x 192]  SEGA MEGA DRIVE [320 x 224]