mirror of https://github.com/mgba-emu/mgba.git
Test: Add initial configuration bits to CInema
This commit is contained in:
parent
7b32b2a63a
commit
e1bd52a3d0
|
@ -11,6 +11,7 @@
|
||||||
#include <mgba/feature/video-logger.h>
|
#include <mgba/feature/video-logger.h>
|
||||||
|
|
||||||
#include <mgba-util/png-io.h>
|
#include <mgba-util/png-io.h>
|
||||||
|
#include <mgba-util/table.h>
|
||||||
#include <mgba-util/vector.h>
|
#include <mgba-util/vector.h>
|
||||||
#include <mgba-util/vfs.h>
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
|
@ -66,7 +67,10 @@ static bool dryRun = false;
|
||||||
static int verbosity = 0;
|
static int verbosity = 0;
|
||||||
|
|
||||||
bool CInemaTestInit(struct CInemaTest*, const char* directory, const char* filename);
|
bool CInemaTestInit(struct CInemaTest*, const char* directory, const char* filename);
|
||||||
void CInemaTestRun(struct CInemaTest*);
|
void CInemaTestRun(struct CInemaTest*, struct Table* configTree);
|
||||||
|
|
||||||
|
bool CInemaConfigGetUInt(struct Table* configTree, const char* testName, const char* key, unsigned* value);
|
||||||
|
void CInemaConfigLoad(struct Table* configTree, const char* testName, struct mCore* core);
|
||||||
|
|
||||||
static void _log(struct mLogger* log, int category, enum mLogLevel level, const char* format, va_list args);
|
static void _log(struct mLogger* log, int category, enum mLogLevel level, const char* format, va_list args);
|
||||||
|
|
||||||
|
@ -207,6 +211,101 @@ static void reduceTestList(struct CInemaTestList* tests) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testToPath(const char* testName, char* path) {
|
||||||
|
strncpy(path, base, PATH_MAX);
|
||||||
|
|
||||||
|
bool dotSeen = true;
|
||||||
|
size_t i;
|
||||||
|
for (i = strlen(path); testName[0] && i < PATH_MAX; ++testName) {
|
||||||
|
if (testName[0] == '.') {
|
||||||
|
dotSeen = true;
|
||||||
|
} else {
|
||||||
|
if (dotSeen) {
|
||||||
|
strncpy(&path[i], PATH_SEP, PATH_MAX - i);
|
||||||
|
i += strlen(PATH_SEP);
|
||||||
|
dotSeen = false;
|
||||||
|
if (!i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path[i] = testName[0];
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _loadConfigTree(struct Table* configTree, const char* testName) {
|
||||||
|
char key[MAX_TEST];
|
||||||
|
strncpy(key, testName, sizeof(key));
|
||||||
|
|
||||||
|
struct mCoreConfig* config;
|
||||||
|
while (!(config = HashTableLookup(configTree, key))) {
|
||||||
|
char path[PATH_MAX - 1];
|
||||||
|
config = malloc(sizeof(*config));
|
||||||
|
mCoreConfigInit(config, "cinema");
|
||||||
|
testToPath(key, path);
|
||||||
|
strncat(path, PATH_SEP, sizeof(path) - 1);
|
||||||
|
strncat(path, "config.ini", sizeof(path) - 1);
|
||||||
|
mCoreConfigLoadPath(config, path);
|
||||||
|
HashTableInsert(configTree, key, config);
|
||||||
|
char* pos = strrchr(key, '.');
|
||||||
|
if (!pos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos[0] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _unloadConfigTree(const char* key, void* value, void* user) {
|
||||||
|
UNUSED(key);
|
||||||
|
UNUSED(user);
|
||||||
|
mCoreConfigDeinit(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* _lookupValue(struct Table* configTree, const char* testName, const char* key) {
|
||||||
|
_loadConfigTree(configTree, testName);
|
||||||
|
|
||||||
|
char testKey[MAX_TEST];
|
||||||
|
strncpy(testKey, testName, sizeof(testKey));
|
||||||
|
|
||||||
|
struct mCoreConfig* config;
|
||||||
|
while (true) {
|
||||||
|
config = HashTableLookup(configTree, testKey);
|
||||||
|
if (!config) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const char* str = ConfigurationGetValue(&config->configTable, "testinfo", key);
|
||||||
|
if (str) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
char* pos = strrchr(testKey, '.');
|
||||||
|
if (!pos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos[0] = '\0';
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CInemaConfigGetUInt(struct Table* configTree, const char* testName, const char* key, unsigned* out) {
|
||||||
|
const char* charValue = _lookupValue(configTree, testName, key);
|
||||||
|
if (!charValue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char* end;
|
||||||
|
unsigned long value = strtoul(charValue, &end, 10);
|
||||||
|
if (*end) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CInemaConfigLoad(struct Table* configTree, const char* testName, struct mCore* core) {
|
||||||
|
_loadConfigTree(configTree, testName);
|
||||||
|
// TODO: Write
|
||||||
|
}
|
||||||
|
|
||||||
bool CInemaTestInit(struct CInemaTest* test, const char* directory, const char* filename) {
|
bool CInemaTestInit(struct CInemaTest* test, const char* directory, const char* filename) {
|
||||||
if (strncmp(base, directory, strlen(base)) != 0) {
|
if (strncmp(base, directory, strlen(base)) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -223,7 +322,7 @@ bool CInemaTestInit(struct CInemaTest* test, const char* directory, const char*
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInemaTestRun(struct CInemaTest* test) {
|
void CInemaTestRun(struct CInemaTest* test, struct Table* configTree) {
|
||||||
struct VDir* dir = VDirOpen(test->directory);
|
struct VDir* dir = VDirOpen(test->directory);
|
||||||
if (!dir) {
|
if (!dir) {
|
||||||
CIerr(0, "Failed to open test directory\n");
|
CIerr(0, "Failed to open test directory\n");
|
||||||
|
@ -261,14 +360,25 @@ void CInemaTestRun(struct CInemaTest* test) {
|
||||||
core->setVideoBuffer(core, buffer, width);
|
core->setVideoBuffer(core, buffer, width);
|
||||||
mCoreConfigInit(&core->config, "cinema");
|
mCoreConfigInit(&core->config, "cinema");
|
||||||
|
|
||||||
|
unsigned limit = 9999;
|
||||||
|
unsigned skip = 0;
|
||||||
|
unsigned fail = 0;
|
||||||
|
|
||||||
|
CInemaConfigGetUInt(configTree, test->name, "frames", &limit);
|
||||||
|
CInemaConfigGetUInt(configTree, test->name, "skip", &skip);
|
||||||
|
CInemaConfigGetUInt(configTree, test->name, "fail", &fail);
|
||||||
|
CInemaConfigLoad(configTree, test->name, core);
|
||||||
|
|
||||||
core->loadROM(core, rom);
|
core->loadROM(core, rom);
|
||||||
core->reset(core);
|
core->reset(core);
|
||||||
|
|
||||||
test->status = CI_PASS;
|
test->status = CI_PASS;
|
||||||
|
|
||||||
unsigned minFrame = core->frameCounter(core);
|
unsigned minFrame = core->frameCounter(core);
|
||||||
unsigned limit = 9999;
|
|
||||||
size_t frame;
|
size_t frame;
|
||||||
|
for (frame = 0; frame < skip; ++frame) {
|
||||||
|
core->runFrame(core);
|
||||||
|
}
|
||||||
for (frame = 0; limit; ++frame, --limit) {
|
for (frame = 0; limit; ++frame, --limit) {
|
||||||
char baselineName[32];
|
char baselineName[32];
|
||||||
snprintf(baselineName, sizeof(baselineName), "baseline_%04" PRIz "u.png", frame);
|
snprintf(baselineName, sizeof(baselineName), "baseline_%04" PRIz "u.png", frame);
|
||||||
|
@ -345,7 +455,16 @@ void CInemaTestRun(struct CInemaTest* test) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fail) {
|
||||||
|
if (test->status == CI_FAIL) {
|
||||||
|
test->status = CI_XFAIL;
|
||||||
|
} else if (test->status == CI_PASS) {
|
||||||
|
test->status = CI_XPASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
mCoreConfigDeinit(&core->config);
|
||||||
core->deinit(core);
|
core->deinit(core);
|
||||||
dir->close(dir);
|
dir->close(dir);
|
||||||
}
|
}
|
||||||
|
@ -395,27 +514,7 @@ int main(int argc, char** argv) {
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < (size_t) argc; ++i) {
|
for (i = 0; i < (size_t) argc; ++i) {
|
||||||
char path[PATH_MAX + 1] = {0};
|
char path[PATH_MAX + 1] = {0};
|
||||||
char* arg = argv[i];
|
testToPath(argv[i], path);
|
||||||
strncpy(path, base, sizeof(path));
|
|
||||||
|
|
||||||
bool dotSeen = true;
|
|
||||||
size_t j;
|
|
||||||
for (arg = argv[i], j = strlen(path); arg[0] && j < sizeof(path); ++arg) {
|
|
||||||
if (arg[0] == '.') {
|
|
||||||
dotSeen = true;
|
|
||||||
} else {
|
|
||||||
if (dotSeen) {
|
|
||||||
strncpy(&path[j], PATH_SEP, sizeof(path) - j);
|
|
||||||
j += strlen(PATH_SEP);
|
|
||||||
dotSeen = false;
|
|
||||||
if (!j) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path[j] = arg[0];
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!collectTests(&tests, path)) {
|
if (!collectTests(&tests, path)) {
|
||||||
status = 1;
|
status = 1;
|
||||||
|
@ -433,6 +532,9 @@ int main(int argc, char** argv) {
|
||||||
reduceTestList(&tests);
|
reduceTestList(&tests);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Table configTree;
|
||||||
|
HashTableInit(&configTree, 0, free);
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < CInemaTestListSize(&tests); ++i) {
|
for (i = 0; i < CInemaTestListSize(&tests); ++i) {
|
||||||
struct CInemaTest* test = CInemaTestListGetPointer(&tests, i);
|
struct CInemaTest* test = CInemaTestListGetPointer(&tests, i);
|
||||||
|
@ -440,7 +542,7 @@ int main(int argc, char** argv) {
|
||||||
CIlog(-1, "%s\n", test->name);
|
CIlog(-1, "%s\n", test->name);
|
||||||
} else {
|
} else {
|
||||||
CIerr(1, "%s: ", test->name);
|
CIerr(1, "%s: ", test->name);
|
||||||
CInemaTestRun(test);
|
CInemaTestRun(test, &configTree);
|
||||||
switch (test->status) {
|
switch (test->status) {
|
||||||
case CI_PASS:
|
case CI_PASS:
|
||||||
CIerr(1, "pass");
|
CIerr(1, "pass");
|
||||||
|
@ -467,6 +569,8 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashTableEnumerate(&configTree, _unloadConfigTree, NULL);
|
||||||
|
HashTableDeinit(&configTree);
|
||||||
CInemaTestListDeinit(&tests);
|
CInemaTestListDeinit(&tests);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
Loading…
Reference in New Issue