mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 17:55:23 +02:00
Two leftovers from the sample point having been a sixteenth of a pixel off center. They're one commit because they can't be separated: each was compensating for the other, so applying either alone makes gpu/filtering/precisionnearest3d fail. I tried both orderings. 1. DrawRectangle advanced ST to the first sample with (minX - entireX1 + 1). The +1 existed to make up for centerOff being 7 instead of 8; now that minX already sits at the pixel center it double-counts and pushes the texture coordinate a sixteenth of a texel too far. Only visible when that lands exactly on a texel boundary, which is what precisionnearest2d's offset-7 case constructs: the sprite spans x from -7/16, so u at pixel 0's center is 0.9375 and should sample texel 0, but the extra sixteenth made it exactly 1.0. 2. Removing the +1 exposed the other one. ClipToScreenInternal used a plain (int) cast, which truncates toward zero - so once the region offset makes the value negative it rounds the opposite way from the positive case, and from the through-mode path that computes screenpos directly. The two disagreed by one subpixel for negative coordinates, which is why the 2D and 3D variants of the same test failed at different offsets, 7 and 8. floorf is what the +0.375 nudge was always meant to pair with, and it makes both paths agree. Now passing: gpu/filtering/precisionnearest2d, promoted to tests_good since it passes on Vulkan too. precisionlinear2d and precisionlinear3d also start passing on software but still fail on the hardware backends, so they stay in tests_next with a comment saying so, as does gpu/primitives/continue from the last commit. 317 pspautotests pass, 0 fail. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vd8ntC2brCUtCrDJMqLbs8
611 lines
16 KiB
Python
Executable File
611 lines
16 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Automated script to run the pspautotests test suite in PPSSPP.
|
|
|
|
import sys
|
|
import os
|
|
import subprocess
|
|
import threading
|
|
import glob
|
|
|
|
|
|
PPSSPP_EXECUTABLES = [
|
|
# Windows
|
|
"Windows\\Debug\\PPSSPPHeadless.exe",
|
|
"Windows\\Release\\PPSSPPHeadless.exe",
|
|
"Windows\\x64\\Debug\\PPSSPPHeadless.exe",
|
|
"Windows\\x64\\Release\\PPSSPPHeadless.exe",
|
|
"build*/PPSSPPHeadless.exe",
|
|
"./PPSSPPHeadless.exe",
|
|
# Mac
|
|
"build*/Debug/PPSSPPHeadless",
|
|
"build*/Release/PPSSPPHeadless",
|
|
"build*/RelWithDebInfo/PPSSPPHeadless",
|
|
"build*/MinSizeRel/PPSSPPHeadless",
|
|
# Linux
|
|
"build*/PPSSPPHeadless",
|
|
"./PPSSPPHeadless",
|
|
# CI
|
|
"ppsspp/PPSSPPHeadless",
|
|
"ppsspp\\PPSSPPHeadless.exe",
|
|
]
|
|
|
|
PPSSPP_EXE = None
|
|
TEST_ROOT = "pspautotests/tests/"
|
|
TIMEOUT = 5
|
|
|
|
class Command(object):
|
|
def __init__(self, cmd, data = None):
|
|
self.cmd = cmd
|
|
self.data = data
|
|
self.process = None
|
|
self.output = None
|
|
self.timeout = False
|
|
|
|
def run(self, timeout):
|
|
def target():
|
|
self.process = subprocess.Popen(self.cmd, stdin=subprocess.PIPE, stdout=sys.stdout, stderr=subprocess.STDOUT)
|
|
self.process.stdin.write(self.data.encode('utf-8'))
|
|
self.process.stdin.close()
|
|
self.process.communicate()
|
|
|
|
thread = threading.Thread(target=target)
|
|
thread.start()
|
|
|
|
thread.join(timeout)
|
|
if thread.is_alive():
|
|
self.timeout = True
|
|
if sys.version_info < (2, 6):
|
|
os.kill(self.process.pid, signal.SIGKILL)
|
|
else:
|
|
self.process.terminate()
|
|
thread.join()
|
|
|
|
return self.process.returncode
|
|
|
|
# Test names are the C files without the .c extension.
|
|
# These have worked and should keep working always - regression tests.
|
|
# -g flag runs these.
|
|
tests_good = [
|
|
"cpu/cpu_alu/cpu_alu",
|
|
"cpu/cpu_alu/cpu_branch",
|
|
"cpu/cpu_alu/cpu_branch2",
|
|
"cpu/vfpu/colors",
|
|
"cpu/vfpu/convert",
|
|
"cpu/vfpu/gum",
|
|
"cpu/vfpu/matrix",
|
|
"cpu/vfpu/vavg",
|
|
"cpu/icache/icache",
|
|
"cpu/lsu/lsu",
|
|
"cpu/fpu/fpu",
|
|
|
|
"audio/atrac/addstreamdata",
|
|
"audio/atrac/atractest",
|
|
"audio/atrac/decode",
|
|
"audio/atrac/getremainframe",
|
|
"audio/atrac/getsoundsample",
|
|
"audio/atrac/ids",
|
|
"audio/atrac/resetpos",
|
|
"audio/atrac/resetting",
|
|
"audio/atrac/replay",
|
|
"audio/atrac/stream",
|
|
"audio/atrac/reset2",
|
|
"audio/atrac/second/resetting",
|
|
"audio/atrac/second/getinfo",
|
|
"audio/atrac/second/needed",
|
|
"audio/atrac/second/setbuffer",
|
|
"audio/atrac/setdata",
|
|
"audio/atrac/sas",
|
|
"audio/mp3/checkneeded",
|
|
"audio/mp3/getbitrate",
|
|
"audio/mp3/getchannel",
|
|
"audio/mp3/getframenum",
|
|
"audio/mp3/getloopnum",
|
|
"audio/mp3/getmaxoutput",
|
|
"audio/mp3/getmpegversion",
|
|
"audio/mp3/getsamplerate",
|
|
"audio/mp3/getsumdecoded",
|
|
"audio/mp3/initresource",
|
|
"audio/mp3/mp3test",
|
|
"audio/mp3/release",
|
|
"audio/mp3/reserve",
|
|
"audio/mp3/setloopnum",
|
|
"audio/output2/changelength",
|
|
"audio/output2/reserve",
|
|
"audio/output2/threads",
|
|
"audio/reverb/basic",
|
|
"audio/reverb/volume",
|
|
"audio/sascore/sascore",
|
|
"audio/sascore/adsrcurve",
|
|
"audio/sascore/getheight",
|
|
"audio/sascore/keyoff",
|
|
"audio/sascore/keyon",
|
|
"audio/sascore/noise",
|
|
"audio/sascore/outputmode",
|
|
"audio/sascore/pause",
|
|
"audio/sascore/pcm",
|
|
"audio/sascore/pitch",
|
|
"audio/sascore/vag",
|
|
"ctrl/ctrl",
|
|
"ctrl/idle/idle",
|
|
"ctrl/sampling/sampling",
|
|
"ctrl/sampling2/sampling2",
|
|
"ctrl/vblank",
|
|
"display/display",
|
|
"display/vblankmulti",
|
|
"display/isstate",
|
|
"display/setframebuf",
|
|
"display/setmode",
|
|
"dmac/dmactest",
|
|
"font/altcharcode",
|
|
"font/charimagerect",
|
|
"font/find",
|
|
"font/fontinfo",
|
|
"font/fontinfobyindex",
|
|
"font/fontlist",
|
|
"font/optimum",
|
|
"font/resolution",
|
|
"font/shadowimagerect",
|
|
"gpu/bounding/count",
|
|
"gpu/bounding/planes",
|
|
"gpu/bounding/vertexaddr",
|
|
"gpu/bounding/viewport",
|
|
"gpu/callbacks/ge_callbacks",
|
|
"gpu/clipping/homogeneous",
|
|
"gpu/clut/address",
|
|
"gpu/clut/masks",
|
|
"gpu/clut/offset",
|
|
"gpu/clut/shifts",
|
|
"gpu/commands/basic",
|
|
"gpu/commands/blend",
|
|
"gpu/commands/blend565",
|
|
"gpu/commands/blocktransfer",
|
|
"gpu/commands/cull",
|
|
"gpu/commands/fog",
|
|
"gpu/commands/material",
|
|
"gpu/complex/complex",
|
|
"gpu/displaylist/alignment",
|
|
"gpu/dither/dither",
|
|
"gpu/filtering/mipmaplinear",
|
|
"gpu/filtering/precisionnearest2d",
|
|
"gpu/filtering/precisionnearest3d",
|
|
"gpu/ge/break",
|
|
"gpu/ge/context",
|
|
"gpu/ge/edram",
|
|
"gpu/ge/enqueueparam",
|
|
"gpu/ge/queue",
|
|
"gpu/primitives/indices",
|
|
"gpu/primitives/invalidprim",
|
|
"gpu/primitives/points",
|
|
"gpu/primitives/rectangles",
|
|
"gpu/primitives/trianglefan",
|
|
"gpu/primitives/trianglestrip",
|
|
"gpu/primitives/triangles",
|
|
"gpu/rendertarget/copy",
|
|
"gpu/rendertarget/depal",
|
|
"gpu/signals/pause",
|
|
"gpu/signals/pause2",
|
|
"gpu/signals/suspend",
|
|
"gpu/signals/sync",
|
|
"gpu/texcolors/dxt1",
|
|
"gpu/texcolors/dxt3",
|
|
"gpu/texcolors/dxt5",
|
|
"gpu/texcolors/rgb565",
|
|
"gpu/texcolors/rgba4444",
|
|
"gpu/texcolors/rgba5551",
|
|
"gpu/texfunc/add",
|
|
"gpu/texfunc/blend",
|
|
"gpu/texfunc/decal",
|
|
"gpu/texfunc/modulate",
|
|
"gpu/texfunc/replace",
|
|
"gpu/texmtx/uvs",
|
|
"gpu/textures/mipmap",
|
|
"gpu/textures/rotate",
|
|
"gpu/transfer/invalid",
|
|
"gpu/transfer/mirrors",
|
|
"gpu/transfer/overlap",
|
|
"gpu/vertices/colors",
|
|
"gpu/vertices/morph",
|
|
# "gpu/vertices/texcoords", # See issue #19093
|
|
"hash/hash",
|
|
"hle/check_not_used_uids",
|
|
"intr/intr",
|
|
"intr/enablesub",
|
|
"intr/suspended",
|
|
"intr/vblank/vblank",
|
|
"io/cwd/cwd",
|
|
"io/open/badparent",
|
|
"jpeg/create",
|
|
"jpeg/delete",
|
|
"jpeg/finish",
|
|
"jpeg/init",
|
|
"loader/bss/bss",
|
|
"malloc/malloc",
|
|
"misc/dcache",
|
|
"misc/deadbeef",
|
|
"misc/libc",
|
|
"misc/sdkver",
|
|
"misc/testgp",
|
|
"misc/timeconv",
|
|
"misc/reg",
|
|
"mstick/mstick",
|
|
"power/cpu",
|
|
"power/power",
|
|
"power/volatile/lock",
|
|
"power/volatile/trylock",
|
|
"power/volatile/unlock",
|
|
"rtc/rtc",
|
|
"rtc/arithmetic",
|
|
"rtc/lookup",
|
|
"rtc/convert",
|
|
"string/string",
|
|
"sysmem/freesize",
|
|
"sysmem/memblock",
|
|
"sysmem/sysmem",
|
|
"sysmem/volatile",
|
|
"threads/alarm/alarm",
|
|
"threads/alarm/cancel/cancel",
|
|
"threads/alarm/refer/refer",
|
|
"threads/alarm/set/set",
|
|
"threads/callbacks/callbacks",
|
|
"threads/callbacks/check",
|
|
"threads/callbacks/create",
|
|
"threads/callbacks/delete",
|
|
"threads/callbacks/exit",
|
|
"threads/callbacks/refer",
|
|
"threads/events/events",
|
|
"threads/events/cancel/cancel",
|
|
"threads/events/clear/clear",
|
|
"threads/events/create/create",
|
|
"threads/events/delete/delete",
|
|
"threads/events/poll/poll",
|
|
"threads/events/refer/refer",
|
|
"threads/events/set/set",
|
|
"threads/events/wait/wait",
|
|
"threads/fpl/fpl",
|
|
"threads/fpl/allocate",
|
|
"threads/fpl/cancel",
|
|
"threads/fpl/create",
|
|
"threads/fpl/delete",
|
|
"threads/fpl/free",
|
|
"threads/fpl/priority",
|
|
"threads/fpl/refer",
|
|
"threads/fpl/tryallocate",
|
|
"threads/k0/k0",
|
|
"threads/lwmutex/create",
|
|
"threads/lwmutex/delete",
|
|
"threads/lwmutex/lock",
|
|
"threads/lwmutex/priority",
|
|
"threads/lwmutex/refer",
|
|
"threads/lwmutex/try",
|
|
"threads/lwmutex/try600",
|
|
"threads/lwmutex/unlock",
|
|
"threads/mbx/mbx",
|
|
"threads/mbx/cancel/cancel",
|
|
"threads/mbx/create/create",
|
|
"threads/mbx/delete/delete",
|
|
"threads/mbx/poll/poll",
|
|
"threads/mbx/priority/priority",
|
|
"threads/mbx/receive/receive",
|
|
"threads/mbx/refer/refer",
|
|
"threads/mbx/send/send",
|
|
"threads/msgpipe/msgpipe",
|
|
"threads/msgpipe/cancel",
|
|
"threads/msgpipe/create",
|
|
"threads/msgpipe/data",
|
|
"threads/msgpipe/delete",
|
|
"threads/msgpipe/receive",
|
|
"threads/msgpipe/refer",
|
|
"threads/msgpipe/send",
|
|
"threads/msgpipe/tryreceive",
|
|
"threads/msgpipe/trysend",
|
|
"threads/mutex/cancel",
|
|
"threads/mutex/create",
|
|
"threads/mutex/delete",
|
|
"threads/mutex/lock",
|
|
"threads/mutex/mutex",
|
|
"threads/mutex/priority",
|
|
"threads/mutex/refer",
|
|
"threads/mutex/try",
|
|
"threads/mutex/unlock",
|
|
"threads/mutex/unlock2",
|
|
"threads/semaphores/semaphores",
|
|
"threads/semaphores/cancel",
|
|
"threads/semaphores/create",
|
|
"threads/semaphores/delete",
|
|
"threads/semaphores/fifo",
|
|
"threads/semaphores/poll",
|
|
"threads/semaphores/priority",
|
|
"threads/semaphores/refer",
|
|
"threads/semaphores/signal",
|
|
"threads/semaphores/wait",
|
|
"threads/threads/change",
|
|
"threads/threads/exitstatus",
|
|
"threads/threads/extend",
|
|
"threads/threads/refer",
|
|
"threads/threads/release",
|
|
"threads/threads/rotate",
|
|
"threads/threads/stackfree",
|
|
"threads/threads/start",
|
|
"threads/threads/suspend",
|
|
"threads/threads/threadend",
|
|
"threads/threads/threadmanidlist",
|
|
"threads/threads/threadmanidtype",
|
|
"threads/threads/threads",
|
|
"threads/tls/create",
|
|
"threads/tls/delete",
|
|
"threads/tls/get",
|
|
"threads/tls/free",
|
|
"threads/tls/priority",
|
|
"threads/tls/refer",
|
|
"threads/vpl/allocate",
|
|
"threads/vpl/cancel",
|
|
"threads/vpl/delete",
|
|
"threads/vpl/fifo",
|
|
"threads/vpl/free",
|
|
"threads/vpl/order",
|
|
"threads/vpl/priority",
|
|
"threads/vpl/refer",
|
|
"threads/vpl/try",
|
|
"threads/vpl/vpl",
|
|
"threads/vtimers/vtimer",
|
|
"threads/vtimers/cancelhandler",
|
|
"threads/vtimers/create",
|
|
"threads/vtimers/delete",
|
|
"threads/vtimers/getbase",
|
|
"threads/vtimers/gettime",
|
|
"threads/vtimers/interrupt",
|
|
"threads/vtimers/refer",
|
|
"threads/vtimers/sethandler",
|
|
"threads/vtimers/settime",
|
|
"threads/vtimers/start",
|
|
"threads/vtimers/stop",
|
|
"threads/wakeup/wakeup",
|
|
"utility/msgdialog/abort",
|
|
"utility/savedata/autosave",
|
|
"utility/savedata/filelist",
|
|
"utility/savedata/makedata",
|
|
"umd/callbacks/umd",
|
|
"umd/register",
|
|
"video/mpeg/ringbuffer/avail",
|
|
"video/mpeg/ringbuffer/construct",
|
|
"video/mpeg/ringbuffer/destruct",
|
|
"video/mpeg/ringbuffer/memsize",
|
|
"video/mpeg/ringbuffer/packnum",
|
|
"video/psmfplayer/break",
|
|
"video/psmfplayer/create",
|
|
"video/psmfplayer/delete",
|
|
"video/psmfplayer/getaudiodata",
|
|
"video/psmfplayer/getaudiooutsize",
|
|
"video/psmfplayer/getcurrentpts",
|
|
"video/psmfplayer/getcurrentstatus",
|
|
"video/psmfplayer/getcurrentstream",
|
|
"video/psmfplayer/getpsmfinfo",
|
|
"video/psmfplayer/releasepsmf",
|
|
"video/psmfplayer/selectspecific",
|
|
"video/psmfplayer/setpsmf",
|
|
"video/psmfplayer/settempbuf",
|
|
"video/psmfplayer/stop",
|
|
]
|
|
|
|
# Broken tests
|
|
# -b flag runs these.
|
|
tests_next = [
|
|
# These are the next tests up for fixing. These run by default.
|
|
"cpu/fpu/fcr",
|
|
"cpu/vfpu/prefixes",
|
|
"cpu/vfpu/vector",
|
|
"cpu/vfpu/vregs",
|
|
"audio/sceaudio/datalen",
|
|
"audio/sceaudio/output",
|
|
"audio/sceaudio/reserve",
|
|
"audio/sascore/setadsr",
|
|
"audio/mp3/infotoadd",
|
|
"audio/mp3/init",
|
|
"audio/mp3/notifyadd",
|
|
"audio/output2/frequency",
|
|
"audio/output2/release",
|
|
"audio/output2/rest",
|
|
"ccc/convertstring",
|
|
"display/hcount",
|
|
"font/fonttest",
|
|
"font/charglyphimage",
|
|
"font/charglyphimageclip",
|
|
"font/charinfo",
|
|
"font/newlib",
|
|
"font/open",
|
|
"font/openfile",
|
|
"font/openmem",
|
|
"font/shadowglyphimage",
|
|
"font/shadowglyphimageclip",
|
|
"font/shadowinfo",
|
|
"gpu/clipping/guardband",
|
|
"gpu/commands/light",
|
|
"gpu/depth/precision",
|
|
"gpu/displaylist/state",
|
|
"gpu/filtering/linear",
|
|
"gpu/filtering/nearest",
|
|
# These two pass with --graphics=software, but still fail on the hardware backends,
|
|
# so they stay here rather than in tests_good until those match too.
|
|
"gpu/filtering/precisionlinear2d",
|
|
"gpu/filtering/precisionlinear3d",
|
|
"gpu/ge/edramswizzle",
|
|
"gpu/ge/get",
|
|
"gpu/primitives/bezier",
|
|
# Passes with --graphics=software, still fails on the hardware backends.
|
|
"gpu/primitives/continue",
|
|
"gpu/primitives/immediate",
|
|
"gpu/primitives/lines",
|
|
"gpu/primitives/linestrip",
|
|
"gpu/primitives/spline",
|
|
"gpu/reflection/reflection",
|
|
"gpu/rendertarget/rendertarget",
|
|
"gpu/signals/continue",
|
|
"gpu/signals/jumps",
|
|
"gpu/signals/simple",
|
|
"gpu/simple/simple",
|
|
"gpu/texmtx/normals",
|
|
"gpu/texmtx/prims",
|
|
"gpu/texmtx/source",
|
|
"gpu/textures/size",
|
|
"gpu/triangle/triangle",
|
|
"intr/registersub",
|
|
"intr/releasesub",
|
|
"intr/waits",
|
|
"io/directory/directory",
|
|
"io/file/file",
|
|
"io/file/rename",
|
|
"io/io/io",
|
|
"io/iodrv/iodrv",
|
|
"io/open/tty0",
|
|
"jpeg/csc",
|
|
"jpeg/decode",
|
|
"jpeg/decodes",
|
|
"jpeg/decodeycbcr",
|
|
"jpeg/decodeycbcrs",
|
|
"jpeg/getoutputinfo",
|
|
"jpeg/mjpegcsc",
|
|
# Doesn't work on a PSP for security reasons, hangs in PPSSPP currently.
|
|
# Commented out to make tests run much faster.
|
|
#"modules/loadexec/loader",
|
|
"net/http/http",
|
|
"net/primary/ether",
|
|
"power/freq",
|
|
"sysmem/partition",
|
|
"threads/callbacks/cancel",
|
|
"threads/callbacks/count",
|
|
"threads/callbacks/notify",
|
|
# These two mbx tests only appeared to work because they papered over bugs
|
|
|
|
|
|
"threads/scheduling/dispatch",
|
|
"threads/scheduling/scheduling",
|
|
"threads/threads/create",
|
|
"threads/threads/terminate",
|
|
"threads/vpl/create",
|
|
"umd/io/umd_io",
|
|
"umd/raw_access/raw_access",
|
|
"umd/wait/wait",
|
|
"utility/msgdialog/dialog",
|
|
"utility/savedata/getsize",
|
|
"utility/savedata/idlist",
|
|
# These tests appear to be broken and just hang.
|
|
#"utility/savedata/deletebroken",
|
|
#"utility/savedata/deletedata",
|
|
#"utility/savedata/deleteemptyfilename",
|
|
#"utility/savedata/loadbroken",
|
|
#"utility/savedata/loaddata",
|
|
#"utility/savedata/loademptyfilename",
|
|
#"utility/savedata/saveemptyfilename",
|
|
"utility/savedata/secureversion",
|
|
"utility/savedata/sizes",
|
|
"utility/systemparam/systemparam",
|
|
"video/mpeg/basic",
|
|
"video/pmf/pmf",
|
|
"video/pmf_simple/pmf_simple",
|
|
"video/psmfplayer/basic",
|
|
"video/psmfplayer/configplayer",
|
|
"video/psmfplayer/getvideodata",
|
|
"video/psmfplayer/playmode",
|
|
"video/psmfplayer/selectstream",
|
|
"video/psmfplayer/setpsmfoffset",
|
|
"video/psmfplayer/start",
|
|
"video/psmfplayer/update",
|
|
]
|
|
|
|
|
|
# These are the tests we ignore (not important, or impossible to run)
|
|
tests_ignored = [
|
|
"kirk/kirk",
|
|
"me/me",
|
|
]
|
|
|
|
|
|
|
|
def init():
|
|
global PPSSPP_EXE, TEST_ROOT
|
|
if not os.path.exists("pspautotests"):
|
|
if os.path.exists(os.path.dirname(__file__) + "/pspautotests"):
|
|
TEST_ROOT = os.path.dirname(__file__) + "/pspautotests/tests/";
|
|
else:
|
|
print("Please run git submodule init; git submodule update;")
|
|
sys.exit(1)
|
|
|
|
if not os.path.exists(TEST_ROOT + "cpu/cpu_alu/cpu_alu.prx"):
|
|
print("Please install the pspsdk and run make in common/ and in all the tests")
|
|
print("(checked for existence of cpu/cpu_alu/cpu_alu.prx)")
|
|
sys.exit(1)
|
|
|
|
possible_exes = [glob.glob(f) for f in PPSSPP_EXECUTABLES]
|
|
possible_exes = [x for sublist in possible_exes for x in sublist]
|
|
existing = filter(os.path.exists, possible_exes)
|
|
if existing:
|
|
PPSSPP_EXE = max((os.path.getmtime(f), f) for f in existing)[1]
|
|
else:
|
|
PPSSPP_EXE = None
|
|
|
|
if not PPSSPP_EXE:
|
|
print("PPSSPPHeadless executable missing, please build one.")
|
|
sys.exit(1)
|
|
|
|
def run_tests(test_list, args):
|
|
global PPSSPP_EXE, TIMEOUT
|
|
returncode = 0
|
|
|
|
test_filenames = []
|
|
for test in test_list:
|
|
# Try prx first
|
|
elf_filename = TEST_ROOT + test + ".prx"
|
|
if not os.path.exists(elf_filename):
|
|
print("WARNING: no prx, trying elf")
|
|
elf_filename = TEST_ROOT + test + ".elf"
|
|
|
|
test_filenames.append(elf_filename)
|
|
|
|
if len(test_filenames):
|
|
# TODO: Maybe --compare should detect --graphics?
|
|
cmdline = [PPSSPP_EXE, '--root', TEST_ROOT + '../', '--compare', '--timeout=' + str(TIMEOUT), '@-']
|
|
cmdline.extend([i for i in args if i not in ['-g', '-m', '-b']])
|
|
|
|
c = Command(cmdline, '\n'.join(test_filenames))
|
|
returncode = c.run(TIMEOUT * len(test_filenames))
|
|
|
|
print("Ran " + ' '.join(cmdline))
|
|
|
|
return returncode
|
|
|
|
def main():
|
|
init()
|
|
tests = []
|
|
args = []
|
|
teamcity = False
|
|
for arg in sys.argv[1:]:
|
|
if arg == '--teamcity':
|
|
args.append(arg)
|
|
teamcity = True
|
|
elif arg[0] == '-':
|
|
args.append(arg)
|
|
else:
|
|
tests.append(arg)
|
|
|
|
if not tests:
|
|
if '-g' in args:
|
|
tests = tests_good
|
|
elif '-b' in args:
|
|
tests = tests_next
|
|
else:
|
|
tests = tests_next + tests_good
|
|
elif '-m' in args and '-g' in args:
|
|
tests = [i for i in tests_good if i.startswith(tests[0])]
|
|
elif '-m' in args and '-b' in args:
|
|
tests = [i for i in tests_next if i.startswith(tests[0])]
|
|
elif '-m' in args:
|
|
tests = [i for i in tests_next + tests_good if i.startswith(tests[0])]
|
|
|
|
returncode = run_tests(tests, args)
|
|
if teamcity:
|
|
return 0
|
|
return returncode
|
|
|
|
exit(main())
|