<commit_before>//------------------------------------------------------------------------------
//  main.cc
//  yakc app main source.
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/Main.h"
#include "Core/String/StringBuilder.h"
#include "Core/Time/Clock.h"
#include "Gfx/Gfx.h"
#include "Input/Input.h"
#include "IO/IO.h"
#include "HttpFS/HTTPFileSystem.h"
#include "yakc/yakc.h"
#include "yakc/systems/kc85.h"
#include "yakc_oryol/Draw.h"
#include "yakc_oryol/Audio.h"
#include "yakc_oryol/Keyboard.h"
#if YAKC_UI
#include "yakc_ui/UI.h"
#endif
#include "yakc/roms/rom_dumps.h"
#if ORYOL_EMSCRIPTEN
#include <emscripten/emscripten.h>
#endif

using namespace Oryol;
using namespace YAKC;

class YakcApp : public App {
public:
    static YakcApp* self;
    YakcApp() { self = this; };
    ~YakcApp() { self = nullptr; };
    AppState::Code OnInit();
    AppState::Code OnRunning();
    AppState::Code OnCleanup();
    void initRoms();
    void initModules();

    yakc emu;
    Draw draw;
    Audio audio;
    Keyboard keyboard;
    #if YAKC_UI
    UI ui;
    #endif
    TimePoint lapTimePoint;
};
OryolMain(YakcApp);

YakcApp* YakcApp::self = nullptr;

//------------------------------------------------------------------------------
AppState::Code
YakcApp::OnInit() {

    // setup IO system for loading from webserver
    #if ORYOL_DEBUG
    String baseUrl = "http://localhost:8000/";
    #elif ORYOL_EMSCRIPTEN
    // ok, this is strange, why is the github URL different from Oryol??
    String baseUrl = "http://floooh.github.com/";
    #else
    String baseUrl = "http://floooh.github.com/virtualkc/";
    #endif
    IOSetup ioSetup;
    ioSetup.FileSystems.Add("http", HTTPFileSystem::Creator());
    ioSetup.Assigns.Add("kcc:", baseUrl);
    ioSetup.Assigns.Add("rom:", baseUrl);
    IO::Setup(ioSetup);

    // we only need few resources, so don't waste memory
    const int frameSizeX = 24;
    const int frameSizeY = 8;
    const int width = 2*frameSizeX + 2*320;
    const int height = 2*frameSizeY + 2*256;
    auto gfxSetup = GfxSetup::Window(width, height, "YAKC Emulator");
    gfxSetup.ResourcePoolSize[GfxResourceType::Mesh] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Texture] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Pipeline] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Shader] = 8;
    gfxSetup.HtmlTrackElementSize = true;
    gfxSetup.HtmlElement = "canvas";
    Gfx::Setup(gfxSetup);
    Input::Setup();

    // initialize Oryol platform wrappers
    this->draw.Setup(gfxSetup, frameSizeX, frameSizeY);
    this->audio.Setup(&this->emu);
    this->keyboard.Setup(this->emu);

    // initialize the emulator
    ext_funcs sys_funcs;
    sys_funcs.assertmsg_func = Oryol::Log::AssertMsg;
    sys_funcs.malloc_func = [] (size_t s) -> void* { return Oryol::Memory::Alloc((int)s); };
    sys_funcs.free_func = [] (void* p) { Oryol::Memory::Free(p); };
    this->emu.init(sys_funcs);

    // initialize the ROM dumps and modules
    this->initRoms();

    // switch the emulator on
    this->emu.poweron(YAKC::system::kc85_3, os_rom::caos_3_1);

    #if YAKC_UI
    this->ui.Setup(this->emu, &this->audio);
    #endif

    // on KC85/3 put a 16kByte module into slot 8 by default, CAOS will initialize
    // this automatically on startup
    this->initModules();
    if (kc85.on) {
        kc85.exp.insert_module(0x08, kc85_exp::m022_16kbyte);
    }

    this->lapTimePoint = Clock::Now();

    return AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
YakcApp::OnRunning() {
    #if ORYOL_DEBUG
    Duration frameTime = Duration::FromSeconds(1.0/60.0);
    #else
    Duration frameTime = Clock::LapTime(this->lapTimePoint);
    #endif

    #if YAKC_UI
    // toggle UI?
    if (Input::KeyDown(Key::Tab)) {
        this->ui.Toggle();
    }
    // check if a text dump is ready to feed into keyboard handler
    if (this->ui.FileLoader.State == FileLoader::TextReady) {
        this->keyboard.StartPlayback(this->ui.FileLoader.ObtainTextBuffer());
    }
    // don't handle KC input if IMGUI has the keyboard focus
    if (!ImGui::GetIO().WantCaptureKeyboard) {
        this->keyboard.HandleInput();
    }
    #else
    this->keyboard.HandleInput();
    #endif

    int micro_secs = (int) frameTime.AsMicroSeconds();
    uint64_t processed_audio_cycles = this->audio.GetProcessedCycles();
    TimePoint emu_start_time = Clock::Now();
    #if YAKC_UI
        // keep CPU synchronized to a small time window ahead of audio playback
        this->emu.exec(micro_secs, processed_audio_cycles);
        this->draw.UpdateParams(
            this->ui.Settings.crtEffect,
            this->ui.Settings.colorTV,<commit_msg>don't feed input while ImGui has the focus<commit_after>//------------------------------------------------------------------------------
//  main.cc
//  yakc app main source.
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/Main.h"
#include "Core/String/StringBuilder.h"
#include "Core/Time/Clock.h"
#include "Gfx/Gfx.h"
#include "Input/Input.h"
#include "IO/IO.h"
#include "HttpFS/HTTPFileSystem.h"
#include "yakc/yakc.h"
#include "yakc/systems/kc85.h"
#include "yakc_oryol/Draw.h"
#include "yakc_oryol/Audio.h"
#include "yakc_oryol/Keyboard.h"
#if YAKC_UI
#include "yakc_ui/UI.h"
#endif
#include "yakc/roms/rom_dumps.h"
#if ORYOL_EMSCRIPTEN
#include <emscripten/emscripten.h>
#endif

using namespace Oryol;
using namespace YAKC;

class YakcApp : public App {
public:
    static YakcApp* self;
    YakcApp() { self = this; };
    ~YakcApp() { self = nullptr; };
    AppState::Code OnInit();
    AppState::Code OnRunning();
    AppState::Code OnCleanup();
    void initRoms();
    void initModules();

    yakc emu;
    Draw draw;
    Audio audio;
    Keyboard keyboard;
    #if YAKC_UI
    UI ui;
    #endif
    TimePoint lapTimePoint;
};
OryolMain(YakcApp);

YakcApp* YakcApp::self = nullptr;

//------------------------------------------------------------------------------
AppState::Code
YakcApp::OnInit() {

    // setup IO system for loading from webserver
    #if ORYOL_DEBUG
    String baseUrl = "http://localhost:8000/";
    #elif ORYOL_EMSCRIPTEN
    // ok, this is strange, why is the github URL different from Oryol??
    String baseUrl = "http://floooh.github.com/";
    #else
    String baseUrl = "http://floooh.github.com/virtualkc/";
    #endif
    IOSetup ioSetup;
    ioSetup.FileSystems.Add("http", HTTPFileSystem::Creator());
    ioSetup.Assigns.Add("kcc:", baseUrl);
    ioSetup.Assigns.Add("rom:", baseUrl);
    IO::Setup(ioSetup);

    // we only need few resources, so don't waste memory
    const int frameSizeX = 24;
    const int frameSizeY = 8;
    const int width = 2*frameSizeX + 2*320;
    const int height = 2*frameSizeY + 2*256;
    auto gfxSetup = GfxSetup::Window(width, height, "YAKC Emulator");
    gfxSetup.ResourcePoolSize[GfxResourceType::Mesh] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Texture] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Pipeline] = 8;
    gfxSetup.ResourcePoolSize[GfxResourceType::Shader] = 8;
    gfxSetup.HtmlTrackElementSize = true;
    gfxSetup.HtmlElement = "canvas";
    Gfx::Setup(gfxSetup);
    Input::Setup();

    // initialize Oryol platform wrappers
    this->draw.Setup(gfxSetup, frameSizeX, frameSizeY);
    this->audio.Setup(&this->emu);
    this->keyboard.Setup(this->emu);

    // initialize the emulator
    ext_funcs sys_funcs;
    sys_funcs.assertmsg_func = Oryol::Log::AssertMsg;
    sys_funcs.malloc_func = [] (size_t s) -> void* { return Oryol::Memory::Alloc((int)s); };
    sys_funcs.free_func = [] (void* p) { Oryol::Memory::Free(p); };
    this->emu.init(sys_funcs);

    // initialize the ROM dumps and modules
    this->initRoms();

    // switch the emulator on
    this->emu.poweron(YAKC::system::kc85_3, os_rom::caos_3_1);

    #if YAKC_UI
    this->ui.Setup(this->emu, &this->audio);
    #endif

    // on KC85/3 put a 16kByte module into slot 8 by default, CAOS will initialize
    // this automatically on startup
    this->initModules();
    if (kc85.on) {
        kc85.exp.insert_module(0x08, kc85_exp::m022_16kbyte);
    }

    this->lapTimePoint = Clock::Now();

    return AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
YakcApp::OnRunning() {
    #if ORYOL_DEBUG
    Duration frameTime = Duration::FromSeconds(1.0/60.0);
    #else
    Duration frameTime = Clock::LapTime(this->lapTimePoint);
    #endif

    #if YAKC_UI
    // toggle UI?
    if (Input::KeyDown(Key::Tab)) {
        this->ui.Toggle();
    }
    // check if a text dump is ready to feed into keyboard handler
    if (this->ui.FileLoader.State == FileLoader::TextReady) {
        this->keyboard.StartPlayback(this->ui.FileLoader.ObtainTextBuffer());
    }
    // don't handle KC input if IMGUI has the keyboard focus
    this->keyboard.hasInputFocus = !ImGui::GetIO().WantCaptureKeyboard;
    #endif
    this->keyboard.HandleInput();

    int micro_secs = (int) frameTime.AsMicroSeconds();
    uint64_t processed_audio_cycles = this->audio.GetProcessedCycles();
    TimePoint emu_start_time = Clock::Now();
    #if YAKC_UI
        // keep CPU synchronized to a small time window ahead of audio playback
        this->emu.exec(micro_secs, processed_audio_cycles);
        this->draw.UpdateParams(
            this->ui.Settings.crtEffect,
            this->ui.Settings.colorTV,
{'fraction_non_alphanumeric': 0.19417779632721202, 'fraction_numerical': 0.011477462437395659, 'mean_word_length': 2.5912326714125142, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2806251', 'n_tokens_mistral': 3306, 'n_tokens_neox': 3181, 'n_words': 678}