using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.O2Hawk { public partial class O2Hawk : IEmulator, IVideoProvider { public IEmulatorServiceProvider ServiceProvider { get; } public ControllerDefinition ControllerDefinition => _controllerDeck.Definition; public byte controller_state_1, controller_state_2, kb_state_row, kb_state_col; public bool in_vblank_old; public bool in_vblank; public bool vblank_rise; public uint ticker; public bool FrameAdvance(IController controller, bool render, bool rendersound) { //Console.WriteLine("-----------------------FRAME-----------------------"); if (_tracer.Enabled) { cpu.TraceCallback = s => _tracer.Put(s); } else { cpu.TraceCallback = null; } _frame++; if (controller.IsPressed("Power")) { HardReset(); } if (controller.IsPressed("Reset")) { SoftReset(); } _islag = true; do_frame(controller); if (_islag) { _lagcount++; } return true; } public void do_frame(IController controller) { // update the controller state on VBlank GetControllerState(controller); bool frame_chk = true; //Console.WriteLine("----------FRAME----------"); if (is_pal) { // PAL timing is: 17.7 / 5 ppu // and 17.7 / 9 for cpu (divide by 3 externally then by 3 again internally) while (frame_chk) { ticker++; if (ticker % 5 == 0) { ppu.tick(); if (ticker % 10 == 0) { ppu.Audio_tick(); } } if ((ticker % 9) == 0) { cpu.ExecuteOne(); } if (!in_vblank && in_vblank_old) { frame_chk = false; } in_vblank_old = in_vblank; } } else { // NTSC is 2 to 1 ppu to cpu ticks while (frame_chk) { ppu.tick(); ppu.tick(); ppu.Audio_tick(); cpu.ExecuteOne(); if (!in_vblank && in_vblank_old) { frame_chk = false; } in_vblank_old = in_vblank; } } // send the image on VBlank SendVideoBuffer(); } public void do_single_step() { ppu.tick(); ppu.tick(); ppu.Audio_tick(); cpu.ExecuteOne(); } public void GetControllerState(IController controller) { InputCallbacks.Call(); controller_state_1 = _controllerDeck.ReadPort1(controller); controller_state_2 = _controllerDeck.ReadPort2(controller); kb_state_row = 8; // nothing pressed if (controller.IsPressed("0")) { kb_state_row = 0; kb_state_col = 7; } if (controller.IsPressed("1")) { kb_state_row = 0; kb_state_col = 6; } if (controller.IsPressed("2")) { kb_state_row = 0; kb_state_col = 5; } if (controller.IsPressed("3")) { kb_state_row = 0; kb_state_col = 4; } if (controller.IsPressed("4")) { kb_state_row = 0; kb_state_col = 3; } if (controller.IsPressed("5")) { kb_state_row = 0; kb_state_col = 2; } if (controller.IsPressed("6")) { kb_state_row = 0; kb_state_col = 1; } if (controller.IsPressed("7")) { kb_state_row = 0; kb_state_col = 0; } if (controller.IsPressed("8")) { kb_state_row = 1; kb_state_col = 7; } if (controller.IsPressed("9")) { kb_state_row = 1; kb_state_col = 6; } if (controller.IsPressed("SPC")) { kb_state_row = 1; kb_state_col = 3; } if (controller.IsPressed("?")) { kb_state_row = 1; kb_state_col = 2; } if (controller.IsPressed("L")) { kb_state_row = 1; kb_state_col = 1; } if (controller.IsPressed("P")) { kb_state_row = 1; kb_state_col = 0; } if (controller.IsPressed("+")) { kb_state_row = 2; kb_state_col = 7; } if (controller.IsPressed("W")) { kb_state_row = 2; kb_state_col = 6; } if (controller.IsPressed("E")) { kb_state_row = 2; kb_state_col = 5; } if (controller.IsPressed("R")) { kb_state_row = 2; kb_state_col = 4; } if (controller.IsPressed("T")) { kb_state_row = 2; kb_state_col = 3; } if (controller.IsPressed("U")) { kb_state_row = 2; kb_state_col = 2; } if (controller.IsPressed("I")) { kb_state_row = 2; kb_state_col = 1; } if (controller.IsPressed("O")) { kb_state_row = 2; kb_state_col = 0; } if (controller.IsPressed("Q")) { kb_state_row = 3; kb_state_col = 7; } if (controller.IsPressed("S")) { kb_state_row = 3; kb_state_col = 6; } if (controller.IsPressed("D")) { kb_state_row = 3; kb_state_col = 5; } if (controller.IsPressed("F")) { kb_state_row = 3; kb_state_col = 4; } if (controller.IsPressed("G")) { kb_state_row = 3; kb_state_col = 3; } if (controller.IsPressed("H")) { kb_state_row = 3; kb_state_col = 2; } if (controller.IsPressed("J")) { kb_state_row = 3; kb_state_col = 1; } if (controller.IsPressed("K")) { kb_state_row = 3; kb_state_col = 0; } if (controller.IsPressed("A")) { kb_state_row = 4; kb_state_col = 7; } if (controller.IsPressed("Z")) { kb_state_row = 4; kb_state_col = 6; } if (controller.IsPressed("X")) { kb_state_row = 4; kb_state_col = 5; } if (controller.IsPressed("C")) { kb_state_row = 4; kb_state_col = 4; } if (controller.IsPressed("V")) { kb_state_row = 4; kb_state_col = 3; } if (controller.IsPressed("B")) { kb_state_row = 4; kb_state_col = 2; } if (controller.IsPressed("M")) { kb_state_row = 4; kb_state_col = 1; } if (controller.IsPressed(".")) { kb_state_row = 4; kb_state_col = 0; } if (controller.IsPressed("-")) { kb_state_row = 5; kb_state_col = 7; } if (controller.IsPressed("*")) { kb_state_row = 5; kb_state_col = 6; } if (controller.IsPressed("/")) { kb_state_row = 5; kb_state_col = 5; } if (controller.IsPressed("=")) { kb_state_row = 5; kb_state_col = 4; } if (controller.IsPressed("YES")) { kb_state_row = 5; kb_state_col = 3; } if (controller.IsPressed("NO")) { kb_state_row = 5; kb_state_col = 2; } if (controller.IsPressed("CLR")) { kb_state_row = 5; kb_state_col = 1; } if (controller.IsPressed("ENT")) { kb_state_row = 5; kb_state_col = 0; } } public void KB_Scan() { if (kb_byte == kb_state_row) { kb_byte &= 0xEF; kb_byte |= (byte)(kb_state_col << 5); } else { kb_byte |= 0x10; } } public int Frame => _frame; public string SystemId => "O2"; public bool DeterministicEmulation { get; set; } public void ResetCounters() { _frame = 0; _lagcount = 0; _islag = false; } public void Dispose() { ppu.DisposeSound(); } #region Video provider public int _frameHz = 60; public int[] _vidbuffer; public int[] frame_buffer; public int[] GetVideoBuffer() { return frame_buffer; } public void SendVideoBuffer() { for (int j = 0; j < pic_height; j++) { for (int i = 0; i < 320; i++) { frame_buffer[j * 320 + i] = _vidbuffer[j * 372 + i]; _vidbuffer[j * 372 + i] = 0; } for (int k = 320; k < 372; k++) { _vidbuffer[j * 372 + k] = 0; } } } public int pic_height; public int VirtualWidth => 320; public int VirtualHeight => pic_height; public int BufferWidth => 320; public int BufferHeight => pic_height; public int BackgroundColor => unchecked((int)0xFF000000); public int VsyncNumerator => _frameHz; public int VsyncDenominator => 1; public static readonly uint[] color_palette_BW = { 0xFFFFFFFF , 0xFFAAAAAA, 0xFF555555, 0xFF000000 }; public static readonly uint[] color_palette_Gr = { 0xFFA4C505, 0xFF88A905, 0xFF1D551D, 0xFF052505 }; public uint[] color_palette = new uint[4]; #endregion } }