TIC-80-guile/src/run.c

160 lines
3.5 KiB
C
Raw Normal View History

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);
}
}