--- fceu-orig/src/x6502.c 2005-04-13 13:54:28.000000000 +0300 +++ fceu/src/x6502.c 2005-10-04 17:13:04.000000000 +0300 @@ -25,6 +25,8 @@ #include "fceu.h" #include "sound.h" +#include "bisqbot.hh" + X6502 X; void (*X6502_Run)(int32 cycles); @@ -649,6 +651,9 @@ } _PI=_P; + + BisqBotMonitorCPU(_PC, X.A, X.X, X.Y); + b1=RdMem(_PC); //printf("$%04x, $%02x\n",_PC,b1); ADDCYC(CycTable[b1]); --- fceu-orig/src/bisqbot.cc 1970-01-01 02:00:00.000000000 +0200 +++ fceu/src/bisqbot.cc 2005-10-04 21:31:34.000000000 +0300 @@ -0,0 +1,72 @@ +#include +#define BISQBOT_INTERNAL +#include "bisqbot.hh" +static const unsigned MAX_FRAMES = 120; + +static BisqBotVar Bonus, Hurt, Item, Kill; + +void BisqBotMonitorCPU( + unsigned short PC, + unsigned char A, + unsigned char X, + unsigned char Y) +{ + /* GAME MONITORING */ + /* A, X, Y, PC correspond to the values of the CPU registers. */ + + static const unsigned short FrameUpd = 0xD57D; + static const unsigned short RandomFunc = 0xC5AB; + static const unsigned short CreateDrop = 0xBF25; + static const unsigned short HurtFunc = 0xA231; + static const unsigned short GotItem = 0xC833; + static const unsigned short KillFunc = 0xC219; + static const unsigned short EnemyKill = 0xBEEC; + if(PC == CreateDrop) Bonus.Set(Y); + if(PC == HurtFunc) Hurt.Set(1); + if(PC == KillFunc) Hurt.Set(2); + if(PC == GotItem) Item.Set(A); + if(PC == EnemyKill) Kill.Set(A); +} + +void BisqBotReset() +{ + Bonus.Clear(); + Hurt.Clear(); + Item.Clear(); + Kill.Clear(); +} + +unsigned char BisqBotInput(unsigned FrameNo) +{ + static const unsigned char InputTable[] = + { + 0x00, 0x01, + 0x40, 0x41, + 0x80, 0x81, + 0x01, 0x41, 0x81, + 0x01, 0x41, 0x81, + 0x01, 0x41, 0x81 + }; + static unsigned LastInput = 0x00; + unsigned char Input = 0x00; + if(!(rand()%20)) Input |= 0x02; + if(!(rand()%20)) LastInput = InputTable[rand()%sizeof(InputTable)]; + Input |= LastInput; + return Input; +} + +enum BisqBotInstruction BisqBotTick(unsigned FrameNo) +{ + if(Hurt.Count() + || Item.Count() + || !Bonus.LimitedTo(0x3B, 0x3F) + || FrameNo >= MAX_FRAMES) + { + return BisqBotRestart; + } + if(Bonus.Has(0x3F, 2)) + { + return BisqBotAccept; + } + return BisqBotContinue; +} --- fceu-orig/src/drivers/pc/sdl-video.c 2005-04-13 13:54:26.000000000 +0300 +++ fceu/src/drivers/pc/sdl-video.c 2005-10-04 21:35:06.000000000 +0300 @@ -358,6 +359,13 @@ XBuf+=srendline*256; +#if 1 /* DISABLE VIDEO? */ + extern int BotFrontDisableVideo; + if(BotFrontDisableVideo) { + static unsigned Frame=0; + if(++Frame>=40){Frame=0;}else return; + } +#endif if(BlitBuf) TmpScreen=BlitBuf; else TmpScreen=screen; --- fceu-orig/src/Makefile.am 2005-04-13 13:54:30.000000000 +0300 +++ fceu/src/Makefile.am 2005-10-04 17:30:11.000000000 +0300 @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = subdir-objects bin_PROGRAMS = fceu -fceu_SOURCES = fceustr.c cart.c cheat.c crc32.c debug.c endian.c fceu.c fds.c file.c filter.c general.c ines.c input.c md5.c memory.c netplay.c nsf.c palette.c ppu.c sound.c state.c unif.c video.c vsuni.c wave.c x6502.c movie.c +fceu_SOURCES = fceustr.c cart.c cheat.c crc32.c debug.c endian.c fceu.c fds.c file.c filter.c general.c ines.c input.c md5.c memory.c netplay.c nsf.c palette.c ppu.c sound.c state.c unif.c video.c vsuni.c wave.c x6502.c movie.c bisqbot.cc # soundexp.c fceu_SOURCES += unzip.c @@ -24,6 +24,5 @@ endif fceu_SOURCES += $(fceud_SOURCES) -fceu_LIBS = $(fceud_LIBS) DEFAULT_INCLUDES = --- fceu-orig/src/drivers/pc/input.c 2005-04-13 13:55:02.000000000 +0300 +++ fceu/src/drivers/pc/input.c 2005-10-04 21:53:23.000000000 +0300 @@ -19,6 +19,9 @@ */ #include +#include /* rand() */ +#include +#include #include "main.h" #include "dface.h" @@ -26,6 +29,9 @@ #include "../common/cheat.h" +#define BOTFRONT_INTERNAL +#include "../../bisqbot.hh" + /* UsrInputType[] is user-specified. InputType[] is current (game loading can override user settings) */ @@ -204,9 +395,17 @@ if(keyonly(3) && is_shift) { FCEUI_StopMovie(); } + if(keyonly(K)) + { + if(BotFrontMode.SeqPos < 0) + BotFrontStart(); + else + BotFrontEnd(); + } + else BotFrontIter(); if(keyonly(F5) || keyonly(S)) { FCEUI_SaveState(NULL); } @@ -345,24 +642,31 @@ rapid^=1; +#ifdef BISQWIT_ROCKMAN_DEBUGGATION + if(BotFrontMode.SeqPos >= 0) + JS |= BotFrontMode.Seq[BotFrontMode.SeqPos]; +#endif + for(wg=0;wg<4;wg++) { for(x=0;x<8;x++) if(DTestButton(&GamePadConfig[wg][x])) JS|=(1< 0 && a < values.size(); ++a) + if(values[a] == v) --min_count; + return min_count == 0; + } + bool LimitedTo(unsigned a,unsigned b) const + { + for(unsigned ind=0; ind values; +}; +#endif + +#ifdef BOTFRONT_INTERNAL +int BotFrontDisableVideo=0; + +/* Maximum length of the sequence */ +#define ROCKMAN_SEQMAX 65536 +static struct BotFrontMode +{ + unsigned char Seq[ROCKMAN_SEQMAX]; + int SeqPos; + int Cap; +} BotFrontMode = { {}, -1, -1, -1 }; + +static void BotFrontGenInput() +{ + BotFrontMode.Seq[BotFrontMode.SeqPos] = + BisqBotInput(BotFrontMode.SeqPos); +} +static void BotFrontMsg(const char*fmt, ...) +{ + FILE*fp; + + va_list ap; + va_start(ap,fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + fp = fopen("rockman.log", "at"); + if(!fp) fp = fopen("rockman.log", "wt"); + + va_start(ap,fmt); + vfprintf(fp, fmt, ap); + va_end(ap); + + fclose(fp); +} +static void BotFrontReset() +{ + BotFrontMode.SeqPos = 0; + BisqBotReset(); + BotFrontGenInput(); +} +static void BotFrontStart() +{ + fprintf(stderr,"BotFrontStart\n"); + FCEUI_SelectState(1, 1); + FCEUI_SaveState(NULL); + if(!FCEUI_EmulationPaused()) FCEUI_ToggleEmulationPause(); + BotFrontReset(); + BotFrontMode.Cap = ROCKMAN_SEQMAX; + BotFrontDisableVideo=1; + BotFrontMsg("--------------- New run ------------------ \n"); + srand(time(NULL)); +} +static void BotFrontEnd() +{ + fprintf(stderr,"BotFrontEnd\n"); + BotFrontReset(); + BotFrontMode.SeqPos = -1; + BotFrontDisableVideo=0; +} +static void BotFrontIter() +{ + if(BotFrontMode.SeqPos < 0) return; + + switch(BisqBotTick(BotFrontMode.SeqPos)) + { + case BisqBotRestart: + { + //BotFrontStateDump(); + Restart: + fprintf(stderr, "\r"); + FCEUI_LoadState(NULL); + fprintf(stderr, "\r"); // LoadState will display a line. + BotFrontReset(); + FCEUI_FrameAdvance(); + break; + } + case BisqBotContinue: + { + ++BotFrontMode.SeqPos; + if(BotFrontMode.SeqPos >= BotFrontMode.Cap) + goto Restart; + + BotFrontGenInput(); + FCEUI_FrameAdvance(); + break; + } + case BisqBotAccept: + { + /* Report how we got there. */ + unsigned a; + BotFrontMsg("\n***  Bingo in %u frames:\n", BotFrontMode.SeqPos); + for(a=0; a