// Final Fight

#include "cps.h"

static struct BurnInputInfo DrvInputList[] =
{
  {"P1 Coin"       , 0, CpsInp018+0, "p1 coin"   },
  {"P1 Start"      , 0, CpsInp018+4, "p1 start"  },
  {"P1 Up"         , 0, CpsInp001+3, "p1 up"     },
  {"P1 Down"       , 0, CpsInp001+2, "p1 down"   },
  {"P1 Left"       , 0, CpsInp001+1, "p1 left"   },
  {"P1 Right"      , 0, CpsInp001+0, "p1 right"  },
  {"P1 Attack"     , 0, CpsInp001+4, "p1 fire 1" },
  {"P1 Jump"       , 0, CpsInp001+5, "p1 fire 2" },
  {"P1 Special"    , 0, CpsInp001+6, "p1 fire 3" },

  {"P2 Coin"       , 0, CpsInp018+1, "p2 coin"   },
  {"P2 Start"      , 0, CpsInp018+5, "p2 start"  },
  {"P2 Up"         , 0, CpsInp000+3, "p2 up"     },
  {"P2 Down"       , 0, CpsInp000+2, "p2 down"   },
  {"P2 Left"       , 0, CpsInp000+1, "p2 left"   },
  {"P2 Right"      , 0, CpsInp000+0, "p2 right"  },
  {"P2 Attack"     , 0, CpsInp000+4, "p2 fire 1" },
  {"P2 Jump"       , 0, CpsInp000+5, "p2 fire 2" },
  {"P2 Special"    , 0, CpsInp000+6, "p2 fire 3" },

  {"Reset"         , 0, &CpsReset,   "reset"},
  {"Diagnostic"    , 0, CpsInp018+6, "diag"},
  {"Service"       , 0, CpsInp018+2, "service"},
  {"Dip A"         , 2, &Cpi01A    , "dip"},
  {"Dip B"         , 2, &Cpi01C    , "dip"},
  {"Dip C"         , 2, &Cpi01E    , "dip"},
};

STDINPUTINFO(Drv);

static struct BurnDIPInfo ffightDIPList[]=
{
	// Defaults
	{0x15, 0xff, 0xff, 0x00, NULL                },
	{0x16, 0xff, 0xff, 0x00, NULL                },
	{0x17, 0xff, 0xff, 0x00, NULL                },

	// Dip A
	{0   , 0xfe, 0   , 8   , "Coin 1"                 },
	{0x15, 0x01, 0x07, 0x07, "4 Coins 1 Credit"       },
	{0x15, 0x01, 0x07, 0x06, "3 Coins 1 Credit"       },
	{0x15, 0x01, 0x07, 0x05, "2 Coins 1 Credit"       },
	{0x15, 0x01, 0x07, 0x00, "1 Coin 1 Credit"        },
	{0x15, 0x01, 0x07, 0x01, "1 Coin 2 Credits"       },
	{0x15, 0x01, 0x07, 0x02, "1 Coin 3 Credits"       },
	{0x15, 0x01, 0x07, 0x03, "1 Coin 4 Credits"       },
	{0x15, 0x01, 0x07, 0x04, "1 Coin 6 Credits"       },

	{0   , 0xfe, 0   , 8   , "Coin 2"                 },
	{0x15, 0x01, 0x38, 0x38, "4 Coins 1 Credit"       },
	{0x15, 0x01, 0x38, 0x30, "3 Coins 1 Credit"       },
	{0x15, 0x01, 0x38, 0x28, "2 Coins 1 Credit"       },
	{0x15, 0x01, 0x38, 0x00, "1 Coin 1 Credit"        },
	{0x15, 0x01, 0x38, 0x08, "1 Coin 2 Credits"       },
	{0x15, 0x01, 0x38, 0x10, "1 Coin 3 Credits"       },
	{0x15, 0x01, 0x38, 0x18, "1 Coin 4 Credits"       },
	{0x15, 0x01, 0x38, 0x20, "1 Coin 6 Credits"       },

	{0   , 0xfe, 0   , 2   , "Continue Coin"          },
	{0x15, 0x01, 0x40, 0x00, "Off"                    },
	{0x15, 0x01, 0x40, 0x40, "On"                     },

//	{0   , 0xfe, 0   , 2   , "Unknown"           },
//	{0x15, 0x01, 0x80, 0x00, "Off"               },
//	{0x15, 0x01, 0x80, 0x80, "On"                },

	// Dip B
	{0   , 0xfe, 0   , 8   , "Difficulty"        },
	{0x16, 0x01, 0x07, 0x00, "01"            },
	{0x16, 0x01, 0x07, 0x01, "02"            },
	{0x16, 0x01, 0x07, 0x02, "03"            },
	{0x16, 0x01, 0x07, 0x03, "04"         },
	{0x16, 0x01, 0x07, 0x04, "05"       },
	{0x16, 0x01, 0x07, 0x05, "06"       },
	{0x16, 0x01, 0x07, 0x06, "07"       },
	{0x16, 0x01, 0x07, 0x07, "08"    },

	{0   , 0xfe, 0   , 4   , "Difficulty 2"      },
	{0x16, 0x01, 0x18, 0x00, "01"              },
	{0x16, 0x01, 0x18, 0x08, "02"            },
	{0x16, 0x01, 0x18, 0x10, "03"              },
	{0x16, 0x01, 0x18, 0x18, "04"           },

	{0   , 0xfe, 0   , 4   , "Bonus Life"        },
	{0x16, 0x01, 0x60, 0x00, "100k"              },
	{0x16, 0x01, 0x60, 0x20, "200k"              },
	{0x16, 0x01, 0x60, 0x40, "100k and every 200k"},
	{0x16, 0x01, 0x60, 0x60, "None"              },

//	{0   , 0xfe, 0   , 2   , "Unknown"           },
//	{0x16, 0x01, 0x80, 0x00, "Off"               },
//	{0x16, 0x01, 0x80, 0x80, "On"                },

	// Dip C
	{0   , 0xfe, 0   , 4   , "Lives"             },
	{0x17, 0x01, 0x03, 0x03, "1"                 },
	{0x17, 0x01, 0x03, 0x00, "2"                 },
	{0x17, 0x01, 0x03, 0x01, "3"                 },
	{0x17, 0x01, 0x03, 0x02, "4"                 },

	{0   , 0xfe, 0   , 2   , "Free Play"         },
	{0x17, 0x01, 0x04, 0x00, "Off"               },
	{0x17, 0x01, 0x04, 0x04, "On"                },

	{0   , 0xfe, 0   , 2   , "Freeze"            },
	{0x17, 0x01, 0x08, 0x00, "Off"               },
	{0x17, 0x01, 0x08, 0x08, "On"                },

	{0   , 0xfe, 0   , 2   , "Flip"              },
	{0x17, 0x01, 0x10, 0x00, "Off"               },
	{0x17, 0x01, 0x10, 0x10, "On"                },

	{0   , 0xfe, 0   , 2   , "Demo Sound"        },
	{0x17, 0x01, 0x20, 0x00, "Off"               },
	{0x17, 0x01, 0x20, 0x20, "On"                },

	{0   , 0xfe, 0   , 2   , "Continue"          },
	{0x17, 0x01, 0x40, 0x00, "Off"               },
	{0x17, 0x01, 0x40, 0x40, "On"                },
};

STDDIPINFO(ffight);


static int DrvExit()
{


  CpsRunExit();

  StartScroll[SCROLL_2]=0;
  StartScroll[SCROLL_3]=0;

  CpsExit();
  nCpsAdLen=0; nCpsZRomLen=0; nCpsGfxLen=0; nCpsRomLen=0;
  Cps=0;
  return 0;
}


//===================
//Final Fight (World)
//===================

static int FfightInit()
{
  int nRet=0;
  Cps=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 4*0x080000;
  nCpsZRomLen=  0x010000;
  nCpsAdLen  =2*0x020000;
  nRet=CpsInit(); if (nRet!=0) return 1;

  // Load program roms
  nRet=BurnLoadRom(CpsRom+0x000001,0,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x000000,1,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040001,2,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040000,3,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x080000,4,1); if (nRet!=0) return 1; // Already byteswapped

  // Load graphics roms
  CpsLoadTiles(CpsGfx,5);

  nCpsLcReg=0x6e; // Layer control register is at 0x6e
  CpsLayEn[1]=0x02;
  CpsLayEn[2]=0x0c;
  CpsLayEn[3]=0x0c;

  MaskAddr[0]=0x66;
  MaskAddr[1]=0x70;
  MaskAddr[2]=0x68;
  MaskAddr[3]=0x72;

  StartScroll[SCROLL_2]=1;
  StartScroll[SCROLL_3]=1;

  // Load Z80 Rom
  nRet=BurnLoadRom(CpsZRom,9,1);

  // Load ADPCM data
  nRet=BurnLoadRom(CpsAd        ,10,1);
  nRet=BurnLoadRom(CpsAd+0x20000,11,1);


  nRet=CpsRunInit(); if (nRet!=0) return 1;
  // Ready to go
  return 0;
}

// Count possible zip names and (if pszName!=NULL) return them

// Rom information
static struct BurnRomInfo FfightRomDesc[]=
{
  {"ff30-36.bin" ,0x20000,0xf9a5ce83,0x10}, // 0 even 68000 code
  {"ff35-42.bin" ,0x20000,0x65f11215,0x10}, // 1 odd
  {"ff31-37.bin" ,0x20000,0xe1033784,0x10}, // 2 even
  {"ff36-43.bin" ,0x20000,0x995e968a,0x10}, // 3 odd
  {"ff32-32m.bin",0x80000,0xc747696e,0x10}, // 4 both

  // graphics:
  {"ff05-05m.bin",0x80000,0x9c284108,   1}, // 5
  {"ff07-07m.bin",0x80000,0xa7584dfb,   1},
  {"ff01-01m.bin",0x80000,0x0b605e44,   1},
  {"ff03-03m.bin",0x80000,0x52291cd2,   1},

  // z80 rom
  {"ff09-09.bin" ,0x10000,0xb8367eb5,   1}, // 9
  // samples
  {"ff18-18.bin" ,0x20000,0x375c66e7,   1},
  {"ff19-19.bin" ,0x20000,0x1ef137f9,   1},
};

// Make The RomInfo/Name functions for the game
STD_ROM_PICK(Ffight) STD_ROM_FN(Ffight)

struct BurnDriver BurnDrvCpsFfight=
{
  {"ffight","Final Fight (World)","","Capcom","CPS1","1989",NULL, NULL},
  1,2,HARDWARE_CAPCOM_CPS1,
  NULL,FfightRomInfo,FfightRomName,DrvInputInfo, ffightDIPInfo,
  FfightInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};

//=================
//Final Fight (USA)
//=================

static int FfightuInit()
{
  int nRet=0;
  Cps=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 4*0x080000;
  nCpsZRomLen=  0x010000;
  nCpsAdLen  =2*0x020000;
  nRet=CpsInit(); if (nRet!=0) return 1;

  // Load program roms
  nRet=BurnLoadRom(CpsRom+0x000001,0,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x000000,1,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040001,2,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040000,3,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x080000,4,1); if (nRet!=0) return 1; // Already byteswapped

  // Load graphics roms
  CpsLoadTiles(CpsGfx,5);

  nCpsLcReg=0x66; // Layer control register is at 0x66
  CpsLayEn[1]=0x02;
  CpsLayEn[2]=0x04;
  CpsLayEn[3]=0x08;

  MaskAddr[0]=0x68;
  MaskAddr[1]=0x6a;
  MaskAddr[2]=0x6c;
  MaskAddr[3]=0x6e;

  StartScroll[SCROLL_2]=1;
  StartScroll[SCROLL_3]=1;

  // Load Z80 Rom
  nRet=BurnLoadRom(CpsZRom,9,1);

  // Load ADPCM data
  nRet=BurnLoadRom(CpsAd        ,10,1);
  nRet=BurnLoadRom(CpsAd+0x20000,11,1);


  nRet=CpsRunInit(); if (nRet!=0) return 1;
  // Ready to go
  return 0;
}

// Count possible zip names and (if pszName!=NULL) return them

// Rom information
static struct BurnRomInfo FfightuRomDesc[]=
{
  {"36" ,0x20000,0xe2a48af9,0x10}, // 0 even 68000 code
  {"42" ,0x20000,0xf4bb480e,0x10}, // 1 odd
  {"37" ,0x20000,0xc371c667,0x10}, // 2 even
  {"43" ,0x20000,0x2f5771f9,0x10}, // 3 odd
  {"ff32-32m.bin",0x80000,0xc747696e,0x10}, // 4 both

  // graphics:
  {"ff05-05m.bin",0x80000,0x9c284108,   1}, // 5
  {"ff07-07m.bin",0x80000,0xa7584dfb,   1},
  {"ff01-01m.bin",0x80000,0x0b605e44,   1},
  {"ff03-03m.bin",0x80000,0x52291cd2,   1},

  // z80 rom
  {"ff09-09.bin" ,0x10000,0xb8367eb5,   1}, // 9
  // samples
  {"ff18-18.bin" ,0x20000,0x375c66e7,   1},
  {"ff19-19.bin" ,0x20000,0x1ef137f9,   1},
};

// Make The RomInfo/Name functions for the game
STD_ROM_PICK(Ffightu) STD_ROM_FN(Ffightu)

struct BurnDriver BurnDrvCpsFfightu=
{
  {"ffightu","Final Fight (US)","","Capcom","CPS1","1989","ffight", NULL},
  1,2,HARDWARE_CAPCOM_CPS1,
  NULL,FfightuRomInfo,FfightuRomName,DrvInputInfo, ffightDIPInfo,
  FfightuInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};

//===================
//Final Fight (Japan)
//===================

static int FfightjInit()
{
  int nRet=0;
  Cps=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 16*0x020000;
  nCpsZRomLen=  0x010000;
  nCpsAdLen  =2*0x020000;
  nRet=CpsInit(); if (nRet!=0) return 1;

  // Load program roms
  nRet=BurnLoadRom(CpsRom+0x000001,0,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x000000,1,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040001,2,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040000,3,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x080000,4,1); if (nRet!=0) return 1; // Already byteswapped

  // Load graphics roms
  CpsLoadTilesByte(CpsGfx, 5);
  CpsLoadTilesByte(CpsGfx+(8*0x020000), 5+8);

  nCpsLcReg=0x6e; // Layer control register is at 0x6e
  CpsLayEn[1]=0x02;
  CpsLayEn[2]=0x0c;
  CpsLayEn[3]=0x0c;

  MaskAddr[0]=0x66;
  MaskAddr[1]=0x70;
  MaskAddr[2]=0x68;
  MaskAddr[3]=0x72;

  StartScroll[SCROLL_2]=1;
  StartScroll[SCROLL_3]=1;

  // Load Z80 Rom
  nRet=BurnLoadRom(CpsZRom,21,1);

  // Load ADPCM data
  nRet=BurnLoadRom(CpsAd        ,22,1);
  nRet=BurnLoadRom(CpsAd+0x20000,23,1);

  nRet=CpsRunInit(); if (nRet!=0) return 1;
  // Ready to go
  return 0;
}

// Count possible zip names and (if pszName!=NULL) return them

// Rom information
static struct BurnRomInfo FfightjRomDesc[]=
{
  {"ff30-36.bin" ,0x20000,0xf9a5ce83,0x10}, // 0 even 68000 code
  {"ff35-42.bin" ,0x20000,0x65f11215,0x10}, // 1 odd
  {"ff31-37.bin" ,0x20000,0xe1033784,0x10}, // 2 even
  {"ff43.bin" ,0x20000,0xb6dee1c3,0x10}, // 3 odd
  {"ff32-32m.bin",0x80000,0xc747696e,0x10}, // 4 both

  // graphics:
  {"ff09.bin",0x20000,0x5b116d0d,   1}, // 5
  {"ff01.bin",0x20000,0x815b1797,   1},
  {"ff13.bin",0x20000,0x8721a7da,   1},
  {"ff05.bin",0x20000,0xd0fcd4b5,   1},
  {"ff24.bin",0x20000,0xa1ab607a,   1}, // 9
  {"ff17.bin",0x20000,0x2dc18cf4,   1},
  {"ff38.bin",0x20000,0x6535a57f,   1},
  {"ff32.bin",0x20000,0xc8bc4a57,   1},
  {"ff10.bin",0x20000,0x624a924a,   1}, // 13
  {"ff02.bin",0x20000,0x5d91f694,   1},
  {"ff14.bin",0x20000,0x0a2e9101,   1},
  {"ff06.bin",0x20000,0x1c18f042,   1},
  {"ff25.bin",0x20000,0x6e8181ea,   1}, // 17
  {"ff18.bin",0x20000,0xb19ede59,   1},
  {"ff39.bin",0x20000,0x9416b477,   1},
  {"ff33.bin",0x20000,0x7369fa07,   1},

  // z80 rom
  {"ff09-09.bin" ,0x10000,0xb8367eb5,   1}, // 21
  // samples
  {"ff18-18.bin" ,0x20000,0x375c66e7,   1},
  {"ff19-19.bin" ,0x20000,0x1ef137f9,   1},
};

// Make The RomInfo/Name functions for the game
STD_ROM_PICK(Ffightj) STD_ROM_FN(Ffightj)

struct BurnDriver BurnDrvCpsFfightj=
{
  {"ffightj","Final Fight (Japan)","","Capcom","CPS1","1989","ffight", NULL},
  1,2,HARDWARE_CAPCOM_CPS1,
  NULL,FfightjRomInfo,FfightjRomName,DrvInputInfo, ffightDIPInfo,
  FfightjInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};
