sdd1 support
authorJavier S. Pedro <maemo@javispedro.com>
Fri, 12 Mar 2010 20:15:59 +0000 (21:15 +0100)
committerJavier S. Pedro <maemo@javispedro.com>
Fri, 12 Mar 2010 20:15:59 +0000 (21:15 +0100)
debian/changelog
platform/sdl.cpp
sdd1.cpp

index 03498e2..1d61505 100644 (file)
@@ -2,8 +2,9 @@ drnoksnes (1.3.1) unstable; urgency=low
 
   * Fixed issue with Fremantle player 2 GUI.
   * Adding (single) zeemote support.
+  * Initial SDD1 pack support.
 
- -- Javier S. Pedro <maemo@javispedro.com>  Tue, 23 Feb 2010 23:54:34 +0100
+ -- Javier S. Pedro <maemo@javispedro.com>  Fri, 12 Mar 2010 21:15:25 +0100
 
 drnoksnes (1.3.0) unstable; urgency=low
 
index b07adbf..1558c6a 100644 (file)
@@ -31,11 +31,6 @@ void S9xMessage(int type, int number, const char * message)
        printf("%s\n", message);
 }
 
-void S9xLoadSDD1Data()
-{TRACE
-       Settings.SDD1Pack=FALSE;
-}
-
 void S9xAutoSaveSRAM()
 {
        Memory.SaveSRAM(S9xGetFilename(FILE_SRAM));
index e8f5afb..e894d5c 100644 (file)
--- a/sdd1.cpp
+++ b/sdd1.cpp
  * Super NES and Super Nintendo Entertainment System are trademarks of
  * Nintendo Co., Limited and its subsidiary companies.
  */
+
+#include <stdio.h>
+#include <dirent.h>
+
 #include "snes9x.h"
 #include "memmap.h"
 #include "ppu.h"
 #include "sdd1.h"
 #include "display.h"
 
-#ifdef __linux
-//#include <unistd.h>
+static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2)
+{
+    return (*(uint32 *) p1 - *(uint32 *) p2);
+}
+
+static int S9xGetSDD1Dir(char * packdir)
+{
+       char dir[_MAX_DIR + 1];
+       char drive[_MAX_DRIVE + 1];
+       char name[_MAX_FNAME + 1];
+       char ext[_MAX_EXT + 1];
+
+       PathSplit(S9xGetFilename(FILE_ROM), drive, dir, name, ext);
+
+       if (strncmp(Memory.ROMName, "Star Ocean", 10) == 0) {
+        PathMake(packdir, drive, dir, "socnsdd1", 0);
+        return 1;
+       } else if(strncmp(Memory.ROMName, "STREET FIGHTER ALPHA2", 21) == 0) {
+               PathMake(packdir, drive, dir, "sfa2sdd1", 0);
+               return 1;
+       } else {
+               S9xMessage(S9X_WARNING, S9X_ROM_INFO,
+                       "WARNING: No default SDD1 pack for this ROM");
+               return 0;
+       }
+}
+
+void S9xLoadSDD1Data ()
+{
+       char packdir[_MAX_PATH + 1];
+
+       // Unload any previous pack
+       Settings.SDD1Pack = FALSE;
+       Memory.FreeSDD1Data();
+
+       if (!S9xGetSDD1Dir(packdir)) {
+               printf("SDD1: Didn't found pack for this ROM\n");
+               return;
+       }
+
+       printf("SDD1: Searching for pack in %s\n", packdir);
+       Settings.SDD1Pack=TRUE;
+
+       char index[_MAX_PATH + 1];
+       char data[_MAX_PATH + 1];
+       char patch[_MAX_PATH + 1];
+       DIR *dir = opendir(packdir);
+
+       index[0] = 0;
+       data[0] = 0;
+       patch[0] = 0;
+
+       if (dir) {
+               struct dirent *d;
+
+               while ((d = readdir (dir))) {
+                       if (strcasecmp (d->d_name, "SDD1GFX.IDX") == 0) {
+                               strcpy(index, packdir);
+                               strcat(index, "/");
+                               strcat(index, d->d_name);
+                       } else if (strcasecmp (d->d_name, "SDD1GFX.DAT") == 0) {
+                               strcpy(data, packdir);
+                               strcat(data, "/");
+                               strcat(data, d->d_name);
+                       } else if (strcasecmp (d->d_name, "SDD1GFX.PAT") == 0) {
+                               strcpy(patch, packdir);
+                               strcat(patch, "/");
+                               strcat(patch, d->d_name);
+                       }
+               }
+               closedir (dir);
+       }
+
+       if (strlen (index) && strlen (data)) {
+               FILE *fs = fopen (index, "rb");
+               int len = 0;
+
+               if (fs) {
+                       // Index is stored as a sequence of entries, each entry being
+                       // 12 bytes consisting of:
+                       // 4 byte key: (24bit address & 0xfffff * 16) | translated block
+                       // 4 byte ROM offset
+                       // 4 byte length
+
+                       fseek (fs, 0, SEEK_END);
+                       len = ftell (fs);
+                       rewind (fs);
+                       Memory.SDD1Index = (uint8 *) malloc (len);
+                       fread (Memory.SDD1Index, 1, len, fs);
+                       fclose (fs);
+                       Memory.SDD1Entries = len / 12;
+               } else {
+                       fprintf(stderr, "Failed to read SDD1 index file %s\n", index);
+                       return;
+               }
+               printf("SDD1: index: %s\n", PathBasename(index));
+
+               if (!(fs = fopen (data, "rb"))) {
+                       fprintf(stderr, "Failed to read SDD1 data file %s\n", data);
+                       free ((char *) Memory.SDD1Index);
+                       Memory.SDD1Index = NULL;
+                       Memory.SDD1Entries = 0;
+                       return;
+               } else {
+                       fseek (fs, 0, SEEK_END);
+                       len = ftell (fs);
+                       rewind (fs);
+                       Memory.SDD1Data = (uint8 *) malloc (len);
+                       fread (Memory.SDD1Data, 1, len, fs);
+                       fclose (fs);
+               }
+               printf("SDD1: data pack: %s\n", PathBasename(data));
+
+               if (strlen (patch) > 0 && (fs = fopen (patch, "rb"))) {
+                       fclose (fs);
+               }
+
+#ifdef MSB_FIRST
+               // Swap the byte order of the 32-bit value triplets on
+               // MSBFirst machines.
+               uint8 *ptr = Memory.SDD1Index;
+               for (int i = 0; i < Memory.SDD1Entries; i++, ptr += 12)         {
+                       SWAP_DWORD ((*(uint32 *) (ptr + 0)));
+                       SWAP_DWORD ((*(uint32 *) (ptr + 4)));
+                       SWAP_DWORD ((*(uint32 *) (ptr + 8)));
+               }
 #endif
 
+               qsort(Memory.SDD1Index, Memory.SDD1Entries, 12,
+                       S9xCompareSDD1IndexEntries);
+               printf("SDD1: Pack loaded succesfully\n", data);
+       } else {
+               fprintf(stderr, "SDD1: SDD1 data pack not found in '%s'\n",
+                       packdir);
+               fprintf(stderr, "SDD1: Check if sdd1gfx files exist\n",
+                       packdir);
+               printf("SDD1: Failed to load pack\n", data);
+       }
+}
+
 void S9xSetSDD1MemoryMap (uint32 bank, uint32 value)
 {
     bank = 0xc00 + bank * 0x100;