Version 5.5b with improved overlay handling, numerous overlay graphical tweaks and better search-and-find for system BIOS roms.

This commit is contained in:
Dave Bernazzani 2024-10-02 07:23:06 -04:00
parent 0d92a5bdcd
commit 42c8e43e2d
6 changed files with 203 additions and 33 deletions

View File

@ -14,7 +14,7 @@ include $(DEVKITARM)/ds_rules
export TARGET := NINTV-DS export TARGET := NINTV-DS
export TOPDIR := $(CURDIR) export TOPDIR := $(CURDIR)
export VERSION := 5.5a export VERSION := 5.5b
ICON := -b $(CURDIR)/logo.bmp "NINTV-DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/NINTV-DS" ICON := -b $(CURDIR)/logo.bmp "NINTV-DS $(VERSION);wavemotion-dave;https://github.com/wavemotion-dave/NINTV-DS"

Binary file not shown.

View File

@ -8,7 +8,7 @@
// //
// The NINTV-DS emulator is offered as-is, without any warranty. // The NINTV-DS emulator is offered as-is, without any warranty.
// ===================================================================================== // =====================================================================================
#include <nds.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "CRC32.h" #include "CRC32.h"
@ -59,7 +59,7 @@ CRC32::CRC32() {
reset(); reset();
} }
UINT8 crcBuffer[256]; UINT8 crcBuffer[1024];
UINT32 CRC32::getCrc(const CHAR* filename) UINT32 CRC32::getCrc(const CHAR* filename)
{ {
CRC32 crc; CRC32 crc;
@ -71,7 +71,7 @@ UINT32 CRC32::getCrc(const CHAR* filename)
{ {
while (!feof(file)) while (!feof(file))
{ {
int read = fread(crcBuffer, sizeof(UINT8), 256, file); // Read up to 256 bytes into a buffer int read = fread(crcBuffer, sizeof(UINT8), 1024, file); // Read up to 1024 bytes into a buffer
crc.update(crcBuffer, (UINT32)read); // And compute the CRC of any bytes read crc.update(crcBuffer, (UINT32)read); // And compute the CRC of any bytes read
} }
fclose(file); fclose(file);
@ -97,7 +97,7 @@ void CRC32::update(UINT8 data) {
crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ data]; crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ data];
} }
void CRC32::update(UINT8* data, UINT32 length) { ITCM_CODE void CRC32::update(UINT8* data, UINT32 length) {
for (UINT32 i = 0; i < length; i++) for (UINT32 i = 0; i < length; i++)
crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ data[i]]; crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ data[i]];
} }

View File

@ -36,6 +36,7 @@ FICA_INTV intvromlist[512];
u16 countintv=0, ucFicAct=0; u16 countintv=0, ucFicAct=0;
char szName[256]; char szName[256];
char szName2[256]; char szName2[256];
extern char directory[];
UINT8 load_options = 0x00; UINT8 load_options = 0x00;
@ -184,7 +185,7 @@ void CheckFirstTimeLoad(void)
} }
} }
void SearchForFile(char *szFoundName, UINT16 size, UINT32 crc32) void SearchForFile(char *directory, char *szFoundName, UINT16 size, UINT32 crc32)
{ {
// Look through all files in the current directory to see if we get a CRC32 match... // Look through all files in the current directory to see if we get a CRC32 match...
DIR *pdir; DIR *pdir;
@ -192,7 +193,7 @@ void SearchForFile(char *szFoundName, UINT16 size, UINT32 crc32)
CheckFirstTimeLoad(); CheckFirstTimeLoad();
pdir = opendir("."); pdir = opendir(directory);
if (pdir) if (pdir)
{ {
@ -201,13 +202,15 @@ void SearchForFile(char *szFoundName, UINT16 size, UINT32 crc32)
if (pent->d_type != DT_DIR) if (pent->d_type != DT_DIR)
{ {
struct stat st; struct stat st;
stat(pent->d_name, &st); strcpy(szName2, directory);
strcat(szName2, pent->d_name);
stat(szName2, &st);
if (st.st_size == size) if (st.st_size == size)
{ {
if (CRC32::getCrc(pent->d_name) == crc32) if (CRC32::getCrc(szName2) == crc32)
{ {
// Found it!! // Found it!!
strcpy(szFoundName, pent->d_name); strcpy(szFoundName, szName2);
break; break;
} }
} }
@ -223,46 +226,50 @@ void SearchForFile(char *szFoundName, UINT16 size, UINT32 crc32)
// will only look at files that are exactly 8k in size. This will still take a solid // will only look at files that are exactly 8k in size. This will still take a solid
// second or two on the NDS - it's better if the user has the right filename to avoid this. // second or two on the NDS - it's better if the user has the right filename to avoid this.
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
void FindAndLoadExec(char *szFoundName) void FindAndLoadExec(char *directory, char *szFoundName)
{ {
SearchForFile(szFoundName, 8192, 0xcbce86f7); // Look for the normal exec.bin SearchForFile(directory, szFoundName, 8192, 0xcbce86f7); // Look for the normal exec.bin
} }
void FindAndLoadTutorExec(char *directory, char *szFoundName)
void FindAndLoadTutorExec(char *szFoundName)
{ {
SearchForFile(szFoundName, 16384, 0x7558a4cf); // Look for the Tutorvision wbexec.bin SearchForFile(directory, szFoundName, 16384, 0x7558a4cf); // Look for the Tutorvision wbexec.bin
} }
void FindAndLoadGrom(char *szFoundName) void FindAndLoadGrom(char *directory, char *szFoundName)
{ {
SearchForFile(szFoundName, 2048, 0x683a4158); // Look for the normal grom.bin SearchForFile(directory, szFoundName, 2048, 0x683a4158); // Look for the normal grom.bin
} }
void FindAndLoadTutorGrom(char *szFoundName) void FindAndLoadTutorGrom(char *directory, char *szFoundName)
{ {
SearchForFile(szFoundName, 2048, 0x82736456); // Look for the Tutorvision wbgrom.bin SearchForFile(directory, szFoundName, 2048, 0x82736456); // Look for the Tutorvision wbgrom.bin
} }
void FindAndLoadIVoice(char *szFoundName) void FindAndLoadIVoice(char *directory, char *szFoundName)
{ {
SearchForFile(szFoundName, 2048, 0x0de7579d); // Look for the Intellivioice ivoice.bin SearchForFile(directory, szFoundName, 2048, 0x0de7579d); // Look for the Intellivioice ivoice.bin
}
void FindAndLoadECS(char *directory, char *szFoundName)
{
SearchForFile(directory, szFoundName, (24*1024), 0xea790a06); // Look for the ecs.bin
} }
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// Peripheral roms are basically our BIOS files... grom.bin, exec.bin and ivoice.bin // Peripheral roms are basically our BIOS files... grom.bin, exec.bin and ivoice.bin
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
CHAR nextFile[MAX_PATH];
BOOL LoadPeripheralRoms(Peripheral* peripheral) BOOL LoadPeripheralRoms(Peripheral* peripheral)
{ {
UINT16 count = peripheral->GetROMCount(); UINT16 count = peripheral->GetROMCount();
for (UINT16 i = 0; i < count; i++) { for (UINT16 i = 0; i < count; i++)
{
ROM* r = peripheral->GetROM(i); ROM* r = peripheral->GetROM(i);
if (r->isLoaded()) // If already loaded, we don't need to read the file again... if (r->isLoaded()) // If already loaded, we don't need to read the file again...
continue; continue;
CHAR nextFile[MAX_PATH];
if (myGlobalConfig.bios_dir == 1) // In: /ROMS/BIOS if (myGlobalConfig.bios_dir == 1) // In: /ROMS/BIOS
{ {
strcpy(nextFile, "/roms/bios/"); strcpy(nextFile, "/roms/bios/");
@ -280,17 +287,20 @@ BOOL LoadPeripheralRoms(Peripheral* peripheral)
strcpy(nextFile, "./"); // In: Same DIR as ROM files strcpy(nextFile, "./"); // In: Same DIR as ROM files
} }
strcpy(directory, nextFile);
strcat(nextFile, r->getDefaultFileName()); strcat(nextFile, r->getDefaultFileName());
if (!r->load(nextFile, r->getDefaultFileOffset())) if (!r->load(nextFile, r->getDefaultFileOffset()))
{ {
if (strstr(nextFile, "wbgrom") != NULL) FindAndLoadTutorGrom(nextFile); if (strstr(nextFile, "wbgrom") != NULL) FindAndLoadTutorGrom(directory, nextFile);
else if (strstr(nextFile, "grom") != NULL) FindAndLoadGrom(nextFile); else if (strstr(nextFile, "grom") != NULL) FindAndLoadGrom(directory, nextFile);
if (strstr(nextFile, "wbexec") != NULL) FindAndLoadTutorExec(nextFile); if (strstr(nextFile, "wbexec") != NULL) FindAndLoadTutorExec(directory, nextFile);
else if (strstr(nextFile, "exec") != NULL) FindAndLoadExec(nextFile); else if (strstr(nextFile, "exec") != NULL) FindAndLoadExec(directory, nextFile);
if (strstr(nextFile, "ivoice") != NULL) FindAndLoadIVoice(nextFile); if (strstr(nextFile, "ivoice") != NULL) FindAndLoadIVoice(directory, nextFile);
if (strstr(nextFile, "ecs") != NULL) FindAndLoadECS(directory, nextFile);
if (!r->load(nextFile, r->getDefaultFileOffset())) if (!r->load(nextFile, r->getDefaultFileOffset()))
{ {

View File

@ -161,8 +161,152 @@ unsigned int *customTiles = (unsigned int *) 0x06880000; //60K of video
unsigned short *customMap = (unsigned short *)0x0688F000; // 4K of video memory for the map (generally about 2.5K) unsigned short *customMap = (unsigned short *)0x0688F000; // 4K of video memory for the map (generally about 2.5K)
unsigned short customPal[512]; unsigned short customPal[512];
char directory[128]; char directory[192];
char filename[128]; char filename[192];
// -----------------------------------------------------------------------
// Map of game CRC to default Overlay file... this will help so that
// users don't need to rename every .rom file to match exactly the
// .ovl file. Most users just want to pick game, play game, enjoy game.
// -----------------------------------------------------------------------
struct MapRomToOvl_t
{
UINT32 crc;
const char *ovl_filename;
};
struct MapRomToOvl_t MapRomToOvl[] =
{
{0xA6E89A53 , "A Tale of Dragons and Swords.ovl"},
{0xA60E25FC , "ABPA Backgammon.ovl"},
{0xF8B1F2B7 , "AD&D Cloudy Mountain.ovl"},
{0x11C3BCFA , "AD&D Cloudy Mountain.ovl"},
{0x16C3B62F , "AD&D Treasure of Tarmin.ovl"},
{0x6746607B , "AD&D Treasure of Tarmin.ovl"},
{0x5A4CE519 , "AD&D Treasure of Tarmin.ovl"},
{0xBD731E3C , "AD&D Treasure of Tarmin.ovl"},
{0x2F9C93FC , "AD&D Treasure of Tarmin.ovl"},
{0x9BA5A798 , "Antarctic Tales.ovl"},
{0x5578C764 , "Astro Invaders.ovl"},
{0x00BE8BBA , "Astrosmash.ovl"},
{0xFAB2992C , "Astrosmash.ovl"},
{0x13FF363C , "Atlantis.ovl"},
{0xB35C1101 , "Auto Racing.ovl"},
{0x8AD19AB3 , "B-17 Bomber.ovl"},
{0xFC49B63E , "Bank Panic.ovl"},
{0x8B2727D9 , "BeachHead.ovl"},
{0xEAF650CC , "Beamrider.ovl"},
{0xC047D487 , "Beauty and the Beast.ovl"},
{0x32697B72 , "Bomb Squad.ovl"},
{0xF8E5398D , "Buck Rogers.ovl"},
{0x999CCEED , "Bump 'n' Jump.ovl"},
{0x43806375 , "Burger Time.ovl"},
{0xC92BAAE8 , "Burger Time.ovl"},
{0xFA492BBD , "Buzz Bombers.ovl"},
{0xFA492BBD , "Buzz Bombers.ovl"},
{0x2A1E0C1C , "Championship Tennis.ovl"},
{0x36E1D858 , "Checkers.ovl"},
{0x0BF464C6 , "Chip Shot - Super Pro Golf.ovl"},
{0x3289C8BA , "Commando.ovl"},
{0x060E2D82 , "D1K.ovl"},
{0x5E6A8CD8 , "Demon Attack.ovl"},
{0x13EE56F1 , "Diner.ovl"},
{0x84BEDCC1 , "Dracula.ovl"},
{0xC5182457 , "Dragon Quest.ovl"},
{0xAF8718A1 , "Dragonfire.ovl"},
{0x3B99B889 , "Dreadnaught Factor.ovl"},
{0x99f5783d , "Dreadnaught Factor.ovl"},
{0xB1BFA8B8 , "FinalRound.ovl"},
{0x3A8A4351 , "Fox Quest.ovl"},
{0x912E7C64 , "Frankenstien.ovl"},
{0xAC764495 , "GosubDigital.ovl"},
{0x4B8C5932 , "Happy Trails.ovl"},
{0x120b53a9 , "Happy Trails.ovl"},
{0xB5C7F25D , "Horse Racing.ovl"},
{0x94EA650B , "Hover Bovver.ovl"},
{0xFF83FF80 , "Hover Force.ovl"},
{0x4F3E3F69 , "Ice Trek.ovl"},
{0x5F2607E1 , "Infiltrator.ovl"},
{0xEE5F1BE2 , "Jetsons.ovl"},
{0x4422868E , "King of the Mountain.ovl"},
{0x87D95C72 , "King of the Mountain.ovl"},
{0x8C9819A2 , "Kool-Aid Man.ovl"},
{0x604611C0 , "Las Vegas Poker & Blackjack.ovl"},
{0xE00D1399 , "Lock-n-Chase.ovl"},
{0x5C7E9848 , "Lock-n-Chase.ovl"},
{0x6B6E80EE , "Loco-Motion.ovl"},
{0x80764301 , "Lode Runner.ovl"},
{0x573B9B6D , "Masters of the Universe - The Power of He-Man.ovl"},
{0xEB4383E0 , "Maxit.ovl"},
{0xE806AD91 , "Microsurgeon.ovl"},
{0x9D57498F , "Mind Strike.ovl"},
{0x598662F2 , "Mouse Trap.ovl"},
{0xE367E450 , "MrChess.ovl"},
{0x0753544F , "Ms Pac-Man.ovl"},
{0x7334CD44 , "Night Stalker.ovl"},
{0x36A7711B , "Operation Cloudfire.ovl"},
{0x169E3584 , "PBA Bowling.ovl"},
{0xFF87FAEC , "PGA Golf.ovl"},
{0xA21C31C3 , "Pac-Man.ovl"},
{0x6E4E8EB4 , "Pac-Man.ovl"},
{0x6084B48A , "Parsec.ovl"},
{0x1A7AAC88 , "Penguin Land.ovl"},
{0x9C75EFCC , "Pitfall!.ovl"},
{0x0CF06519 , "Poker Risque.ovl"},
{0x5AEF02C6 , "Rick Dynamite.ovl"},
{0x8910C37A , "River Raid.ovl"},
{0x95466AD3 , "River Raid.ovl"},
{0xDCF4B15D , "Royal Dealer.ovl"},
{0x8F959A6E , "SNAFU.ovl"},
{0x47AA7977 , "Safecracker.ovl"},
{0x6E0882E7 , "SameGame and Robots.ovl"},
{0x12BA58D1 , "SameGame and Robots.ovl"},
{0x20eb8b7c , "SameGame and Robots.ovl"},
{0xe9e3f60d , "Scooby Doo's Maze Chase.ovl"},
{0xBEF0B0C7 , "Scooby Doo's Maze Chase.ovl"},
{0x99AE29A9 , "Sea Battle.ovl"},
{0x2A4C761D , "Shark! Shark!.ovl"},
{0xd7b8208b , "Shark! Shark!.ovl"},
{0xFF7CB79E , "Sharp Shot.ovl"},
{0xF093E801 , "Skiing.ovl"},
{0x800B572F , "Slam Dunk - Super Pro Basketball.ovl"},
{0xE8B8EBA5 , "Space Armada.ovl"},
{0x1AAC64CA , "Space Bandits.ovl"},
{0xF95504E0 , "Space Battle.ovl"},
{0x39D3B895 , "Space Hawk.ovl"},
{0xCF39471A , "Space Panic.ovl"},
{0x3784DC52 , "Space Spartans.ovl"},
{0xB745C1CA , "Stadium Mud Buggies.ovl"},
{0x2DEACD15 , "Stampede.ovl"},
{0x72E11FCA , "Star Strike.ovl"},
{0x3D9949EA , "Sub Hunt.ovl"},
{0xbe4d7996 , "Super NFL Football (ECS).ovl"},
{0x15E88FCE , "Swords & Serpents.ovl"},
{0xD6F44FA5 , "TNT Cowboy.ovl"},
{0xCA447BBD , "TRON Deadly Discs.ovl"},
{0x07FB9435 , "TRON Solar Sailor.ovl"},
{0x03E9E62E , "Tennis.ovl"},
{0xB7923858 , "The Show Must Go On.ovl"},
{0xC1F1CA74 , "Thunder Castle.ovl"},
{0x67CA7C0A , "Thunder Castle.ovl"},
{0xD1D352A0 , "Tower of Doom.ovl"},
{0x734F3260 , "Truckin.ovl"},
{0x752FD927 , "USCF Chess.ovl"},
{0xF9E0789E , "Utopia.ovl"},
{0xC9624608 , "Vanguard.ovl"},
{0xA4A20354 , "Vectron.ovl"},
{0xF1ED7D27 , "White Water.ovl"},
{0x10D64E48 , "World Championship Baseball.ovl"},
{0xC2063C08 , "World Series Major League Baseball.ovl"},
{0x24B667B9 , "Worm Whomper.ovl"},
{0x740C9C49 , "X-Rally.ovl"},
{0x45119649 , "Yars Revenge.ovl"},
{0xC00CBA0D , "gorf.ovl"},
{0x00000000 , "generic.ovl"},
};
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// Custom overlays are read in and must be in a very strict format. See the documenatation // Custom overlays are read in and must be in a very strict format. See the documenatation
@ -181,7 +325,7 @@ void load_custom_overlay(bool bCustomGeneric)
{ {
strcpy(directory, "/roms/ovl/"); strcpy(directory, "/roms/ovl/");
} }
else if (myGlobalConfig.ovl_dir == 2) // In: /ROMS/INTY/OVL else if (myGlobalConfig.ovl_dir == 2) // In: /ROMS/INTV/OVL
{ {
strcpy(directory, "/roms/intv/ovl/"); strcpy(directory, "/roms/intv/ovl/");
} }
@ -207,6 +351,22 @@ void load_custom_overlay(bool bCustomGeneric)
{ {
bFound = 1; bFound = 1;
} }
else // Not found... try to find it using the RomToOvl[] table
{
UINT16 i=0;
while (MapRomToOvl[i].crc != 0x00000000)
{
if (MapRomToOvl[i].crc == currentRip->GetCRC())
{
strcpy(filename, directory);
strcat(filename, MapRomToOvl[i].ovl_filename);
fp = fopen(filename, "rb");
if (fp != NULL) bFound = 1;
break;
}
i++;
}
}
} }
if (bFound == 0) if (bFound == 0)

Binary file not shown.