ips patches, 0.4 r162 rel?
[fceu.git] / fce.c
diff --git a/fce.c b/fce.c
index 6e30c00..89a54a3 100644 (file)
--- a/fce.c
+++ b/fce.c
@@ -39,6 +39,7 @@
 #include       "fds.h"
 #include       "ines.h"
 #include       "unif.h"
+#include       "vsuni.h"
 #include        "cheat.h"
 
 #include       "state.h"
@@ -145,6 +146,8 @@ void asmcpu_unpack(void)
        X6502_Rebase_a();
        nes_registers[4] = X.S << 24;
        nes_registers[4]|= X.IRQlow << 8;
+       if (MapIRQHook)
+               nes_registers[4] |= 1<<16; // MapIRQHook set bit
        nes_registers[7] = (uint32)X.count << 16;
 
        // NVUB DIZC
@@ -604,17 +607,25 @@ void FCEUI_FrameSkip(int x)
 static void LineUpdate(uint8 *target)
 {
        uint32 tem;
+       int y;
 
        /* PRefreshLine() will not get called on skipped frames.  This
         * could cause a problem, but the solution would be rather complex,
         * due to the current sprite 0 hit code.
         */
-       if(FSkip) return;
+       if(FSkip)
+       {
+        y=(int)SPRAM[0] + 1;
+        if(scanline==y && SpriteON) PPU_status|=0x40; // hack
+        return;
+       }
 
        if(scanline < FSettings.FirstSLine || scanline > FSettings.LastSLine)
        {
           if(PPU_hook)
            PRefreshLine();
+          y=(int)SPRAM[0] + 1;
+          if(scanline==y && SpriteON) PPU_status|=0x40;
        }
        else
        {
@@ -1098,7 +1109,7 @@ int NSFLoad(int fp);
 FCEUGI *FCEUI_LoadGame(char *name)
 {
        char name2[512];
-       int have_movie = 0;
+       int have_movie = 0, have_ips = 0;
         int fp;
 
         //Exit=1;
@@ -1118,24 +1129,39 @@ FCEUGI *FCEUI_LoadGame(char *name)
 
         {
         char *p = name2 + strlen(name2) - 4;
-        if (strcmp(p, ".fcm") == 0)
+        if (strcasecmp(p, ".fcm") == 0) printf("movie detected\n"), have_movie = 1;
+        if (strcasecmp(p, ".ips") == 0) printf("ips detected\n"), have_ips = 1;
+        if (have_movie || have_ips)
         {
          // movie detected
-         printf("movie detected\n");
          FCEU_fclose(fp);
          *p = 0;
          fp=FCEU_fopen(name2,"rb");
-         if (!fp && p - name2 > 2)  p[-2] = 0;
-         fp=FCEU_fopen(name2,"rb");
+         if (!fp && p - name2 > 2)
+         {
+          for (p--; p > name2 && *p != '.'; p--);
+           *p = 0;
+          fp=FCEU_fopen(name2,"rb");
+         }
          if (!fp) {
-          printf("no ROM for movie\n");
+          printf("no ROM for ips/movie\n");
           LoadGameLastError = 2;
           return 0;
          }
-         have_movie = 1;
         }
        }
 
+       // do IPS patch
+       if (have_ips)
+       {
+        FCEU_fclose(fp);
+        FILE *ips = fopen(name, "rb");
+        if (!ips) return 0;
+         fp=FCEU_fopen_forcemem(name2);
+        if (!fp) { fclose(ips); return 0; }
+        ApplyIPS(ips, fp); // closes ips
+       }
+
         GetFileBase(name2);
         if(iNESLoad(name2,fp))
          goto endlseq;
@@ -1506,15 +1532,18 @@ void PowerNES(void)
         memset(RAM,0x00,0x800);
 #endif
         ResetMapping();
-       GameInterface(GI_POWER, 0);
         PowerSound();
        PowerPPU();
-       timestampbase=0;
+       GameInterface(GI_POWER, 0);
+        if(FCEUGameInfo.type==GIT_VSUNI)
+         FCEU_VSUniPower();
 #ifdef ASM_6502
        if (geniestage)
         GenieSetPages(0);
 #endif
+       timestampbase=0;
        X6502_Power();
+       FCEU_PowerCheats();
 }