454 lines
17 KiB
C#
454 lines
17 KiB
C#
using MAME.Core;
|
||
using System.IO;
|
||
|
||
namespace MAME.Core
|
||
{
|
||
public class Mame
|
||
{
|
||
public enum PlayState
|
||
{
|
||
PLAY_RUNNING = 0,
|
||
PLAY_SAVE,
|
||
PLAY_LOAD,
|
||
PLAY_RESET,
|
||
PLAY_RECORDSTART,
|
||
PLAY_RECORDRUNNING,
|
||
PLAY_RECORDEND,
|
||
PLAY_REPLAYSTART,
|
||
PLAY_REPLAYRUNNING,
|
||
PLAY_REPLAYEND,
|
||
}
|
||
public static PlayState playState;
|
||
public static bool is_foreground;
|
||
public static bool paused;
|
||
public static bool exit_pending;
|
||
public static EmuTimer.emu_timer soft_reset_timer;
|
||
public static BinaryReader brRecord = null;
|
||
public static BinaryWriter bwRecord = null;
|
||
public static bool bPP = true;
|
||
public static string RomRoot = string.Empty;
|
||
public class AA
|
||
{
|
||
public int fr;
|
||
public string fi;
|
||
public AA(int i1, string s1)
|
||
{
|
||
fr = i1;
|
||
fi = s1;
|
||
}
|
||
}
|
||
public static AA[] aa = new AA[]{
|
||
new AA(1055,"1"),
|
||
new AA(6547,"2"),
|
||
new AA(13955,"3")
|
||
};
|
||
private static FileStream fsRecord = null;
|
||
|
||
public static void mame_execute()
|
||
{
|
||
soft_reset();
|
||
//mame_pause(true);
|
||
//开始不暂停
|
||
mame_pause(false);
|
||
while (!exit_pending)
|
||
{
|
||
if (!paused)
|
||
{
|
||
Cpuexec.cpuexec_timeslice();
|
||
}
|
||
else
|
||
{
|
||
//TODO 暂停时,不应该更新画面帧
|
||
//Video.video_frame_update();
|
||
}
|
||
/*if (bPP)
|
||
{
|
||
foreach (AA a in aa)
|
||
{
|
||
if (Video.screenstate.frame_number == a.fr)
|
||
{
|
||
mame_pause(true);
|
||
State.savestate_callback(new BinaryWriter(new FileStream(@"G:\VS2008\compare1\compare1\bin\Debug\sta1\silentd\" + a.fi + ".sta", FileMode.Create)));
|
||
bPP = false;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
foreach (AA a in aa)
|
||
{
|
||
if (Video.screenstate.frame_number == a.fr + 1)
|
||
{
|
||
bPP = true;
|
||
}
|
||
}
|
||
}*/
|
||
handlestate();
|
||
}
|
||
}
|
||
|
||
#region
|
||
|
||
public static void mame_execute_UpdateMode_Start()
|
||
{
|
||
soft_reset();
|
||
//mame_pause(true);
|
||
//开始不暂停
|
||
mame_pause(false);
|
||
}
|
||
|
||
public static void mame_execute_UpdateMode_NextFrame()
|
||
{
|
||
if (exit_pending)
|
||
return;
|
||
|
||
long lastframe = Video.screenstate.frame_number;
|
||
//执行CPU命令,直到一次画面更新
|
||
while (lastframe == Video.screenstate.frame_number)
|
||
{
|
||
if (!paused)
|
||
{
|
||
Cpuexec.cpuexec_timeslice();
|
||
}
|
||
else
|
||
{
|
||
Video.video_frame_update();
|
||
}
|
||
handlestate();
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
public static void mame_schedule_soft_reset()
|
||
{
|
||
EmuTimer.timer_adjust_periodic(soft_reset_timer, Attotime.ATTOTIME_ZERO, Attotime.ATTOTIME_NEVER);
|
||
mame_pause(false);
|
||
if (Cpuexec.activecpu >= 0)
|
||
{
|
||
Cpuexec.cpu[Cpuexec.activecpu].PendingCycles = -1;
|
||
}
|
||
}
|
||
private static void handlestate()
|
||
{
|
||
if (playState == PlayState.PLAY_SAVE)
|
||
{
|
||
mame_pause(true);
|
||
Motion.motion_handler_callback = handle_save;
|
||
}
|
||
else if (playState == PlayState.PLAY_LOAD)
|
||
{
|
||
mame_pause(true);
|
||
Motion.motion_handler_callback = handle_load;
|
||
}
|
||
else if (playState == PlayState.PLAY_RESET)
|
||
{
|
||
soft_reset();
|
||
playState = PlayState.PLAY_RUNNING;
|
||
}
|
||
else if (playState == PlayState.PLAY_RECORDSTART)
|
||
{
|
||
mame_pause(true);
|
||
Motion.motion_handler_callback = handle_record;
|
||
}
|
||
else if (playState == PlayState.PLAY_RECORDEND)
|
||
{
|
||
handle_record();
|
||
}
|
||
else if (playState == PlayState.PLAY_REPLAYSTART)
|
||
{
|
||
mame_pause(true);
|
||
Motion.motion_handler_callback = handle_replay;
|
||
}
|
||
else if (playState == PlayState.PLAY_REPLAYEND)
|
||
{
|
||
handle_replay();
|
||
}
|
||
}
|
||
public static void init_machine()
|
||
{
|
||
Inptport.input_init();
|
||
Palette.palette_init();
|
||
Generic.generic_machine_init();
|
||
EmuTimer.timer_init();
|
||
soft_reset_timer = EmuTimer.timer_alloc_common(soft_reset, "soft_reset", false);
|
||
Window.osd_init();
|
||
Inptport.input_port_init();
|
||
Cpuexec.cpuexec_init();
|
||
Watchdog.watchdog_init();
|
||
Cpuint.cpuint_init();
|
||
Machine.driver_init();
|
||
Video.video_init();
|
||
Tilemap.tilemap_init();
|
||
Crosshair.crosshair_init();
|
||
Sound.sound_init();
|
||
State.state_init();
|
||
Machine.machine_start();
|
||
}
|
||
public static void mame_pause(bool pause)
|
||
{
|
||
if (paused == pause)
|
||
return;
|
||
EmuLogger.Log($"mame_pause->{pause}");
|
||
paused = pause;
|
||
Window.wininput_pause(paused);
|
||
Sound.sound_pause(paused);
|
||
}
|
||
public static bool mame_is_paused()
|
||
{
|
||
return (playState != PlayState.PLAY_RUNNING && playState != PlayState.PLAY_RECORDRUNNING && playState != PlayState.PLAY_REPLAYRUNNING) || paused;
|
||
}
|
||
public static void soft_reset()
|
||
{
|
||
Memory.memory_reset();
|
||
Cpuint.cpuint_reset();
|
||
Machine.machine_reset_callback();
|
||
Generic.interrupt_reset();
|
||
Cpuexec.cpuexec_reset();
|
||
Watchdog.watchdog_internal_reset();
|
||
Sound.sound_reset();
|
||
playState = PlayState.PLAY_RUNNING;
|
||
EmuTimer.timer_set_global_time(EmuTimer.get_current_time());
|
||
}
|
||
private static void handle_save()
|
||
{
|
||
//是否焦点
|
||
is_foreground = true;
|
||
if (is_foreground)
|
||
{
|
||
Video.sDrawText = "Select position to save to";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 1000;
|
||
if (Keyboard.IsTriggered(MotionKey.Escape))
|
||
{
|
||
Video.sDrawText = "Save cancelled";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
playState = PlayState.PLAY_RUNNING;
|
||
mame_pause(false);
|
||
Motion.motion_handler_callback = Motion.handler_ingame;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
private static void handle_load()
|
||
{
|
||
//是否焦点
|
||
bool is_foreground = true;
|
||
if (is_foreground)
|
||
{
|
||
Video.sDrawText = "Select position to load from";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 1000;
|
||
if (Keyboard.IsTriggered(MotionKey.Escape))
|
||
{
|
||
Video.sDrawText = "Load cancelled";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
playState = PlayState.PLAY_RUNNING;
|
||
mame_pause(false);
|
||
Motion.motion_handler_callback = Motion.handler_ingame;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
private static void handle_record()
|
||
{
|
||
//是否焦点
|
||
bool is_foreground = true;
|
||
if (is_foreground)
|
||
{
|
||
if (playState == PlayState.PLAY_RECORDSTART)
|
||
{
|
||
Video.sDrawText = "Select position to record to";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 1000;
|
||
if (Keyboard.IsTriggered(MotionKey.Escape))
|
||
{
|
||
Video.sDrawText = "Record cancelled";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
playState = PlayState.PLAY_RUNNING;
|
||
mame_pause(false);
|
||
Motion.motion_handler_callback = Motion.handler_ingame;
|
||
return;
|
||
}
|
||
}
|
||
else if (playState == PlayState.PLAY_RECORDEND)
|
||
{
|
||
Video.sDrawText = "Record end";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
bwRecord.Close();
|
||
bwRecord = null;
|
||
playState = PlayState.PLAY_RUNNING;
|
||
}
|
||
}
|
||
}
|
||
private static void handle_replay()
|
||
{
|
||
//是否焦点
|
||
bool is_foreground = true;
|
||
if (is_foreground)
|
||
{
|
||
if (playState == PlayState.PLAY_REPLAYSTART)
|
||
{
|
||
Video.sDrawText = "Select position to replay from";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 1000;
|
||
if (Keyboard.IsTriggered(MotionKey.Escape))
|
||
{
|
||
Video.sDrawText = "Replay cancelled";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
playState = PlayState.PLAY_RUNNING;
|
||
mame_pause(false);
|
||
Motion.motion_handler_callback = Motion.handler_ingame;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
if (playState == PlayState.PLAY_REPLAYEND)
|
||
{
|
||
Video.sDrawText = "Replay end";
|
||
Video.popup_text_end = Wintime.osd_ticks() + Wintime.ticks_per_second * 2;
|
||
brRecord.Close();
|
||
brRecord = null;
|
||
//mame_pause(true);
|
||
playState = PlayState.PLAY_RUNNING;
|
||
}
|
||
}
|
||
public static void postload()
|
||
{
|
||
int i;
|
||
switch (Machine.sBoard)
|
||
{
|
||
case "CPS-1":
|
||
for (i = 0; i < 3; i++)
|
||
{
|
||
CPS.ttmap[i].all_tiles_dirty = true;
|
||
}
|
||
YM2151.ym2151_postload();
|
||
break;
|
||
case "CPS-1(QSound)":
|
||
case "CPS2":
|
||
for (i = 0; i < 3; i++)
|
||
{
|
||
CPS.ttmap[i].all_tiles_dirty = true;
|
||
}
|
||
break;
|
||
case "Data East":
|
||
Dataeast.bg_tilemap.all_tiles_dirty = true;
|
||
YM2203.FF2203[0].ym2203_postload();
|
||
break;
|
||
case "Tehkan":
|
||
Tehkan.bg_tilemap.all_tiles_dirty = true;
|
||
Tehkan.fg_tilemap.all_tiles_dirty = true;
|
||
break;
|
||
case "Neo Geo":
|
||
Neogeo.regenerate_pens();
|
||
YM2610.F2610.ym2610_postload();
|
||
break;
|
||
case "Namco System 1":
|
||
for (i = 0; i < 6; i++)
|
||
{
|
||
Namcos1.ttmap[i].all_tiles_dirty = true;
|
||
}
|
||
YM2151.ym2151_postload();
|
||
break;
|
||
case "IGS011":
|
||
break;
|
||
case "PGM":
|
||
PGM.pgm_tx_tilemap.all_tiles_dirty = true;
|
||
PGM.pgm_bg_tilemap.all_tiles_dirty = true;
|
||
break;
|
||
case "M72":
|
||
M72.bg_tilemap.all_tiles_dirty = true;
|
||
M72.fg_tilemap.all_tiles_dirty = true;
|
||
break;
|
||
case "M92":
|
||
for (i = 0; i < 3; i++)
|
||
{
|
||
M92.pf_layer[i].tmap.all_tiles_dirty = true;
|
||
M92.pf_layer[i].wide_tmap.all_tiles_dirty = true;
|
||
}
|
||
break;
|
||
case "Taito":
|
||
switch (Machine.sName)
|
||
{
|
||
case "tokio":
|
||
case "tokioo":
|
||
case "tokiou":
|
||
case "tokiob":
|
||
case "bublbobl":
|
||
case "bublbobl1":
|
||
case "bublboblr":
|
||
case "bublboblr1":
|
||
case "boblbobl":
|
||
case "sboblbobl":
|
||
case "sboblbobla":
|
||
case "sboblboblb":
|
||
case "sboblbobld":
|
||
case "sboblboblc":
|
||
case "bub68705":
|
||
case "dland":
|
||
case "bbredux":
|
||
case "bublboblb":
|
||
case "bublcave":
|
||
case "boblcave":
|
||
case "bublcave11":
|
||
case "bublcave10":
|
||
YM2203.FF2203[0].ym2203_postload();
|
||
break;
|
||
case "opwolf":
|
||
case "opwolfa":
|
||
case "opwolfj":
|
||
case "opwolfu":
|
||
case "opwolfb":
|
||
case "opwolfp":
|
||
Taito.PC080SN_tilemap[0][0].all_tiles_dirty = true;
|
||
Taito.PC080SN_tilemap[0][1].all_tiles_dirty = true;
|
||
break;
|
||
}
|
||
break;
|
||
case "Taito B":
|
||
Taitob.bg_tilemap.all_tiles_dirty = true;
|
||
Taitob.fg_tilemap.all_tiles_dirty = true;
|
||
Taitob.tx_tilemap.all_tiles_dirty = true;
|
||
YM2610.F2610.ym2610_postload();
|
||
break;
|
||
case "Konami 68000":
|
||
Konami68000.K052109_tilemap[0].all_tiles_dirty = true;
|
||
Konami68000.K052109_tilemap[1].all_tiles_dirty = true;
|
||
Konami68000.K052109_tilemap[2].all_tiles_dirty = true;
|
||
break;
|
||
case "Capcom":
|
||
switch (Machine.sName)
|
||
{
|
||
case "gng":
|
||
case "gnga":
|
||
case "gngbl":
|
||
case "gngprot":
|
||
case "gngblita":
|
||
case "gngc":
|
||
case "gngt":
|
||
case "makaimur":
|
||
case "makaimurc":
|
||
case "makaimurg":
|
||
case "diamond":
|
||
Capcom.bg_tilemap.all_tiles_dirty = true;
|
||
Capcom.fg_tilemap.all_tiles_dirty = true;
|
||
Capcom.bg_tilemap.tilemap_set_scrollx(0, Capcom.scrollx[0] + 256 * Capcom.scrollx[1]);
|
||
Capcom.fg_tilemap.tilemap_set_scrollx(0, Capcom.scrolly[0] + 256 * Capcom.scrolly[1]);
|
||
YM2203.FF2203[0].ym2203_postload();
|
||
YM2203.FF2203[1].ym2203_postload();
|
||
break;
|
||
case "sf":
|
||
case "sfua":
|
||
case "sfj":
|
||
case "sfjan":
|
||
case "sfan":
|
||
case "sfp":
|
||
Capcom.bg_tilemap.all_tiles_dirty = true;
|
||
Capcom.fg_tilemap.all_tiles_dirty = true;
|
||
Capcom.tx_tilemap.all_tiles_dirty = true;
|
||
Capcom.bg_tilemap.tilemap_set_scrollx(0, Capcom.bg_scrollx);
|
||
Capcom.fg_tilemap.tilemap_set_scrollx(0, Capcom.fg_scrollx);
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|