add support for the joypad

This commit is contained in:
Colby 2016-08-02 23:44:46 +10:00
parent 84c90c4665
commit aeab98baaf
5 changed files with 74 additions and 5 deletions

View file

@ -12,6 +12,7 @@ require "waterfoul/screen"
require "waterfoul/gpu"
require "waterfoul/cartridge"
require "waterfoul/emulator"
require "waterfoul/input"
require "byebug"
module Waterfoul

View file

@ -1,7 +1,9 @@
require 'pp'
require 'sdl2'
module Waterfoul
class Emulator
def initialize(rom_filename, options = {})
SDL2.init SDL2::INIT_EVERYTHING
# read the rom into host memory
rom = read_program(rom_filename).bytes
# initialize emulated CPU, GPU & Sound components
@ -12,6 +14,7 @@ module Waterfoul
cpu = CPU.new
@cpu = options.has_key?('skip_boot') ? SkipBoot.set_state(cpu) : cpu
@gpu = GPU.new
@input = Input.new
@screen = Screen.new
# @sound = Sound.new
end
@ -21,6 +24,7 @@ module Waterfoul
@cpu.step
@gpu.step @cpu.m
@screen.render @gpu.framebuffer if @gpu.vblank?
@input.step @cpu.m
# @sound.step
end
end

65
lib/waterfoul/input.rb Normal file
View file

@ -0,0 +1,65 @@
require 'sdl2'
module Waterfoul
class Input
UP_INPUT_KEYCODE = 82
DOWN_INPUT_KEYCODE = 81
LEFT_INPUT_KEYCODE = 80
RIGHT_INPUT_KEYCODE = 79
A_INPUT_KEYCODE = 4
B_INPUT_KEYCODE = 5
START_INPUT_KEYCODE = 40
SELECT_INPUT_KEYCODE = 229
POLL_RATE = 65536
def initialize
@modeclock = 0
@current_key = 0
$mmu.write_byte 0xFF00, 0x3F, hardware_operation: true
end
def step(cycles = 1)
@modeclock =+ cycles
event = SDL2::Event.poll
if @modeclock >= POLL_RATE
@modeclock -= POLL_RATE
return unless @current_key > 0
joypad_byte = $mmu.read_byte 0xFF00
key_byte = 0x3F
if joypad_byte & 0x10 == 0x00
case @current_key
when UP_INPUT_KEYCODE
key_byte ^= 0x4
when DOWN_INPUT_KEYCODE
key_byte ^= 0x8
when RIGHT_INPUT_KEYCODE
key_byte ^= 0x1
when LEFT_INPUT_KEYCODE
key_byte ^= 0x2
end
p "bar!"
elsif joypad_byte & 0x20 == 0x00
case @current_key
when A_INPUT_KEYCODE
key_byte ^= 0x1
when B_INPUT_KEYCODE
key_byte ^= 0x2
when START_INPUT_KEYCODE
key_byte ^= 0x8
when SELECT_INPUT_KEYCODE
key_byte ^= 0x4
end
p "foo!"
end
$mmu.write_byte 0xFF00, (joypad_byte & key_byte), hardware_operation: true
Interrupt.request_interrupt Interrupt::INTERRUPT_JOYPAD
elsif event.kind_of? SDL2::Event::KeyDown
@current_key = event.scancode
end
end
end
end

View file

@ -35,8 +35,6 @@ module Waterfoul
raise MemoryOutOfBounds if i > MEMORY_SIZE || i < 0
case i
when 0xFF00
0xFF
when 0x0000...0x8000 # ROM Bank 0 + n
if @map_boot_rom && i <= BOOT_ROM_END_MEM_LOC
BootROM[i]
@ -68,6 +66,9 @@ module Waterfoul
case i
when UNMAP_BOOT_ROM_MEM_LOC # unmap the boot rom when 0xFF50 is wrtiten to in memory
@map_boot_rom = false if v == 0x1 && @map_boot_rom
when 0xFF00
current = self[0xFF00]
@memory[0xFF00] = (current & 0xF) | (v & 0x30)
when 0xFF46 # DMA transfer
dma_transfer v
@memory[i] = v

View file

@ -1,4 +1,3 @@
require 'sdl2'
require 'waterfoul/io/lcd_status'
module Waterfoul
@ -15,7 +14,6 @@ module Waterfoul
}
def initialize
SDL2.init SDL2::INIT_VIDEO
@screen = SDL2::Window.create('main', 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0)
@renderer = @screen.create_renderer 1, 0
@lcd_status = IO::LCDStatus.new