2017-09-26 08:59:34 +02:00
|
|
|
// MIT License
|
|
|
|
|
|
|
|
// Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com
|
|
|
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
|
|
// copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
// SOFTWARE.
|
|
|
|
|
|
|
|
#include "run.h"
|
|
|
|
#include "console.h"
|
|
|
|
#include "fs.h"
|
|
|
|
#include "ext/md5.h"
|
|
|
|
|
|
|
|
static void onTrace(void* data, const char* text, u8 color)
|
|
|
|
{
|
|
|
|
Run* run = (Run*)data;
|
|
|
|
|
|
|
|
run->console->trace(run->console, text, color);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onError(void* data, const char* info)
|
|
|
|
{
|
|
|
|
Run* run = (Run*)data;
|
|
|
|
|
|
|
|
setStudioMode(TIC_CONSOLE_MODE);
|
|
|
|
run->console->error(run->console, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onExit(void* data)
|
|
|
|
{
|
|
|
|
Run* run = (Run*)data;
|
|
|
|
|
|
|
|
run->exit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char* data2md5(const void* data, s32 length)
|
|
|
|
{
|
|
|
|
const char *str = data;
|
|
|
|
MD5_CTX c;
|
|
|
|
|
|
|
|
static char out[33];
|
|
|
|
|
|
|
|
MD5_Init(&c);
|
|
|
|
|
|
|
|
while (length > 0)
|
|
|
|
{
|
|
|
|
MD5_Update(&c, str, length > 512 ? 512: length);
|
|
|
|
|
|
|
|
length -= 512;
|
|
|
|
str += 512;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
u8 digest[16];
|
|
|
|
MD5_Final(digest, &c);
|
|
|
|
|
|
|
|
for (s32 n = 0; n < 16; ++n)
|
|
|
|
snprintf(&(out[n*2]), 16*2, "%02x", (u32)digest[n]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char* getPMemName(Run* run)
|
|
|
|
{
|
|
|
|
static char buffer[FILENAME_MAX];
|
|
|
|
|
2017-11-06 15:27:42 +01:00
|
|
|
const char* data = strlen(run->tic->saveid) ? run->tic->saveid : run->tic->code.data;
|
2017-09-26 08:59:34 +02:00
|
|
|
char* md5 = data2md5(data, (s32)strlen(data));
|
|
|
|
strcpy(buffer, TIC_LOCAL);
|
|
|
|
strcat(buffer, md5);
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tick(Run* run)
|
|
|
|
{
|
2017-11-08 12:07:23 +01:00
|
|
|
// tic_mem* tic = run->tic;
|
2017-11-06 15:27:42 +01:00
|
|
|
|
2017-09-26 08:59:34 +02:00
|
|
|
while(pollEvent());
|
|
|
|
|
|
|
|
if (getStudioMode() != TIC_RUN_MODE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(!run->init)
|
|
|
|
{
|
2017-11-08 12:07:23 +01:00
|
|
|
if(processDoFile())
|
|
|
|
return;
|
|
|
|
|
2017-09-26 08:59:34 +02:00
|
|
|
run->tickData.start = run->tickData.counter(),
|
|
|
|
run->init = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
run->tic->api.tick(run->tic, &run->tickData);
|
|
|
|
|
|
|
|
enum {Size = sizeof(tic_persistent)};
|
|
|
|
|
|
|
|
if(SDL_memcmp(&run->tic->ram.persistent, run->persistent, Size) != 0)
|
|
|
|
{
|
|
|
|
fsSaveRootFile(run->console->fs, getPMemName(run), &run->tic->ram.persistent, Size, true);
|
|
|
|
|
|
|
|
SDL_memcpy(run->persistent, &run->tic->ram.persistent, Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(run->exit)
|
|
|
|
setStudioMode(TIC_CONSOLE_MODE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void initRun(Run* run, Console* console, tic_mem* tic)
|
|
|
|
{
|
|
|
|
*run = (Run)
|
|
|
|
{
|
|
|
|
.tic = tic,
|
|
|
|
.console = console,
|
|
|
|
.tick = tick,
|
|
|
|
.exit = false,
|
|
|
|
.init = false,
|
|
|
|
.tickData =
|
|
|
|
{
|
|
|
|
.error = onError,
|
|
|
|
.trace = onTrace,
|
|
|
|
.counter = SDL_GetPerformanceCounter,
|
|
|
|
.freq = SDL_GetPerformanceFrequency,
|
|
|
|
.start = 0,
|
|
|
|
.data = run,
|
|
|
|
.exit = onExit,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
{
|
|
|
|
enum {Size = sizeof(tic_persistent)};
|
|
|
|
SDL_memset(&run->tic->ram.persistent, 0, Size);
|
|
|
|
|
|
|
|
s32 size = 0;
|
|
|
|
void* data = fsLoadRootFile(run->console->fs, getPMemName(run), &size);
|
|
|
|
|
|
|
|
if(size == Size && data)
|
|
|
|
{
|
|
|
|
SDL_memcpy(&run->tic->ram.persistent, data, Size);
|
|
|
|
SDL_memcpy(run->persistent, data, Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(data) SDL_free(data);
|
|
|
|
}
|
|
|
|
}
|