Beispiel #1
0
static void* nes_thread_proc(void *param)
{
    NES *nes = (NES*)param;
    int totalpclk, nmi, irq;

    while (!nes->thread_exit)
    {
        //++ for run/pause ++//
        if (!nes->isrunning)
        {
            nes->ispaused = 1;
            nes->ppu.vdev->dequeue(nes->ppu.vctxt, NULL, NULL);
            nes->ppu.vdev->enqueue(nes->ppu.vctxt);
            continue;
        }
        //-- for run/pause --//

        //++ for replay playing ++//
        if (!replay_progress(&(nes->replay)) && nes->request_reset == 0)
        {
            nes->ppu.vdev->dequeue(nes->ppu.vctxt, NULL, NULL);
            nes->ppu.vdev->enqueue(nes->ppu.vctxt);
            continue;
        }
        //-- for replay playing --//

        //++ for nes reset ++//
        if (nes->request_reset == 1)
        {
            nes->request_reset = 0;
            nes_do_reset(nes);
        }
        //-- for nes reset --//

        //++ run cpu & apu & ppu
        do {
            cpu_run_pclk(&(nes->cpu)); // run cpu
            ppu_run_pclk(&(nes->ppu)); // run ppu
            apu_run_pclk(&(nes->apu)); // run apu

            //+ for cpu nmi & irq
            nmi =   nes->ppu.pinvbl;
            irq = !(nes->apu.regs[0x0015] & 0xC0);
            cpu_nmi(&(nes->cpu), nmi);
            cpu_irq(&(nes->cpu), irq);
            //- for cpu nmi & irq
        } while (nes->ppu.pclk_frame != NES_HTOTAL * 241 + 2);
        // at frame clk (241, 2) the frame buffer will be enqueued
        //-- run cpu & apu & ppu

        // run joypad for turbo key function
        joypad_run(&(nes->pad));
    }
    return NULL;
}
Beispiel #2
0
// 内部函数实现
static DWORD WINAPI nes_thread_proc(LPVOID lpParam)
{
    NES *nes = (NES*)lpParam;
    DWORD dwTickLast  = 0;
    DWORD dwTickCur   = 0;
    DWORD dwTickDiff  = 0;
    DWORD dwTickSleep = 0;
    int   scanline    = 0;

    while (1)
    {
        WaitForSingleObject(nes->hNesEvent, -1);
        if (nes->bExitThread) break;

        // run cpu & ppu
        for (scanline=0; scanline<NES_VTOTAL; scanline++)
        {
            cpu_run_pclk(&(nes->cpu), NES_HTOTAL);
            ppu_run(&(nes->ppu), scanline );
            cpu_nmi(&(nes->cpu), nes->ppu.pin_vbl);
        }

        // apu render frame
        apu_run_pclk(&(nes->apu), NES_HTOTAL * NES_VTOTAL);

        //++ framerate control ++//
        dwTickCur  = GetTickCount();
        dwTickDiff = dwTickCur - dwTickLast;
        dwTickLast = dwTickCur;
        if (dwTickDiff > 16) {
            if (dwTickSleep > 0) dwTickSleep--;
        }
        else if (dwTickDiff < 16) {
            dwTickSleep++;
        }
        if (dwTickSleep) Sleep(dwTickSleep);
        //-- framerate control --//
        log_printf("%d, %d\n", dwTickDiff, dwTickSleep);
    }
    return 0;
}