Merge pull request #549 from pgrimsrud/judge

Judge
This commit is contained in:
adelikat 2015-12-16 12:38:46 -05:00
commit bb3731da29
8 changed files with 226 additions and 9 deletions

View File

@ -24,5 +24,7 @@ namespace BizHawk.Client.EmuHawk
public static OSDManager OSD = new OSDManager();
public static DisplayManager DisplayManager;
public static GLManager GLManager;
public static int ExitCode;
}
}

View File

@ -662,6 +662,12 @@ namespace BizHawk.Client.EmuHawk
_exit = true;
}
public void CloseEmulator(int exitCode)
{
_exit = true;
_exitCode = exitCode;
}
#endregion
#region Emulation Menu

View File

@ -462,7 +462,7 @@ namespace BizHawk.Client.EmuHawk
private bool _supressSyncSettingsWarning = false;
public void ProgramRunLoop()
public int ProgramRunLoop()
{
CheckMessages(); //can someone leave a note about why this is needed?
LogConsole.PositionConsole();
@ -545,6 +545,7 @@ namespace BizHawk.Client.EmuHawk
}
Shutdown();
return _exitCode;
}
/// <summary>
@ -1322,6 +1323,7 @@ namespace BizHawk.Client.EmuHawk
private bool _avwriterpad;
private bool _exit;
private int _exitCode;
private bool _exitRequestPending;
private bool _runloopFrameProgress;
private long _frameAdvanceTimestamp;

View File

@ -34,15 +34,17 @@ namespace BizHawk.Client.EmuHawk
}
[STAThread]
static void Main(string[] args)
static int Main(string[] args)
{
SubMain(args);
return SubMain(args);
}
//NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static void SubMain(string[] args)
static int SubMain(string[] args)
{
GlobalWin.ExitCode = 0;
// this check has to be done VERY early. i stepped through a debug build with wrong .dll versions purposely used,
// and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?)
// zero 25-dec-2012 - only do for public builds. its annoying during development
@ -55,7 +57,7 @@ namespace BizHawk.Client.EmuHawk
if (thisversion != utilversion || thisversion != emulversion)
{
MessageBox.Show("Conflicting revisions found! Don't mix .dll versions!");
return;
return -1;
}
}
@ -138,7 +140,7 @@ namespace BizHawk.Client.EmuHawk
mf.Show();
mf.Text = title;
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
}
}
@ -169,13 +171,13 @@ namespace BizHawk.Client.EmuHawk
if (System.Diagnostics.Debugger.IsAttached)
{
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
else
{
try
{
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
catch (Exception e)
{
@ -227,6 +229,8 @@ namespace BizHawk.Client.EmuHawk
// GlobalWin.GL.Dispose();
//((IDisposable)GlobalWin.IGL_GL).Dispose();
//return 0 assuming things have gone well, non-zero values could be used as error codes or for scripting purposes
return GlobalWin.ExitCode;
} //SubMain
//declared here instead of a more usual place to avoid dependencies on the more usual place
@ -319,7 +323,7 @@ namespace BizHawk.Client.EmuHawk
var title = MainForm.Text;
MainForm.Show();
MainForm.Text = title;
(MainForm as MainForm).ProgramRunLoop();
GlobalWin.ExitCode = (MainForm as MainForm).ProgramRunLoop();
}
}

View File

@ -45,6 +45,15 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.MainForm.CloseEmulator();
}
[LuaMethodAttributes(
"exitCode",
"Closes the emulator and returns the provided code"
)]
public void CloseEmulatorWithCode(int exitCode)
{
GlobalWin.MainForm.CloseEmulator(exitCode);
}
[LuaMethodAttributes(
"borderheight",
"Gets the current height in pixels of the letter/pillarbox area (top side only) around the emu display surface, excluding the gameExtraPadding you've set. This function (the whole lot of them) should be renamed or refactored since the padding areas have got more complex."

38
output/Lua/tasjudy.bat Normal file
View File

@ -0,0 +1,38 @@
@echo off
ECHO Hello. I am TASJudy. Prepare to be Judged.
setlocal EnableDelayedExpansion
del results\failed.txt >nul 2>&1
for /r %%i in (movies\*) do (
set currentmovie=%%i
echo Processing %%i...
start "" /B "F:\competition\bizhawk\EmuHawk.exe" rom\mystery.nes --movie=%%i
echo Waiting for run to finish...
TIMEOUT /T 1 >nul
call :CheckForExe
)
echo Done
pause
exit /b
:CheckForExe
tasklist /FI "IMAGENAME eq EmuHawk.exe" 2>NUL | find /I /N "EmuHawk.exe">NUL
if %ERRORLEVEL% == 1 goto ResultsAreIn
TIMEOUT /T 1 >nul
call :CheckForExe
exit /b
:ResultsAreIn
echo Results are in for !currentmovie!
call :kill
exit /b
:kill
taskkill /f /im EmuHawk.exe >nul 2>&1
exit /b

138
output/Lua/tasjudy.lua Normal file
View File

@ -0,0 +1,138 @@
--
-- TASJudy - Judges so you don't have to.
-- Author: Raiscan
-- Timestamp: 201508041957
-- Version: 0.1
-- To change this template use File | Settings | File Templates.
--
local resultsFilePath = "F:\\competition\\results\\results.txt"
local gracePeriod = 10000
local gracePeriodCounter = 0
local separator = ","
local exitOnResults = true
local FAILURE_DOES_NOT_FINISH = "DNF"
local FAILURE_DISQUALIFIED = "DQ"
-- Main Function --
function judge()
if movie.startsfromsavestate() then
console.log("Movie starts from savestate, so disqualifying")
writeFailureToResults(FAILURE_DISQUALIFIED)
endScript()
return
end
while not hasCompletedGame() do
if movieHasFinished() then
if gracePeriodLimiter() then
console.log("Movie does not finish the game :(")
writeFailureToResults(FAILURE_DOES_NOT_FINISH)
endScript()
return
end
end
--The show must go on
emu.frameadvance()
end
--We must have finished!
console.log("Movie finished game.")
writeSuccessToResults(emu.framecount(), getInGameTime())
endScript()
end
-------- HELPER FUNCTIONS BELOW ---------
-- Edit this with game completion criteria as necessary --
function hasCompletedGame()
return mainmemory.read_s8(0x002C) == 1
end
-- Edit this with functionality for in game time --
function getInGameTime()
local millis = bizstring.hex(mainmemory.read_u8(0x0050)):reverse()
local seconds = bizstring.hex(mainmemory.read_u8(0x004F)):reverse()
local minutes = bizstring.hex(mainmemory.read_u8(0x004E)):reverse()
return minutes .. ":" .. seconds .. "." .. millis
end
-- Ends the script. If exitOnResults set, exits emulator.
function endScript()
client.pause()
if exitOnResults then
client.closerom()
client.exitCode(emu.framecount())
end
end
-- Parses the hash of the movie file calculated by RGamma's uploader.
function parseHash()
local moviePath = movie.filename()
local movieFile = moviePath:match("([^\\]+)$")
local hash = movieFile:match("^([^.]+)")
return hash
end
-- Alias for writing results; blanks out times with reason.
function writeFailureToResults(reason)
writeResults(parseHash(), movie.getheader()["Author"], reason, reason, reason)
end
-- Alias for writing results; takes in endFrame and in game time --
function writeSuccessToResults(endFrame, inGameTime)
writeResults(parseHash(), movie.getheader()["Author"], endFrame, movie.length(), inGameTime)
end
function movieHasFinished()
return movie.mode() == "FINISHED" or not movie.isloaded()
end
-- Opens results file and writes a single line of all information gathered --
function writeResults(hash, author, endFrame, length, inGameTime)
local resultsFile, err = io.open(resultsFilePath, "a")
if err then
console.log("Could not write results " .. err)
else
local hash = parseHash()
local resultsLine = hash ..
separator ..
author ..
separator ..
endFrame ..
separator ..
length ..
separator ..
inGameTime
resultsFile:write(resultsLine .. "\n")
resultsFile:close()
end
end
function gracePeriodLimiter()
if gracePeriodCounter < gracePeriod then
gracePeriodCounter = gracePeriodCounter + 1
end
return gracePeriodCounter >= gracePeriod
end
judge()

18
output/Lua/tasjudy.py Normal file
View File

@ -0,0 +1,18 @@
import os
import datetime
from multiprocessing import Pool
bizhawkPath = ""
romPath = ""
moviePath = ""
def emu(arg):
ret = os.system(bizhawkPath + " " + romPath + " --movie=" + moviePath)
print("Ending %d with %d at %s" % (arg,ret,datetime.datetime.now().time()))
if __name__ == '__main__':
print("Starting at %s" % datetime.datetime.now().time())
p = Pool(processes=4)
p.map(emu,range(1))
print("Ending parent at %s" % datetime.datetime.now().time())