// The King of Dragons

#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"},

  {"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"},

  {"P3 Coin"       , 0, CpsInp177+6, "p3 coin"  },
  {"P3 Start"      , 0, CpsInp177+7, "p3 start" },
  {"P3 Up"         , 0, CpsInp177+3, "p3 up"    },
  {"P3 Down"       , 0, CpsInp177+2, "p3 down"  },
  {"P3 Left"       , 0, CpsInp177+1, "p3 left"  },
  {"P3 Right"      , 0, CpsInp177+0, "p3 right" },
  {"P3 Attack"     , 0, CpsInp177+4, "p3 fire 1"},
  {"P3 Jump"       , 0, CpsInp177+5, "p3 fire 2"},

  {"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 kodDIPList[]=
{
	// Defaults
	{0x1b, 0xff, 0xff, 0x00, NULL                },
	{0x1c, 0xff, 0xff, 0x00, NULL                },
	{0x1d, 0xff, 0xff, 0x00, NULL                },

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

	{0   , 0xfe, 0   , 2   , "Shooter"                },
	{0x1b, 0x01, 0x08, 0x08, "1"                      },
	{0x1b, 0x01, 0x08, 0x00, "3"                      },

	{0   , 0xfe, 0   , 2   , "Max Players"            },
	{0x1b, 0x01, 0x10, 0x10, "2"                      },
	{0x1b, 0x01, 0x10, 0x00, "3"                      },

//	{0   , 0xfe, 0   , 2   , "Unknown"                },
//	{0x1b, 0x01, 0x20, 0x00, "Off"                    },
//	{0x1b, 0x01, 0x20, 0x20, "On"                     },

	{0   , 0xfe, 0   , 2   , "2C to Start, 1 to Cont" },
	{0x1b, 0x01, 0x40, 0x00, "Off"                    },
	{0x1b, 0x01, 0x40, 0x40, "On"                     },

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

	// Dip B
	{0   , 0xfe, 0   , 8   , "Difficulty"             },
	{0x1c, 0x01, 0x07, 0x00, "Easiest"                },
	{0x1c, 0x01, 0x07, 0x01, "Very Easy"              },
	{0x1c, 0x01, 0x07, 0x02, "Easy"                   },
	{0x1c, 0x01, 0x07, 0x03, "Normal"                 },
	{0x1c, 0x01, 0x07, 0x04, "Medium"                 },
	{0x1c, 0x01, 0x07, 0x05, "Hard"                   },
	{0x1c, 0x01, 0x07, 0x06, "Very Hard"              },
	{0x1c, 0x01, 0x07, 0x07, "Hardest"                },

	{0   , 0xfe, 0   , 8   , "Lives"                  },
	{0x1c, 0x01, 0x38, 0x08, "1"                      },
	{0x1c, 0x01, 0x38, 0x00, "2"                      },
	{0x1c, 0x01, 0x38, 0x10, "3"                      },
	{0x1c, 0x01, 0x38, 0x18, "4"                      },
	{0x1c, 0x01, 0x38, 0x20, "5"                      },
	{0x1c, 0x01, 0x38, 0x28, "6"                      },
	{0x1c, 0x01, 0x38, 0x30, "7"                      },
	{0x1c, 0x01, 0x38, 0x38, "8"                      },

	{0   , 0xfe, 0   , 4   , "Bonus Life"             },
	{0x1c, 0x01, 0xc0, 0x40, "80k and every 400k"     },
	{0x1c, 0x01, 0xc0, 0x80, "160k and every 450k"    },
	{0x1c, 0x01, 0xc0, 0x00, "200k and every 450k"    },
	{0x1c, 0x01, 0xc0, 0xc0, "None"                   },

	// Dip C
//	{0   , 0xfe, 0   , 2   , "Unknown"                },
//	{0x1d, 0x01, 0x01, 0x00, "Off"                    },
//	{0x1d, 0x01, 0x01, 0x01, "On"                     },

//	{0   , 0xfe, 0   , 2   , "Unknown"                },
//	{0x1d, 0x01, 0x02, 0x00, "Off"                    },
//	{0x1d, 0x01, 0x02, 0x02, "On"                     },

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

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

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

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

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

STDDIPINFO(kod);


static int DrvExit()
{


  CpsRunExit();

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

//========================
//The King of Dragons Init
//========================

static int DrvInit()
{
  int nRet=0;
  Cps=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 8*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; // Already byteswapped
  nRet=BurnLoadRom(CpsRom+0x040001,2,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040000,3,2); if (nRet!=0) return 1; // Already byteswapped
  nRet=BurnLoadRom(CpsRom+0x080001,4,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x080000,5,2); if (nRet!=0) return 1; // Already byteswapped
  nRet=BurnLoadRom(CpsRom+0x0c0001,6,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x0c0000,7,2); if (nRet!=0) return 1; // Already byteswapped

  // Load graphics roms
  CpsLoadTiles(CpsGfx+0x000000,8+0*4);
  CpsLoadTiles(CpsGfx+0x200000,8+1*4);

  //Layer enable code by KEV
  nCpsLcReg=0x60; // Layer control register is at 0x60
  CpsLayEn[1]=0x30;
  CpsLayEn[2]=0x08;
  CpsLayEn[3]=0x30;

  // Protection enable code by KEV
  CpsMProt[0]=0x5e;
  CpsMProt[1]=0x5c;
  CpsMProt[2]=0x5a;
  CpsMProt[3]=0x58;

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

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

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


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

//================================
//The King of Dragons (Japan) Init
//================================

static int KodjInit()
{
  int nRet=0;
  Cps=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 8*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; // Already byteswapped
  nRet=BurnLoadRom(CpsRom+0x040001,2,2); if (nRet!=0) return 1;
  nRet=BurnLoadRom(CpsRom+0x040000,3,2); if (nRet!=0) return 1; // Already byteswapped
  nRet=BurnLoadRom(CpsRom+0x080000,4,1); if (nRet!=0) return 1;

  // Load graphics roms
  CpsLoadTiles(CpsGfx         ,5);
  CpsLoadTiles(CpsGfx+0x200000,9);

  //Layer enable code by KEV
  nCpsLcReg=0x60; // Layer control register is at 0x60
  CpsLayEn[1]=0x30;
  CpsLayEn[2]=0x08;
  CpsLayEn[3]=0x30;

  // Protection enable code by KEV
  CpsMProt[0]=0x5e;
  CpsMProt[1]=0x5c;
  CpsMProt[2]=0x5a;
  CpsMProt[3]=0x58;

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

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

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

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

//==================================
//The King of Dragons (Bootleg) Init
//==================================

static int KodbInit()
{
  int nRet=0;
  Cps=1; Kodb=1;
  nCpsRomLen=   0x100000;
  nCpsCodeLen=0; // not encrypted
  nCpsGfxLen= 8*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; // Already byteswapped

  // Load graphics roms
  CpsLoadTiles(CpsGfx         ,2);
  CpsLoadTiles(CpsGfx+0x200000,6);

  //Layer enable code by KEV
  nCpsLcReg=0x60; // Layer control register is at 0x60
  CpsLayEn[1]=0x30;
  CpsLayEn[2]=0x08;
  CpsLayEn[3]=0x30;

  // Protection enable code by KEV
  CpsMProt[0]=0x5e;
  CpsMProt[1]=0x5c;
  CpsMProt[2]=0x5a;
  CpsMProt[3]=0x58;

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

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

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


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

//===========================
//The King of Dragons (World)
//===========================

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

// Rom information
static struct BurnRomInfo KodRomDesc[]=
{
  {"kod30.rom" ,0x20000,0xc7414fd4,0x10}, // 0 even
  {"kod37.rom" ,0x20000,0xa5bf40d2,0x10}, // 1 odd
  {"kod31.rom" ,0x20000,0x1fffc7bd,0x10}, // 2 even
  {"kod38.rom" ,0x20000,0x89e57a82,0x10}, // 3 odd
  {"kod28.rom" ,0x20000,0x9367bcd9,0x10}, // 4 even
  {"kod35.rom" ,0x20000,0x4ca6a48a,0x10}, // 5 odd
  {"kod29.rom" ,0x20000,0x6a0ba878,0x10}, // 6 even
  {"kod36.rom" ,0x20000,0xb509b39d,0x10}, // 7 odd

  // graphics:
  {"kod02.rom",0x80000,0xe45b8701,   1}, // 8
  {"kod04.rom",0x80000,0xa7750322,   1},
  {"kod01.rom",0x80000,0x5f74bf78,   1},
  {"kod03.rom",0x80000,0x5e5303bf,   1},
  {"kod11.rom",0x80000,0x113358f3,   1}, // 12
  {"kod13.rom",0x80000,0x38853c44,   1},
  {"kod10.rom",0x80000,0x9ef36604,   1},
  {"kod12.rom",0x80000,0x402b9b4f,   1},

  // z80 rom
  {"kod09.rom" ,0x10000,0xf5514510,   1}, // 16
  // samples
  {"kod18.rom" ,0x20000,0x69ecb2c8,   1},
  {"kod19.rom" ,0x20000,0x02d851c1,   1},
};

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

struct BurnDriver BurnDrvCpsKod=
{
  {"kod","The King of Dragons (World)","","Capcom","CPS1","1991",NULL, NULL},
  1,3,HARDWARE_CAPCOM_CPS1,
  NULL,KodRomInfo,KodRomName,DrvInputInfo, kodDIPInfo,
  DrvInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};

//=========================
//The King of Dragons (USA)
//=========================

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

// Rom information
static struct BurnRomInfo KoduRomDesc[]=
{
  {"kdu-30b.bin" ,0x20000,0x825817f9,0x10}, // 0
  {"kdu-37b.bin" ,0x20000,0xd2422dfb,0x10}, // 1
  {"kdu-31b.bin" ,0x20000,0x9af36039,0x10}, // 2
  {"kdu-38b.bin" ,0x20000,0xbe8405a1,0x10}, // 3
  {"kod28.rom" ,0x20000,0x9367bcd9,0x10}, // 4
  {"kod35.rom" ,0x20000,0x4ca6a48a,0x10}, // 5
  {"kd-29.bin" ,0x20000,0x0360fa72,0x10}, // 6
  {"kd-36a.bin" ,0x20000,0x95a3cef8,0x10}, // 7

  // graphics:
  {"kod02.rom",0x80000,0xe45b8701,   1}, // 8
  {"kod04.rom",0x80000,0xa7750322,   1},
  {"kod01.rom",0x80000,0x5f74bf78,   1},
  {"kod03.rom",0x80000,0x5e5303bf,   1},
  {"kod11.rom",0x80000,0x113358f3,   1}, // 12
  {"kod13.rom",0x80000,0x38853c44,   1},
  {"kod10.rom",0x80000,0x9ef36604,   1},
  {"kod12.rom",0x80000,0x402b9b4f,   1},

  // z80 rom
  {"kd09.bin" ,0x10000,0xbac6ec26,   1}, // 16
  // samples
  {"kd18.bin" ,0x20000,0x4c63181d,   1},
  {"kd19.bin" ,0x20000,0x92941b80,   1},
};

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

struct BurnDriver BurnDrvCpsKodu=
{
  {"kodu","The King of Dragons (US)","","Capcom","CPS1","1991","kod", NULL},
  1,3,HARDWARE_CAPCOM_CPS1,
  NULL,KoduRomInfo,KoduRomName,DrvInputInfo, kodDIPInfo,
  DrvInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};

//===========================
//The King of Dragons (Japan)
//===========================

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

// Rom information
static struct BurnRomInfo KodjRomDesc[]=
{
  {"kd30.bin" ,0x20000,0xebc788ad,0x10}, // 0 even
  {"kd37.bin" ,0x20000,0xe55c3529,0x10}, // 1 odd
  {"kd31.bin" ,0x20000,0xc710d722,0x10}, // 2 even
  {"kd38.bin" ,0x20000,0x57d6ed3a,0x10}, // 3 odd
  {"kd33.bin" ,0x80000,0x9bd7ad4b,0x10}, // 4 both

  // graphics:
  {"kod02.rom",0x80000,0xe45b8701,   1}, // 8
  {"kod04.rom",0x80000,0xa7750322,   1},
  {"kod01.rom",0x80000,0x5f74bf78,   1},
  {"kod03.rom",0x80000,0x5e5303bf,   1},
  {"kod11.rom",0x80000,0x113358f3,   1}, // 12
  {"kod13.rom",0x80000,0x38853c44,   1},
  {"kod10.rom",0x80000,0x9ef36604,   1},
  {"kod12.rom",0x80000,0x402b9b4f,   1},

  // z80 rom
  {"kd09.bin" ,0x10000,0xbac6ec26,   1}, // 16
  // samples
  {"kd18.bin" ,0x20000,0x4c63181d,   1},
  {"kd19.bin" ,0x20000,0x92941b80,   1},
};

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

struct BurnDriver BurnDrvCpsKodj=
{
  {"kodj","The King of Dragons (Japan)","","Capcom","CPS1","1991","kod", NULL},
  1,3,HARDWARE_CAPCOM_CPS1,
  NULL,KodjRomInfo,KodjRomName,DrvInputInfo, kodDIPInfo,
  KodjInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};

//=============================
//The King of Dragons (Bootleg)
//=============================

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

// Rom information
static struct BurnRomInfo KodbRomDesc[]=
{
  {"kod.17" ,0x80000,0x036dd74c,0x10}, // 0
  {"kod.18" ,0x80000,0x3e4b7295,0x10}, // 1

  // graphics:
  {"kod02.rom",0x80000,0xe45b8701,   1}, // 2
  {"kod04.rom",0x80000,0xa7750322,   1},
  {"kod01.rom",0x80000,0x5f74bf78,   1},
  {"kod03.rom",0x80000,0x5e5303bf,   1},
  {"kod11.rom",0x80000,0x113358f3,   1}, // 6
  {"kod13.rom",0x80000,0x38853c44,   1},
  {"kod10.rom",0x80000,0x9ef36604,   1},
  {"kod12.rom",0x80000,0x402b9b4f,   1},

  // z80 rom
  {"kod.15" ,0x10000,0x01cae60c,   1}, // 10
  // samples
  {"kd18.bin" ,0x20000,0x4c63181d,   1},
  {"kd19.bin" ,0x20000,0x92941b80,   1},
};

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

struct BurnDriverD BurnDrvCpsKodb=
{
  {"kodb","The King of Dragons (bootleg)","No Sprites","Capcom","CPS1","1991","kod", NULL},
  0,3,HARDWARE_CAPCOM_CPS1,
  NULL,KodbRomInfo,KodbRomName,DrvInputInfo, kodDIPInfo,
  KodbInit,DrvExit,Cps1Frame,CpsRedraw,CpsAreaScan,
  &CpsRecalcPal,384,224,4,3
};
