Merge branch 'master' into master
|
@ -1,251 +1,371 @@
|
|||
-- Gargoyles, Genesis
|
||||
-- feos, 2015
|
||||
-- Gargoyles, Genesis (BizHawk)
|
||||
-- feos, 2015-2016
|
||||
|
||||
--== Shortcuts ==--
|
||||
local rb = memory.read_u8
|
||||
local rw = memory.read_u16_be
|
||||
local rws = memory.read_s16_be
|
||||
local rl = memory.read_u32_be
|
||||
local box = gui.drawBox
|
||||
local text = gui.pixelText
|
||||
local line = gui.drawLine
|
||||
local AND = bit.band
|
||||
local SHIFT= bit.rshift
|
||||
rb = memory.read_u8
|
||||
rw = memory.read_u16_be
|
||||
rws = memory.read_s16_be
|
||||
r24 = memory.read_u24_be
|
||||
rl = memory.read_u32_be
|
||||
box = gui.drawBox
|
||||
text = gui.pixelText
|
||||
line = gui.drawLine
|
||||
AND = bit.band
|
||||
SHIFT = bit.rshift
|
||||
|
||||
--== RAM addresses ==--
|
||||
local GlobalBase = 0x1c76
|
||||
local GolBase = 0x2c76
|
||||
local MapA_Buff = 0x4af0
|
||||
local mapline_tab = 0x0244
|
||||
local LevelFlr = 0x00c0
|
||||
local LevelCon = 0x00c4
|
||||
local levnum = 0x00ba
|
||||
levnum = 0xff00ba
|
||||
LevelFlr = 0xff00c0
|
||||
LevelCon = 0xff00c4
|
||||
mapline_tab = 0xff0244
|
||||
GlobalBase = 0xff1c76
|
||||
GolBase = 0xff2c76
|
||||
MapA_Buff = 0xff4af0
|
||||
|
||||
--== Camera Hack ==--
|
||||
local camhack = false
|
||||
local div = 1 -- scale
|
||||
local size = 16/div -- block size
|
||||
camhack = false
|
||||
div = 1 -- scale
|
||||
size = 16/div -- block size
|
||||
|
||||
--== Block cache ==--
|
||||
col = 0 -- block color
|
||||
opout = 0x33000000 -- outer opacity
|
||||
opin = 0x66000000 -- inner opacity
|
||||
op = 0xff000000
|
||||
cache = {}
|
||||
|
||||
--== Other stuff ==--
|
||||
local XposLast = 0
|
||||
local YposLast = 0
|
||||
XposLast = 0
|
||||
YposLast = 0
|
||||
room = 0
|
||||
workinglast = 0
|
||||
lagcount = emu.lagcount()
|
||||
gui.defaultPixelFont("fceux")
|
||||
|
||||
function main()
|
||||
camx = (rws(0x010c)+16)
|
||||
camy = (rws(0x010e)+16)
|
||||
backx = camx
|
||||
backy = camy
|
||||
mapw = rw(0x00d4)*8
|
||||
maph = rw(0x00d6)*8
|
||||
-- text(100,0,mapw.." "..maph)
|
||||
Xpos = rws(0x0106)
|
||||
Ypos = rws(0x0108)
|
||||
health = rws(0x2cc6)
|
||||
facing = AND(rb(GolBase+0x48),2) -- object flag 1
|
||||
working= rb(0x0073)
|
||||
if camhack then
|
||||
camx = Xpos-320/2*div
|
||||
camy = Ypos-224/2*div
|
||||
rnd1 = rl (0xff001c)
|
||||
rnd2 = rw (0xff0020)
|
||||
working = rb (0xff0073)
|
||||
xblocks = rw (0xff00d4)
|
||||
mapw = rw (0xff00d4)*8
|
||||
maph = rw (0xff00d6)*8
|
||||
Xpos = rws(0xff0106)
|
||||
Ypos = rws(0xff0108)
|
||||
camx = rws(0xff010c)+16
|
||||
camy = rws(0xff010e)+16
|
||||
run = rb (0xff1699)
|
||||
inv = rw (0xff16d2)
|
||||
health = rws(0xff2cc6)
|
||||
backx = camx
|
||||
backy = camy
|
||||
Xspd = Xpos-XposLast
|
||||
Yspd = Ypos-YposLast
|
||||
facing = AND(rb(GolBase+0x48),2) -- object flag 1
|
||||
|
||||
Background()
|
||||
CamhackHUD()
|
||||
Objects()
|
||||
PlayerBoxes()
|
||||
HUD()
|
||||
RoomTime()
|
||||
Input()
|
||||
end
|
||||
|
||||
function RoomTime()
|
||||
local start11 = 894--767
|
||||
local start12 = 2294
|
||||
local start13 = 4101
|
||||
local startl4 = 6000
|
||||
timer = emu.framecount()
|
||||
|
||||
if timer < start11 then room = timer
|
||||
elseif timer < start12 then room = timer - start11
|
||||
elseif timer < start13 then room = timer - start12
|
||||
elseif timer < startl4 then room = timer - start13
|
||||
end
|
||||
run = rb(0x1699)
|
||||
inv = rw(0x16d2)
|
||||
rnd1 = rl(0x001c)
|
||||
rnd2 = rw(0x0020)
|
||||
Xspd = Xpos-XposLast
|
||||
Yspd = Ypos-YposLast
|
||||
XposLast = Xpos
|
||||
YposLast = Ypos
|
||||
rndlast = rnd1
|
||||
--[ [--
|
||||
if camhack then box(0,0,320,240,0,0x66000000) end
|
||||
text(160,214,"room cnt: "..room, "white")
|
||||
end
|
||||
|
||||
function HUD()
|
||||
text(1, 0,emu.framecount(), framecol)
|
||||
text(1,20,emu.lagcount(), "red")
|
||||
text(1,30,movie.rerecordcount(),"orange")
|
||||
|
||||
if working>0 then return end
|
||||
if rndlast ~= rnd1 then rndcol = "red" else rndcol = "white" end
|
||||
|
||||
text( 0,214,"rnd: ","yellow")
|
||||
text( 26,214,string.format("%08X %04X",rnd1,rnd2),rndcol)
|
||||
text(277, 0,string.format(
|
||||
"x: %4d\ny: %4d\ndx: %3d\ndy: %3d\nhp: %3d\nrun:%3d\ninv:%3d",
|
||||
Xpos,Ypos,Xspd,Yspd,health,run,inv)
|
||||
)
|
||||
end
|
||||
|
||||
function CamhackHUD()
|
||||
if working==0 then
|
||||
box(
|
||||
(backx-camx- 1)/div,
|
||||
-- screen edge
|
||||
box((backx-camx- 1)/div,
|
||||
(backy-camy- 1)/div,
|
||||
(backx-camx+320)/div,
|
||||
(backy-camy+224)/div,
|
||||
0x0000ffff)
|
||||
0xff0000ff)
|
||||
-- map edge
|
||||
box( 0-camx/div+size,
|
||||
0-camy/div+size,
|
||||
mapw/div-camx/div,
|
||||
maph/div-camy/div,
|
||||
0xff0000ff)
|
||||
end
|
||||
for i=0,20*div do
|
||||
for j=0,14*div do
|
||||
GetBlock(i,j)
|
||||
end
|
||||
end
|
||||
--]]--
|
||||
Objects()
|
||||
PlayerBoxes()
|
||||
HUD()
|
||||
RoomTime()
|
||||
|
||||
text(260,206,string.format("cHack: %s\nscale: %d",ch,div))
|
||||
end
|
||||
|
||||
function RoomTime()
|
||||
local start11 = 767
|
||||
local start12 = 2294
|
||||
local start13 = 4101
|
||||
local startl4 = 6000
|
||||
timer = emu.framecount()
|
||||
if timer < start11 then room = timer
|
||||
elseif timer < start12 then room = timer - start11
|
||||
elseif timer < start13 then room = timer - start12
|
||||
elseif timer < startl4 then room = timer - start13
|
||||
function Background()
|
||||
if working>0 then
|
||||
cache = {}
|
||||
return
|
||||
end
|
||||
|
||||
if camhack then
|
||||
camx = Xpos-320/2*div
|
||||
camy = Ypos-224/2*div
|
||||
box(0,0,320,240,0,0x66000000)
|
||||
ch = "on"
|
||||
else
|
||||
ch = "off"
|
||||
end
|
||||
|
||||
local border = 0
|
||||
local offset = 32
|
||||
local basex = camx+border
|
||||
local basey = camy+border
|
||||
local basei = PosToIndex(basex-offset,basey-offset)
|
||||
local boundx = 320*div-border
|
||||
local boundy = 224*div-border
|
||||
local xblockstockeck = ((camx+boundx+offset)-(basex-offset))/size/div
|
||||
local yblockstockeck = ((camy+boundy+offset)-(basey-offset))/size/div
|
||||
|
||||
for yblock = 0,yblockstockeck do
|
||||
for xblock = 0,xblockstockeck do
|
||||
local i = yblock*xblocks+xblock+basei
|
||||
local x = basex+xblock*size*div
|
||||
local y = basey+yblock*size*div
|
||||
|
||||
if InBounds(x,basex-offset,camx+boundx+offset) then
|
||||
local unit = cache[i]
|
||||
|
||||
if unit == nil or workinglast>0 then
|
||||
if InBounds(x,basex,camx+boundx)
|
||||
and InBounds(y,basey,camy+boundy)
|
||||
then cache[i] = GetBlock(x,y)
|
||||
end
|
||||
else
|
||||
if not InBounds(x,basex,camx+boundx)
|
||||
and not InBounds(y,basey,camy+boundy)
|
||||
then cache[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if unit ~= nil then
|
||||
DrawBG(unit,x,y)
|
||||
end
|
||||
elseif cache[i] ~= nil
|
||||
then cache[i] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DrawBG(unit, x, y)
|
||||
local val= 0
|
||||
local x1 = x/div-camx/div-(camx%16)/div
|
||||
local x2 = x1+size-1
|
||||
local y1 = y/div-camy/div-(camy%16)/div
|
||||
local y2 = y1+size-1
|
||||
|
||||
if unit.contour ~= nil then
|
||||
box(x1,y1,x2,y2,0x5500ff00,0x5500ff00)
|
||||
|
||||
for pixel=0,15 do
|
||||
val = unit.contour[pixel]
|
||||
if val>0 then
|
||||
gui.drawPixel(
|
||||
x1+pixel/div,
|
||||
y1+val/div-1/div,
|
||||
0xffffff00)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if unit.block>0 then
|
||||
local Fn = DrawBlock[unit.block] or DrawBlockDefault
|
||||
Fn(x1,y1,x2,y2)
|
||||
box(x1,y1,x2,y2,col+opin,col+opout)
|
||||
end
|
||||
text(100,217,"room cnt: "..room)
|
||||
end
|
||||
|
||||
function GetBlock(x,y)
|
||||
if working>0 then return end
|
||||
x = camx+x*size*div-AND(camx,0xF)
|
||||
y = camy+y*size*div-AND(camy,0xF)
|
||||
if x>0 and x<mapw and y>0 and y<maph then
|
||||
local x1 = x/div-camx/div
|
||||
local x2 = x1+size-1
|
||||
local y1 = y/div-camy/div
|
||||
local y2 = y1+size-1
|
||||
local d4 = rw(mapline_tab+SHIFT(y,4)*2)
|
||||
local a1 = AND(rl(LevelFlr),0xffff)
|
||||
local d1 = SHIFT(rw(MapA_Buff+d4+SHIFT(x,4)*2),1)
|
||||
local ret = rb(a1+d1+2) -- block
|
||||
local col = 0 -- block color
|
||||
local opout = 0x33000000 -- outer opacity
|
||||
local opin = 0x66000000 -- inner opacity
|
||||
local op = 0xff000000
|
||||
if working>0 then return nil end
|
||||
|
||||
local final = { contour={}, block=0 }
|
||||
|
||||
if x>0 and x<mapw
|
||||
and y>0 and y<maph then
|
||||
local pixels = 0
|
||||
local x1 = x/div-camx/div
|
||||
local x2 = x1+size-1
|
||||
local y1 = y/div-camy/div
|
||||
local y2 = y1+size-1
|
||||
local d4 = rw(mapline_tab+SHIFT(y,4)*2)
|
||||
local a1 = r24(LevelFlr+1)
|
||||
local d1 = SHIFT(rw(MapA_Buff+d4+SHIFT(x,4)*2),1)
|
||||
final.block = rb(a1+d1+2)
|
||||
d1 = rw(a1+d1)
|
||||
a1 = AND(rl(LevelCon),0xffffff)+d1
|
||||
if rb(a1,"MD CART")>0 or rb(a1+8,"MD CART")>0 then
|
||||
box(x1,y1,x2,y2,0x5500ff00,0x5500ff00)
|
||||
a1 = r24(LevelCon+1)+d1
|
||||
|
||||
if rb(a1)>0 or rb(a1+8)>0 then
|
||||
for pixel=0,15 do
|
||||
retc = rb(a1+pixel,"MD CART") -- contour
|
||||
if retc>0 then
|
||||
gui.drawPixel(x1+pixel/div,y1+retc/div-1/div,0xffffff00)
|
||||
-- text(x1,y1,string.format("%X",retc))
|
||||
end
|
||||
final.contour[pixel] = rb(a1+pixel)
|
||||
end
|
||||
else
|
||||
final.contour = nil
|
||||
end
|
||||
local lol = 0
|
||||
--if lol==0 then return end
|
||||
if ret>0 then
|
||||
if ret==0x80 then -- WALL
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
elseif ret==0x81 then -- CEILING
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y2,x2,y2,col+op) -- bottom
|
||||
elseif ret==0x82 then -- CLIMB_U
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y2,x2,y2,col+op) -- bottom
|
||||
elseif ret==0x83 then -- CLIMB_R
|
||||
-- col = 0x00ffffff -- white
|
||||
-- line(x2,y1,x2,y2,col+op) -- right
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
elseif ret==0x84 then -- CLIMB_L
|
||||
-- col = 0x00ffffff -- white
|
||||
-- line(x1,y1,x1,y2,col+op) -- left
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
elseif ret==0x85 then -- CLIMB_LR
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
elseif ret==0x86 then -- CLIMB_R_STAND_R
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
elseif ret==0x87 then -- CLIMB_L_STAND_L
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
elseif ret==0x87 then -- CLIMB_LR_STAND_LR
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x00ff00ff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
elseif ret==0x70 then -- GRAB_SWING
|
||||
col = 0x0000ff00 -- green
|
||||
box(x1,y1,x2,y2,col,col+opout)
|
||||
-- elseif ret==0x72 then -- FORCE_TURN (for enemies)
|
||||
-- col = 0x0088ff00 -- green
|
||||
-- box(x1,y1,x2,y2,col,col+opout)
|
||||
elseif ret==0x7f then -- EXIT
|
||||
col = 0x00ffff00 -- yellow
|
||||
elseif ret==0xd0 or ret==0xd1 then -- SPIKES
|
||||
col = 0x00ff0000 -- red
|
||||
box(x1,y1,x2,y2,col,col+opout)
|
||||
else -- LEVEL_SPECIFIC
|
||||
col = 0x00ff8800 -- orange
|
||||
box(x1,y1,x2,y2,col+opin,col+opout)
|
||||
end
|
||||
box(x1,y1,x2,y2,col+opin,col+opout)
|
||||
-- text(x1,y1,string.format("%X",ret))
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
return final
|
||||
end
|
||||
|
||||
function PosToIndex(x,y)
|
||||
return math.floor(x/16)+math.floor(y/16)*xblocks
|
||||
end
|
||||
|
||||
function IndexToPos(i)
|
||||
return { x=(i%xblocks)*16, y=math.floor(i/xblocks)*16 }
|
||||
end
|
||||
|
||||
function InBounds(x,minimum,maximum)
|
||||
if x>=minimum and x<=maximum
|
||||
then return true
|
||||
else return false
|
||||
end
|
||||
end
|
||||
|
||||
function HUD()
|
||||
if working>0 then return end
|
||||
if camhack then ch = "on" else ch = "off" end
|
||||
if rndlast~= rnd1 then rndcol = "red" else rndcol = "white" end
|
||||
if memory.readbyte(0xF6D4)==0 then text(170,217,"LAG","red") end
|
||||
text(280,210,string.format("cHack: %s\nscale: %d",ch,div))
|
||||
text( 0,217,"rnd: ","yellow")
|
||||
text( 20,217,string.format("%08X %04X",rnd1,rnd2),rndcol)
|
||||
text(290, 0,string.format(
|
||||
"x: %4d\ny: %4d\ndx: %3d\ndy: %3d\nhp: %3d\nrun:%3d\ninv:%3d",
|
||||
Xpos,Ypos,Xspd,Yspd,health,run,inv),"yellow"
|
||||
)
|
||||
DrawBlock = {
|
||||
[0x80] = function(x1,y1,x2,y2) -- WALL
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
end,
|
||||
[0x81] = function(x1,y1,x2,y2) -- CEILING
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y2,x2,y2,col+op) -- bottom
|
||||
end,
|
||||
[0x82] = function(x1,y1,x2,y2) -- CLIMB_U
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y2,x2,y2,col+op) -- bottom
|
||||
end,
|
||||
[0x83] = function(x1,y1,x2,y2) -- CLIMB_R
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
end,
|
||||
[0x84] = function(x1,y1,x2,y2) -- CLIMB_L
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
end,
|
||||
[0x85] = function(x1,y1,x2,y2) -- CLIMB_LR
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
end,
|
||||
[0x86] = function(x1,y1,x2,y2) -- CLIMB_R_STAND_R
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
end,
|
||||
[0x87] = function(x1,y1,x2,y2) -- CLIMB_L_STAND_L
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
end,
|
||||
[0x88] = function(x1,y1,x2,y2) -- CLIMB_LR_STAND_LR
|
||||
col = 0x00ffffff -- white
|
||||
line(x1,y1,x2,y1,col+op) -- top
|
||||
col = 0x00ff00ff -- cyan
|
||||
line(x1,y1,x1,y2,col+op) -- left
|
||||
col = 0x0000ffff -- cyan
|
||||
line(x2,y1,x2,y2,col+op) -- right
|
||||
end,
|
||||
[0x70] = function(x1,y1,x2,y2) -- GRAB_SWING
|
||||
col = 0x0000ff00 -- green
|
||||
box(x1,y1,x2,y2,col,col+opout)
|
||||
end,
|
||||
[0x7f] = function(x1,y1,x2,y2) -- EXIT
|
||||
col = 0x00ffff00 -- yellow
|
||||
end,
|
||||
[0xd0] = function(x1,y1,x2,y2) -- SPIKES
|
||||
col = 0x00ff0000 -- red
|
||||
box(x1,y1,x2,y2,col,col+opout)
|
||||
end,
|
||||
[0xd1] = function(x1,y1,x2,y2) -- SPIKES
|
||||
col = 0x00ff0000 -- red
|
||||
box(x1,y1,x2,y2,col,col+opout)
|
||||
end
|
||||
}
|
||||
|
||||
function DrawBlockDefault(x1,y1,x2,y2)-- LEVEL_SPECIFIC
|
||||
col = 0x00ff8800 -- orange
|
||||
box(x1,y1,x2,y2,col+opin,col+opout)
|
||||
end
|
||||
|
||||
function Objects()
|
||||
if working>0 then return end
|
||||
|
||||
for i=0,63 do
|
||||
local base = GlobalBase+i*128
|
||||
local flag2 = AND(rb(base+0x49),0x10) -- active
|
||||
|
||||
if flag2==0x10 then
|
||||
local xpos = rw(base+0x00)
|
||||
local ypos = rw(base+0x02)
|
||||
-- local anm = rl(base+0x20)
|
||||
local dmg = rb(base+0x10)
|
||||
local type = rw(base+0x40)
|
||||
local hp = rw(base+0x50)
|
||||
local cRAM = rw(base+0x76) -- pointer to 4 collision boxes per object
|
||||
local col = 0 -- collision color
|
||||
local xpos = rw (base+0x00)
|
||||
local ypos = rw (base+0x02)
|
||||
local dmg = rb (base+0x10)
|
||||
local type = rw (base+0x40)
|
||||
local hp = rw (base+0x50)
|
||||
local cRAM = r24(base+0x75) -- pointer to 4 collision boxes per object
|
||||
local col = 0 -- collision color
|
||||
local xscr = (xpos-camx)/div
|
||||
local yscr = (ypos-camy)/div
|
||||
if type==0 then
|
||||
-- gui.text(xscr,yscr,string.format("%X",anm))
|
||||
end
|
||||
|
||||
for boxx=0,4 do
|
||||
local x1 = (rws(cRAM+boxx*8+0)-camx)/div
|
||||
local y1 = (rws(cRAM+boxx*8+2)-camy)/div
|
||||
local x2 = (rws(cRAM+boxx*8+4)-camx)/div
|
||||
local y2 = (rws(cRAM+boxx*8+6)-camy)/div
|
||||
|
||||
if boxx==0 then
|
||||
col = 0xff00ff00 -- body
|
||||
col = 0xff00ff00 -- body
|
||||
if type==282 or type==258 then hp = 1 end -- archer hp doesn't matter
|
||||
if hp>0 and type>0 then
|
||||
text(x1+2,y1+1,string.format("%d",hp),col)
|
||||
text(x1+2,y1+1,string.format("%d",hp),col,0x88000000,"gens")
|
||||
end
|
||||
elseif boxx==1 then
|
||||
col = 0xffffff00 -- floor
|
||||
elseif boxx==1 then
|
||||
col = 0xffffff00 -- floor
|
||||
elseif boxx==2 then
|
||||
if dmg>0 then
|
||||
col = 0xffff0000 -- projectile
|
||||
else
|
||||
col = 0xff8800ff -- item
|
||||
if dmg>0
|
||||
then col = 0xffff0000 -- projectile
|
||||
else col = 0xff8800ff -- item
|
||||
end
|
||||
if dmg>0 then
|
||||
text(x1+2,y2+1,string.format("%d",dmg),col)
|
||||
text(x1+2,y2+1,string.format("%d",dmg),col,0x88000000,"gens")
|
||||
end
|
||||
else
|
||||
col = 0xffffffff -- other
|
||||
col = 0xffffffff -- other
|
||||
end
|
||||
|
||||
if x1~=0x8888 and x2<320 and x1>0 and y2<224 and y1>0 then
|
||||
box(x1,y1,x2,y2,col)
|
||||
end
|
||||
|
@ -256,20 +376,24 @@ end
|
|||
|
||||
function PlayerBoxes()
|
||||
if working>0 then return end
|
||||
xx = (Xpos-camx)/div
|
||||
yy = (Ypos-camy)/div
|
||||
|
||||
local xx = (Xpos-camx)/div
|
||||
local yy = (Ypos-camy)/div
|
||||
local col = 0xff00ffff
|
||||
local swcol = col -- usual detection
|
||||
if Yspd>0 then -- gimme swings to grab!!!
|
||||
local swcol = col -- usual detection
|
||||
|
||||
if Yspd>0 then -- gimme swings to grab!
|
||||
swcol = 0xff00ff00
|
||||
elseif Yspd==0 then -- can tell that too
|
||||
elseif Yspd==0 then -- can tell that too
|
||||
swcol = 0xffffffff
|
||||
end
|
||||
|
||||
if facing==2 then
|
||||
box(xx-0xf /div-2,yy-0x2c/div-1,xx-0xf /div+0,yy-0x2c/div+1,swcol) -- lefttop
|
||||
else
|
||||
box(xx+0xf /div-1,yy-0x2c/div-1,xx+0xf /div+1,yy-0x2c/div+1,swcol) -- rightttop
|
||||
end
|
||||
|
||||
box(xx -1,yy-0x2c/div-1,xx +1,yy-0x2c/div+1,col) -- top
|
||||
box(xx-0xf /div-2,yy-0x1f/div-1,xx-0xf /div+0,yy-0x1f/div+1,col) -- left
|
||||
box(xx+0x10/div-1,yy-0x1f/div-1,xx+0x10/div+1,yy-0x1f/div+1,col) -- right
|
||||
|
@ -279,7 +403,44 @@ function PlayerBoxes()
|
|||
-- box(xx -1,yy+0x10/div-1,xx +1,yy+0x10/div+1,col) -- ground
|
||||
end
|
||||
|
||||
--event.onframeend(main)
|
||||
function Input()
|
||||
local i,u,d,l,r,a,b,c,s
|
||||
|
||||
if movie.isloaded() then
|
||||
i = movie.getinput(emu.framecount()-1)
|
||||
else
|
||||
i = joypad.getimmediate()
|
||||
end
|
||||
|
||||
if i["P1 Up" ] then u = "U" else u = " " end
|
||||
if i["P1 Down" ] then d = "D" else d = " " end
|
||||
if i["P1 Left" ] then l = "L" else l = " " end
|
||||
if i["P1 Right"] then r = "R" else r = " " end
|
||||
if i["P1 A" ] then a = "A" else a = " " end
|
||||
if i["P1 B" ] then b = "B" else b = " " end
|
||||
if i["P1 C" ] then c = "C" else c = " " end
|
||||
if i["P1 Start"] then s = "S" else s = " " end
|
||||
|
||||
text(1,10,u..d..l..r..a..b..c..s,"yellow")
|
||||
end
|
||||
|
||||
event.onframeend(function()
|
||||
emu.setislagged(rb(0xfff6d4)==0)
|
||||
|
||||
if rb(0xfff6d4)==0 then
|
||||
lagcount = lagcount+1
|
||||
framecol = "red"
|
||||
else
|
||||
framecol = "white"
|
||||
end
|
||||
|
||||
emu.setlagcount(lagcount)
|
||||
|
||||
rndlast = rnd1
|
||||
workinglast = working
|
||||
XposLast = Xpos
|
||||
YposLast = Ypos
|
||||
end)
|
||||
|
||||
while true do
|
||||
main()
|
||||
|
|
|
@ -238,14 +238,14 @@
|
|||
"P4 R": ""
|
||||
},
|
||||
"Nintento 64 Controller": {
|
||||
"P1 A Up": "UpArrow, J1 DpadUp, X1 LStickUp",
|
||||
"P1 A Down": "DownArrow, J1 POV1D, X1 DpadDown, X1 LStickDown",
|
||||
"P1 A Left": "LeftArrow, J1 POV1L, X1 DpadLeft, X1 LStickLeft",
|
||||
"P1 A Right": "RightArrow, J1 POV1R, X1 DpadRight, X1 LStickRight",
|
||||
"P1 DPad U": "",
|
||||
"P1 DPad D": "",
|
||||
"P1 DPad L": "",
|
||||
"P1 DPad R": "",
|
||||
"P1 A Up": "UpArrow, J1 POV1U",
|
||||
"P1 A Down": "DownArrow, J1 POV1D",
|
||||
"P1 A Left": "LeftArrow, J1 POV1L",
|
||||
"P1 A Right": "RightArrow, J1 POV1R",
|
||||
"P1 DPad U": "X1 DpadUp",
|
||||
"P1 DPad D": "X1 DpadDown",
|
||||
"P1 DPad L": "X1 DpadLeft",
|
||||
"P1 DPad R": "X1 DpadRight",
|
||||
"P1 Start": "Return, J1 B10, X1 Start",
|
||||
"P1 Z": "D, J1 B3, X1 B",
|
||||
"P1 B": "S, J1 B1, X1 X",
|
||||
|
@ -1192,12 +1192,12 @@
|
|||
},
|
||||
"Nintento 64 Controller": {
|
||||
"P1 X Axis": {
|
||||
"Value": "J1 X",
|
||||
"Value": "X1 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P1 Y Axis": {
|
||||
"Value": "J1 Y",
|
||||
"Value": "X1 LeftThumbY",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include gamedb_msx1.txt
|
||||
#include gamedb_msx2.txt
|
||||
#include gamedb_vs.txt
|
||||
#include gamedb_intv.txt
|
||||
|
||||
; ************ NES / Famicom ************
|
||||
|
||||
|
@ -311,6 +312,7 @@ sha1:35C157A921156E47FD3F6573D150F54108D0EDFC Blargg's 5.MMC3_rev_A.nes NES bo
|
|||
sha1:0E971E2CCAD1DEE51A0C305ED38FAFD2E6CA3B41 Blargg's 6.MMC3_rev_B.nes NES board=MAPPER004;MMC3=MMC3B
|
||||
sha1:F794FDA12D34E611D58E652319ED583AE61B81E0 Blargg's 6-MMC6.nes NES board=MAPPER004_MMC6
|
||||
sha1:2F29F3DC724027FAD926BC9D4470A481884E42A5 Blargg's 6-MMC6.nes (newer) NES board=MAPPER004_MMC6
|
||||
sha1:6F3184ACDC7333683D459C7613CA1C235CEAFD3F Aladdin (SuperGame) (Mapper 4) [!] NES board=MAPPER004;MMC3=MMC3A
|
||||
;;;;;;;;;;;;;;;;;;;-----------------------------------------------------------------------
|
||||
|
||||
;datach stuff
|
||||
|
@ -324,6 +326,9 @@ EDD7A45A7F27E396B6D686F1861642D509863132 Datach SD Gundam Gundam Wars NES boar
|
|||
6F3C65BD945FE13305A7A39D8CD884A5BF314A8F Datach Crayon Shin Chan Ora to Poi Poi NES board=MAPPER157
|
||||
1218C891DEE878C18D31D38D07CAD5FB06B3B2CE Datach Yuu Yuu akusho Baktutou NES board=MAPPER157
|
||||
|
||||
;testrom
|
||||
sha1:E925A172C29DD46BA385D526F3C317DB039FA2BF mmc1_a12 NES board=NES-SNROM
|
||||
|
||||
; ArcadePit hacks
|
||||
; Why does this one need NesHawk?
|
||||
sha1:90acbbdfad1465032dfff77175320bab8aa4adb7 H Mike Tyson's Punch-Out!! [Buck Edit] (USA) NES NesHawk
|
||||
|
@ -349,7 +354,6 @@ C94257E7 B Looney Tunes - Sheep Raider (STATiC Dump) PSX dh=00000000
|
|||
829A295C B Monster Rancher 2 (U) (EXE Patched) PSX dh=00000000
|
||||
|
||||
#include gamedb_neshomebrew.txt
|
||||
#include gamedb_vs.txt
|
||||
#include gamedb_user.txt
|
||||
#include gamedb_ws.txt
|
||||
#include gamedb_wsc.txt
|
||||
|
|
|
@ -137,7 +137,7 @@ sha1:5DE3BD9B7234A0EEA7551DDBEDD7F55CD47AA9F7 Kevtris by Kevin Horton (1996) (P
|
|||
sha1:77CD01E29071DECE70D18CF9E7E2D2CE455D001F Keystone Kapers (1983-84) (Activision) Coleco
|
||||
sha1:50A1BE08F8CD5445EE32C1702A3D3607948867B6 Kill Barney in Tokyo by Daniel Bienvenu (1997) (PD) Coleco
|
||||
sha1:40324590797F32915021CFD0D6EB4112020939BF Killer Instinct by Daniel Bienvenu (1997) (PD) Coleco
|
||||
sha1:AFA8E2F119D63463DBDD0C88BE6873B0C6A27594 Lady Bug (1982) (Universal) Coleco
|
||||
sha1:AFA8E2F119D63463DBDD0C88BE6873B0C6A27594 Lady Bug (1982) (Universal) Coleco NoSkip
|
||||
sha1:0CE165B3C2A9E60964D33F37E8AEC7CBF9E9D00F Learning With Leeper (1983) (Sierravision) [!] Coleco
|
||||
sha1:198767E1C8794F974F3434674CB0E542108D0011 Linking Logic (1984) (Fisher-Price) Coleco
|
||||
sha1:C5A4D39C1AA5A643DAABC9A163F366F9BA5AFEF2 Logic Levels (1984) (Fisher-Price) Coleco
|
||||
|
@ -235,8 +235,8 @@ sha1:F828B172ED3B51CC5F65843032BD2F4E2BF5C418 Space Invasion Demo by John Dondz
|
|||
sha1:530870501F322F1D72E820A722790D300F43A6DE Space Panic (1983) (Universal) Coleco NoSkip
|
||||
sha1:5A1E9E8CFE6D6E1CD685EC4AFD0FC159E20A69FF Spectank Demo by Daniel Bienvenu (2000) (PD) Coleco
|
||||
sha1:8C83391F512D20CBBB4F36B0ADD06A6CF0BD8E65 Spectron (1983) (Spectravideo) Coleco
|
||||
sha1:E9814F694FAD5548E9CE7295DDC9F8B9EEE29332 B Spy Hunter (1983-84) (Midway) [b1] Coleco
|
||||
sha1:97865D067BD531209857C3C8502C1260E0A30366 Spy Hunter (1983-84) (Midway) Coleco
|
||||
sha1:E9814F694FAD5548E9CE7295DDC9F8B9EEE29332 B Spy Hunter (1983-84) (Midway) [b1] Coleco NoSkip
|
||||
sha1:97865D067BD531209857C3C8502C1260E0A30366 Spy Hunter (1983-84) (Midway) Coleco NoSkip
|
||||
sha1:D4C1A98A35DC79727B6E8838B1B0815919496601 Squish 'Em Sam! (1983) (Interphase) Coleco
|
||||
sha1:870D1A39AA85AC1D0E270348B56944BA47170557 St-Valentine's Day (2002) (PD) Coleco
|
||||
sha1:003F07FA755F632348694E7C6E6AC0DE10E1B3E7 St-Valentine's Day (No Alien Head) (2002) (PD) Coleco
|
||||
|
@ -264,7 +264,7 @@ sha1:EFA3B89899839E062E072921148716E8B82923CE Super Cross Force (1983) (Spectra
|
|||
sha1:B1AC18780E36821A8D41FC4410E14AB0CE80AC91 Super DK! (1983) (Prototype) Coleco
|
||||
sha1:44A22E508002A069F7953668F2E8A3C901C677D6 Super DK! Junior (1983) (Prototype) Coleco
|
||||
sha1:FF8F73F9BF16BB67799BBE8E52C541D727F501F4 Superpong Demo (2000) (PD) Coleco
|
||||
sha1:A79CBE906A6DF960F790C3139704F534B09A378B Tank Wars (1983) (Bit Corp) [!] Coleco
|
||||
sha1:A79CBE906A6DF960F790C3139704F534B09A378B Tank Wars (1983) (Bit Corp) [!] Coleco NoSkip
|
||||
sha1:459393F07792EE1B2C878E1257A21C6C351D5C29 B Tapper (1984) (Midway) [b1] Coleco
|
||||
sha1:BBB25E64AEFA3ADAFF9F864713ECABE3B6F0316B Tapper (1984) (Midway) Coleco
|
||||
sha1:2D61D96FD15C614BDE450813AA88092CF814E60A Tarzan (1984) (Coleco) Coleco
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
; NOTE: games not in this database will default to mapper 0
|
||||
|
||||
sha1:AAD9D2691F63A993B984143D8457FC4A86CFC472 Atlantis INTV board=7
|
||||
sha1:280A14898F1AB2C26209D3B28AD67054504C0856 Beauty and the Beast (1982) (Imagic) [!] INTV board=7
|
||||
sha1:A27144195AE123FA4FC9F9848B77B7B5208D5FFC Body Slam - Super Pro Wrestling (1988) (Intv Corp) INTV board=2
|
||||
sha1:C50B818CB1E5041BAD1087A03BF8B6E021579BC5 Centipede (1983) (Atarisoft) INTV board=6
|
||||
sha1:39BF9C38E1A9F0472A6254A4700FC0D2695E8A71 Championship Tennis (1985) (Mattel) INTV board=1
|
||||
sha1:C7146409D4791F45C517475FC5068038E388EDA2 Chip Shot - Super Pro Golf (1987) (Intv Corp) INTV board=2
|
||||
sha1:059A73EC21E71985A6724974F864AE8A82041AA8 Commando (1987) (Mattel) INTV board=2
|
||||
sha1:E8E3DCB80ED8273D079DEF0793BEB1D6070C9A08 Congo Bongo (1983) (Sega) INTV board=5
|
||||
sha1:D41F0B32703A15A8406901905224205451D7B59C Defender (1983) (Atarisoft) INTV board=5
|
||||
sha1:E27310C6C26C07D9FF59E723AFFA8E48BEE7D820 Demon Attack (1982) (Imagic) [!] INTV board=7
|
||||
sha1:997846CEE15A81E51255CBE378379216B01DE0F2 Dig Dug (1987) (Intv Corp) INTV board=5
|
||||
sha1:C649D6A822062B3DD7151E27005979ACF1C6FDFD Diner (1987) (Intv Corp) INTV board=2
|
||||
sha1:B883C75D3ABCB9638E8ED3D4E11CFCC1322462A8 Game Factory (Prototype) (1983) (Mattel) [!] INTV board=9
|
||||
sha1:208147F393AF35ECE134D2CD056214E4A4DCCA5E Hover Force (1986) (Intv Corp) INTV board=2
|
||||
sha1:9800325E3C8A82BBEE66FE0402C9F76A5D996AB0 King of the Mountain (1982) (Mattel) INTV board=1
|
||||
sha1:8E28A7AD0DB9CB0E7D7DA008A16C0F8654810826 Land Battle (1982) (Mattel) INTV board=4
|
||||
sha1:18AE3B7BC158B7FFCDFCFA84AF86D16B1545769C Learning Fun I - Math Master Factor Fun (1987) (Intv Corp) INTV board=2
|
||||
sha1:A01DB79795CCB7F20B45D3C44791F52065600DEB Learning Fun II - Word Wizard Memory Fun (1987) (Intv Corp) INTV board=2
|
||||
sha1:13BDECAF48094920F257C8A25686EEC91C0ADADC Microsurgeon (1982) (Imagic) [!] INTV board=7
|
||||
sha1:21F6AABE3462594EA5E20EEED7AEF493BE427911 Ms PcaMan INTV board=10
|
||||
sha1:350313B04570F0F30B8E6730C999B5DA8EE26ABE MTE201 Intellivision Test Cartridge (1978) (Mattel) INTV board=8
|
||||
sha1:68AC0AE38753D0F3EDC69E004954B0575DF85DD6 Pac-Man (1983) (Atarisoft) INTV board=5
|
||||
sha1:7E44A63186C66A80DF20DF26036F48E5A309256F Pac-Man (1983) (Intv Corp) INTV board=5
|
||||
sha1:FB32AE847476A5BC7625100D85985E99A377CE39 Pole Position (1986) (Intv Corp) INTV board=2
|
||||
sha1:30399A9B4AAA0B4E0D8C7987AEF56D0AB7AE4B09 Stadium Mud Buggies (1988) (Intv Corp) INTV board=2
|
||||
sha1:004ABB06C3C5A4641EAE488DD78858C10C9F0A42 Super Pro Decathlon (1988) (Intv Corp) INTV board=2
|
||||
sha1:6E1261F456070F3EBBE124B6DCEC2A31C5BCC0EE Super Pro Football (1986) (Intv Corp) INTV board=2
|
||||
sha1:57B8BFAD43CD7F0CC0E30029870CA6BA0454AE38 Tower of Doom (1986) (Intv Corp) INTV board=3
|
||||
sha1:307D7DF3EE36000D1BE8C1151EA6484245602C5D USCF Chess (1981) (Mattel) INTV board=4
|
|
@ -349,8 +349,8 @@ EA608A53121D0C905DCFE6544248C275 Shaq Fu (UE) GG USA;Europe
|
|||
A952A843A123092AAFBEB37B428EF6FF Shikinjou (J) GG Japan
|
||||
8EAFD80D35251B5D3F07D5CAE27241C1 Shining Force Gaiden - Ensei, Jashin no Kuni e (J) GG Strategy;RPG SRAM=16384 Japan
|
||||
35EF27F6B4B4DDC4A6AD6C78DB8C890B Shining Force Gaiden - Final Conflict (J) GG Strategy;RPG SRAM=32768 Japan
|
||||
8857422E565412A59C77CB29550715E4 Shining Force Gaiden II - Jashin no Kakusei (J) GG Strategy;RPG SRAM=24576 Japan
|
||||
0A0FA9CBCC3DB467191E907794C8C02B Shining Force II - The Sword of Hajya (U) GG Strategy;RPG SRAM=24576 USA
|
||||
8857422E565412A59C77CB29550715E4 Shining Force Gaiden II - Jashin no Kakusei (J) GG Strategy;RPG SRAM=32768 Japan
|
||||
0A0FA9CBCC3DB467191E907794C8C02B Shining Force II - The Sword of Hajya (U) GG Strategy;RPG SRAM=32768 USA
|
||||
48D741774004EAB9C19C1DD43758BF2B Shinobi II - The Silent Fury (W) (Ja) GG World
|
||||
8FA7438DEC1403F2E9D7B1CA60B29F1A Shinobi (UE) GG USA;Europe
|
||||
21D2E4E7C508E6ABBB12BB96C7AAC868 Shinobi (J) GG Japan
|
||||
|
|
|
@ -340,8 +340,8 @@ namespace BizHawk.Client.ApiHawk
|
|||
{
|
||||
AutoFireStickyXorAdapter joypadAdaptor = Global.AutofireStickyXORAdapter;
|
||||
|
||||
IEnumerable<string> pressedButtons = from button in joypadAdaptor.Type.BoolButtons
|
||||
where joypadAdaptor[button]
|
||||
IEnumerable<string> pressedButtons = from button in joypadAdaptor.Definition.BoolButtons
|
||||
where joypadAdaptor.IsPressed(button)
|
||||
select button;
|
||||
|
||||
foreach (Joypad j in allJoypads)
|
||||
|
|
|
@ -83,7 +83,8 @@ namespace BizHawk.Client.ApiHawk
|
|||
ToolStripMenuItem item = null;
|
||||
|
||||
try
|
||||
{
|
||||
{
|
||||
BizHawk.Common.Win32Hacks.RemoveMOTW(fileName);
|
||||
externalToolFile = Assembly.LoadFrom(fileName);
|
||||
object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false);
|
||||
if (attributes != null && attributes.Count() == 1)
|
||||
|
|
|
@ -154,9 +154,14 @@
|
|||
<Compile Include="Global.cs" />
|
||||
<Compile Include="inputAdapters\AutoPattern.cs" />
|
||||
<Compile Include="inputAdapters\BitwiseAdapters.cs" />
|
||||
<Compile Include="inputAdapters\ClickyVirtualPadController.cs" />
|
||||
<Compile Include="inputAdapters\CopyController.cs" />
|
||||
<Compile Include="inputAdapters\InputAdapterExtensions.cs" />
|
||||
<Compile Include="inputAdapters\InputAdapters.cs" />
|
||||
<Compile Include="inputAdapters\StickyAdapters.cs" />
|
||||
<Compile Include="inputAdapters\InputManager.cs" />
|
||||
<Compile Include="inputAdapters\OverrideAdaptor.cs" />
|
||||
<Compile Include="inputAdapters\SimpleController.cs" />
|
||||
<Compile Include="inputAdapters\UDLRController.cs" />
|
||||
<Compile Include="IonicZipWriter.cs" />
|
||||
<Compile Include="IPS.cs" />
|
||||
<Compile Include="IZipWriter.cs" />
|
||||
|
|
|
@ -9,14 +9,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public class Controller : IController
|
||||
{
|
||||
private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>();
|
||||
private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>();
|
||||
private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>();
|
||||
private readonly Dictionary<string, ControllerDefinition.FloatRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.FloatRange>();
|
||||
private readonly Dictionary<string, Config.AnalogBind> _floatBinds = new Dictionary<string, Config.AnalogBind>();
|
||||
|
||||
private ControllerDefinition _type;
|
||||
|
||||
public Controller(ControllerDefinition definition)
|
||||
{
|
||||
_type = definition;
|
||||
|
@ -27,16 +19,37 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public ControllerDefinition Type { get { return _type; } }
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
|
||||
/// <summary>don't do this</summary>
|
||||
public void ForceType(ControllerDefinition newtype) { _type = newtype; }
|
||||
public bool this[string button] { get { return IsPressed(button); } }
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return _buttons[button];
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return _floatButtons[name];
|
||||
}
|
||||
|
||||
private readonly WorkingDictionary<string, List<string>> _bindings = new WorkingDictionary<string, List<string>>();
|
||||
private readonly WorkingDictionary<string, bool> _buttons = new WorkingDictionary<string, bool>();
|
||||
private readonly WorkingDictionary<string, float> _floatButtons = new WorkingDictionary<string, float>();
|
||||
private readonly Dictionary<string, ControllerDefinition.FloatRange> _floatRanges = new WorkingDictionary<string, ControllerDefinition.FloatRange>();
|
||||
private readonly Dictionary<string, Config.AnalogBind> _floatBinds = new Dictionary<string, Config.AnalogBind>();
|
||||
|
||||
private ControllerDefinition _type;
|
||||
|
||||
/// <summary>don't do this</summary>
|
||||
public void ForceType(ControllerDefinition newtype) { _type = newtype; }
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get { return IsPressed(button); }
|
||||
}
|
||||
|
||||
public bool AnyPressed
|
||||
{
|
||||
get
|
||||
|
@ -50,8 +63,6 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public float GetFloat(string name) { return _floatButtons[name]; }
|
||||
|
||||
// Looks for bindings which are activated by the supplied physical button.
|
||||
public List<string> SearchBindings(string button)
|
||||
{
|
||||
|
@ -132,7 +143,7 @@ namespace BizHawk.Client.Common
|
|||
_buttons[kvp.Key] = false;
|
||||
foreach (var bound_button in kvp.Value)
|
||||
{
|
||||
if (controller[bound_button])
|
||||
if (controller.IsPressed(bound_button))
|
||||
{
|
||||
_buttons[kvp.Key] = true;
|
||||
}
|
||||
|
@ -165,9 +176,9 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
// change: or from each button that the other input controller has
|
||||
// foreach (string button in type.BoolButtons)
|
||||
if (controller.Type != null)
|
||||
if (controller.Definition != null)
|
||||
{
|
||||
foreach (var button in controller.Type.BoolButtons)
|
||||
foreach (var button in controller.Definition.BoolButtons)
|
||||
{
|
||||
if (controller.IsPressed(button))
|
||||
{
|
||||
|
@ -181,7 +192,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
foreach (var button in controller.Overrides)
|
||||
{
|
||||
_buttons[button] = controller[button];
|
||||
_buttons[button] = controller.IsPressed(button);
|
||||
}
|
||||
|
||||
foreach (var button in controller.FloatOverrides)
|
||||
|
@ -259,8 +270,8 @@ namespace BizHawk.Client.Common
|
|||
public int On { get; set; }
|
||||
public int Off { get; set; }
|
||||
|
||||
public ControllerDefinition Type { get { return _type; } }
|
||||
public bool this[string button] { get { return IsPressed(button); } }
|
||||
public ControllerDefinition Definition { get { return _type; } }
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
if (_autofire)
|
||||
|
@ -295,7 +306,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
foreach (var bound_button in kvp.Value)
|
||||
{
|
||||
if (_buttons[kvp.Key] == false && controller[bound_button])
|
||||
if (_buttons[kvp.Key] == false && controller.IsPressed(bound_button))
|
||||
{
|
||||
_buttonStarts[kvp.Key] = _emulator.Frame;
|
||||
}
|
||||
|
@ -308,7 +319,7 @@ namespace BizHawk.Client.Common
|
|||
_buttons[kvp.Key] = false;
|
||||
foreach (var bound_button in kvp.Value)
|
||||
{
|
||||
if (controller[bound_button])
|
||||
if (controller.IsPressed(bound_button))
|
||||
{
|
||||
_buttons[kvp.Key] = true;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ using BizHawk.Emulation.Cores.ColecoVision;
|
|||
using BizHawk.Emulation.Cores.Computers.Commodore64;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
|
||||
using GPGX64=BizHawk.Emulation.Cores.Consoles.Sega.gpgx64;
|
||||
using BizHawk.Emulation.Cores.Intellivision;
|
||||
using BizHawk.Emulation.Cores.Nintendo.Gameboy;
|
||||
using BizHawk.Emulation.Cores.Nintendo.GBA;
|
||||
|
@ -474,9 +475,16 @@ namespace BizHawk.Client.Common
|
|||
switch (game.System)
|
||||
{
|
||||
case "GEN":
|
||||
var genesis = new GPGX(
|
||||
nextComm, null, disc, GetCoreSettings<GPGX>(), GetCoreSyncSettings<GPGX>());
|
||||
nextEmulator = genesis;
|
||||
if (Environment.Is64BitProcess)
|
||||
{
|
||||
var genesis = new GPGX64.GPGX(nextComm, null, disc, GetCoreSettings<GPGX64.GPGX>(), GetCoreSyncSettings<GPGX64.GPGX>());
|
||||
nextEmulator = genesis;
|
||||
}
|
||||
else
|
||||
{
|
||||
var genesis = new GPGX(nextComm, null, disc, GetCoreSettings<GPGX>(), GetCoreSyncSettings<GPGX>());
|
||||
nextEmulator = genesis;
|
||||
}
|
||||
break;
|
||||
case "SAT":
|
||||
nextEmulator = new Yabause(nextComm, disc, GetCoreSyncSettings<Yabause>());
|
||||
|
@ -750,7 +758,7 @@ namespace BizHawk.Client.Common
|
|||
if(Global.Config.NES_InQuickNES) preference = "quicknes";
|
||||
|
||||
//if user has saw fit to override in gamedb, apply that
|
||||
if(Global.Config.CoreForcingViaGameDB)
|
||||
if (Global.Config.CoreForcingViaGameDB && !string.IsNullOrEmpty(game.ForcedCore))
|
||||
preference = game.ForcedCore;
|
||||
|
||||
//but only neshawk is accurate
|
||||
|
@ -816,8 +824,11 @@ namespace BizHawk.Client.Common
|
|||
nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
|
||||
break;
|
||||
case "GEN":
|
||||
// discard "Genplus-gx64", auto-added due to implementing IEmulator
|
||||
core = CoreInventory.Instance["GEN", "Genplus-gx"];
|
||||
// discard "Genplus-gx64", auto-added due to implementing IEmulator // HUH?
|
||||
//core = CoreInventory.Instance["GEN", "Genplus-gx"];
|
||||
if (Environment.Is64BitProcess)
|
||||
core = CoreInventory.Instance["GEN", "Genplus-gx64"];
|
||||
else core = CoreInventory.Instance["GEN", "Genplus-gx"];
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace BizHawk.Client.Common
|
|||
bs.PutLump(BinaryStateLump.Corestate, bw => core.SaveStateBinary(bw));
|
||||
}
|
||||
|
||||
if (Global.Config.SaveScreenshotWithStates)
|
||||
if (Global.Config.SaveScreenshotWithStates && Global.Emulator.HasVideoProvider())
|
||||
{
|
||||
var vp = Global.Emulator.VideoProvider();
|
||||
var vp = Global.Emulator.AsVideoProvider();
|
||||
var buff = vp.GetVideoBuffer();
|
||||
if (buff.Length == 1)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ namespace BizHawk.Client.Common
|
|||
out_h /= 2;
|
||||
}
|
||||
using (new SimpleTime("Save Framebuffer"))
|
||||
bs.PutLump(BinaryStateLump.Framebuffer, (s) => QuickBmpFile.Save(Global.Emulator.VideoProvider(), s, out_w, out_h));
|
||||
bs.PutLump(BinaryStateLump.Framebuffer, (s) => QuickBmpFile.Save(Global.Emulator.AsVideoProvider(), s, out_w, out_h));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,14 +96,19 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public static void PopulateFramebuffer(BinaryReader br)
|
||||
{
|
||||
if (!Global.Emulator.HasVideoProvider())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (new SimpleTime("Load Framebuffer"))
|
||||
QuickBmpFile.Load(Global.Emulator.VideoProvider(), br.BaseStream);
|
||||
QuickBmpFile.Load(Global.Emulator.AsVideoProvider(), br.BaseStream);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var buff = Global.Emulator.VideoProvider().GetVideoBuffer();
|
||||
var buff = Global.Emulator.AsVideoProvider().GetVideoBuffer();
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < buff.Length; i++)
|
||||
|
@ -219,9 +224,9 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
var args = str.Split(' ');
|
||||
if (args[0] == "Framebuffer")
|
||||
if (args[0] == "Framebuffer" && Global.Emulator.HasVideoProvider())
|
||||
{
|
||||
Global.Emulator.VideoProvider().GetVideoBuffer().ReadFromHex(args[1]);
|
||||
Global.Emulator.AsVideoProvider().GetVideoBuffer().ReadFromHex(args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ namespace BizHawk.Client.Common
|
|||
Bind("General", "Exit Program"),
|
||||
Bind("General", "Screen Raw to Clipboard", "Ctrl+C"),
|
||||
Bind("General", "Screen Client to Clipboard", "Ctrl+Shift+C"),
|
||||
Bind("General", "Toggle Skip Lag Frame"),
|
||||
|
||||
Bind("Save States", "Save State 0", "Shift+F10"),
|
||||
Bind("Save States", "Save State 1", "Shift+F1"),
|
||||
|
@ -229,6 +230,12 @@ namespace BizHawk.Client.Common
|
|||
Bind("TAStudio", "Insert Frame", "Insert"),
|
||||
Bind("TAStudio", "Delete Frames", "Ctrl+Delete"),
|
||||
Bind("TAStudio", "Clone Frames", "Ctrl+Insert"),
|
||||
Bind("TAStudio", "Analog Increment", "UpArrow"),
|
||||
Bind("TAStudio", "Analog Decrement", "DownArrow"),
|
||||
Bind("TAStudio", "Analog Incr. by 10", "Shift+UpArrow"),
|
||||
Bind("TAStudio", "Analog Decr. by 10", "Shift+DownArrow"),
|
||||
Bind("TAStudio", "Analog Maximum", "RightArrow"),
|
||||
Bind("TAStudio", "Analog Minimum", "LeftArrow"),
|
||||
|
||||
Bind("SNES", "Toggle BG 1"),
|
||||
Bind("SNES", "Toggle BG 2"),
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public int TargetScanlineFilterIntensity = 128; // choose between 0 and 256
|
||||
public int TargetDisplayFilter = 0;
|
||||
public int DispFinalFilter = 1; //bilinear
|
||||
public int DispFinalFilter = 0; //None
|
||||
public string DispUserFilterPath = "";
|
||||
public RecentFiles RecentRoms = new RecentFiles(10);
|
||||
public RecentFiles RecentRomSessions = new RecentFiles(8); // Only used for MultiHawk
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Drawing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
|
@ -56,6 +58,25 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the top left corner coordinate, if Wndx and Wndy form a valid point
|
||||
/// Throws an InvalidOperationException if Wndx or Wndy is null
|
||||
/// It is expected to check for this before using this property
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public Point TopLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_wndx.HasValue && _wndy.HasValue)
|
||||
{
|
||||
return new Point(_wndx.Value, _wndy.Value);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("TopLeft can not be used when one of the coordinates is null");
|
||||
}
|
||||
}
|
||||
|
||||
public int? Width { get; set; }
|
||||
public int? Height { get; set; }
|
||||
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class AutoPatternBool
|
||||
{
|
||||
|
|
|
@ -1,74 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class AndAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
if (Source != null && SourceAnd != null)
|
||||
{
|
||||
return Source.IsPressed(button) & SourceAnd.IsPressed(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// pass floats solely from the original source
|
||||
// this works in the code because SourceOr is the autofire controller
|
||||
public float GetFloat(string name) { return Source.GetFloat(name); }
|
||||
|
||||
public IController Source { get; set; }
|
||||
public IController SourceAnd { get; set; }
|
||||
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||
|
||||
public bool this[string button]
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Source != null && SourceAnd != null)
|
||||
{
|
||||
return Source[button] & SourceAnd[button];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
internal IController Source { get; set; }
|
||||
internal IController SourceAnd { get; set; }
|
||||
}
|
||||
|
||||
public class ORAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
return (Source != null ? Source.IsPressed(button) : false)
|
||||
| (SourceOr != null ? SourceOr.IsPressed(button) : false);
|
||||
}
|
||||
|
||||
// pass floats solely from the original source
|
||||
// this works in the code because SourceOr is the autofire controller
|
||||
public float GetFloat(string name) { return Source.GetFloat(name); }
|
||||
|
||||
public IController Source { get; set; }
|
||||
public IController SourceOr { get; set; }
|
||||
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||
|
||||
public bool this[string button]
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Source != null ? Source[button] : false) |
|
||||
(SourceOr != null ? SourceOr[button] : false);
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
internal IController Source { get; set; }
|
||||
internal IController SourceOr { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
using System.Collections.Generic;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Will hold buttons for 1 frame and then release them.
|
||||
/// (Calling Click() from your button click is what you want to do)
|
||||
/// TODO - should the duration be controllable?
|
||||
/// </summary>
|
||||
public class ClickyVirtualPadController : IController
|
||||
{
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return _pressed.Contains(button);
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this once per frame to do the timekeeping for the hold and release
|
||||
/// </summary>
|
||||
public void FrameTick()
|
||||
{
|
||||
_pressed.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this to hold the button down for one frame
|
||||
/// </summary>
|
||||
public void Click(string button)
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
|
||||
public void Unclick(string button)
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
|
||||
public void Toggle(string button)
|
||||
{
|
||||
if (IsPressed(button))
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBool(string button, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HashSet<string> _pressed = new HashSet<string>();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints.
|
||||
/// </summary>
|
||||
public class CopyControllerAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Curr.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return Curr.IsPressed(button);
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Curr.GetFloat(name);
|
||||
}
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
private IController Curr
|
||||
{
|
||||
get
|
||||
{
|
||||
return Source == null
|
||||
? NullController.Instance
|
||||
: Source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common.InputAdapterExtensions
|
||||
{
|
||||
|
|
|
@ -1,889 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// will hold buttons for 1 frame and then release them. (Calling Click() from your button click is what you want to do)
|
||||
/// TODO - should the duration be controllable?
|
||||
/// </summary>
|
||||
public class ClickyVirtualPadController : IController
|
||||
{
|
||||
public ControllerDefinition Type { get; set; }
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get { return IsPressed(button); }
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// TODO
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return _pressed.Contains(button);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// call this once per frame to do the timekeeping for the hold and release
|
||||
/// </summary>
|
||||
public void FrameTick()
|
||||
{
|
||||
_pressed.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// call this to hold the button down for one frame
|
||||
/// </summary>
|
||||
public void Click(string button)
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
|
||||
public void Unclick(string button)
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
|
||||
public void Toggle(string button)
|
||||
{
|
||||
if (IsPressed(button))
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBool(string button, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_pressed.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
_pressed.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HashSet<string> _pressed = new HashSet<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters input for things called Up and Down while considering the client's AllowUD_LR option.
|
||||
/// This is a bit gross but it is unclear how to do it more nicely
|
||||
/// </summary>
|
||||
public class UD_LR_ControllerAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Type
|
||||
{
|
||||
get { return Source.Type; }
|
||||
}
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get { return IsPressed(button); }
|
||||
}
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
// The float format implies no U+D and no L+R no matter what, so just passthru
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
HashSet<string> Unpresses = new HashSet<string>();
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
bool PriorityUD_LR = !Global.Config.AllowUD_LR && !Global.Config.ForbidUD_LR; //implied by neither of the others being set (left as non-enum for back-compatibility)
|
||||
|
||||
|
||||
if (Global.Config.AllowUD_LR)
|
||||
{
|
||||
return Source.IsPressed(button);
|
||||
}
|
||||
|
||||
string prefix;
|
||||
|
||||
//" C " is for N64 "P1 C Up" and the like, which should not be subject to mutexing
|
||||
|
||||
//regarding the unpressing and UDLR logic...... don't think about it. don't question it. don't look at it.
|
||||
|
||||
if (button.Contains("Down") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button)) Unpresses.Remove(button);
|
||||
prefix = button.GetPrecedingString("Down");
|
||||
string other = prefix + "Up";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button)) return false;
|
||||
if (Global.Config.ForbidUD_LR) return false;
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
if (button.Contains("Up") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button)) Unpresses.Remove(button);
|
||||
prefix = button.GetPrecedingString("Up");
|
||||
string other = prefix + "Down";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button)) return false;
|
||||
if (Global.Config.ForbidUD_LR) return false;
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
|
||||
if (button.Contains("Right") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button)) Unpresses.Remove(button);
|
||||
prefix = button.GetPrecedingString("Right");
|
||||
string other = prefix + "Left";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button)) return false;
|
||||
if (Global.Config.ForbidUD_LR) return false;
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
if (button.Contains("Left") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button)) Unpresses.Remove(button);
|
||||
prefix = button.GetPrecedingString("Left");
|
||||
string other = prefix + "Right";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button)) return false;
|
||||
if (Global.Config.ForbidUD_LR) return false;
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
return Source.IsPressed(button);
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleController : IController
|
||||
{
|
||||
public ControllerDefinition Type { get; set; }
|
||||
|
||||
protected WorkingDictionary<string, bool> Buttons = new WorkingDictionary<string, bool>();
|
||||
protected WorkingDictionary<string, float> Floats = new WorkingDictionary<string, float>();
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
Buttons = new WorkingDictionary<string, bool>();
|
||||
Floats = new WorkingDictionary<string, float>();
|
||||
}
|
||||
|
||||
public virtual bool this[string button]
|
||||
{
|
||||
get { return Buttons[button]; }
|
||||
set { Buttons[button] = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Floats[name];
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, bool>> BoolButtons()
|
||||
{
|
||||
return Buttons;
|
||||
}
|
||||
|
||||
public virtual void LatchFrom(IController source)
|
||||
{
|
||||
foreach (var button in source.Type.BoolButtons)
|
||||
{
|
||||
Buttons[button] = source[button];
|
||||
}
|
||||
}
|
||||
|
||||
public void AcceptNewFloats(IEnumerable<Tuple<string, float>> newValues)
|
||||
{
|
||||
foreach (var sv in newValues)
|
||||
{
|
||||
Floats[sv.Item1] = sv.Item2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by input display, to determine if either autofire or regular stickies are "in effect" because we color this scenario differently
|
||||
public class StickyOrAdapter : IController
|
||||
{
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
|
||||
// pass floats solely from the original source
|
||||
// this works in the code because SourceOr is the autofire controller
|
||||
public float GetFloat(string name) { return 0.0F; } // Floats don't make sense in sticky land
|
||||
|
||||
public ISticky Source { get; set; }
|
||||
public ISticky SourceStickyOr { get; set; }
|
||||
public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get
|
||||
{
|
||||
return Source.StickyIsInEffect(button) ||
|
||||
SourceStickyOr.StickyIsInEffect(button);
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface ISticky : IController
|
||||
{
|
||||
bool StickyIsInEffect(string button);
|
||||
}
|
||||
|
||||
public class StickyXorAdapter : IController, ISticky
|
||||
{
|
||||
protected HashSet<string> stickySet = new HashSet<string>();
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
public ControllerDefinition Type
|
||||
{
|
||||
get { return Source.Type; }
|
||||
set { throw new InvalidOperationException(); }
|
||||
}
|
||||
|
||||
public bool Locked { get; set; } // Pretty much a hack,
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
|
||||
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
|
||||
// otherwise, the source is passed thru.
|
||||
protected readonly WorkingDictionary<string, float?> _floatSet = new WorkingDictionary<string, float?>();
|
||||
|
||||
public void SetFloat(string name, float? value)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
_floatSet[name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatSet.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
var val = _floatSet[name];
|
||||
|
||||
if (val.HasValue)
|
||||
{
|
||||
return val.Value;
|
||||
}
|
||||
|
||||
if (Source == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
public void ClearStickyFloats()
|
||||
{
|
||||
_floatSet.Clear();
|
||||
}
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get
|
||||
{
|
||||
var source = Source[button];
|
||||
source ^= stickySet.Contains(button);
|
||||
return source;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a sticky is current mashing the button itself,
|
||||
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||
/// </summary>
|
||||
public bool StickyIsInEffect(string button)
|
||||
{
|
||||
if (IsSticky(button))
|
||||
{
|
||||
return !Source.IsPressed(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetSticky(string button, bool isSticky)
|
||||
{
|
||||
if (isSticky)
|
||||
{
|
||||
stickySet.Add(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void Unset(string button)
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
_floatSet.Remove(button);
|
||||
}
|
||||
|
||||
public bool IsSticky(string button)
|
||||
{
|
||||
return stickySet.Contains(button);
|
||||
}
|
||||
|
||||
public HashSet<string> CurrentStickies
|
||||
{
|
||||
get
|
||||
{
|
||||
return stickySet;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickies()
|
||||
{
|
||||
stickySet.Clear();
|
||||
_floatSet.Clear();
|
||||
}
|
||||
|
||||
public void MassToggleStickyState(List<string> buttons)
|
||||
{
|
||||
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
|
||||
{
|
||||
if (stickySet.Contains(button))
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
stickySet.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
_justPressed = buttons;
|
||||
}
|
||||
|
||||
private List<string> _justPressed = new List<string>();
|
||||
}
|
||||
|
||||
///// SuuperW: I'm leaving the old class in case I accidentally screwed something up
|
||||
//public class AutoFireStickyXorAdapter : IController, ISticky
|
||||
//{
|
||||
// public int On { get; set; }
|
||||
// public int Off { get; set; }
|
||||
// public WorkingDictionary<string, int> buttonStarts = new WorkingDictionary<string, int>();
|
||||
// public WorkingDictionary<string, int> lagStarts = new WorkingDictionary<string, int>(); // TODO: need a data structure not misc dictionaries
|
||||
|
||||
// private readonly HashSet<string> _stickySet = new HashSet<string>();
|
||||
|
||||
// public IController Source { get; set; }
|
||||
|
||||
// public void SetOnOffPatternFromConfig()
|
||||
// {
|
||||
// On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
|
||||
// Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff;
|
||||
// }
|
||||
|
||||
// public AutoFireStickyXorAdapter()
|
||||
// {
|
||||
// //On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
|
||||
// //Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff;
|
||||
// On = 1;
|
||||
// Off = 1;
|
||||
// }
|
||||
|
||||
// public bool IsPressed(string button)
|
||||
// {
|
||||
// return this[button];
|
||||
// }
|
||||
|
||||
// public bool this[string button]
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// var source = Source[button];
|
||||
|
||||
// if (_stickySet.Contains(button))
|
||||
// {
|
||||
// var lagcount = 0;
|
||||
// if (Global.Emulator.CanPollInput() && Global.Config.AutofireLagFrames)
|
||||
// {
|
||||
// lagcount = Global.Emulator.AsInputPollable().LagCount;
|
||||
// }
|
||||
|
||||
// var a = ((Global.Emulator.Frame - lagcount) - (buttonStarts[button] - lagStarts[button])) % (On + Off);
|
||||
// if (a < On)
|
||||
// {
|
||||
// return source ^= true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return source ^= false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return source;
|
||||
// }
|
||||
|
||||
// set
|
||||
// {
|
||||
// throw new InvalidOperationException();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public ControllerDefinition Type { get { return Source.Type; } set { throw new InvalidOperationException(); } }
|
||||
// public bool Locked { get; set; } // Pretty much a hack,
|
||||
|
||||
// // dumb passthrough for floats, because autofire doesn't care about them
|
||||
// public float GetFloat(string name)
|
||||
// {
|
||||
// return Source.GetFloat(name);
|
||||
// }
|
||||
|
||||
// public void SetSticky(string button, bool isSticky)
|
||||
// {
|
||||
// if (isSticky)
|
||||
// {
|
||||
// _stickySet.Add(button);
|
||||
// buttonStarts.Add(button, Global.Emulator.Frame);
|
||||
|
||||
// if (Global.Emulator.CanPollInput())
|
||||
// {
|
||||
// lagStarts.Add(button, Global.Emulator.AsInputPollable().LagCount);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// lagStarts.Add(button, 0);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _stickySet.Remove(button);
|
||||
// buttonStarts.Remove(button);
|
||||
// lagStarts.Remove(button);
|
||||
// }
|
||||
// }
|
||||
|
||||
// public bool IsSticky(string button)
|
||||
// {
|
||||
// return this._stickySet.Contains(button);
|
||||
// }
|
||||
|
||||
// public HashSet<string> CurrentStickies
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return this._stickySet;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public void ClearStickies()
|
||||
// {
|
||||
// _stickySet.Clear();
|
||||
// buttonStarts.Clear();
|
||||
// lagStarts.Clear();
|
||||
// }
|
||||
|
||||
// public void MassToggleStickyState(List<string> buttons)
|
||||
// {
|
||||
// foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
|
||||
// {
|
||||
// if (_stickySet.Contains(button))
|
||||
// {
|
||||
// _stickySet.Remove(button);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _stickySet.Add(button);
|
||||
// }
|
||||
// }
|
||||
|
||||
// _justPressed = buttons;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Determines if a sticky is current mashing the button itself,
|
||||
// /// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||
// /// </summary>
|
||||
// public bool StickyIsInEffect(string button)
|
||||
// {
|
||||
// if (Source.IsPressed(button))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return (IsPressed(button)); // Shortcut logic since we know the Source isn't pressed, Ispressed can only return true if the autofire sticky is in effect for this frame
|
||||
// }
|
||||
|
||||
// private List<string> _justPressed = new List<string>();
|
||||
//}
|
||||
|
||||
// commenting this out, it breaks the autofire hotkey
|
||||
public class AutoFireStickyXorAdapter : IController, ISticky
|
||||
{
|
||||
// TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0?
|
||||
// Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once.
|
||||
private int On;
|
||||
private int Off;
|
||||
public void SetOnOffPatternFromConfig()
|
||||
{
|
||||
On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
|
||||
Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff;
|
||||
}
|
||||
|
||||
private WorkingDictionary<string, AutoPatternBool> _boolPatterns = new WorkingDictionary<string, AutoPatternBool>();
|
||||
private WorkingDictionary<string, AutoPatternFloat> _floatPatterns = new WorkingDictionary<string, AutoPatternFloat>();
|
||||
|
||||
public AutoFireStickyXorAdapter()
|
||||
{
|
||||
On = 1; Off = 1;
|
||||
}
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
public ControllerDefinition Type
|
||||
{
|
||||
get { return Source.Type; }
|
||||
}
|
||||
|
||||
public bool Locked { get; set; } // Pretty much a hack,
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float? value, AutoPatternFloat pattern = null)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
if (pattern == null)
|
||||
pattern = new AutoPatternFloat(value.Value, On, 0, Off);
|
||||
_floatPatterns[name] = pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatPatterns.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
if (_floatPatterns.ContainsKey(name))
|
||||
return _floatPatterns[name].PeekNextValue();
|
||||
|
||||
if (Source == null)
|
||||
return 0;
|
||||
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
public void ClearStickyFloats()
|
||||
{
|
||||
_floatPatterns.Clear();
|
||||
}
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get
|
||||
{
|
||||
var source = Source[button];
|
||||
bool patternValue = false;
|
||||
if (_boolPatterns.ContainsKey(button))
|
||||
{ // I can't figure a way to determine right here if it should Peek or Get.
|
||||
patternValue = _boolPatterns[button].PeekNextValue();
|
||||
}
|
||||
source ^= patternValue;
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a sticky is current mashing the button itself,
|
||||
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||
/// </summary>
|
||||
public bool StickyIsInEffect(string button)
|
||||
{
|
||||
if (IsSticky(button))
|
||||
{
|
||||
return !Source.IsPressed(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetSticky(string button, bool isSticky, AutoPatternBool pattern = null)
|
||||
{
|
||||
if (isSticky)
|
||||
{
|
||||
if (pattern == null)
|
||||
pattern = new AutoPatternBool(On, Off);
|
||||
_boolPatterns[button] = pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_boolPatterns.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void Unset(string button)
|
||||
{
|
||||
_boolPatterns.Remove(button);
|
||||
_floatPatterns.Remove(button);
|
||||
}
|
||||
|
||||
public bool IsSticky(string button)
|
||||
{
|
||||
return _boolPatterns.ContainsKey(button) || _floatPatterns.ContainsKey(button);
|
||||
}
|
||||
|
||||
public HashSet<string> CurrentStickies
|
||||
{
|
||||
get
|
||||
{
|
||||
return new HashSet<string>(_boolPatterns.Keys);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickies()
|
||||
{
|
||||
_boolPatterns.Clear();
|
||||
_floatPatterns.Clear();
|
||||
}
|
||||
|
||||
public void IncrementLoops(bool lagged)
|
||||
{
|
||||
for (int i = 0; i < _boolPatterns.Count; i++)
|
||||
_boolPatterns.ElementAt(i).Value.GetNextValue(lagged);
|
||||
for (int i = 0; i < _floatPatterns.Count; i++)
|
||||
_floatPatterns.ElementAt(i).Value.GetNextValue(lagged);
|
||||
}
|
||||
|
||||
private List<string> _justPressed = new List<string>();
|
||||
public void MassToggleStickyState(List<string> buttons)
|
||||
{
|
||||
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
|
||||
{
|
||||
if (_boolPatterns.ContainsKey(button))
|
||||
SetSticky(button, false);
|
||||
else
|
||||
SetSticky(button, true);
|
||||
}
|
||||
|
||||
_justPressed = buttons;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints.
|
||||
/// </summary>
|
||||
public class CopyControllerAdapter : IController
|
||||
{
|
||||
public IController Source { get; set; }
|
||||
|
||||
private readonly NullController _null = new NullController();
|
||||
|
||||
private IController Curr
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Source == null)
|
||||
{
|
||||
return _null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ControllerDefinition Type
|
||||
{
|
||||
get { return Curr.Type; }
|
||||
}
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get { return Curr[button]; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return Curr.IsPressed(button);
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Curr.GetFloat(name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to pass into an Override method to manage the logic overriding input
|
||||
/// This only works with bool buttons!
|
||||
/// </summary>
|
||||
public class OverrideAdaptor : IController
|
||||
{
|
||||
private readonly Dictionary<string, bool> _overrides = new Dictionary<string, bool>();
|
||||
private readonly Dictionary<string, float> _floatOverrides = new Dictionary<string, float>();
|
||||
private readonly List<string> _inverses = new List<string>();
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_overrides.ContainsKey(button))
|
||||
{
|
||||
return _overrides[button];
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_overrides.ContainsKey(button))
|
||||
{
|
||||
_overrides[button] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_overrides.Add(button, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ControllerDefinition Type { get; set; }
|
||||
|
||||
public IEnumerable<string> Overrides
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var kvp in _overrides)
|
||||
{
|
||||
yield return kvp.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> FloatOverrides
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var kvp in _floatOverrides)
|
||||
{
|
||||
yield return kvp.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> InversedButtons
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var name in _inverses)
|
||||
{
|
||||
yield return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
if (_floatOverrides.ContainsKey(name))
|
||||
{
|
||||
_floatOverrides[name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatOverrides.Add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
if (_floatOverrides.ContainsKey(name))
|
||||
{
|
||||
return _floatOverrides[name];
|
||||
}
|
||||
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public bool IsPressed(string button) { return this[button]; }
|
||||
|
||||
public void SetButton(string button, bool value)
|
||||
{
|
||||
this[button] = value;
|
||||
_inverses.Remove(button);
|
||||
}
|
||||
|
||||
public void UnSet(string button)
|
||||
{
|
||||
_overrides.Remove(button);
|
||||
_inverses.Remove(button);
|
||||
}
|
||||
|
||||
public void SetInverse(string button)
|
||||
{
|
||||
_inverses.Add(button);
|
||||
}
|
||||
|
||||
public void FrameTick()
|
||||
{
|
||||
_overrides.Clear();
|
||||
_floatOverrides.Clear();
|
||||
_inverses.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
|
|||
public static void RewireInputChain()
|
||||
{
|
||||
Global.ControllerInputCoalescer.Clear();
|
||||
Global.ControllerInputCoalescer.Type = Global.ActiveController.Type;
|
||||
Global.ControllerInputCoalescer.Definition = Global.ActiveController.Definition;
|
||||
|
||||
Global.UD_LR_ControllerAdapter.Source = Global.ActiveController.Or(Global.AutoFireController);
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace BizHawk.Client.Common
|
|||
Global.ControllerOutput.Source = Global.MovieOutputHardpoint;
|
||||
|
||||
Global.Emulator.Controller = Global.ControllerOutput;
|
||||
Global.MovieSession.MovieControllerAdapter.Type = Global.MovieInputSourceAdapter.Type;
|
||||
Global.MovieSession.MovieControllerAdapter.Definition = Global.MovieInputSourceAdapter.Definition;
|
||||
|
||||
// connect the movie session before MovieOutputHardpoint if it is doing anything
|
||||
// otherwise connect the MovieInputSourceAdapter to it, effectively bypassing the movie session
|
||||
|
@ -45,7 +45,7 @@ namespace BizHawk.Client.Common
|
|||
// allow propogating controls that are in the current controller definition but not in the prebaked one
|
||||
// these two lines shouldn't be required anymore under the new system?
|
||||
Global.ActiveController.ForceType(new ControllerDefinition(def));
|
||||
Global.ClickyVirtualPadController.Type = new ControllerDefinition(def);
|
||||
Global.ClickyVirtualPadController.Definition = new ControllerDefinition(def);
|
||||
RewireInputChain();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to pass into an Override method to manage the logic overriding input
|
||||
/// This only works with bool buttons!
|
||||
/// </summary>
|
||||
public class OverrideAdaptor : IController
|
||||
{
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
private readonly Dictionary<string, bool> _overrides = new Dictionary<string, bool>();
|
||||
private readonly Dictionary<string, float> _floatOverrides = new Dictionary<string, float>();
|
||||
private readonly List<string> _inverses = new List<string>();
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
if (_overrides.ContainsKey(button))
|
||||
{
|
||||
return _overrides[button];
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
if (_floatOverrides.ContainsKey(name))
|
||||
{
|
||||
return _floatOverrides[name];
|
||||
}
|
||||
|
||||
return 0.0F;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Overrides
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var kvp in _overrides)
|
||||
{
|
||||
yield return kvp.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> FloatOverrides
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var kvp in _floatOverrides)
|
||||
{
|
||||
yield return kvp.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> InversedButtons
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var name in _inverses)
|
||||
{
|
||||
yield return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
if (_floatOverrides.ContainsKey(name))
|
||||
{
|
||||
_floatOverrides[name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatOverrides.Add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetButton(string button, bool value)
|
||||
{
|
||||
if (_overrides.ContainsKey(button))
|
||||
{
|
||||
_overrides[button] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_overrides.Add(button, value);
|
||||
}
|
||||
|
||||
_inverses.Remove(button);
|
||||
}
|
||||
|
||||
public void UnSet(string button)
|
||||
{
|
||||
_overrides.Remove(button);
|
||||
_inverses.Remove(button);
|
||||
}
|
||||
|
||||
public void SetInverse(string button)
|
||||
{
|
||||
_inverses.Add(button);
|
||||
}
|
||||
|
||||
public void FrameTick()
|
||||
{
|
||||
_overrides.Clear();
|
||||
_floatOverrides.Clear();
|
||||
_inverses.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A basic implementation of IController
|
||||
/// </summary>
|
||||
public class SimpleController : IController
|
||||
{
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
||||
protected WorkingDictionary<string, bool> Buttons = new WorkingDictionary<string, bool>();
|
||||
protected WorkingDictionary<string, float> Floats = new WorkingDictionary<string, float>();
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
Buttons = new WorkingDictionary<string, bool>();
|
||||
Floats = new WorkingDictionary<string, float>();
|
||||
}
|
||||
|
||||
public virtual bool this[string button]
|
||||
{
|
||||
get { return Buttons[button]; }
|
||||
set { Buttons[button] = value; }
|
||||
}
|
||||
|
||||
public virtual bool IsPressed(string button)
|
||||
{
|
||||
return this[button];
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Floats[name];
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, bool>> BoolButtons()
|
||||
{
|
||||
return Buttons;
|
||||
}
|
||||
|
||||
public virtual void LatchFrom(IController source)
|
||||
{
|
||||
foreach (var button in source.Definition.BoolButtons)
|
||||
{
|
||||
Buttons[button] = source.IsPressed(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void AcceptNewFloats(IEnumerable<Tuple<string, float>> newValues)
|
||||
{
|
||||
foreach (var sv in newValues)
|
||||
{
|
||||
Floats[sv.Item1] = sv.Item2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,325 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public interface ISticky : IController
|
||||
{
|
||||
bool StickyIsInEffect(string button);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by input display, to determine if either autofire or regular stickies
|
||||
/// are "in effect" because we color this scenario differently
|
||||
/// </summary>
|
||||
public class StickyOrAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return Source.StickyIsInEffect(button)
|
||||
|| SourceStickyOr.StickyIsInEffect(button);
|
||||
}
|
||||
|
||||
// pass floats solely from the original source
|
||||
// this works in the code because SourceOr is the autofire controller
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
int i = Source.Definition.FloatControls.IndexOf(name);
|
||||
return Source.Definition.FloatRanges[i].Mid; // Floats don't make sense in sticky land
|
||||
}
|
||||
|
||||
public ISticky Source { get; set; }
|
||||
public ISticky SourceStickyOr { get; set; }
|
||||
}
|
||||
|
||||
public class StickyXorAdapter : ISticky, IController
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if a sticky is current mashing the button itself,
|
||||
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||
/// </summary>
|
||||
public bool StickyIsInEffect(string button)
|
||||
{
|
||||
if (IsSticky(button))
|
||||
{
|
||||
return !Source.IsPressed(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
var source = Source.IsPressed(button);
|
||||
source ^= stickySet.Contains(button);
|
||||
return source;
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
var val = _floatSet[name];
|
||||
|
||||
if (val.HasValue)
|
||||
{
|
||||
return val.Value;
|
||||
}
|
||||
|
||||
if (Source == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
public bool Locked { get; set; } // Pretty much a hack,
|
||||
|
||||
private List<string> _justPressed = new List<string>();
|
||||
|
||||
protected readonly HashSet<string> stickySet = new HashSet<string>();
|
||||
|
||||
// if SetFloat() is called (typically virtual pads), then that float will entirely override the Source input
|
||||
// otherwise, the source is passed thru.
|
||||
protected readonly WorkingDictionary<string, float?> _floatSet = new WorkingDictionary<string, float?>();
|
||||
|
||||
public void SetFloat(string name, float? value)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
_floatSet[name] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatSet.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickyFloats()
|
||||
{
|
||||
_floatSet.Clear();
|
||||
}
|
||||
|
||||
public void SetSticky(string button, bool isSticky)
|
||||
{
|
||||
if (isSticky)
|
||||
{
|
||||
stickySet.Add(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void Unset(string button)
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
_floatSet.Remove(button);
|
||||
}
|
||||
|
||||
public bool IsSticky(string button)
|
||||
{
|
||||
return stickySet.Contains(button);
|
||||
}
|
||||
|
||||
public HashSet<string> CurrentStickies
|
||||
{
|
||||
get
|
||||
{
|
||||
return stickySet;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickies()
|
||||
{
|
||||
stickySet.Clear();
|
||||
_floatSet.Clear();
|
||||
}
|
||||
|
||||
public void MassToggleStickyState(List<string> buttons)
|
||||
{
|
||||
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
|
||||
{
|
||||
if (stickySet.Contains(button))
|
||||
{
|
||||
stickySet.Remove(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
stickySet.Add(button);
|
||||
}
|
||||
}
|
||||
|
||||
_justPressed = buttons;
|
||||
}
|
||||
}
|
||||
|
||||
public class AutoFireStickyXorAdapter : ISticky, IController
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if a sticky is current mashing the button itself,
|
||||
/// If sticky is not set then false, if set, it returns true if the Source is not pressed, else false
|
||||
/// </summary>
|
||||
public bool StickyIsInEffect(string button)
|
||||
{
|
||||
if (IsSticky(button))
|
||||
{
|
||||
return !Source.IsPressed(button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
var source = Source.IsPressed(button);
|
||||
bool patternValue = false;
|
||||
if (_boolPatterns.ContainsKey(button))
|
||||
{ // I can't figure a way to determine right here if it should Peek or Get.
|
||||
patternValue = _boolPatterns[button].PeekNextValue();
|
||||
}
|
||||
source ^= patternValue;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
if (_floatPatterns.ContainsKey(name))
|
||||
{
|
||||
return _floatPatterns[name].PeekNextValue();
|
||||
}
|
||||
|
||||
if (Source == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
// TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0?
|
||||
// Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once.
|
||||
private int On;
|
||||
private int Off;
|
||||
|
||||
public void SetOnOffPatternFromConfig()
|
||||
{
|
||||
On = Global.Config.AutofireOn < 1 ? 0 : Global.Config.AutofireOn;
|
||||
Off = Global.Config.AutofireOff < 1 ? 0 : Global.Config.AutofireOff;
|
||||
}
|
||||
|
||||
private WorkingDictionary<string, AutoPatternBool> _boolPatterns = new WorkingDictionary<string, AutoPatternBool>();
|
||||
private WorkingDictionary<string, AutoPatternFloat> _floatPatterns = new WorkingDictionary<string, AutoPatternFloat>();
|
||||
|
||||
public AutoFireStickyXorAdapter()
|
||||
{
|
||||
On = 1; Off = 1;
|
||||
}
|
||||
|
||||
public IController Source { get; set; }
|
||||
|
||||
public bool Locked { get; set; } // Pretty much a hack,
|
||||
|
||||
public void SetFloat(string name, float? value, AutoPatternFloat pattern = null)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
if (pattern == null)
|
||||
pattern = new AutoPatternFloat(value.Value, On, 0, Off);
|
||||
_floatPatterns[name] = pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatPatterns.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickyFloats()
|
||||
{
|
||||
_floatPatterns.Clear();
|
||||
}
|
||||
|
||||
public void SetSticky(string button, bool isSticky, AutoPatternBool pattern = null)
|
||||
{
|
||||
if (isSticky)
|
||||
{
|
||||
if (pattern == null)
|
||||
pattern = new AutoPatternBool(On, Off);
|
||||
_boolPatterns[button] = pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
_boolPatterns.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
public void Unset(string button)
|
||||
{
|
||||
_boolPatterns.Remove(button);
|
||||
_floatPatterns.Remove(button);
|
||||
}
|
||||
|
||||
public bool IsSticky(string button)
|
||||
{
|
||||
return _boolPatterns.ContainsKey(button) || _floatPatterns.ContainsKey(button);
|
||||
}
|
||||
|
||||
public HashSet<string> CurrentStickies
|
||||
{
|
||||
get
|
||||
{
|
||||
return new HashSet<string>(_boolPatterns.Keys);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearStickies()
|
||||
{
|
||||
_boolPatterns.Clear();
|
||||
_floatPatterns.Clear();
|
||||
}
|
||||
|
||||
public void IncrementLoops(bool lagged)
|
||||
{
|
||||
for (int i = 0; i < _boolPatterns.Count; i++)
|
||||
_boolPatterns.ElementAt(i).Value.GetNextValue(lagged);
|
||||
for (int i = 0; i < _floatPatterns.Count; i++)
|
||||
_floatPatterns.ElementAt(i).Value.GetNextValue(lagged);
|
||||
}
|
||||
|
||||
private List<string> _justPressed = new List<string>();
|
||||
|
||||
public void MassToggleStickyState(List<string> buttons)
|
||||
{
|
||||
foreach (var button in buttons.Where(button => !_justPressed.Contains(button)))
|
||||
{
|
||||
if (_boolPatterns.ContainsKey(button))
|
||||
SetSticky(button, false);
|
||||
else
|
||||
SetSticky(button, true);
|
||||
}
|
||||
|
||||
_justPressed = buttons;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters input for things called Up and Down while considering the client's AllowUD_LR option.
|
||||
/// This is a bit gross but it is unclear how to do it more nicely
|
||||
/// </summary>
|
||||
public class UD_LR_ControllerAdapter : IController
|
||||
{
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get { return Source.Definition; }
|
||||
}
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
bool PriorityUD_LR = !Global.Config.AllowUD_LR && !Global.Config.ForbidUD_LR; // implied by neither of the others being set (left as non-enum for back-compatibility)
|
||||
|
||||
if (Global.Config.AllowUD_LR)
|
||||
{
|
||||
return Source.IsPressed(button);
|
||||
}
|
||||
|
||||
string prefix;
|
||||
|
||||
//" C " is for N64 "P1 C Up" and the like, which should not be subject to mutexing
|
||||
|
||||
//regarding the unpressing and UDLR logic...... don't think about it. don't question it. don't look at it.
|
||||
|
||||
if (button.Contains("Down") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button))
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
prefix = button.GetPrecedingString("Down");
|
||||
string other = prefix + "Up";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Global.Config.ForbidUD_LR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
if (button.Contains("Up") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button))
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
prefix = button.GetPrecedingString("Up");
|
||||
string other = prefix + "Down";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Global.Config.ForbidUD_LR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
if (button.Contains("Right") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button))
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
prefix = button.GetPrecedingString("Right");
|
||||
string other = prefix + "Left";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Global.Config.ForbidUD_LR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
if (button.Contains("Left") && !button.Contains(" C "))
|
||||
{
|
||||
if (!Source.IsPressed(button))
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
|
||||
prefix = button.GetPrecedingString("Left");
|
||||
string other = prefix + "Right";
|
||||
if (Source.IsPressed(other))
|
||||
{
|
||||
if (Unpresses.Contains(button))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Global.Config.ForbidUD_LR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Unpresses.Add(other);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unpresses.Remove(button);
|
||||
}
|
||||
}
|
||||
|
||||
return Source.IsPressed(button);
|
||||
}
|
||||
|
||||
// The float format implies no U+D and no L+R no matter what, so just passthru
|
||||
public float GetFloat(string name)
|
||||
{
|
||||
return Source.GetFloat(name);
|
||||
}
|
||||
|
||||
private readonly HashSet<string> Unpresses = new HashSet<string>();
|
||||
|
||||
public IController Source { get; set; }
|
||||
}
|
||||
}
|
|
@ -34,6 +34,9 @@ namespace BizHawk.Client.Common
|
|||
[OptionalService]
|
||||
public IInputPollable InputPollableCore { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
public IRegionable RegionableCore { get; set; }
|
||||
|
||||
public Action FrameAdvanceCallback { get; set; }
|
||||
public Action YieldCallback { get; set; }
|
||||
|
||||
|
@ -185,6 +188,31 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
[LuaMethodAttributes(
|
||||
"totalexecutedcycles",
|
||||
"gets the total number of executed cpu cycles"
|
||||
)]
|
||||
public int TotalExecutedycles()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DebuggableCore == null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
return DebuggableCore.TotalExecutedCycles;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Log(string.Format(
|
||||
"Error: {0} does not yet implement totalexecutedcycles()",
|
||||
Emulator.Attributes().CoreName));
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
[LuaMethodAttributes(
|
||||
"getsystemid",
|
||||
"Returns the ID string of the current core loaded. Note: No ROM loaded will return the string NULL"
|
||||
|
@ -364,13 +392,9 @@ namespace BizHawk.Client.Common
|
|||
)]
|
||||
public string GetDisplayType()
|
||||
{
|
||||
if (Global.Game != null)
|
||||
if (RegionableCore != null)
|
||||
{
|
||||
var displaytype = Emulator.GetType().GetProperty("DisplayType");
|
||||
if (displaytype != null)
|
||||
{
|
||||
return displaytype.GetValue(Emulator, null).ToString();
|
||||
}
|
||||
return RegionableCore.Region.ToString();
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
|
|
|
@ -21,19 +21,19 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
var buttons = Lua.NewTable();
|
||||
var adaptor = Global.AutofireStickyXORAdapter;
|
||||
foreach (var button in adaptor.Source.Type.BoolButtons)
|
||||
foreach (var button in adaptor.Source.Definition.BoolButtons)
|
||||
{
|
||||
if (!controller.HasValue)
|
||||
{
|
||||
buttons[button] = adaptor[button];
|
||||
buttons[button] = adaptor.IsPressed(button);
|
||||
}
|
||||
else if (button.Length >= 3 && button.Substring(0, 2) == "P" + controller)
|
||||
{
|
||||
buttons[button.Substring(3)] = adaptor["P" + controller + " " + button.Substring(3)];
|
||||
buttons[button.Substring(3)] = adaptor.IsPressed("P" + controller + " " + button.Substring(3));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var button in adaptor.Source.Type.FloatControls)
|
||||
foreach (var button in adaptor.Source.Definition.FloatControls)
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ namespace BizHawk.Client.Common
|
|||
return buttons;
|
||||
}
|
||||
|
||||
// TODO: what about float controls?
|
||||
[LuaMethodAttributes(
|
||||
"getimmediate",
|
||||
"returns a lua table of any controller buttons currently pressed by the user"
|
||||
|
@ -59,9 +60,9 @@ namespace BizHawk.Client.Common
|
|||
public LuaTable GetImmediate()
|
||||
{
|
||||
var buttons = Lua.NewTable();
|
||||
foreach (var button in Global.ActiveController.Type.BoolButtons)
|
||||
foreach (var button in Global.ActiveController.Definition.BoolButtons)
|
||||
{
|
||||
buttons[button] = Global.ActiveController[button];
|
||||
buttons[button] = Global.ActiveController.IsPressed(button);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
|
@ -78,12 +79,12 @@ namespace BizHawk.Client.Common
|
|||
var lg = Global.MovieSession.MovieControllerInstance();
|
||||
lg.SetControllersAsMnemonic(inputLogEntry);
|
||||
|
||||
foreach (var button in lg.Type.BoolButtons)
|
||||
foreach (var button in lg.Definition.BoolButtons)
|
||||
{
|
||||
Global.LuaAndAdaptor.SetButton(button, lg.IsPressed(button));
|
||||
}
|
||||
|
||||
foreach (var floatButton in lg.Type.FloatControls)
|
||||
foreach (var floatButton in lg.Definition.FloatControls)
|
||||
{
|
||||
Global.LuaAndAdaptor.SetFloat(floatButton, lg.GetFloat(floatButton));
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
|
||||
using LuaInterface;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -20,26 +21,21 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private readonly Dictionary<Guid, byte[]> MemorySavestates = new Dictionary<Guid, byte[]>();
|
||||
|
||||
[RequiredService]
|
||||
private IStatable _statableCore { get; set; }
|
||||
|
||||
[LuaMethodAttributes(
|
||||
"savecorestate",
|
||||
"creates a core savestate and stores it in memory. Note: a core savestate is only the raw data from the core, and not extras such as movie input logs, or framebuffers. Returns a unique identifer for the savestate"
|
||||
)]
|
||||
public string SaveCoreStateToMemory()
|
||||
{
|
||||
if (Global.Emulator.HasSavestates())
|
||||
{
|
||||
var guid = Guid.NewGuid();
|
||||
var bytes = (byte[])Global.Emulator.AsStatable().SaveStateBinary().Clone();
|
||||
var guid = Guid.NewGuid();
|
||||
var bytes = (byte[])_statableCore.SaveStateBinary().Clone();
|
||||
|
||||
MemorySavestates.Add(guid, bytes);
|
||||
MemorySavestates.Add(guid, bytes);
|
||||
|
||||
return guid.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("Savestates not supported on this core");
|
||||
return Guid.Empty.ToString();
|
||||
}
|
||||
return guid.ToString();
|
||||
}
|
||||
|
||||
[LuaMethodAttributes(
|
||||
|
@ -50,27 +46,19 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
var guid = new Guid(identifier);
|
||||
|
||||
if (Global.Emulator.HasSavestates())
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var statableCore = Global.Emulator.AsStatable();
|
||||
var state = MemorySavestates[guid];
|
||||
var state = MemorySavestates[guid];
|
||||
|
||||
using (MemoryStream ms = new MemoryStream(state))
|
||||
using (BinaryReader br = new BinaryReader(ms))
|
||||
{
|
||||
statableCore.LoadStateBinary(br);
|
||||
}
|
||||
}
|
||||
catch
|
||||
using (MemoryStream ms = new MemoryStream(state))
|
||||
using (BinaryReader br = new BinaryReader(ms))
|
||||
{
|
||||
Log("Unable to find the given savestate in memory");
|
||||
_statableCore.LoadStateBinary(br);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
Log("Savestates not supported on this core");
|
||||
Log("Unable to find the given savestate in memory");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,14 +63,14 @@ namespace BizHawk.Client.Common
|
|||
return null;
|
||||
}
|
||||
|
||||
foreach (var button in adapter.Type.BoolButtons)
|
||||
foreach (var button in adapter.Definition.BoolButtons)
|
||||
{
|
||||
input[button] = adapter[button];
|
||||
input[button] = adapter.IsPressed(button);
|
||||
}
|
||||
|
||||
foreach (var button in adapter.Type.FloatControls)
|
||||
foreach (var button in adapter.Definition.FloatControls)
|
||||
{
|
||||
input[button] = adapter[button];
|
||||
input[button] = adapter.GetFloat(button);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
@ -199,10 +199,6 @@ namespace BizHawk.Client.Common
|
|||
)]
|
||||
public static void SetReadOnly(bool readOnly)
|
||||
{
|
||||
int x = 0;
|
||||
x++;
|
||||
int y = x;
|
||||
|
||||
Global.MovieSession.ReadOnly = readOnly;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ using System.ComponentModel;
|
|||
using System.Linq;
|
||||
|
||||
using LuaInterface;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
|
||||
|
||||
|
@ -22,11 +22,17 @@ namespace BizHawk.Client.Common
|
|||
|
||||
[OptionalService]
|
||||
private NES _neshawk { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private QuickNES _quicknes { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IMemoryDomains _memoryDomains { get; set; }
|
||||
|
||||
private bool NESAvailable { get { return _neshawk != null || _quicknes != null; } }
|
||||
|
||||
private bool HasMemoryDOmains { get { return _memoryDomains != null; } }
|
||||
|
||||
public NesLuaLibrary(Lua lua, Action<string> logOutputCallback)
|
||||
: base(lua, logOutputCallback) { }
|
||||
|
||||
|
@ -38,11 +44,11 @@ namespace BizHawk.Client.Common
|
|||
)]
|
||||
public void AddGameGenie(string code)
|
||||
{
|
||||
if (NESAvailable)
|
||||
if (NESAvailable && HasMemoryDOmains)
|
||||
{
|
||||
var decoder = new NESGameGenieDecoder(code);
|
||||
var watch = Watch.GenerateWatch(
|
||||
Global.Emulator.AsMemoryDomains()["System Bus"],
|
||||
_memoryDomains["System Bus"],
|
||||
decoder.Address,
|
||||
WatchSize.Byte,
|
||||
DisplayType.Hex,
|
||||
|
|
|
@ -61,10 +61,18 @@ namespace BizHawk.Client.Common
|
|||
public void Toggle()
|
||||
{
|
||||
if (State == RunState.Paused)
|
||||
{
|
||||
State = RunState.Running;
|
||||
}
|
||||
else if (State == RunState.Disabled)
|
||||
{
|
||||
State = RunState.Running;
|
||||
else State = RunState.Disabled;
|
||||
FrameWaiting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
State = RunState.Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
public void TogglePause()
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace BizHawk.Client.Common
|
|||
public IMovieController MovieControllerInstance()
|
||||
{
|
||||
var adapter = Movie.LogGeneratorInstance().MovieControllerAdapter;
|
||||
adapter.Type = MovieControllerAdapter.Type;
|
||||
adapter.Definition = MovieControllerAdapter.Definition;
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ namespace BizHawk.Client.Common
|
|||
// Movie may go into finished mode as a result from latching
|
||||
if (!Movie.IsFinished)
|
||||
{
|
||||
if (Global.ClientControls["Scrub Input"])
|
||||
if (Global.ClientControls.IsPressed("Scrub Input"))
|
||||
{
|
||||
LatchInputFromPlayer(Global.MovieInputSourceAdapter);
|
||||
ClearFrame();
|
||||
|
@ -294,13 +294,17 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private void HandleFrameLoopForRecordMode()
|
||||
{
|
||||
if (MultiTrack.IsActive)
|
||||
// tasmovie is appended via recording frames, but we don't want it to latch input outside its inetrnal recording mode
|
||||
if (!(Movie is TasMovie) || !Movie.IsPlaying)
|
||||
{
|
||||
LatchMultitrackPlayerInput(Global.MovieInputSourceAdapter, Global.MultitrackRewiringAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
LatchInputFromPlayer(Global.MovieInputSourceAdapter);
|
||||
if (MultiTrack.IsActive)
|
||||
{
|
||||
LatchMultitrackPlayerInput(Global.MovieInputSourceAdapter, Global.MultitrackRewiringAdapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
LatchInputFromPlayer(Global.MovieInputSourceAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
// the movie session makes sure that the correct input has been read and merged to its MovieControllerAdapter;
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace BizHawk.Client.Common
|
|||
public int PlayerSource { get; set; }
|
||||
public int PlayerTargetMask { get; set; }
|
||||
|
||||
public ControllerDefinition Type { get { return Source.Type; } }
|
||||
public ControllerDefinition Definition { get { return Source.Definition; } }
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace BizHawk.Client.Common
|
|||
{"C64_NTSC", NTSC_CARRIER*2/7/263/65},
|
||||
{"C64_NTSC_OLD", NTSC_CARRIER*2/7/262/64},
|
||||
{"C64_DREAN", PAL_N_CARRIER*2/7/312/65},
|
||||
{"INTV", 59.92 }
|
||||
|
||||
|
||||
//according to ryphecha, using
|
||||
//clocks[2] = { 53.693182e06, 53.203425e06 }; //ntsc console, pal console
|
||||
|
|
|
@ -37,8 +37,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
#region IController Implementation
|
||||
|
||||
// TODO: get rid of this, add a SetBool() method or something for the set access, replace get wtih IsPressed
|
||||
public bool this[string button]
|
||||
{
|
||||
get
|
||||
|
@ -55,6 +54,8 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
#region IController Implementation
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
return MyBoolButtons[button];
|
||||
|
@ -71,7 +72,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private Bk2ControllerDefinition _type = new Bk2ControllerDefinition();
|
||||
|
||||
public ControllerDefinition Type
|
||||
public ControllerDefinition Definition
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -90,7 +91,7 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public void LatchPlayerFromSource(IController playerSource, int playerNum)
|
||||
{
|
||||
foreach (var button in playerSource.Type.BoolButtons)
|
||||
foreach (var button in playerSource.Definition.BoolButtons)
|
||||
{
|
||||
var bnp = ButtonNameParser.Parse(button);
|
||||
if (bnp == null)
|
||||
|
@ -103,11 +104,11 @@ namespace BizHawk.Client.Common
|
|||
continue;
|
||||
}
|
||||
|
||||
var val = playerSource[button];
|
||||
var val = playerSource.IsPressed(button);
|
||||
MyBoolButtons[button] = val;
|
||||
}
|
||||
|
||||
foreach (var button in Type.FloatControls)
|
||||
foreach (var button in Definition.FloatControls)
|
||||
{
|
||||
var bnp = ButtonNameParser.Parse(button);
|
||||
if (bnp == null)
|
||||
|
@ -131,12 +132,12 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public void LatchFromSource(IController source)
|
||||
{
|
||||
foreach (var button in Type.BoolButtons)
|
||||
foreach (var button in Definition.BoolButtons)
|
||||
{
|
||||
MyBoolButtons[button] = source.IsPressed(button);
|
||||
}
|
||||
|
||||
foreach (var name in Type.FloatControls)
|
||||
foreach (var name in Definition.FloatControls)
|
||||
{
|
||||
MyFloatControls[name] = source.GetFloat(name);
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
var def = Global.Emulator.ControllerDefinition;
|
||||
var trimmed = mnemonic.Replace("|", "");
|
||||
var buttons = Type.ControlsOrdered.SelectMany(x => x).ToList();
|
||||
var buttons = Definition.ControlsOrdered.SelectMany(x => x).ToList();
|
||||
var iterator = 0;
|
||||
|
||||
foreach (var key in buttons)
|
||||
|
|
|
@ -44,7 +44,8 @@ namespace BizHawk.Client.Common
|
|||
{ "LStick X", "lsX" },
|
||||
{ "LStick Y", "lsY" },
|
||||
{ "RStick X", "rsX" },
|
||||
{ "RStick Y", "rsY" }
|
||||
{ "RStick Y", "rsY" },
|
||||
{ "Disc Select", "Disc" }
|
||||
};
|
||||
|
||||
private readonly Dictionary<string, Dictionary<string, string>> SystemOverrides = new Dictionary<string, Dictionary<string, string>>
|
||||
|
|
|
@ -36,16 +36,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public string GenerateInputDisplay()
|
||||
{
|
||||
var le = GenerateLogEntry();
|
||||
if (le == EmptyEntry)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return le
|
||||
.Replace(".", " ")
|
||||
.Replace("|", "")
|
||||
.Replace(" 0,", " "); //zero 04-aug-2015 - changed from a 2-dimensional type string to support emptying out the one-dimensional PSX disc select control
|
||||
return CreateLogEntry(forInputDisplay: true);
|
||||
}
|
||||
|
||||
public bool IsEmpty
|
||||
|
@ -76,7 +67,7 @@ namespace BizHawk.Client.Common
|
|||
var sb = new StringBuilder();
|
||||
sb.Append("LogKey:");
|
||||
|
||||
foreach (var group in _source.Type.ControlsOrdered.Where(c => c.Any()))
|
||||
foreach (var group in _source.Definition.ControlsOrdered.Where(c => c.Any()))
|
||||
{
|
||||
sb.Append("#");
|
||||
foreach (var button in group)
|
||||
|
@ -93,15 +84,15 @@ namespace BizHawk.Client.Common
|
|||
public Dictionary<string, string> Map()
|
||||
{
|
||||
var dict = new Dictionary<string, string>();
|
||||
foreach (var group in _source.Type.ControlsOrdered.Where(c => c.Any()))
|
||||
foreach (var group in _source.Definition.ControlsOrdered.Where(c => c.Any()))
|
||||
{
|
||||
foreach (var button in group)
|
||||
{
|
||||
if (_source.Type.BoolButtons.Contains(button))
|
||||
if (_source.Definition.BoolButtons.Contains(button))
|
||||
{
|
||||
dict.Add(button, Mnemonics[button].ToString());
|
||||
}
|
||||
else if (_source.Type.FloatControls.Contains(button))
|
||||
else if (_source.Definition.FloatControls.Contains(button))
|
||||
{
|
||||
dict.Add(button, FloatLookup[button]);
|
||||
}
|
||||
|
@ -111,30 +102,40 @@ namespace BizHawk.Client.Common
|
|||
return dict;
|
||||
}
|
||||
|
||||
private string CreateLogEntry(bool createEmpty = false)
|
||||
private string CreateLogEntry(bool createEmpty = false, bool forInputDisplay = false)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append('|');
|
||||
|
||||
foreach (var group in _source.Type.ControlsOrdered)
|
||||
if (!forInputDisplay)
|
||||
sb.Append('|');
|
||||
|
||||
foreach (var group in _source.Definition.ControlsOrdered)
|
||||
{
|
||||
if (group.Any())
|
||||
{
|
||||
foreach (var button in group)
|
||||
{
|
||||
if (_source.Type.FloatControls.Contains(button))
|
||||
if (_source.Definition.FloatControls.Contains(button))
|
||||
{
|
||||
int val;
|
||||
int i = _source.Definition.FloatControls.IndexOf(button);
|
||||
int mid = (int)_source.Definition.FloatRanges[i].Mid;
|
||||
|
||||
if (createEmpty)
|
||||
{
|
||||
sb.Append(" 0,");
|
||||
val = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
var val = (int)_source.GetFloat(button);
|
||||
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
||||
val = (int)_source.GetFloat(button);
|
||||
}
|
||||
|
||||
if (forInputDisplay && val == mid)
|
||||
sb.Append(" ");
|
||||
else
|
||||
sb.Append(val.ToString().PadLeft(5, ' ')).Append(',');
|
||||
}
|
||||
else if (_source.Type.BoolButtons.Contains(button))
|
||||
else if (_source.Definition.BoolButtons.Contains(button))
|
||||
{
|
||||
if (createEmpty)
|
||||
{
|
||||
|
@ -142,12 +143,13 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
sb.Append(_source.IsPressed(button) ? Mnemonics[button] : '.');
|
||||
sb.Append(_source.IsPressed(button) ? Mnemonics[button] : forInputDisplay ? ' ' : '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append('|');
|
||||
if (!forInputDisplay)
|
||||
sb.Append('|');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,10 @@ namespace BizHawk.Client.Common
|
|||
{ "Square", 'Q' },
|
||||
|
||||
{ "Toggle Left Difficulty", 'l' },
|
||||
{ "Toggle Right Difficulty", 'r' }
|
||||
{ "Toggle Right Difficulty", 'r' },
|
||||
|
||||
{ "Open", 'O' },
|
||||
{ "Close", 'C' }
|
||||
};
|
||||
|
||||
private readonly Dictionary<string, Dictionary<string, char>> SystemOverrides = new Dictionary<string, Dictionary<string, char>>
|
||||
|
@ -279,6 +282,27 @@ namespace BizHawk.Client.Common
|
|||
{ "L", 'L' },
|
||||
{ "R", 'R' }
|
||||
}
|
||||
},
|
||||
{
|
||||
"INTV",
|
||||
new Dictionary<string, char>
|
||||
{
|
||||
{ "Clear", 'C' },
|
||||
{ "Enter", 'E' },
|
||||
{ "Top", 'T' },
|
||||
{ "NNE", 'n' },
|
||||
{ "NE", '/' },
|
||||
{ "ENE", 'e' },
|
||||
{ "ESE", 'e' },
|
||||
{ "SE", '\\' },
|
||||
{ "SSE", 's' },
|
||||
{ "SSW", 's' },
|
||||
{ "SW", '/' },
|
||||
{ "WSW", 'w' },
|
||||
{ "WNW", 'w' },
|
||||
{ "NW", '\\' },
|
||||
{ "NNW", 'n' }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -321,7 +321,7 @@ namespace BizHawk.Client.Common
|
|||
private string ConvertLogEntryFromFile(string line, string logKey)
|
||||
{
|
||||
var adapter = new Bk2LogEntryGenerator(logKey).MovieControllerAdapter;
|
||||
adapter.Type = Global.MovieSession.MovieControllerAdapter.Type;
|
||||
adapter.Definition = Global.MovieSession.MovieControllerAdapter.Definition;
|
||||
adapter.SetControllersAsMnemonic(line);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
|
|
|
@ -143,7 +143,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
var adapter = new Bk2ControllerAdapter
|
||||
{
|
||||
Type = Global.MovieSession.MovieControllerAdapter.Type
|
||||
Definition = Global.MovieSession.MovieControllerAdapter.Definition
|
||||
};
|
||||
|
||||
adapter.SetControllersAsMnemonic(_log[getframe]);
|
||||
|
|
|
@ -9,10 +9,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
#region IController Implementation
|
||||
|
||||
public bool this[string button]
|
||||
{
|
||||
get { return MyBoolButtons[button]; }
|
||||
}
|
||||
public ControllerDefinition Definition { get; set; }
|
||||
|
||||
public bool IsPressed(string button)
|
||||
{
|
||||
|
@ -28,14 +25,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#region IMovieController Implementation
|
||||
|
||||
public ControllerDefinition Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// latches one player from the source
|
||||
/// </summary>
|
||||
public void LatchPlayerFromSource(IController playerSource, int playerNum)
|
||||
{
|
||||
foreach (var button in playerSource.Type.BoolButtons)
|
||||
foreach (var button in playerSource.Definition.BoolButtons)
|
||||
{
|
||||
var bnp = ButtonNameParser.Parse(button);
|
||||
if (bnp == null)
|
||||
|
@ -48,7 +43,7 @@ namespace BizHawk.Client.Common
|
|||
continue;
|
||||
}
|
||||
|
||||
var val = playerSource[button];
|
||||
var val = playerSource.IsPressed(button);
|
||||
MyBoolButtons[button] = val;
|
||||
}
|
||||
}
|
||||
|
@ -58,12 +53,12 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public void LatchFromSource(IController source)
|
||||
{
|
||||
foreach (var button in Type.BoolButtons)
|
||||
foreach (var button in Definition.BoolButtons)
|
||||
{
|
||||
MyBoolButtons[button] = source[button];
|
||||
MyBoolButtons[button] = source.IsPressed(button);
|
||||
}
|
||||
|
||||
foreach (var name in Type.FloatControls)
|
||||
foreach (var name in Definition.FloatControls)
|
||||
{
|
||||
MyFloatControls[name] = source.GetFloat(name);
|
||||
}
|
||||
|
@ -258,7 +253,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private bool IsGenesis6Button()
|
||||
{
|
||||
return this.Type.BoolButtons.Contains("P1 X");
|
||||
return this.Definition.BoolButtons.Contains("P1 X");
|
||||
}
|
||||
|
||||
private void Force(string button, bool state)
|
||||
|
@ -271,7 +266,7 @@ namespace BizHawk.Client.Common
|
|||
MyFloatControls[name] = state;
|
||||
}
|
||||
|
||||
private string ControlType { get { return Type.Name; } }
|
||||
private string ControlType { get { return Definition.Name; } }
|
||||
|
||||
private void SetGBAControllersAsMnemonic(string mnemonic)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Client.Common
|
|||
public void SetSource(IController source)
|
||||
{
|
||||
_source = source;
|
||||
_controlType = source.Type.Name;
|
||||
_controlType = source.Definition.Name;
|
||||
}
|
||||
|
||||
public string GenerateLogEntry()
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
var adapter = new BkmControllerAdapter
|
||||
{
|
||||
Type = Global.MovieSession.MovieControllerAdapter.Type
|
||||
Definition = Global.MovieSession.MovieControllerAdapter.Definition
|
||||
};
|
||||
adapter.SetControllersAsMnemonic(_log[getframe]);
|
||||
return adapter;
|
||||
|
|
|
@ -241,7 +241,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private static IController EmptyLmsvFrame(string line)
|
||||
{
|
||||
var emptyController = new SimpleController { Type = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
var emptyController = new SimpleController { Definition = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
emptyController["Reset"] = false;
|
||||
emptyController["Power"] = false;
|
||||
|
||||
|
@ -294,7 +294,7 @@ namespace BizHawk.Client.Common
|
|||
controller = "Saturn Controller";
|
||||
break;
|
||||
}
|
||||
var controllers = new SimpleController { Type = new ControllerDefinition { Name = controller } };
|
||||
var controllers = new SimpleController { Definition = new ControllerDefinition { Name = controller } };
|
||||
// Split up the sections of the frame.
|
||||
string[] sections = line.Split('|');
|
||||
if (ext == ".FM2" && sections.Length >= 2 && sections[1].Length != 0)
|
||||
|
@ -373,14 +373,14 @@ namespace BizHawk.Client.Common
|
|||
int player = section + player_offset;
|
||||
string prefix = "P" + (player) + " ";
|
||||
// Gameboy doesn't currently have a prefix saying which player the input is for.
|
||||
if (controllers.Type.Name == "Gameboy Controller")
|
||||
if (controllers.Definition.Name == "Gameboy Controller")
|
||||
{
|
||||
prefix = "";
|
||||
}
|
||||
// Only count lines with that have the right number of buttons and are for valid players.
|
||||
if (
|
||||
sections[section].Length == buttons.Length &&
|
||||
player <= BkmMnemonicConstants.PLAYERS[controllers.Type.Name]
|
||||
player <= BkmMnemonicConstants.PLAYERS[controllers.Definition.Name]
|
||||
)
|
||||
{
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
|
@ -724,7 +724,7 @@ namespace BizHawk.Client.Common
|
|||
m.Header[HeaderKeys.AUTHOR] = author;
|
||||
// Advance to first byte of input data.
|
||||
r.BaseStream.Position = firstFrameOffset;
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "NES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "NES Controller" } };
|
||||
string[] buttons = { "A", "B", "Select", "Start", "Up", "Down", "Left", "Right" };
|
||||
bool fds = false;
|
||||
bool fourscore = false;
|
||||
|
@ -955,7 +955,7 @@ namespace BizHawk.Client.Common
|
|||
*/
|
||||
m.Header[HeaderKeys.PAL] = "False";
|
||||
// 090 frame data begins here
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "NES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "NES Controller" } };
|
||||
/*
|
||||
* 01 Right
|
||||
* 02 Left
|
||||
|
@ -1042,14 +1042,14 @@ namespace BizHawk.Client.Common
|
|||
string player1Config = r.ReadStringFixedAscii(1);
|
||||
// 015 ASCII-encoded controller config for player 2. '3' or '6'.
|
||||
string player2Config = r.ReadStringFixedAscii(1);
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition() };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition() };
|
||||
if (player1Config == "6" || player2Config == "6")
|
||||
{
|
||||
controllers.Type.Name = "GPGX Genesis Controller";
|
||||
controllers.Definition.Name = "GPGX Genesis Controller";
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers.Type.Name = "GPGX 3-Button Controller";
|
||||
controllers.Definition.Name = "GPGX 3-Button Controller";
|
||||
}
|
||||
// 016 special flags (Version A and up only)
|
||||
byte flags = r.ReadByte();
|
||||
|
@ -1474,7 +1474,7 @@ namespace BizHawk.Client.Common
|
|||
r.ReadBytes(103);
|
||||
// TODO: Verify if NTSC/"PAL" mode used for the movie can be detected or not.
|
||||
// 100 variable Input data
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = name + " Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = name + " Controller" } };
|
||||
int bytes = 256;
|
||||
// The input stream consists of 1 byte for power-on and reset, and then X bytes per each input port per frame.
|
||||
if (platform == "nes")
|
||||
|
@ -1595,7 +1595,7 @@ namespace BizHawk.Client.Common
|
|||
// 00e4-00f3: binary: rom MD5 digest
|
||||
byte[] md5 = r.ReadBytes(16);
|
||||
m.Header[MD5] = string.Format("{0:x8}", md5.BytesToHexString().ToLower());
|
||||
var controllers = new SimpleController { Type = new ControllerDefinition { Name = "SMS Controller" } };
|
||||
var controllers = new SimpleController { Definition = new ControllerDefinition { Name = "SMS Controller" } };
|
||||
/*
|
||||
76543210
|
||||
* bit 0 (0x01): up
|
||||
|
@ -1820,7 +1820,7 @@ namespace BizHawk.Client.Common
|
|||
// ... 4-byte little-endian unsigned int: length of controller data in bytes
|
||||
uint length = r.ReadUInt32();
|
||||
// ... (variable) controller data
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "NES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "NES Controller" } };
|
||||
/*
|
||||
Standard controllers store data in the following format:
|
||||
* 01: A
|
||||
|
@ -1923,7 +1923,7 @@ namespace BizHawk.Client.Common
|
|||
* bit 4: controller 5 in use
|
||||
* other: reserved, set to 0
|
||||
*/
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
bool[] controllersUsed = new bool[5];
|
||||
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||
{
|
||||
|
@ -2109,7 +2109,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
ushort controllerState = (ushort)(((controllerState1 << 4) & 0x0F00) | controllerState2);
|
||||
if (player <= BkmMnemonicConstants.PLAYERS[controllers.Type.Name])
|
||||
if (player <= BkmMnemonicConstants.PLAYERS[controllers.Definition.Name])
|
||||
{
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
{
|
||||
|
@ -2334,14 +2334,14 @@ namespace BizHawk.Client.Common
|
|||
string movieDescription = NullTerminated(r.ReadStringFixedAscii(128));
|
||||
m.Comments.Add(COMMENT + " " + movieDescription);
|
||||
r.BaseStream.Position = firstFrameOffset;
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition() };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition() };
|
||||
if (platform != "GBA")
|
||||
{
|
||||
controllers.Type.Name = "Gameboy Controller";
|
||||
controllers.Definition.Name = "Gameboy Controller";
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers.Type.Name = "GBA Controller";
|
||||
controllers.Definition.Name = "GBA Controller";
|
||||
}
|
||||
/*
|
||||
* 01 00 A
|
||||
|
@ -2512,7 +2512,7 @@ namespace BizHawk.Client.Common
|
|||
return m;
|
||||
}
|
||||
r.BaseStream.Position = firstFrameOffset;
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "NES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "NES Controller" } };
|
||||
/*
|
||||
* 01 A
|
||||
* 02 B
|
||||
|
@ -2749,7 +2749,7 @@ namespace BizHawk.Client.Common
|
|||
uint savestateSize = (uint)((r.ReadByte() | (r.ReadByte() << 8) | (r.ReadByte() << 16)) & 0x7FFFFF);
|
||||
// Next follows a ZST format savestate.
|
||||
r.ReadBytes((int)savestateSize);
|
||||
SimpleController controllers = new SimpleController { Type = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
SimpleController controllers = new SimpleController { Definition = new ControllerDefinition { Name = "SNES Controller" } };
|
||||
/*
|
||||
* bit 11: A
|
||||
* bit 10: X
|
||||
|
@ -2903,7 +2903,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
leftOver = !leftOver;
|
||||
if (player <= BkmMnemonicConstants.PLAYERS[controllers.Type.Name])
|
||||
if (player <= BkmMnemonicConstants.PLAYERS[controllers.Definition.Name])
|
||||
{
|
||||
if (player != 2 || !superScope)
|
||||
{
|
||||
|
|
|
@ -183,7 +183,7 @@ namespace BizHawk.Client.Common
|
|||
info.player2Type,
|
||||
OctoshockDll.ePeripheralType.None,OctoshockDll.ePeripheralType.None,OctoshockDll.ePeripheralType.None
|
||||
};
|
||||
controllers.Type = Octoshock.CreateControllerDefinition(settings);
|
||||
controllers.Definition = Octoshock.CreateControllerDefinition(settings);
|
||||
|
||||
string[] buttons = { "Select", "L3", "R3", "Start", "Up", "Right", "Down", "Left",
|
||||
"L2", "R2", "L1", "R1", "Triangle", "Circle", "Cross", "Square"};
|
||||
|
@ -290,7 +290,7 @@ namespace BizHawk.Client.Common
|
|||
info.player2Type,
|
||||
OctoshockDll.ePeripheralType.None,OctoshockDll.ePeripheralType.None,OctoshockDll.ePeripheralType.None
|
||||
};
|
||||
controllers.Type = Octoshock.CreateControllerDefinition(settings);
|
||||
controllers.Definition = Octoshock.CreateControllerDefinition(settings);
|
||||
|
||||
string[] buttons = { "Select", "L3", "R3", "Start", "Up", "Right", "Down", "Left",
|
||||
"L2", "R2", "L1", "R1", "Triangle", "Circle", "Cross", "Square"};
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public interface IMovieController: IController
|
||||
{
|
||||
new ControllerDefinition Type { get; set; }
|
||||
new ControllerDefinition Definition { get; set; }
|
||||
|
||||
void LatchPlayerFromSource(IController playerSource, int playerNum);
|
||||
|
||||
|
|
|
@ -125,7 +125,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
foreach (var frame in frames.OrderByDescending(x => x)) // Removin them in reverse order allows us to remove by index;
|
||||
{
|
||||
_log.RemoveAt(frame);
|
||||
if (frame < _log.Count)
|
||||
_log.RemoveAt(frame);
|
||||
if (BindMarkersToInput) // TODO: This is slow, is there a better way to do it?
|
||||
{
|
||||
bool wasRecording = ChangeLog.IsRecording;
|
||||
|
@ -370,7 +371,7 @@ namespace BizHawk.Client.Common
|
|||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.AddBoolToggle(frame, buttonName, !adapter[buttonName], "Toggle " + buttonName + ": " + frame);
|
||||
ChangeLog.AddBoolToggle(frame, buttonName, !adapter.IsPressed(buttonName), "Toggle " + buttonName + ": " + frame);
|
||||
}
|
||||
|
||||
public void SetBoolState(int frame, string buttonName, bool val)
|
||||
|
@ -379,7 +380,7 @@ namespace BizHawk.Client.Common
|
|||
ExtendMovieForEdit(frame - _log.Count + 1);
|
||||
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
var old = adapter[buttonName];
|
||||
var old = adapter.IsPressed(buttonName);
|
||||
adapter[buttonName] = val;
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
|
@ -405,7 +406,7 @@ namespace BizHawk.Client.Common
|
|||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var adapter = GetInputState(frame + i) as Bk2ControllerAdapter;
|
||||
bool old = adapter[buttonName];
|
||||
bool old = adapter.IsPressed(buttonName);
|
||||
adapter[buttonName] = val;
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
|
|
|
@ -36,11 +36,6 @@ namespace BizHawk.Client.Common
|
|||
// TasProj extras
|
||||
bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(StateManager.Settings.ToString()));
|
||||
|
||||
if (StateManager.Settings.SaveStateHistory)
|
||||
{
|
||||
bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw));
|
||||
}
|
||||
|
||||
bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw));
|
||||
bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));
|
||||
|
||||
|
@ -81,6 +76,11 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(Session.ToString()));
|
||||
|
||||
if (StateManager.Settings.SaveStateHistory)
|
||||
{
|
||||
bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw));
|
||||
}
|
||||
}
|
||||
|
||||
if (!backup)
|
||||
|
@ -201,21 +201,6 @@ namespace BizHawk.Client.Common
|
|||
StateManager.Settings.PopulateFromString(tr.ReadToEnd());
|
||||
});
|
||||
|
||||
if(!preload)
|
||||
{
|
||||
if (StateManager.Settings.SaveStateHistory)
|
||||
{
|
||||
bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length)
|
||||
{
|
||||
StateManager.Load(br);
|
||||
});
|
||||
}
|
||||
|
||||
// Movie should always have a state at frame 0.
|
||||
if (!this.StartsFromSavestate && Global.Emulator.Frame == 0)
|
||||
StateManager.Capture();
|
||||
}
|
||||
|
||||
bl.GetLump(BinaryStateLump.Markers, false, delegate(TextReader tr)
|
||||
{
|
||||
string line;
|
||||
|
@ -280,6 +265,21 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
Session.PopulateFromString(tr.ReadToEnd());
|
||||
});
|
||||
|
||||
if (!preload)
|
||||
{
|
||||
if (StateManager.Settings.SaveStateHistory)
|
||||
{
|
||||
bl.GetLump(BinaryStateLump.StateHistory, false, delegate(BinaryReader br, long length)
|
||||
{
|
||||
StateManager.Load(br);
|
||||
});
|
||||
}
|
||||
|
||||
// Movie should always have a state at frame 0.
|
||||
if (!this.StartsFromSavestate && Global.Emulator.Frame == 0)
|
||||
StateManager.Capture();
|
||||
}
|
||||
}
|
||||
|
||||
Changes = false;
|
||||
|
|
|
@ -268,14 +268,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public string CreateDisplayValueForButton(IController adapter, string buttonName)
|
||||
{
|
||||
if (adapter.Type.BoolButtons.Contains(buttonName))
|
||||
if (adapter.Definition.BoolButtons.Contains(buttonName))
|
||||
{
|
||||
return adapter.IsPressed(buttonName) ?
|
||||
Mnemonics[buttonName].ToString() :
|
||||
string.Empty;
|
||||
}
|
||||
|
||||
if (adapter.Type.FloatControls.Contains(buttonName))
|
||||
if (adapter.Definition.FloatControls.Contains(buttonName))
|
||||
{
|
||||
return adapter.GetFloat(buttonName).ToString();
|
||||
}
|
||||
|
@ -543,7 +543,9 @@ namespace BizHawk.Client.Common
|
|||
StateManager.SetState(branch.Frame, branch.CoreData);
|
||||
|
||||
//ChangeLog = branch.ChangeLog;
|
||||
Markers = branch.Markers;
|
||||
if (BindMarkersToInput) // pretty critical not to erase them
|
||||
Markers = branch.Markers;
|
||||
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,6 +282,11 @@ namespace BizHawk.Client.Common
|
|||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public int FindIndex(string markerName)
|
||||
{
|
||||
return this.FindIndex(m => m.Message == markerName);
|
||||
}
|
||||
|
||||
public bool IsMarker(int frame)
|
||||
{
|
||||
return this.Any(m => m == frame);
|
||||
|
|
|
@ -773,7 +773,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
// Check if there are any branch states for the given frame.
|
||||
if (!BranchStates.ContainsKey(frame) || BranchStates[frame] == null)
|
||||
if (!BranchStates.ContainsKey(frame) || BranchStates[frame] == null || branchHash == -1)
|
||||
return -2;
|
||||
|
||||
// Loop through branch states for the given frame.
|
||||
|
|
|
@ -524,20 +524,28 @@ namespace BizHawk.Client.Common
|
|||
_history.Clear();
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
public int Undo()
|
||||
{
|
||||
int origCount = _watchList.Count;
|
||||
if (_keepHistory)
|
||||
{
|
||||
_watchList = _history.Undo().ToList();
|
||||
return _watchList.Count - origCount;
|
||||
}
|
||||
|
||||
return _watchList.Count;
|
||||
}
|
||||
|
||||
public void Redo()
|
||||
public int Redo()
|
||||
{
|
||||
int origCount = _watchList.Count;
|
||||
if (_keepHistory)
|
||||
{
|
||||
_watchList = _history.Redo().ToList();
|
||||
return origCount - _watchList.Count;
|
||||
}
|
||||
|
||||
return _watchList.Count;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -17,8 +17,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private long _soundRemainder; // audio timekeeping for video dumping
|
||||
|
||||
public void DumpAV(IVideoProvider v, ISoundProvider s, out short[] samples, out int samplesprovided)
|
||||
public void DumpAV(IVideoProvider v, ISoundProvider asyncSoundProvider, out short[] samples, out int samplesprovided)
|
||||
{
|
||||
// Sound refactor TODO: we could try set it here, but we want the client to be responsible for mode switching? There may be non-trivial complications with when to switch modes that we don't want this object worrying about
|
||||
if (asyncSoundProvider.SyncMode != SyncSoundMode.Async)
|
||||
{
|
||||
throw new InvalidOperationException("Only async mode is supported, set async mode before passing in the sound provider");
|
||||
}
|
||||
|
||||
if (!aset || !vset)
|
||||
throw new InvalidOperationException("Must set params first!");
|
||||
|
||||
|
@ -29,7 +35,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_soundRemainder = nsampnum % fpsnum;
|
||||
|
||||
samples = new short[nsamp * channels];
|
||||
s.GetSamples(samples);
|
||||
asyncSoundProvider.GetSamplesAsync(samples);
|
||||
samplesprovided = (int)nsamp;
|
||||
|
||||
w.AddFrame(v);
|
||||
|
@ -73,10 +79,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
public void DumpAV(IVideoProvider v, ISyncSoundProvider s, out short[] samples, out int samplesprovided)
|
||||
public void DumpAV(IVideoProvider v, ISoundProvider syncSoundProvider, out short[] samples, out int samplesprovided)
|
||||
{
|
||||
// Sound refactor TODO: we could just set it here, but we want the client to be responsible for mode switching? There may be non-trivial complications with when to switch modes that we don't want this object worrying about
|
||||
if (syncSoundProvider.SyncMode != SyncSoundMode.Sync)
|
||||
{
|
||||
throw new InvalidOperationException("Only sync mode is supported, set sync mode before passing in the sound provider");
|
||||
}
|
||||
|
||||
VerifyParams();
|
||||
s.GetSamples(out samples, out samplesprovided);
|
||||
syncSoundProvider.GetSamplesSync(out samples, out samplesprovided);
|
||||
exaudio_num += samplesprovided * (long)fpsnum;
|
||||
|
||||
// todo: scan for duplicate frames (ie, video content exactly matches previous frame) and for them, skip the threshone step
|
||||
|
|
|
@ -367,6 +367,12 @@
|
|||
<Compile Include="config\InputWidget.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="config\INTV\IntvControllerSettings.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="config\INTV\IntvControllerSettings.Designer.cs">
|
||||
<DependentUpon>IntvControllerSettings.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="config\MessageConfig.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -711,11 +717,14 @@
|
|||
<Compile Include="RomStatusPicker.Designer.cs">
|
||||
<DependentUpon>RomStatusPicker.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Sound\Interfaces\IBufferedSoundProvider.cs" />
|
||||
<Compile Include="Sound\Interfaces\ISoundOutput.cs" />
|
||||
<Compile Include="Sound\Output\DirectSoundSoundOutput.cs" />
|
||||
<Compile Include="Sound\Output\DummySoundOutput.cs" />
|
||||
<Compile Include="Sound\Output\OpenALSoundOutput.cs" />
|
||||
<Compile Include="Sound\Output\XAudio2SoundOutput.cs" />
|
||||
<Compile Include="Sound\Sound.cs" />
|
||||
<Compile Include="Sound\Utilities\BufferedAsync.cs" />
|
||||
<Compile Include="Sound\Utilities\SoundOutputProvider.cs" />
|
||||
<Compile Include="Throttle.cs" />
|
||||
<Compile Include="ToolAttributes.cs" />
|
||||
|
@ -1073,12 +1082,7 @@
|
|||
<Compile Include="tools\TAStudio\PatternsForm.Designer.cs">
|
||||
<DependentUpon>PatternsForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="tools\TAStudio\ScreenshotPopupControl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="tools\TAStudio\ScreenshotPopupControl.Designer.cs">
|
||||
<DependentUpon>ScreenshotPopupControl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="tools\TAStudio\ScreenshotPopup.cs" />
|
||||
<Compile Include="tools\TAStudio\TAStudio.Callbacks.cs">
|
||||
<DependentUpon>TAStudio.cs</DependentUpon>
|
||||
<SubType>Form</SubType>
|
||||
|
@ -1184,6 +1188,7 @@
|
|||
<Compile Include="tools\VirtualPads\schema\GBASchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\GBSchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\GenSchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\IntvSchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\LynxSchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\PSXSchema.cs" />
|
||||
<Compile Include="tools\VirtualPads\schema\SatSchema.cs" />
|
||||
|
@ -1315,6 +1320,9 @@
|
|||
<EmbeddedResource Include="config\InputCompositeWidget.resx">
|
||||
<DependentUpon>InputCompositeWidget.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="config\INTV\IntvControllerSettings.resx">
|
||||
<DependentUpon>IntvControllerSettings.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="config\N64\N64ControllerSettingControl.resx">
|
||||
<DependentUpon>N64ControllerSettingControl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
@ -1566,6 +1574,7 @@
|
|||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\TAStudio\BookmarksBranchesBox.resx">
|
||||
<DependentUpon>BookmarksBranchesBox.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\TAStudio\DefaultGreenzoneSettings.resx">
|
||||
<DependentUpon>DefaultGreenzoneSettings.cs</DependentUpon>
|
||||
|
@ -1588,9 +1597,6 @@
|
|||
<EmbeddedResource Include="tools\TAStudio\PlaybackBox.resx">
|
||||
<DependentUpon>PlaybackBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\TAStudio\ScreenshotPopupControl.resx">
|
||||
<DependentUpon>ScreenshotPopupControl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="tools\TAStudio\TAStudio.resx">
|
||||
<DependentUpon>TAStudio.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
@ -1767,6 +1773,16 @@
|
|||
<None Include="config\ControllerImages\GENController.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="images\WSW.png" />
|
||||
<None Include="images\WNW.png" />
|
||||
<None Include="images\SW.png" />
|
||||
<None Include="images\SSW.png" />
|
||||
<None Include="images\SSE.png" />
|
||||
<None Include="images\SE.png" />
|
||||
<None Include="images\NW.png" />
|
||||
<None Include="images\NNW.png" />
|
||||
<None Include="images\NNE.png" />
|
||||
<None Include="images\NE.png" />
|
||||
<None Include="images\Shark.ico" />
|
||||
<None Include="images\Shark.png" />
|
||||
<None Include="images\ScrollTo.png" />
|
||||
|
@ -2081,6 +2097,9 @@
|
|||
<None Include="images\cdlogger.ico" />
|
||||
<None Include="images\AddEdit.png" />
|
||||
<None Include="images\JumpTo.png" />
|
||||
<None Include="images\ENE.png" />
|
||||
<None Include="images\ESE.png" />
|
||||
<None Include="images\5757344.png" />
|
||||
<Content Include="images\logo.ico" />
|
||||
<None Include="images\Paste.png" />
|
||||
<None Include="images\reboot.png" />
|
||||
|
|
|
@ -37,12 +37,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
// Hiding lag frames (Mainly intended for < 60fps play.)
|
||||
public int LagFramesToHide { get; set; }
|
||||
public bool HideWasLagFrames { get; set; }
|
||||
private byte[] lagFrames = new byte[100]; // Large enough value that it shouldn't ever need resizing.
|
||||
private byte[] lagFrames = new byte[256]; // Large enough value that it shouldn't ever need resizing. // apparently not large enough for 4K
|
||||
|
||||
public bool denoteStatesWithIcons { get; set; }
|
||||
public bool denoteStatesWithBGColor { get; set; }
|
||||
public bool denoteMarkersWithIcons { get; set; }
|
||||
public bool denoteMarkersWithBGColor { get; set; }
|
||||
public bool allowRightClickSelecton { get; set; }
|
||||
public bool letKeysModifySelection { get; set; }
|
||||
public bool suspendHotkeys { get; set; }
|
||||
|
@ -618,6 +614,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
var rollSettings = settings as InputRollSettings;
|
||||
_columns = rollSettings.Columns;
|
||||
_columns.ChangedCallback = ColumnChangedCallback;
|
||||
HorizontalOrientation = rollSettings.HorizontalOrientation;
|
||||
LagFramesToHide = rollSettings.LagFramesToHide;
|
||||
HideWasLagFrames = rollSettings.HideWasLagFrames;
|
||||
|
@ -1155,19 +1152,14 @@ namespace BizHawk.Client.EmuHawk
|
|||
var hadIndex = SelectedItems.Any();
|
||||
SelectedItems.Clear();
|
||||
SelectCell(CurrentCell);
|
||||
|
||||
// In this case the SelectCell did not invoke the change event since there was nothing to select
|
||||
// But we went from selected to unselected, that is a change, so catch it here
|
||||
if (hadIndex && CurrentCell.RowIndex.HasValue && CurrentCell.RowIndex > RowCount)
|
||||
{
|
||||
if (SelectedIndexChanged != null)
|
||||
{
|
||||
SelectedIndexChanged(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
|
||||
if (SelectedIndexChanged != null)
|
||||
{
|
||||
SelectedIndexChanged(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,11 +1674,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
SelectedItems.Add(CurrentCell);
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedIndexChanged != null)
|
||||
{
|
||||
SelectedIndexChanged(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2021,10 +2008,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void DoChangeCallback()
|
||||
{
|
||||
if (ChangedCallback != null)
|
||||
{
|
||||
// no check will make it crash for user too, not sure which way of alarm we prefer. no alarm at all will cause all sorts of subtle bugs
|
||||
if (ChangedCallback == null)
|
||||
System.Diagnostics.Debug.Fail("ColumnChangedCallback has died!");
|
||||
else
|
||||
ChangedCallback();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this shouldn't be exposed. But in order to not expose it, each RollColumn must have a change callback, and all property changes must call it, it is quicker and easier to just call this when needed
|
||||
|
|
|
@ -333,7 +333,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Using the current filter program, turn a emulator screen space coordinat to a window coordinate (suitable for lua layer drawing)
|
||||
/// Using the current filter program, turn a emulator screen space coordinate to a window coordinate (suitable for lua layer drawing)
|
||||
/// </summary>
|
||||
public Point TransformPoint(Point p)
|
||||
{
|
||||
|
|
|
@ -157,9 +157,14 @@ namespace BizHawk.Client.EmuHawk.WinFormExtensions
|
|||
/// <summary>
|
||||
/// Handles EmuHawk specific issues before showing a modal dialog
|
||||
/// </summary>
|
||||
public static DialogResult ShowHawkDialog(this Form form, IWin32Window owner = null)
|
||||
public static DialogResult ShowHawkDialog(this Form form, IWin32Window owner = null, Point position = default(Point))
|
||||
{
|
||||
GlobalWin.Sound.StopSound();
|
||||
if (position != default(Point))
|
||||
{
|
||||
form.StartPosition = FormStartPosition.Manual;
|
||||
form.Location = position;
|
||||
}
|
||||
var result = (owner == null ? form.ShowDialog() : form.ShowDialog(owner));
|
||||
GlobalWin.Sound.StartSound();
|
||||
return result;
|
||||
|
|
|
@ -21,46 +21,46 @@ namespace BizHawk.Client.EmuHawk.CoreExtensions
|
|||
{
|
||||
public static Bitmap Icon(this IEmulator core)
|
||||
{
|
||||
var attributes = Global.Emulator.Attributes();
|
||||
var attributes = core.Attributes();
|
||||
|
||||
if (!attributes.Ported)
|
||||
{
|
||||
return Properties.Resources.CorpHawkSmall;
|
||||
}
|
||||
|
||||
if (Global.Emulator is QuickNES)
|
||||
if (core is QuickNES)
|
||||
{
|
||||
return Properties.Resources.QuickNes;
|
||||
}
|
||||
else if (Global.Emulator is LibsnesCore)
|
||||
else if (core is LibsnesCore)
|
||||
{
|
||||
return Properties.Resources.bsnes;
|
||||
}
|
||||
else if (Global.Emulator is Yabause)
|
||||
else if (core is Yabause)
|
||||
{
|
||||
return Properties.Resources.yabause;
|
||||
}
|
||||
else if (Global.Emulator is Atari7800)
|
||||
else if (core is Atari7800)
|
||||
{
|
||||
return Properties.Resources.emu7800;
|
||||
}
|
||||
else if (Global.Emulator is GBA)
|
||||
else if (core is GBA)
|
||||
{
|
||||
return Properties.Resources.meteor;
|
||||
}
|
||||
else if (Global.Emulator is GPGX)
|
||||
else if (core is GPGX)
|
||||
{
|
||||
return Properties.Resources.genplus;
|
||||
}
|
||||
else if (Global.Emulator is PSP)
|
||||
else if (core is PSP)
|
||||
{
|
||||
return Properties.Resources.ppsspp;
|
||||
}
|
||||
else if (Global.Emulator is Gameboy)
|
||||
else if (core is Gameboy)
|
||||
{
|
||||
return Properties.Resources.gambatte;
|
||||
}
|
||||
else if (Global.Emulator is Snes9x)
|
||||
else if (core is Snes9x)
|
||||
{
|
||||
return Properties.Resources.snes9x;
|
||||
}
|
||||
|
@ -72,14 +72,14 @@ namespace BizHawk.Client.EmuHawk.CoreExtensions
|
|||
|
||||
public static string DisplayName(this IEmulator core)
|
||||
{
|
||||
var attributes = Global.Emulator.Attributes();
|
||||
var attributes = core.Attributes();
|
||||
|
||||
var str = (!attributes.Released ? "(Experimental) " : string.Empty) +
|
||||
attributes.CoreName;
|
||||
|
||||
if (Global.Emulator is LibsnesCore)
|
||||
if (core is LibsnesCore)
|
||||
{
|
||||
str += " (" + ((LibsnesCore)Global.Emulator).CurrentProfile + ")";
|
||||
str += " (" + ((LibsnesCore)core).CurrentProfile + ")";
|
||||
}
|
||||
|
||||
return str;
|
||||
|
|
|
@ -5,11 +5,10 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
//todo - perks - pause, copy to clipboard, backlog length limiting
|
||||
|
||||
|
@ -138,7 +137,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void HideShowGameDbButton()
|
||||
{
|
||||
AddToGameDbBtn.Visible = Global.Emulator.HasExposedMethod("GenerateGameDbEntry")
|
||||
AddToGameDbBtn.Visible = Global.Emulator.CanGenerateGameDBEntries()
|
||||
&& (Global.Game.Status == RomStatus.Unknown || Global.Game.Status == RomStatus.NotInDatabase);
|
||||
}
|
||||
|
||||
|
@ -148,10 +147,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
var result = picker.ShowDialog();
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
var entryObj = (CompactGameInfo)Global.Emulator.InvokeMethod("GenerateGameDbEntry", null);
|
||||
var gameDbEntry = Global.Emulator.AsGameDBEntryGenerator().GenerateGameDbEntry();
|
||||
var userDb = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb_user.txt");
|
||||
Global.Game.Status = entryObj.Status = picker.PickedStatus;
|
||||
Database.SaveDatabaseEntry(userDb, entryObj);
|
||||
Global.Game.Status = gameDbEntry.Status = picker.PickedStatus;
|
||||
Database.SaveDatabaseEntry(userDb, gameDbEntry);
|
||||
GlobalWin.MainForm.UpdateDumpIcon();
|
||||
HideShowGameDbButton();
|
||||
}
|
||||
|
|
|
@ -35,17 +35,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
SaveStateSubMenu.Enabled =
|
||||
LoadStateSubMenu.Enabled =
|
||||
SaveSlotSubMenu.Enabled =
|
||||
Global.Emulator.HasSavestates();
|
||||
Emulator.HasSavestates();
|
||||
|
||||
OpenRomMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Open ROM"].Bindings;
|
||||
CloseRomMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Close ROM"].Bindings;
|
||||
|
||||
MovieSubMenu.Enabled =
|
||||
CloseRomMenuItem.Enabled =
|
||||
!Global.Emulator.IsNull();
|
||||
!Emulator.IsNull();
|
||||
|
||||
var hasSaveRam = Global.Emulator.HasSaveRam();
|
||||
bool needBold = hasSaveRam && Global.Emulator.AsSaveRam().SaveRamModified;
|
||||
var hasSaveRam = Emulator.HasSaveRam();
|
||||
bool needBold = hasSaveRam && Emulator.AsSaveRam().SaveRamModified;
|
||||
|
||||
SaveRAMSubMenu.Enabled = hasSaveRam;
|
||||
if (SaveRAMSubMenu.Font.Bold != needBold)
|
||||
|
@ -53,6 +53,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
var font = new System.Drawing.Font(SaveRAMSubMenu.Font, needBold ? FontStyle.Bold : FontStyle.Regular);
|
||||
SaveRAMSubMenu.Font = font;
|
||||
}
|
||||
|
||||
AVSubMenu.Enabled =
|
||||
ScreenshotSubMenu.Enabled =
|
||||
Emulator.HasVideoProvider();
|
||||
}
|
||||
|
||||
private void RecentRomMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
|
@ -338,7 +342,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
//CLONE OF CODE FROM OpenRom (mostly)
|
||||
var ofd = new OpenFileDialog
|
||||
{
|
||||
InitialDirectory = PathManager.GetRomsPath(Global.Emulator.SystemId),
|
||||
InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId),
|
||||
Filter = filter,
|
||||
RestoreDirectory = false,
|
||||
FilterIndex = _lastOpenRomFilter,
|
||||
|
@ -447,7 +451,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void RecordMovieMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Global.Emulator.Attributes().Released)
|
||||
if (!Emulator.Attributes().Released)
|
||||
{
|
||||
var result = MessageBox.Show
|
||||
(this, "Thanks for using Bizhawk! The emulation core you have selected " +
|
||||
|
@ -460,9 +464,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (Global.Emulator is LibsnesCore)
|
||||
else if (Emulator is LibsnesCore)
|
||||
{
|
||||
var snes = (LibsnesCore)Global.Emulator;
|
||||
var snes = (LibsnesCore)Emulator;
|
||||
if (snes.CurrentProfile == "Performance")
|
||||
{
|
||||
var box = new MsgBox(
|
||||
|
@ -491,7 +495,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
new RecordMovie().ShowDialog();
|
||||
new RecordMovie(Emulator).ShowDialog();
|
||||
}
|
||||
|
||||
private void PlayMovieMenuItem_Click(object sender, EventArgs e)
|
||||
|
@ -513,7 +517,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
var ofd = new OpenFileDialog
|
||||
{
|
||||
InitialDirectory = PathManager.GetRomsPath(Global.Emulator.SystemId),
|
||||
InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId),
|
||||
Multiselect = true,
|
||||
Filter = FormatFilter(
|
||||
"Movie Files", "*.fm2;*.mc2;*.mcm;*.mmv;*.gmv;*.vbm;*.lsmv;*.fcm;*.fmv;*.vmv;*.nmv;*.smv;*.ymv;*.zmv;*.bkm;*.pjm;*.pxm",
|
||||
|
@ -701,10 +705,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
PauseMenuItem.Checked = _didMenuPause ? _wasPaused : EmulatorPaused;
|
||||
|
||||
SoftResetMenuItem.Enabled = Global.Emulator.ControllerDefinition.BoolButtons.Contains("Reset") &&
|
||||
SoftResetMenuItem.Enabled = Emulator.ControllerDefinition.BoolButtons.Contains("Reset") &&
|
||||
(!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished);
|
||||
|
||||
HardResetMenuItem.Enabled = Global.Emulator.ControllerDefinition.BoolButtons.Contains("Power") &&
|
||||
HardResetMenuItem.Enabled = Emulator.ControllerDefinition.BoolButtons.Contains("Power") &&
|
||||
(!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished);
|
||||
|
||||
PauseMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Pause"].Bindings;
|
||||
|
@ -766,7 +770,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
DisplayStatusBarMenuItem.Checked = Global.Config.DispChrome_StatusBarWindowed;
|
||||
DisplayLogWindowMenuItem.Checked = Global.Config.ShowLogWindow;
|
||||
|
||||
DisplayLagCounterMenuItem.Enabled = Global.Emulator.CanPollInput();
|
||||
DisplayLagCounterMenuItem.Enabled = Emulator.CanPollInput();
|
||||
|
||||
DisplayMessagesMenuItem.Checked = Global.Config.DisplayMessages;
|
||||
}
|
||||
|
@ -779,7 +783,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
x4MenuItem.Checked =
|
||||
x5MenuItem.Checked = false;
|
||||
|
||||
switch (Global.Config.TargetZoomFactors[Global.Emulator.SystemId])
|
||||
switch (Global.Config.TargetZoomFactors[Emulator.SystemId])
|
||||
{
|
||||
case 1: x1MenuItem.Checked = true; break;
|
||||
case 2: x2MenuItem.Checked = true; break;
|
||||
|
@ -792,12 +796,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void WindowSize_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == x1MenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 1;
|
||||
if (sender == x2MenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 2;
|
||||
if (sender == x3MenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 3;
|
||||
if (sender == x4MenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 4;
|
||||
if (sender == x5MenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 5;
|
||||
if (sender == mzMenuItem) Global.Config.TargetZoomFactors[Global.Emulator.SystemId] = 10;
|
||||
if (sender == x1MenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 1;
|
||||
if (sender == x2MenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 2;
|
||||
if (sender == x3MenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 3;
|
||||
if (sender == x4MenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 4;
|
||||
if (sender == x5MenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 5;
|
||||
if (sender == mzMenuItem) Global.Config.TargetZoomFactors[Emulator.SystemId] = 10;
|
||||
|
||||
FrameBufferResized();
|
||||
}
|
||||
|
@ -873,8 +877,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void ConfigSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
ControllersMenuItem.Enabled = Global.Emulator.ControllerDefinition.Any();
|
||||
RewindOptionsMenuItem.Enabled = Global.Emulator.HasSavestates();
|
||||
ControllersMenuItem.Enabled = Emulator.ControllerDefinition.Any();
|
||||
RewindOptionsMenuItem.Enabled = Emulator.HasSavestates();
|
||||
}
|
||||
|
||||
private void FrameSkipMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
|
@ -947,7 +951,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void ControllersMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var controller = new ControllerConfig(Global.Emulator.ControllerDefinition);
|
||||
var controller = new ControllerConfig(Emulator.ControllerDefinition);
|
||||
if (controller.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
InitControls();
|
||||
|
@ -1152,7 +1156,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
Global.Config.GB_AsSGB ^= true;
|
||||
|
||||
if (!Global.Emulator.IsNull())
|
||||
if (!Emulator.IsNull())
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
|
@ -1162,7 +1166,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
Global.Config.NES_InQuickNES ^= true;
|
||||
|
||||
if (!Global.Emulator.IsNull())
|
||||
if (!Emulator.IsNull())
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
|
@ -1181,7 +1185,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
Coresnes9xMenuItem.Checked = Global.Config.SNES_InSnes9x;
|
||||
Coresnes9xMenuItem.Visible = VersionInfo.DeveloperBuild;
|
||||
|
||||
var sss = (LibsnesCore.SnesSyncSettings)Global.Config.GetCoreSyncSettings<LibsnesCore>();
|
||||
LibsnesCore.SnesSyncSettings sss = (LibsnesCore.SnesSyncSettings)Global.Config.GetCoreSyncSettings<LibsnesCore>();
|
||||
if (sss == null)
|
||||
{
|
||||
sss = new LibsnesCore.SnesSyncSettings();
|
||||
}
|
||||
|
||||
CorebsnesPerformanceMenuItem.Checked = sss.Profile == "Performance";
|
||||
CorebsnesCompatibilityMenuItem.Checked = sss.Profile == "Compatibility";
|
||||
}
|
||||
|
@ -1199,7 +1208,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
sss.Profile = "Performance";
|
||||
Global.Config.PutCoreSyncSettings<LibsnesCore>(sss);
|
||||
|
||||
if (Global.Emulator is LibsnesCore && orig != sss.Profile)
|
||||
if (Emulator is LibsnesCore && orig != sss.Profile)
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
|
@ -1218,7 +1227,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
sss.Profile = "Compatibility";
|
||||
Global.Config.PutCoreSyncSettings<LibsnesCore>(sss);
|
||||
|
||||
if (Global.Emulator is LibsnesCore && orig != sss.Profile)
|
||||
if (Emulator is LibsnesCore && orig != sss.Profile)
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
|
@ -1228,7 +1237,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
Global.Config.SNES_InSnes9x ^= true;
|
||||
|
||||
if (Global.Emulator is Snes9x || Global.Emulator is LibsnesCore)
|
||||
if (Emulator is Snes9x || Emulator is LibsnesCore)
|
||||
{
|
||||
FlagNeedsReboot();
|
||||
}
|
||||
|
@ -1430,7 +1439,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void TAStudioMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Global.Emulator.CanPollInput())
|
||||
if (!Emulator.CanPollInput())
|
||||
{
|
||||
MessageBox.Show("Current core does not support input polling. TAStudio can't be used.");
|
||||
return;
|
||||
|
@ -1486,25 +1495,26 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void NESSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
FDSControlsMenuItem.Enabled = Global.Emulator.BoardName == "FDS";
|
||||
FDSControlsMenuItem.Enabled = Emulator.BoardName == "FDS";
|
||||
|
||||
VSControlsMenuItem.Enabled = (Global.Emulator is NES) && (Global.Emulator as NES).IsVS;
|
||||
|
||||
VSControlsMenuItem.Enabled =
|
||||
VSSettingsMenuItem.Enabled =
|
||||
((Emulator is NES) && (Emulator as NES).IsVS);
|
||||
|
||||
NESSoundChannelsMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NESSoundConfig>();
|
||||
MovieSettingsMenuItem.Enabled = Global.Emulator is NES && !Global.MovieSession.Movie.IsActive;
|
||||
MovieSettingsMenuItem.Enabled = Emulator is NES && !Global.MovieSession.Movie.IsActive;
|
||||
|
||||
NesControllerSettingsMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NesControllerSettings>()
|
||||
&& !Global.MovieSession.Movie.IsActive;
|
||||
|
||||
barcodeReaderToolStripMenuItem.Enabled = ServiceInjector.IsAvailable(Global.Emulator.ServiceProvider, typeof(BarcodeEntry));
|
||||
barcodeReaderToolStripMenuItem.Enabled = ServiceInjector.IsAvailable(Emulator.ServiceProvider, typeof(BarcodeEntry));
|
||||
|
||||
musicRipperToolStripMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NESMusicRipper>();
|
||||
}
|
||||
|
||||
private void FdsControlsMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
FdsEjectDiskMenuItem.Enabled = Global.Emulator.BoardName == "FDS";
|
||||
FdsEjectDiskMenuItem.Enabled = Emulator.BoardName == "FDS";
|
||||
|
||||
while (FDSControlsMenuItem.DropDownItems.Count > 1)
|
||||
{
|
||||
|
@ -1514,7 +1524,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
var str = "FDS Insert " + i;
|
||||
if (Global.Emulator.ControllerDefinition.BoolButtons.Contains(str))
|
||||
if (Emulator.ControllerDefinition.BoolButtons.Contains(str))
|
||||
{
|
||||
FdsInsertDiskMenuAdd("Insert Disk " + i, str, "FDS Disk " + i + " inserted.");
|
||||
}
|
||||
|
@ -1543,9 +1553,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void NESGraphicSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is NES)
|
||||
if (Emulator is NES)
|
||||
new NESGraphicsConfig().ShowDialog(this);
|
||||
else if (Global.Emulator is QuickNES)
|
||||
else if (Emulator is QuickNES)
|
||||
new QuickNesConfig().ShowDialog(this);
|
||||
}
|
||||
|
||||
|
@ -1556,7 +1566,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VSSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new NESVSSettings().ShowHawkDialog();
|
||||
if (Emulator is NES && (Emulator as NES).IsVS)
|
||||
{
|
||||
new NESVSSettings().ShowHawkDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private void FdsEjectDiskMenuItem_Click(object sender, EventArgs e)
|
||||
|
@ -1570,7 +1583,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VSInsertCoinP1MenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is NES && (Global.Emulator as NES).IsVS)
|
||||
if (Emulator is NES && (Emulator as NES).IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1582,7 +1595,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VSInsertCoinP2MenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is NES && (Global.Emulator as NES).IsVS)
|
||||
if (Emulator is NES && (Emulator as NES).IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1594,7 +1607,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void VSServiceSwitchMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is NES && (Global.Emulator as NES).IsVS)
|
||||
if (Emulator is NES && (Emulator as NES).IsVS)
|
||||
{
|
||||
if (!Global.MovieSession.Movie.IsPlaying || Global.MovieSession.Movie.IsFinished)
|
||||
{
|
||||
|
@ -1606,9 +1619,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void NesControllerSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is NES)
|
||||
if (Emulator is NES)
|
||||
new NesControllerSettings().ShowDialog();
|
||||
else if (Global.Emulator is QuickNES)
|
||||
else if (Emulator is QuickNES)
|
||||
GenericCoreConfig.DoDialog(this, "QuickNES Controller Settings", true, false);
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1644,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void PCESubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((PCEngine)Global.Emulator).GetSettings();
|
||||
var s = ((PCEngine)Emulator).GetSettings();
|
||||
|
||||
PceControllerSettingsMenuItem.Enabled = !Global.MovieSession.Movie.IsActive;
|
||||
|
||||
|
@ -1675,21 +1688,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void PCEAlwaysPerformSpriteLimitMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((PCEngine)Global.Emulator).GetSettings();
|
||||
var s = ((PCEngine)Emulator).GetSettings();
|
||||
s.SpriteLimit ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void PCEAlwaysEqualizeVolumesMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((PCEngine)Global.Emulator).GetSettings();
|
||||
var s = ((PCEngine)Emulator).GetSettings();
|
||||
s.EqualizeVolume ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void PCEArcadeCardRewindEnableMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((PCEngine)Global.Emulator).GetSettings();
|
||||
var s = ((PCEngine)Emulator).GetSettings();
|
||||
s.ArcadeCardRewindHack ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
@ -1700,8 +1713,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SMSSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
SMSregionExportToolStripMenuItem.Checked = ss.ConsoleRegion == "Export";
|
||||
SMSregionJapanToolStripMenuItem.Checked = ss.ConsoleRegion == "Japan";
|
||||
SMSregionAutoToolStripMenuItem.Checked = ss.ConsoleRegion == "Auto";
|
||||
|
@ -1742,105 +1755,105 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SMS_RegionExport_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.ConsoleRegion = "Export";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_RegionJapan_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.ConsoleRegion = "Japan";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_RegionAuto_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.ConsoleRegion = "Auto";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_DisplayNTSC_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.DisplayType = "NTSC";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_DisplayPAL_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.DisplayType = "PAL";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_DisplayAuto_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.DisplayType = "Auto";
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMS_BIOS_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.UseBIOS ^= true;
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMSEnableFMChipMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.EnableFM ^= true;
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMSOverclockMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((SMS)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((SMS)Emulator).GetSyncSettings();
|
||||
ss.AllowOverlock ^= true;
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
||||
private void SMSForceStereoMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.ForceStereoSeparation ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void SMSSpriteLimitMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.SpriteLimit ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void SMSDisplayOverscanMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.DisplayOverscan ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void SMSFix3DDisplayMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.Fix3D ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void ShowClippedRegionsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.ShowClippedRegions ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
||||
private void HighlightActiveDisplayRegionMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Global.Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
s.HighlightActiveDisplayRegion ^= true;
|
||||
PutCoreSettings(s);
|
||||
}
|
||||
|
@ -1883,7 +1896,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
var ofd = new OpenFileDialog
|
||||
{
|
||||
InitialDirectory = PathManager.GetRomsPath(Global.Emulator.SystemId),
|
||||
InitialDirectory = PathManager.GetRomsPath(Emulator.SystemId),
|
||||
Filter = "TI-83 Program Files (*.83p,*.8xp)|*.83P;*.8xp|All Files|*.*",
|
||||
RestoreDirectory = true
|
||||
};
|
||||
|
@ -1892,7 +1905,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
try
|
||||
{
|
||||
(Global.Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(ofd.FileName), true);
|
||||
(Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(ofd.FileName), true);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
|
@ -1900,7 +1913,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (MessageBox.Show(Message, "Upload Failed", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
(Global.Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(ofd.FileName), false);
|
||||
(Emulator as TI83).LinkPort.SendFileToCalc(File.OpenRead(ofd.FileName), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1948,28 +1961,28 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void GBForceDMGMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((Gameboy)Global.Emulator).GetSyncSettings();
|
||||
var s = ((Gameboy)Emulator).GetSyncSettings();
|
||||
s.ForceDMG ^= true;
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void GBAInCGBModeMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((Gameboy)Global.Emulator).GetSyncSettings();
|
||||
var s = ((Gameboy)Emulator).GetSyncSettings();
|
||||
s.GBACGB ^= true;
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void GBMulticartCompatibilityMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((Gameboy)Global.Emulator).GetSyncSettings();
|
||||
var s = ((Gameboy)Emulator).GetSyncSettings();
|
||||
s.MulticartCompat ^= true;
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void GBPaletteConfigMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var gb = Global.Emulator as Gameboy;
|
||||
var gb = Emulator as Gameboy;
|
||||
if (gb.IsCGBMode())
|
||||
CGBColorChooserForm.DoCGBColorChooserFormDialog(this);
|
||||
else
|
||||
|
@ -2049,7 +2062,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SNESSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if ((Global.Emulator as LibsnesCore).IsSGB)
|
||||
if ((Emulator as LibsnesCore).IsSGB)
|
||||
{
|
||||
SnesGBInSGBMenuItem.Visible = true;
|
||||
SnesGBInSGBMenuItem.Checked = Global.Config.GB_AsSGB;
|
||||
|
@ -2062,7 +2075,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SNESDisplayMenuItem_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((LibsnesCore)Global.Emulator).GetSettings();
|
||||
var s = ((LibsnesCore)Emulator).GetSettings();
|
||||
|
||||
SnesBg1MenuItem.Checked = s.ShowBG1_1;
|
||||
SnesBg2MenuItem.Checked = s.ShowBG2_1;
|
||||
|
@ -2171,13 +2184,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void ColecoSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((ColecoVision)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((ColecoVision)Emulator).GetSyncSettings();
|
||||
ColecoSkipBiosMenuItem.Checked = ss.SkipBiosIntro;
|
||||
}
|
||||
|
||||
private void ColecoSkipBiosMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var ss = ((ColecoVision)Global.Emulator).GetSyncSettings();
|
||||
var ss = ((ColecoVision)Emulator).GetSyncSettings();
|
||||
ss.SkipBiosIntro ^= true;
|
||||
PutCoreSyncSettings(ss);
|
||||
}
|
||||
|
@ -2195,21 +2208,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
N64CircularAnalogRangeMenuItem.Checked = Global.Config.N64UseCircularAnalogConstraint;
|
||||
|
||||
var s = ((N64)Global.Emulator).GetSettings();
|
||||
var s = ((N64)Emulator).GetSettings();
|
||||
MupenStyleLagMenuItem.Checked = s.UseMupenStyleLag;
|
||||
|
||||
//var ss = (N64SyncSettings)Global.Emulator.GetSyncSettings();
|
||||
//var ss = (N64SyncSettings)Emulator.GetSyncSettings();
|
||||
//N64ExpansionSlotMenuItem.Checked = !ss.DisableExpansionSlot;
|
||||
|
||||
N64ExpansionSlotMenuItem.Checked = (Global.Emulator as N64).UsingExpansionSlot;
|
||||
N64ExpansionSlotMenuItem.Enabled = !(Global.Emulator as N64).IsOverridingUserExpansionSlotSetting;
|
||||
N64ExpansionSlotMenuItem.Checked = (Emulator as N64).UsingExpansionSlot;
|
||||
N64ExpansionSlotMenuItem.Enabled = !(Emulator as N64).IsOverridingUserExpansionSlotSetting;
|
||||
}
|
||||
|
||||
private void N64PluginSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (new N64VideoPluginconfig().ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (Global.Emulator.IsNull())
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
GlobalWin.OSD.AddMessage("Plugin settings saved");
|
||||
}
|
||||
|
@ -2244,7 +2257,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void MupenStyleLagMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var n64 = (N64)Global.Emulator;
|
||||
var n64 = (N64)Emulator;
|
||||
var s = n64.GetSettings();
|
||||
s.UseMupenStyleLag ^= true;
|
||||
n64.PutSettings(s);
|
||||
|
@ -2252,7 +2265,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void N64ExpansionSlotMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var n64 = (N64)Global.Emulator;
|
||||
var n64 = (N64)Emulator;
|
||||
var ss = n64.GetSyncSettings();
|
||||
ss.DisableExpansionSlot ^= true;
|
||||
n64.PutSyncSettings(ss);
|
||||
|
@ -2322,9 +2335,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void AppleSubMenu_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (Global.Emulator is AppleII)
|
||||
if (Emulator is AppleII)
|
||||
{
|
||||
AppleDisksSubMenu.Enabled = (Global.Emulator as AppleII).DiskCount > 1;
|
||||
AppleDisksSubMenu.Enabled = (Emulator as AppleII).DiskCount > 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2332,9 +2345,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
AppleDisksSubMenu.DropDownItems.Clear();
|
||||
|
||||
if (Global.Emulator is AppleII)
|
||||
if (Emulator is AppleII)
|
||||
{
|
||||
var appleII = Global.Emulator as AppleII;
|
||||
var appleII = Emulator as AppleII;
|
||||
for (int i = 0; i < appleII.DiskCount; i++)
|
||||
{
|
||||
var menuItem = new ToolStripMenuItem
|
||||
|
@ -2366,6 +2379,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
#endregion
|
||||
|
||||
#region Intv
|
||||
|
||||
private void IntVControllerSettingsMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new IntvControllerSettings().ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Help
|
||||
|
||||
private void OnlineHelpMenuItem_Click(object sender, EventArgs e)
|
||||
|
@ -2400,7 +2422,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_didMenuPause = true;
|
||||
PauseEmulator();
|
||||
|
||||
OpenRomContextMenuItem.Visible = Global.Emulator.IsNull() || _inFullscreen;
|
||||
OpenRomContextMenuItem.Visible = Emulator.IsNull() || _inFullscreen;
|
||||
|
||||
bool showMenuVisible = _inFullscreen;
|
||||
if (!MainMenuStrip.Visible) showMenuVisible = true; //need to always be able to restore this as an emergency measure
|
||||
|
@ -2409,7 +2431,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
ShowMenuContextMenuSeparator.Visible =
|
||||
showMenuVisible;
|
||||
|
||||
LoadLastRomContextMenuItem.Visible = Global.Emulator.IsNull();
|
||||
LoadLastRomContextMenuItem.Visible = Emulator.IsNull();
|
||||
|
||||
StopAVContextMenuItem.Visible = _currAviWriter != null;
|
||||
|
||||
|
@ -2418,12 +2440,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
ScreenshotContextMenuItem.Visible =
|
||||
CloseRomContextMenuItem.Visible =
|
||||
UndoSavestateContextMenuItem.Visible =
|
||||
!Global.Emulator.IsNull();
|
||||
!Emulator.IsNull();
|
||||
|
||||
RecordMovieContextMenuItem.Visible =
|
||||
PlayMovieContextMenuItem.Visible =
|
||||
LoadLastMovieContextMenuItem.Visible =
|
||||
!Global.Emulator.IsNull() && !Global.MovieSession.Movie.IsActive;
|
||||
!Emulator.IsNull() && !Global.MovieSession.Movie.IsActive;
|
||||
|
||||
RestartMovieContextMenuItem.Visible =
|
||||
StopMovieContextMenuItem.Visible =
|
||||
|
@ -2437,7 +2459,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
StopNoSaveContextMenuItem.Visible = Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.Changes;
|
||||
|
||||
AddSubtitleContextMenuItem.Visible = !Global.Emulator.IsNull() && Global.MovieSession.Movie.IsActive && !Global.MovieSession.ReadOnly;
|
||||
AddSubtitleContextMenuItem.Visible = !Emulator.IsNull() && Global.MovieSession.Movie.IsActive && !Global.MovieSession.ReadOnly;
|
||||
|
||||
ConfigContextMenuItem.Visible = _inFullscreen;
|
||||
|
||||
|
@ -2572,7 +2594,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
for (int x = 0; x < Global.MovieSession.Movie.Subtitles.Count; x++)
|
||||
{
|
||||
sub = Global.MovieSession.Movie.Subtitles[x];
|
||||
if (Global.Emulator.Frame == sub.Frame)
|
||||
if (Emulator.Frame == sub.Frame)
|
||||
{
|
||||
index = x;
|
||||
break;
|
||||
|
@ -2581,7 +2603,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (index < 0)
|
||||
{
|
||||
sub = new Subtitle { Frame = Global.Emulator.Frame };
|
||||
sub = new Subtitle { Frame = Emulator.Frame };
|
||||
}
|
||||
|
||||
subForm.Sub = sub;
|
||||
|
@ -2636,7 +2658,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void DumpStatusButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
string details = Global.Emulator.CoreComm.RomStatusDetails;
|
||||
string details = Emulator.CoreComm.RomStatusDetails;
|
||||
if (!String.IsNullOrEmpty(details))
|
||||
{
|
||||
GlobalWin.Sound.StopSound();
|
||||
|
@ -2766,6 +2788,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
AutohideCursor(false);
|
||||
}
|
||||
|
||||
public void MainForm_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
MouseWheelTracker += e.Delta;
|
||||
}
|
||||
|
||||
public void MainForm_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
AutohideCursor(false);
|
||||
|
@ -2873,12 +2900,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else if (MovieService.IsValidMovieExtension(ext))
|
||||
{
|
||||
if (Global.Emulator.IsNull())
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
OpenRom();
|
||||
}
|
||||
|
||||
if (Global.Emulator.IsNull())
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2900,7 +2927,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
(GlobalWin.Tools.Get<RamWatch>() as RamWatch).LoadWatchFile(new FileInfo(filePaths[0]), false);
|
||||
}
|
||||
|
||||
else if (ext.ToUpper() == ".CDL" && Global.Emulator is PCEngine)
|
||||
else if (ext.ToUpper() == ".CDL" && Emulator is PCEngine)
|
||||
{
|
||||
GlobalWin.Tools.Load<CDL>();
|
||||
(GlobalWin.Tools.Get<CDL>() as CDL).LoadFile(filePaths[0]);
|
||||
|
@ -2908,12 +2935,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
else if (MovieImport.IsValidMovieExtension(Path.GetExtension(filePaths[0])))
|
||||
{
|
||||
if (Global.Emulator.IsNull())
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
OpenRom();
|
||||
}
|
||||
|
||||
if (Global.Emulator.IsNull())
|
||||
if (Emulator.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
ToggleFrameCounter();
|
||||
break;
|
||||
case "Lag Counter":
|
||||
if (Global.Emulator.CanPollInput())
|
||||
if (Emulator.CanPollInput())
|
||||
{
|
||||
ToggleLagCounter();
|
||||
}
|
||||
|
@ -115,6 +115,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
case "Reboot Core":
|
||||
RebootCore();
|
||||
break;
|
||||
case "Toggle Skip Lag Frame":
|
||||
Global.Config.SkipLagFrame ^= true;
|
||||
GlobalWin.OSD.AddMessage("Skip Lag Frames toggled " + (Global.Config.SkipLagFrame ? "On" : "Off"));
|
||||
break;
|
||||
|
||||
// Save States
|
||||
case "Save State 0":
|
||||
|
@ -397,6 +401,30 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.CloneFramesExternal();
|
||||
break;
|
||||
case "Analog Increment":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogIncrementByOne();
|
||||
break;
|
||||
case "Analog Decrement":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogDecrementByOne();
|
||||
break;
|
||||
case "Analog Incr. by 10":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogIncrementByTen();
|
||||
break;
|
||||
case "Analog Decr. by 10":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogDecrementByTen();
|
||||
break;
|
||||
case "Analog Maximum":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogMax();
|
||||
break;
|
||||
case "Analog Minimum":
|
||||
if (GlobalWin.Tools.IsLoaded<TAStudio>())
|
||||
GlobalWin.Tools.TAStudio.AnalogMin();
|
||||
break;
|
||||
|
||||
// SNES
|
||||
case "Toggle BG 1":
|
||||
|
|
|
@ -33,11 +33,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
var tasmovie = (movie as TasMovie);
|
||||
if (tasmovie != null)
|
||||
tasmovie.TasStateManager.MountWriteAccess();
|
||||
Global.MovieSession.QueueNewMovie(movie, record, Global.Emulator);
|
||||
Global.MovieSession.QueueNewMovie(movie, record, Emulator);
|
||||
}
|
||||
catch (MoviePlatformMismatchException ex)
|
||||
{
|
||||
MessageBox.Show(this, ex.Message, "Movie/Platform Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
MessageBox.Show(new Form(){TopMost = true}, ex.Message, "Movie/Platform Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -63,31 +63,33 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
Global.Config.RecentMovies.Add(movie.Filename);
|
||||
|
||||
if (Global.Emulator.HasSavestates() && movie.StartsFromSavestate)
|
||||
if (Emulator.HasSavestates() && movie.StartsFromSavestate)
|
||||
{
|
||||
if (movie.TextSavestate != null)
|
||||
{
|
||||
Global.Emulator.AsStatable().LoadStateText(new StringReader(movie.TextSavestate));
|
||||
Emulator.AsStatable().LoadStateText(new StringReader(movie.TextSavestate));
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.Emulator.AsStatable().LoadStateBinary(new BinaryReader(new MemoryStream(movie.BinarySavestate, false)));
|
||||
Emulator.AsStatable().LoadStateBinary(new BinaryReader(new MemoryStream(movie.BinarySavestate, false)));
|
||||
}
|
||||
if (movie.SavestateFramebuffer != null)
|
||||
|
||||
if (movie.SavestateFramebuffer != null && Emulator.HasVideoProvider())
|
||||
{
|
||||
var b1 = movie.SavestateFramebuffer;
|
||||
var b2 = Global.Emulator.VideoProvider().GetVideoBuffer();
|
||||
var b2 = Emulator.AsVideoProvider().GetVideoBuffer();
|
||||
int len = Math.Min(b1.Length, b2.Length);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
b2[i] = b1[i];
|
||||
}
|
||||
}
|
||||
Global.Emulator.ResetCounters();
|
||||
|
||||
Emulator.ResetCounters();
|
||||
}
|
||||
else if (Global.Emulator.HasSaveRam() && movie.StartsFromSaveRam)
|
||||
else if (Emulator.HasSaveRam() && movie.StartsFromSaveRam)
|
||||
{
|
||||
Global.Emulator.AsSaveRam().StoreSaveRam(movie.SaveRam);
|
||||
Emulator.AsSaveRam().StoreSaveRam(movie.SaveRam);
|
||||
}
|
||||
|
||||
Global.MovieSession.RunQueuedMovie(record);
|
||||
|
|
|
@ -28,142 +28,143 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.btnLibretroLaunchNoGame = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.txtLibretroCore = new System.Windows.Forms.TextBox();
|
||||
this.btnLibretroLaunchGame = new System.Windows.Forms.Button();
|
||||
this.btnSetLibretroCore = new System.Windows.Forms.Button();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.btnClassicLaunchGame = new System.Windows.Forms.Button();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(6, 25);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(250, 29);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Load a rom with the classic BizHawk autodetection method. But why not just use Op" +
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.btnLibretroLaunchNoGame = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.txtLibretroCore = new System.Windows.Forms.TextBox();
|
||||
this.btnLibretroLaunchGame = new System.Windows.Forms.Button();
|
||||
this.btnSetLibretroCore = new System.Windows.Forms.Button();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.btnClassicLaunchGame = new System.Windows.Forms.Button();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(6, 25);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(250, 29);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Load a rom with the classic BizHawk autodetection method. But why not just use Op" +
|
||||
"en Rom?";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 26);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "Current Core:";
|
||||
//
|
||||
// btnLibretroLaunchNoGame
|
||||
//
|
||||
this.btnLibretroLaunchNoGame.Location = new System.Drawing.Point(217, 50);
|
||||
this.btnLibretroLaunchNoGame.Name = "btnLibretroLaunchNoGame";
|
||||
this.btnLibretroLaunchNoGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchNoGame.TabIndex = 1;
|
||||
this.btnLibretroLaunchNoGame.Text = "Launch No Game";
|
||||
this.btnLibretroLaunchNoGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchNoGame.Click += new System.EventHandler(this.btnLibretroLaunchNoGame_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(370, 176);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.txtLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchGame);
|
||||
this.groupBox2.Controls.Add(this.btnSetLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchNoGame);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(433, 81);
|
||||
this.groupBox2.TabIndex = 3;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Libretro";
|
||||
//
|
||||
// txtLibretroCore
|
||||
//
|
||||
this.txtLibretroCore.Location = new System.Drawing.Point(81, 23);
|
||||
this.txtLibretroCore.Name = "txtLibretroCore";
|
||||
this.txtLibretroCore.ReadOnly = true;
|
||||
this.txtLibretroCore.Size = new System.Drawing.Size(314, 20);
|
||||
this.txtLibretroCore.TabIndex = 6;
|
||||
//
|
||||
// btnLibretroLaunchGame
|
||||
//
|
||||
this.btnLibretroLaunchGame.Location = new System.Drawing.Point(325, 50);
|
||||
this.btnLibretroLaunchGame.Name = "btnLibretroLaunchGame";
|
||||
this.btnLibretroLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchGame.TabIndex = 5;
|
||||
this.btnLibretroLaunchGame.Text = "Launch Game";
|
||||
this.btnLibretroLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchGame.Click += new System.EventHandler(this.btnLibretroLaunchGame_Click);
|
||||
//
|
||||
// btnSetLibretroCore
|
||||
//
|
||||
this.btnSetLibretroCore.AutoSize = true;
|
||||
this.btnSetLibretroCore.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnSetLibretroCore.Location = new System.Drawing.Point(401, 21);
|
||||
this.btnSetLibretroCore.Name = "btnSetLibretroCore";
|
||||
this.btnSetLibretroCore.Size = new System.Drawing.Size(26, 23);
|
||||
this.btnSetLibretroCore.TabIndex = 4;
|
||||
this.btnSetLibretroCore.Text = "...";
|
||||
this.btnSetLibretroCore.UseVisualStyleBackColor = true;
|
||||
this.btnSetLibretroCore.Click += new System.EventHandler(this.btnSetLibretroCore_Click);
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.btnClassicLaunchGame);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Location = new System.Drawing.Point(12, 99);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(277, 100);
|
||||
this.groupBox3.TabIndex = 6;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "BizHawk Classic";
|
||||
//
|
||||
// btnClassicLaunchGame
|
||||
//
|
||||
this.btnClassicLaunchGame.Location = new System.Drawing.Point(169, 71);
|
||||
this.btnClassicLaunchGame.Name = "btnClassicLaunchGame";
|
||||
this.btnClassicLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnClassicLaunchGame.TabIndex = 6;
|
||||
this.btnClassicLaunchGame.Text = "Launch Game";
|
||||
this.btnClassicLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnClassicLaunchGame.Click += new System.EventHandler(this.btnClassicLaunchGame_Click);
|
||||
//
|
||||
// OpenAdvancedChooser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(457, 208);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "OpenAdvancedChooser";
|
||||
this.Text = "Open Advanced";
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(6, 26);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "Current Core:";
|
||||
//
|
||||
// btnLibretroLaunchNoGame
|
||||
//
|
||||
this.btnLibretroLaunchNoGame.Location = new System.Drawing.Point(217, 50);
|
||||
this.btnLibretroLaunchNoGame.Name = "btnLibretroLaunchNoGame";
|
||||
this.btnLibretroLaunchNoGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchNoGame.TabIndex = 1;
|
||||
this.btnLibretroLaunchNoGame.Text = "Launch No Game";
|
||||
this.btnLibretroLaunchNoGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchNoGame.Click += new System.EventHandler(this.btnLibretroLaunchNoGame_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(370, 176);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.Text = "Cancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.txtLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchGame);
|
||||
this.groupBox2.Controls.Add(this.btnSetLibretroCore);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Controls.Add(this.btnLibretroLaunchNoGame);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(433, 81);
|
||||
this.groupBox2.TabIndex = 3;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Libretro";
|
||||
//
|
||||
// txtLibretroCore
|
||||
//
|
||||
this.txtLibretroCore.Location = new System.Drawing.Point(81, 23);
|
||||
this.txtLibretroCore.Name = "txtLibretroCore";
|
||||
this.txtLibretroCore.ReadOnly = true;
|
||||
this.txtLibretroCore.Size = new System.Drawing.Size(314, 20);
|
||||
this.txtLibretroCore.TabIndex = 6;
|
||||
//
|
||||
// btnLibretroLaunchGame
|
||||
//
|
||||
this.btnLibretroLaunchGame.Location = new System.Drawing.Point(325, 50);
|
||||
this.btnLibretroLaunchGame.Name = "btnLibretroLaunchGame";
|
||||
this.btnLibretroLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnLibretroLaunchGame.TabIndex = 5;
|
||||
this.btnLibretroLaunchGame.Text = "Launch Game";
|
||||
this.btnLibretroLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnLibretroLaunchGame.Click += new System.EventHandler(this.btnLibretroLaunchGame_Click);
|
||||
//
|
||||
// btnSetLibretroCore
|
||||
//
|
||||
this.btnSetLibretroCore.AutoSize = true;
|
||||
this.btnSetLibretroCore.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.btnSetLibretroCore.Location = new System.Drawing.Point(401, 21);
|
||||
this.btnSetLibretroCore.Name = "btnSetLibretroCore";
|
||||
this.btnSetLibretroCore.Size = new System.Drawing.Size(26, 23);
|
||||
this.btnSetLibretroCore.TabIndex = 4;
|
||||
this.btnSetLibretroCore.Text = "...";
|
||||
this.btnSetLibretroCore.UseVisualStyleBackColor = true;
|
||||
this.btnSetLibretroCore.Click += new System.EventHandler(this.btnSetLibretroCore_Click);
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.btnClassicLaunchGame);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Location = new System.Drawing.Point(12, 99);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(277, 100);
|
||||
this.groupBox3.TabIndex = 6;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "BizHawk Classic";
|
||||
//
|
||||
// btnClassicLaunchGame
|
||||
//
|
||||
this.btnClassicLaunchGame.Location = new System.Drawing.Point(169, 71);
|
||||
this.btnClassicLaunchGame.Name = "btnClassicLaunchGame";
|
||||
this.btnClassicLaunchGame.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnClassicLaunchGame.TabIndex = 6;
|
||||
this.btnClassicLaunchGame.Text = "Launch Game";
|
||||
this.btnClassicLaunchGame.UseVisualStyleBackColor = true;
|
||||
this.btnClassicLaunchGame.Click += new System.EventHandler(this.btnClassicLaunchGame_Click);
|
||||
//
|
||||
// OpenAdvancedChooser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(457, 208);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "OpenAdvancedChooser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Open Advanced";
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
GraphicsControl.MouseDoubleClick += (o, e) => HandleFullscreenToggle(o, e);
|
||||
GraphicsControl.MouseClick += (o, e) => GlobalWin.MainForm.MainForm_MouseClick(o, e);
|
||||
GraphicsControl.MouseMove += (o, e) => GlobalWin.MainForm.MainForm_MouseMove(o, e);
|
||||
GraphicsControl.MouseWheel += (o, e) => GlobalWin.MainForm.MainForm_MouseWheel(o, e);
|
||||
}
|
||||
|
||||
bool IsDisposed = false;
|
||||
|
|
|
@ -65,6 +65,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
//some people are getting MOTW through a combination of browser used to download bizhawk, and program used to dearchive it
|
||||
WhackAllMOTW(dllDir);
|
||||
|
||||
//We need to do it here too... otherwise people get exceptions when externaltools we distribute try to startup
|
||||
|
||||
//in case assembly resolution fails, such as if we moved them into the dll subdiretory, this event handler can reroute to them
|
||||
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
|
||||
|
||||
|
@ -265,7 +267,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (!VersionInfo.DeveloperBuild && Global.MovieSession.Movie.IsActive)
|
||||
{
|
||||
var result = MessageBox.Show(
|
||||
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may succeed)",
|
||||
"EmuHawk has thrown a fatal exception and is about to close.\nA movie has been detected. Would you like to try to save?\n(Note: Depending on what caused this error, this may or may not succeed)",
|
||||
"Fatal error: " + e.GetType().Name,
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Exclamation
|
||||
|
@ -318,13 +320,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern uint SetDllDirectory(string lpPathName);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)]string lpFileName);
|
||||
static void RemoveMOTW(string path)
|
||||
{
|
||||
DeleteFileW(path + ":Zone.Identifier");
|
||||
}
|
||||
|
||||
static void WhackAllMOTW(string dllDir)
|
||||
{
|
||||
var todo = new Queue<DirectoryInfo>(new[] { new DirectoryInfo(dllDir) });
|
||||
|
@ -333,9 +328,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
var di = todo.Dequeue();
|
||||
foreach (var disub in di.GetDirectories()) todo.Enqueue(disub);
|
||||
foreach (var fi in di.GetFiles("*.dll"))
|
||||
RemoveMOTW(fi.FullName);
|
||||
Win32Hacks.RemoveMOTW(fi.FullName);
|
||||
foreach (var fi in di.GetFiles("*.exe"))
|
||||
RemoveMOTW(fi.FullName);
|
||||
Win32Hacks.RemoveMOTW(fi.FullName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1524,4 +1524,40 @@
|
|||
<data name="whiteTriUp" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\whiteTriUp.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="ENE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\ENE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="ESE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\ESE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="NE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\NE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="NNE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\NNE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="NNW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\NNW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="NW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\NW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\SE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SSE" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\SSE.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SSW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\SSW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\SW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="WNW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\WNW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="WSW" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\images\WSW.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,17 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public interface IBufferedSoundProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The source audio provider.
|
||||
/// </summary>
|
||||
ISoundProvider BaseSoundProvider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears any internally buffered samples, and discards samples from the base provider (if set).
|
||||
/// </summary>
|
||||
void DiscardSamples();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public interface ISoundOutput : IDisposable
|
||||
{
|
||||
void StartSound();
|
||||
void StopSound();
|
||||
void ApplyVolumeSettings(double volume);
|
||||
int MaxSamplesDeficit { get; }
|
||||
int CalculateSamplesNeeded();
|
||||
void WriteSamples(short[] samples, int sampleCount);
|
||||
}
|
||||
}
|
|
@ -129,11 +129,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
int cursorDelta = CircularDistance(_lastWriteCursor, writeCursor, BufferSizeBytes);
|
||||
cursorDelta += BufferSizeBytes * (int)Math.Round((elapsedSeconds - (cursorDelta / (double)(Sound.SampleRate * Sound.BlockAlign))) / bufferSizeSeconds);
|
||||
_filledBufferSizeBytes -= cursorDelta;
|
||||
if (_filledBufferSizeBytes < 0)
|
||||
{
|
||||
_sound.OnUnderrun();
|
||||
detectedUnderrun = true;
|
||||
}
|
||||
detectedUnderrun = _filledBufferSizeBytes < 0;
|
||||
}
|
||||
if (isInitializing || detectedUnderrun)
|
||||
{
|
||||
|
|
|
@ -56,7 +56,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (_remainingSamples < 0)
|
||||
{
|
||||
_remainingSamples = 0;
|
||||
_sound.OnUnderrun();
|
||||
detectedUnderrun = true;
|
||||
}
|
||||
_lastWriteTime = currentWriteTime;
|
||||
|
|
|
@ -81,7 +81,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
bool detectedUnderrun = sourceState == ALSourceState.Stopped;
|
||||
if (detectedUnderrun)
|
||||
{
|
||||
_sound.OnUnderrun();
|
||||
// SampleOffset should reset to 0 when stopped; update the queued sample count to match
|
||||
UnqueueProcessedBuffers();
|
||||
currentSamplesPlayed = 0;
|
||||
|
|
|
@ -102,10 +102,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
bool isInitializing = _runningSamplesQueued == 0;
|
||||
bool detectedUnderrun = !isInitializing && _sourceVoice.State.BuffersQueued == 0;
|
||||
if (detectedUnderrun)
|
||||
{
|
||||
_sound.OnUnderrun();
|
||||
}
|
||||
long samplesAwaitingPlayback = _runningSamplesQueued - _sourceVoice.State.SamplesPlayed;
|
||||
int samplesNeeded = (int)Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0);
|
||||
if (isInitializing || detectedUnderrun)
|
||||
|
|
|
@ -14,27 +14,26 @@ namespace BizHawk.Client.EmuHawk
|
|||
public const int BlockAlign = BytesPerSample * ChannelCount;
|
||||
|
||||
private bool _disposed;
|
||||
private ISoundOutput _soundOutput;
|
||||
private ISyncSoundProvider _syncSoundProvider;
|
||||
private ISoundProvider _asyncSoundProvider;
|
||||
private SoundOutputProvider _outputProvider;
|
||||
private readonly BufferedAsync _semiSync = new BufferedAsync();
|
||||
private readonly ISoundOutput _outputDevice;
|
||||
private readonly SoundOutputProvider _outputProvider = new SoundOutputProvider(); // Buffer for Sync sources
|
||||
private readonly BufferedAsync _bufferedAsync = new BufferedAsync(); // Buffer for Async sources
|
||||
private IBufferedSoundProvider _bufferedProvider; // One of the preceding buffers, or null if no source is set
|
||||
|
||||
public Sound(IntPtr mainWindowHandle)
|
||||
{
|
||||
#if WINDOWS
|
||||
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound)
|
||||
_soundOutput = new DirectSoundSoundOutput(this, mainWindowHandle);
|
||||
_outputDevice = new DirectSoundSoundOutput(this, mainWindowHandle);
|
||||
|
||||
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.XAudio2)
|
||||
_soundOutput = new XAudio2SoundOutput(this);
|
||||
_outputDevice = new XAudio2SoundOutput(this);
|
||||
#endif
|
||||
|
||||
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.OpenAL)
|
||||
_soundOutput = new OpenALSoundOutput(this);
|
||||
_outputDevice = new OpenALSoundOutput(this);
|
||||
|
||||
if (_soundOutput == null)
|
||||
_soundOutput = new DummySoundOutput(this);
|
||||
if (_outputDevice == null)
|
||||
_outputDevice = new DummySoundOutput(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -43,8 +42,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
StopSound();
|
||||
|
||||
_soundOutput.Dispose();
|
||||
_soundOutput = null;
|
||||
_outputDevice.Dispose();
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
@ -57,151 +55,113 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (!Global.Config.SoundEnabled) return;
|
||||
if (IsStarted) return;
|
||||
|
||||
_soundOutput.StartSound();
|
||||
_outputDevice.StartSound();
|
||||
|
||||
_outputProvider = new SoundOutputProvider();
|
||||
_outputProvider.MaxSamplesDeficit = _soundOutput.MaxSamplesDeficit;
|
||||
_outputProvider.BaseSoundProvider = _syncSoundProvider;
|
||||
_outputProvider.MaxSamplesDeficit = _outputDevice.MaxSamplesDeficit;
|
||||
|
||||
Global.SoundMaxBufferDeficitMs = (int)Math.Ceiling(SamplesToMilliseconds(_soundOutput.MaxSamplesDeficit));
|
||||
Global.SoundMaxBufferDeficitMs = (int)Math.Ceiling(SamplesToMilliseconds(_outputDevice.MaxSamplesDeficit));
|
||||
|
||||
IsStarted = true;
|
||||
|
||||
//ApplyVolumeSettings();
|
||||
|
||||
//LogUnderruns = true;
|
||||
//_outputProvider.LogDebug = true;
|
||||
}
|
||||
|
||||
public void StopSound()
|
||||
{
|
||||
if (!IsStarted) return;
|
||||
|
||||
_soundOutput.StopSound();
|
||||
_outputDevice.StopSound();
|
||||
|
||||
_outputProvider = null;
|
||||
if (_bufferedProvider != null) _bufferedProvider.DiscardSamples();
|
||||
|
||||
Global.SoundMaxBufferDeficitMs = 0;
|
||||
|
||||
IsStarted = false;
|
||||
}
|
||||
|
||||
//public void ApplyVolumeSettings()
|
||||
//{
|
||||
// if (!IsStarted) return;
|
||||
|
||||
// double volume = Global.Config.SoundVolume / 100.0;
|
||||
// if (volume < 0.0) volume = 0.0;
|
||||
// if (volume > 1.0) volume = 1.0;
|
||||
// _soundOutput.ApplyVolumeSettings(volume);
|
||||
//}
|
||||
|
||||
public void SetSyncInputPin(ISyncSoundProvider source)
|
||||
/// <summary>
|
||||
/// Attaches a new input pin which will run either in sync or async mode depending
|
||||
/// on its SyncMode property. Once attached, the sync mode must not change unless
|
||||
/// the pin is re-attached.
|
||||
/// </summary>
|
||||
public void SetInputPin(ISoundProvider source)
|
||||
{
|
||||
if (_asyncSoundProvider != null)
|
||||
if (_bufferedProvider != null)
|
||||
{
|
||||
_asyncSoundProvider.DiscardSamples();
|
||||
_asyncSoundProvider = null;
|
||||
_bufferedProvider.BaseSoundProvider = null;
|
||||
_bufferedProvider.DiscardSamples();
|
||||
_bufferedProvider = null;
|
||||
}
|
||||
_semiSync.DiscardSamples();
|
||||
_semiSync.BaseSoundProvider = null;
|
||||
_syncSoundProvider = source;
|
||||
if (_outputProvider != null)
|
||||
{
|
||||
_outputProvider.BaseSoundProvider = source;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAsyncInputPin(ISoundProvider source)
|
||||
{
|
||||
if (_syncSoundProvider != null)
|
||||
if (source == null) return;
|
||||
|
||||
if (source.SyncMode == SyncSoundMode.Sync)
|
||||
{
|
||||
_syncSoundProvider.DiscardSamples();
|
||||
_syncSoundProvider = null;
|
||||
_bufferedProvider = _outputProvider;
|
||||
}
|
||||
if (_outputProvider != null)
|
||||
else if (source.SyncMode == SyncSoundMode.Async)
|
||||
{
|
||||
_outputProvider.DiscardSamples();
|
||||
_outputProvider.BaseSoundProvider = null;
|
||||
_bufferedAsync.RecalculateMagic(Global.Emulator.CoreComm.VsyncRate);
|
||||
_bufferedProvider = _bufferedAsync;
|
||||
}
|
||||
_asyncSoundProvider = source;
|
||||
_semiSync.BaseSoundProvider = source;
|
||||
_semiSync.RecalculateMagic(Global.Emulator.CoreComm.VsyncRate);
|
||||
else throw new InvalidOperationException("Unsupported sync mode.");
|
||||
|
||||
_bufferedProvider.BaseSoundProvider = source;
|
||||
}
|
||||
|
||||
public bool LogUnderruns { get; set; }
|
||||
|
||||
private bool InitializeBufferWithSilence
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
private bool RecoverFromUnderrunsWithSilence
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
private int SilenceLeaveRoomForFrameCount
|
||||
{
|
||||
get { return Global.Config.SoundThrottle ? 1 : 2; } // Why 2? I don't know, but it seems to work well with the clock throttle's behavior.
|
||||
}
|
||||
|
||||
internal void HandleInitializationOrUnderrun(bool isUnderrun, ref int samplesNeeded)
|
||||
{
|
||||
if ((!isUnderrun && InitializeBufferWithSilence) || (isUnderrun && RecoverFromUnderrunsWithSilence))
|
||||
// Fill device buffer with silence but leave enough room for one frame
|
||||
int samplesPerFrame = (int)Math.Round(SampleRate / Global.Emulator.CoreComm.VsyncRate);
|
||||
int silenceSamples = Math.Max(samplesNeeded - samplesPerFrame, 0);
|
||||
_outputDevice.WriteSamples(new short[silenceSamples * 2], silenceSamples);
|
||||
samplesNeeded -= silenceSamples;
|
||||
|
||||
if (isUnderrun)
|
||||
{
|
||||
int samplesPerFrame = (int)Math.Round(Sound.SampleRate / Global.Emulator.CoreComm.VsyncRate);
|
||||
int silenceSamples = Math.Max(samplesNeeded - (SilenceLeaveRoomForFrameCount * samplesPerFrame), 0);
|
||||
_soundOutput.WriteSamples(new short[silenceSamples * 2], silenceSamples);
|
||||
samplesNeeded -= silenceSamples;
|
||||
if (LogUnderruns) Console.WriteLine("Sound underrun detected!");
|
||||
_outputProvider.OnVolatility();
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnUnderrun()
|
||||
{
|
||||
if (!IsStarted) return;
|
||||
|
||||
if (LogUnderruns) Console.WriteLine("Sound underrun detected!");
|
||||
_outputProvider.OnVolatility();
|
||||
}
|
||||
|
||||
public void UpdateSound(float atten)
|
||||
{
|
||||
if (!Global.Config.SoundEnabled || !IsStarted || _disposed)
|
||||
if (!Global.Config.SoundEnabled || !IsStarted || _bufferedProvider == null || _disposed)
|
||||
{
|
||||
if (_asyncSoundProvider != null) _asyncSoundProvider.DiscardSamples();
|
||||
if (_syncSoundProvider != null) _syncSoundProvider.DiscardSamples();
|
||||
if (_outputProvider != null) _outputProvider.DiscardSamples();
|
||||
if (_bufferedProvider != null) _bufferedProvider.DiscardSamples();
|
||||
return;
|
||||
}
|
||||
|
||||
if (atten < 0) atten = 0;
|
||||
if (atten > 1) atten = 1;
|
||||
_soundOutput.ApplyVolumeSettings(atten);
|
||||
_outputDevice.ApplyVolumeSettings(atten);
|
||||
|
||||
short[] samples;
|
||||
int samplesNeeded = _soundOutput.CalculateSamplesNeeded();
|
||||
int samplesNeeded = _outputDevice.CalculateSamplesNeeded();
|
||||
int samplesProvided;
|
||||
|
||||
if (atten==0)
|
||||
if (atten == 0)
|
||||
{
|
||||
samples = new short[samplesNeeded * ChannelCount];
|
||||
samplesProvided = samplesNeeded;
|
||||
|
||||
if (_asyncSoundProvider != null) _asyncSoundProvider.DiscardSamples();
|
||||
if (_syncSoundProvider != null) _syncSoundProvider.DiscardSamples();
|
||||
if (_outputProvider != null) _outputProvider.DiscardSamples();
|
||||
_bufferedProvider.DiscardSamples();
|
||||
}
|
||||
else if (_syncSoundProvider != null)
|
||||
else if (_bufferedProvider == _outputProvider)
|
||||
{
|
||||
if (Global.Config.SoundThrottle)
|
||||
{
|
||||
_syncSoundProvider.GetSamples(out samples, out samplesProvided);
|
||||
_outputProvider.BaseSoundProvider.GetSamplesSync(out samples, out samplesProvided);
|
||||
|
||||
while (samplesNeeded < samplesProvided && !Global.DisableSecondaryThrottling)
|
||||
if (Global.DisableSecondaryThrottling && samplesProvided > samplesNeeded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (samplesProvided > samplesNeeded)
|
||||
{
|
||||
Thread.Sleep((samplesProvided - samplesNeeded) / (SampleRate / 1000)); // Let the audio clock control sleep time
|
||||
samplesNeeded = _soundOutput.CalculateSamplesNeeded();
|
||||
samplesNeeded = _outputDevice.CalculateSamplesNeeded();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -213,11 +173,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
_outputProvider.GetSamples(samplesNeeded, out samples, out samplesProvided);
|
||||
}
|
||||
}
|
||||
else if (_asyncSoundProvider != null)
|
||||
else if (_bufferedProvider == _bufferedAsync)
|
||||
{
|
||||
samples = new short[samplesNeeded * ChannelCount];
|
||||
|
||||
_semiSync.GetSamples(samples);
|
||||
_bufferedAsync.GetSamplesAsync(samples);
|
||||
|
||||
samplesProvided = samplesNeeded;
|
||||
}
|
||||
|
@ -226,7 +186,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
_soundOutput.WriteSamples(samples, samplesProvided);
|
||||
_outputDevice.WriteSamples(samples, samplesProvided);
|
||||
}
|
||||
|
||||
public static int MillisecondsToSamples(int milliseconds)
|
||||
|
@ -239,14 +199,4 @@ namespace BizHawk.Client.EmuHawk
|
|||
return samples * 1000.0 / SampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ISoundOutput : IDisposable
|
||||
{
|
||||
void StartSound();
|
||||
void StopSound();
|
||||
void ApplyVolumeSettings(double volume);
|
||||
int MaxSamplesDeficit { get; }
|
||||
int CalculateSamplesNeeded();
|
||||
void WriteSamples(short[] samples, int sampleCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
// Generates SEMI-synchronous sound, or "buffered asynchronous" sound.
|
||||
|
||||
|
@ -27,16 +30,15 @@ namespace BizHawk.Emulation.Common
|
|||
* TODO: For systems that _really_ don't need BufferedAsync (pce not turbocd, sms), make a way to signal
|
||||
* that and then bypass the BufferedAsync.
|
||||
*/
|
||||
|
||||
public sealed class BufferedAsync : ISoundProvider
|
||||
public sealed class BufferedAsync : ISoundProvider, IBufferedSoundProvider
|
||||
{
|
||||
public ISoundProvider BaseSoundProvider;
|
||||
public ISoundProvider BaseSoundProvider { get; set; }
|
||||
|
||||
readonly Queue<short> buffer = new Queue<short>(4096);
|
||||
private readonly Queue<short> buffer = new Queue<short>(MaxExcessSamples);
|
||||
|
||||
private int SamplesInOneFrame = 1470;
|
||||
private int TargetExtraSamples = 882;
|
||||
const int MaxExcessSamples = 4096;
|
||||
private const int MaxExcessSamples = 4096;
|
||||
|
||||
/// <summary>
|
||||
/// recalculates some internal parameters based on the IEmulator's framerate
|
||||
|
@ -50,13 +52,13 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public void DiscardSamples()
|
||||
{
|
||||
buffer.Clear();
|
||||
|
||||
if (BaseSoundProvider != null)
|
||||
BaseSoundProvider.DiscardSamples();
|
||||
}
|
||||
|
||||
public int MaxVolume { get; set; }
|
||||
|
||||
public void GetSamples(short[] samples)
|
||||
public void GetSamplesAsync(short[] samples)
|
||||
{
|
||||
int samplesToGenerate = SamplesInOneFrame;
|
||||
if (buffer.Count > samples.Length + MaxExcessSamples)
|
||||
|
@ -68,7 +70,11 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
var mySamples = new short[samplesToGenerate];
|
||||
|
||||
BaseSoundProvider.GetSamples(mySamples);
|
||||
if (BaseSoundProvider.SyncMode != SyncSoundMode.Async)
|
||||
{
|
||||
throw new InvalidOperationException("Base sound provider must be in async mode.");
|
||||
}
|
||||
BaseSoundProvider.GetSamplesAsync(mySamples);
|
||||
|
||||
foreach (short s in mySamples)
|
||||
{
|
||||
|
@ -80,5 +86,28 @@ namespace BizHawk.Emulation.Common
|
|||
samples[i] = buffer.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanProvideAsync
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public SyncSoundMode SyncMode
|
||||
{
|
||||
get { return SyncSoundMode.Async; }
|
||||
}
|
||||
|
||||
public void SetSyncMode(SyncSoundMode mode)
|
||||
{
|
||||
if (mode != SyncSoundMode.Async)
|
||||
{
|
||||
throw new NotSupportedException("Sync mode is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public void GetSamplesSync(out short[] samples, out int nsamp)
|
||||
{
|
||||
throw new InvalidOperationException("Sync mode is not supported.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
// perform a "soft" correction by resampling it to hopefully get back inside our
|
||||
// window shortly. If it ends up going too low or too high, we will perform a
|
||||
// "hard" correction by generating silence or discarding samples.
|
||||
public class SoundOutputProvider
|
||||
public class SoundOutputProvider : IBufferedSoundProvider
|
||||
{
|
||||
private const int SampleRate = 44100;
|
||||
private const int ChannelCount = 2;
|
||||
|
@ -54,7 +54,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public int MaxSamplesDeficit { get; set; }
|
||||
|
||||
public ISyncSoundProvider BaseSoundProvider { get; set; }
|
||||
public ISoundProvider BaseSoundProvider { get; set; }
|
||||
|
||||
public void DiscardSamples()
|
||||
{
|
||||
|
@ -164,7 +164,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
short[] samples;
|
||||
int count;
|
||||
|
||||
BaseSoundProvider.GetSamples(out samples, out count);
|
||||
if (BaseSoundProvider.SyncMode != SyncSoundMode.Sync)
|
||||
{
|
||||
throw new InvalidOperationException("Base sound provider must be in sync mode.");
|
||||
}
|
||||
BaseSoundProvider.GetSamplesSync(out samples, out count);
|
||||
|
||||
bool correctedEmptyFrame = false;
|
||||
if (count == 0)
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
endticks = GetCurTime();
|
||||
|
||||
// calculate time since last frame
|
||||
ulong diffticks = endticks - beginticks;
|
||||
ulong diffticks = Math.Max(endticks - beginticks, 1);
|
||||
float diff = (float)diffticks / afsfreq;
|
||||
|
||||
// calculate time since last frame not including throttle sleep time
|
||||
|
|
|
@ -473,32 +473,42 @@ namespace BizHawk.Client.EmuHawk
|
|||
using(var ofd = new OpenFileDialog())
|
||||
{
|
||||
ofd.Multiselect = true;
|
||||
if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
||||
if (ofd.ShowDialog() != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunImportJob(ofd.FileNames);
|
||||
}
|
||||
}
|
||||
|
||||
bool RunImportJobSingle(string basepath, string f, ref string errors)
|
||||
private bool RunImportJobSingle(string basepath, string f, ref string errors)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fi = new FileInfo(f);
|
||||
if (!fi.Exists) return false;
|
||||
if (!fi.Exists)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string target = Path.Combine(basepath, fi.Name);
|
||||
if (new FileInfo(target).Exists)
|
||||
{
|
||||
//compare the files, if theyre the same. dont do anything
|
||||
// compare the files, if theyre the same. dont do anything
|
||||
if (File.ReadAllBytes(target).SequenceEqual(File.ReadAllBytes(f)))
|
||||
{
|
||||
return false;
|
||||
//hmm theyre different. import but rename it
|
||||
}
|
||||
|
||||
// hmm theyre different. import but rename it
|
||||
string dir = Path.GetDirectoryName(target);
|
||||
string ext = Path.GetExtension(target);
|
||||
string name = Path.GetFileNameWithoutExtension(target);
|
||||
name += " (variant)";
|
||||
target = Path.Combine(dir, name) + ext;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(target));
|
||||
fi.CopyTo(target, false);
|
||||
return true;
|
||||
|
@ -511,7 +521,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
void RunImportJob(IEnumerable<string> files)
|
||||
private void RunImportJob(IEnumerable<string> files)
|
||||
{
|
||||
bool didSomething = false;
|
||||
var basepath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null);
|
||||
|
@ -523,9 +533,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (hf.IsArchive)
|
||||
{
|
||||
//blech. the worst extraction code in the universe.
|
||||
string extractpath = System.IO.Path.GetTempFileName() + ".dir";
|
||||
DirectoryInfo di = null;
|
||||
di = System.IO.Directory.CreateDirectory(extractpath);
|
||||
string extractpath = Path.GetTempFileName() + ".dir";
|
||||
DirectoryInfo di = Directory.CreateDirectory(extractpath);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -549,23 +558,31 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
didSomething |= RunImportJobSingle(basepath, f, ref errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors != "")
|
||||
System.Windows.Forms.MessageBox.Show(errors, "Error importing these files");
|
||||
if (!string.IsNullOrEmpty(errors))
|
||||
{
|
||||
MessageBox.Show(errors, "Error importing these files");
|
||||
}
|
||||
|
||||
if (didSomething) DoScan();
|
||||
if (didSomething)
|
||||
{
|
||||
DoScan();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if (keyData == Keys.Escape)
|
||||
{
|
||||
this.Close();
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
partial class IntvControllerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IntvControllerSettings));
|
||||
this.OkBtn = new System.Windows.Forms.Button();
|
||||
this.CancelBtn = new System.Windows.Forms.Button();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.Port2ComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.Port1ComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OkBtn
|
||||
//
|
||||
this.OkBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OkBtn.Location = new System.Drawing.Point(170, 249);
|
||||
this.OkBtn.Name = "OkBtn";
|
||||
this.OkBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.OkBtn.TabIndex = 3;
|
||||
this.OkBtn.Text = "&OK";
|
||||
this.OkBtn.UseVisualStyleBackColor = true;
|
||||
this.OkBtn.Click += new System.EventHandler(this.OkBtn_Click);
|
||||
//
|
||||
// CancelBtn
|
||||
//
|
||||
this.CancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.CancelBtn.Location = new System.Drawing.Point(236, 249);
|
||||
this.CancelBtn.Name = "CancelBtn";
|
||||
this.CancelBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.CancelBtn.TabIndex = 4;
|
||||
this.CancelBtn.Text = "&Cancel";
|
||||
this.CancelBtn.UseVisualStyleBackColor = true;
|
||||
this.CancelBtn.Click += new System.EventHandler(this.CancelBtn_Click);
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(9, 94);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(38, 13);
|
||||
this.label5.TabIndex = 16;
|
||||
this.label5.Text = "Port 2:";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(12, 44);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(38, 13);
|
||||
this.label4.TabIndex = 15;
|
||||
this.label4.Text = "Port 1:";
|
||||
//
|
||||
// Port2ComboBox
|
||||
//
|
||||
this.Port2ComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Port2ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.Port2ComboBox.FormattingEnabled = true;
|
||||
this.Port2ComboBox.Location = new System.Drawing.Point(12, 110);
|
||||
this.Port2ComboBox.Name = "Port2ComboBox";
|
||||
this.Port2ComboBox.Size = new System.Drawing.Size(284, 21);
|
||||
this.Port2ComboBox.TabIndex = 14;
|
||||
//
|
||||
// Port1ComboBox
|
||||
//
|
||||
this.Port1ComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Port1ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.Port1ComboBox.FormattingEnabled = true;
|
||||
this.Port1ComboBox.Location = new System.Drawing.Point(12, 60);
|
||||
this.Port1ComboBox.Name = "Port1ComboBox";
|
||||
this.Port1ComboBox.Size = new System.Drawing.Size(284, 21);
|
||||
this.Port1ComboBox.TabIndex = 13;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 14);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(146, 13);
|
||||
this.label1.TabIndex = 17;
|
||||
this.label1.Text = "Intellivision Controller Settings";
|
||||
//
|
||||
// IntvControllerSettings
|
||||
//
|
||||
this.AcceptButton = this.OkBtn;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.CancelBtn;
|
||||
this.ClientSize = new System.Drawing.Size(308, 284);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.Port2ComboBox);
|
||||
this.Controls.Add(this.Port1ComboBox);
|
||||
this.Controls.Add(this.CancelBtn);
|
||||
this.Controls.Add(this.OkBtn);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "IntvControllerSettings";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Controller Settings";
|
||||
this.Load += new System.EventHandler(this.IntvControllerSettings_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button OkBtn;
|
||||
private System.Windows.Forms.Button CancelBtn;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.ComboBox Port2ComboBox;
|
||||
private System.Windows.Forms.ComboBox Port1ComboBox;
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Emulation.Cores.Intellivision;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public partial class IntvControllerSettings : Form
|
||||
{
|
||||
private Intellivision.IntvSyncSettings _syncSettings;
|
||||
|
||||
public IntvControllerSettings()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void IntvControllerSettings_Load(object sender, EventArgs e)
|
||||
{
|
||||
_syncSettings = (Global.Emulator as Intellivision).SyncSettings.Clone();
|
||||
|
||||
var possibleControllers = IntellivisionControllerDeck.ValidControllerTypes.Select(t => t.Key);
|
||||
|
||||
foreach (var val in possibleControllers)
|
||||
{
|
||||
Port1ComboBox.Items.Add(val);
|
||||
Port2ComboBox.Items.Add(val);
|
||||
}
|
||||
|
||||
Port1ComboBox.SelectedItem = _syncSettings.Port1;
|
||||
Port2ComboBox.SelectedItem = _syncSettings.Port2;
|
||||
}
|
||||
|
||||
private void OkBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
bool changed =
|
||||
_syncSettings.Port1 != Port1ComboBox.SelectedItem.ToString()
|
||||
|| _syncSettings.Port2 != Port2ComboBox.SelectedItem.ToString();
|
||||
|
||||
if (changed)
|
||||
{
|
||||
_syncSettings.Port1 = Port1ComboBox.SelectedItem.ToString();
|
||||
_syncSettings.Port2 = Port2ComboBox.SelectedItem.ToString();
|
||||
|
||||
GlobalWin.MainForm.PutCoreSyncSettings(_syncSettings);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CancelBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
GlobalWin.OSD.AddMessage("Controller settings aborted");
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,624 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAwAMDAQAAAABABoBgAAxgAAACAgEAAAAAQA6AIAAC4HAAAYGBAAAAAEAOgBAAAWCgAAEBAQAAAA
|
||||
BAAoAQAA/gsAADAwAAAAAAgAqA4AACYNAAAgIAAAAAAIAKgIAADOGwAAGBgAAAAACADIBgAAdiQAABAQ
|
||||
AAAAAAgAaAUAAD4rAAAwMAAAAAAgAKglAACmMAAAICAAAAAAIACoEAAATlYAABgYAAAAACAAiAkAAPZm
|
||||
AAAQEAAAAAAgAGgEAAB+cAAAKAAAADAAAABgAAAAAQAEAAAAAACABAAAAAAAAAAAAAAQAAAAEAAAAAAA
|
||||
AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
|
||||
/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAHR3AAAAAAAAAAAAAAAAAAAAAAAAAAAAdHdEcAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAHd0d3QAAAAAAAAAAAAAAAAAAAAAAAAAAEd8d3UAAAAAAAAAAAAAAAAAAAAAAAAAB3yHfHZw
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAd3fIyHVwAAAAAAAAAAAAAAAAAAAAAAAAfHh3jIxwAAAAAAAAAAAAAAAA
|
||||
AAAAAAAHd8jIyHdgAAAAAAAAAAAAAAAAAAAAAAAHd4yHfIdAAAAAAAAAAAAAAAAAAAAAAAAHyMjIyMhQ
|
||||
AAAAAAAAAAAAAAAAAAAAAAB3d3eMh4dgAAAAAAAAAAAAAAAAAAAAAAB8jIyIfIdQAAAAAAAAAAAAAAAA
|
||||
AAAAAAB3h4jIiMh3AAAAAAAAAAAAAAAAAAAAAAB8jIeHeIjHAAAAAAAAAAAAAAAAAAAAAAeIiHh4eMiE
|
||||
AAAAAAAAAAAAB0dHcAAAAAd8h4eIiIiHcAAAAAAAAAB0d3d3RwAAAAeIeIiIiIh3RwAAAAAAAHR3d8h3
|
||||
dAAAAAfIh4iIiHiIx0cAAAAAdHh3eIeHhwAAAAeHiIiIiIiId3R3dHR0eHd4h4eHhAAAAAd4eIiIiIiH
|
||||
x3d2d3eId4iIiIiIhwAAAAd4eIiI+IiIh3d3eHh3iIiIiIeHwAAAAAfIjHeIiIiIyIeHh4iIiIiIiIiI
|
||||
cAAAAAeIQ0R3h3iIiMiIiIiIiIiIiIiEAAAAAAfIR3d3d0iIiIh4iIeIiIiIiHhAAAAAAAB4d3d3SHiI
|
||||
h4fTiIi3iIiIeIwAAAAAAAB3h4d3eIeIiHiJiIuIiIh4jHAAAAAAAAAHyId3h3h4iIh4iIiIiIiHeAAA
|
||||
AAAAAAAAB8iMiMjIiIiIh4h3aMjHAAAAAAAAAAAAAAdYyIeIiIiMjId6d4eAAAAAAAAAAAAAAAAHdsjH
|
||||
eIeH6MiId3AAAAAAAAAAAAAAAIiIh4V8jIh4eIfHcAAAAAAAAAAAAACIiIh3AAAHd3h3fHcAAAAAAAAA
|
||||
AAAAAAiIjHgAAAAAAHx8eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////
|
||||
AAD///////8AAP///////wAA//h/////AAD/4D////8AAP/AP////wAA/8A/////AAD/gB////8AAP8A
|
||||
H////wAA/wAf////AAD+AB////8AAP4AH////wAA/gAf////AAD8AB////8AAPwAH////wAA/AAP////
|
||||
AAD8AA////8AAPgAD//+BwAA+AAH//ADAAD4AAP/wAMAAPgAAP8AAwAA+AAAAAADAAD4AAAAAAMAAPgA
|
||||
AAAABwAA+AAAAAAHAAD4AAAAAA8AAPgAAAAAHwAA/AAAAAA/AAD8AAAAAH8AAP4AAAAA/wAA/4AAAAP/
|
||||
AAD/4AAAB/8AAP/4AAAf/wAA/8AAAH//AAD8A+AD//8AAPgP/A///wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC
|
||||
AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
|
||||
AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdwAAAAAAAAAAAAAAAA
|
||||
AAd0dAAAAAAAAAAAAAAAAAB3x3cAAAAAAAAAAAAAAAAAd3fHcAAAAAAAAAAAAAAAB3yMh3AAAAAAAAAA
|
||||
AAAAAAfIeMdwAAAAAAAAAAAAAAAHjIyHQAAAAAAAAAAAAAAAfId4yHAAAAAAAAAAAAAAAHjIyIdQAAAA
|
||||
AAAAAAAAAAB3iId4YAAAAAAAAAdwAAAAjIiIiIUAAAAAAHd3dAAAB4iIiHh8cAAAAHd3x4dwAAd4iIiI
|
||||
h3Z3d3R3yIh4cAAHh4iIiIfHd3d4iIiIh3AAB3jHiIiIiHeHiIiIiIwAAAh3dXh4iMiIiIiIiIhwAAAA
|
||||
yGd0d4iIeIi4iIiMAAAAAIeHd4iIh32IiIiIcAAAAAAAd4jIyIiIiHeHyAAAAAAAAAB3h4iIh8h3dwAA
|
||||
AAAAAAAIh8fIh4eIaAAAAAAAAACIiHAAB8jIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
|
||||
////////////////////n////g////wP///8B///+Af///gH///4B///8Af///AH///wB//n8AP/A+AB
|
||||
/AHgAAAB4AAAAeAAAAPgAAAH8AAAD/AAAB/8AAA//wAA//4AA//weA//////////////////////////
|
||||
//8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAA
|
||||
AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHRwAAAAAAAAAAAAB3dAAAAAAAAAAAAA
|
||||
d8dwAAAAAAAAAAAAfId3AAAAAAAAAAAHeMjHAAAAAAAAAAAHyHh3AAAAAAAAAAAHh3eEAAAAAAAAAAAI
|
||||
yIiHAAAAAHd2cAAIiIiIQAAAd3d4UACHiIiId3d3eHiIcACHh4iIyHeHiIiIcAAIR3d4iIiIiIiMAAAH
|
||||
d3eIh3iIiIhwAAAAeMh4iIiHiMAAAAAAAHfIiMh4aAAAAAAAiIgHyIfIAAAAAAAIgAAAAIAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD8f/8A+H//APB/
|
||||
/wDwP/8A4D//AOA//wDgP/8A4D/BAOAfAQDAAAEAwAABAOAAAwDgAAcA8AAfAPwAPwDwgP8A5/f/AP//
|
||||
/wD///8A////ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
|
||||
AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAd1AAAAAAAAB8cAAAAAAAB4eAAAAAAAAHyMgAAAAAAAiIhwAAAHcACI
|
||||
iHcAd3hwAIz4jIeIiIAAd3eIiIiIAACHeIiIiHAAAACMeMh4AAAAiAAIgAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAD//wAA//8AAP//AADj/wAA4/8AAMP/AADB/wAAwfkAAMDBAADAAQAAwAMAAMAHAADwDwAAzn8AAP//
|
||||
AAD//wAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAAA9OzsAZD8/AGg8
|
||||
PABtPj4AQkNDAEZIRwBWQkIAV0REAF5AQABbRkYAVklJAFxPTwBTU1MAXFJSAF5ZWQBkQEAAYUREAGZF
|
||||
RQBqQkEAYEtLAGNPTwBwQUEAfUZGAHJKSgB2SUkAfU9PAGBRUQBgVFQAZlZWAGZYWABqWVkAclZWAHpU
|
||||
VAB9W1oAbmJiAGtoaABtaWkAcWdnAHdnZwB8Y2MAe2pqAHJxcQB+dHQAd3l5AHl6egCGT08AiU9PAIFP
|
||||
UACGU1MAjVFRAIlWVgCMV1cAg1xbAIxaWQCQUlIAlVJSAJFXVgCXVVUAmVVVAJZaWQCSXV0AlV9eAJpZ
|
||||
WgCeW1sAml5eAKBZWgCgXFwAql9fAIRmZQCIZWQAhWtrAI5ragCTYmEAnGBhAJ9kYwCaZmYAk25uAJ1s
|
||||
awCFdHQAiXd3AIt+fgCWd3cAmHR0AJV5eQCbfHwAo2JhAKZhYQChZWUApGVkAKplZACsZGQAqmhnAKZr
|
||||
agCnbGsAqmloAKlubQCsbW0AtGZnALhsbACxb3AAv29wAKVxcACrc3IAr35+ALN0cwC5c3MAvXBxALR4
|
||||
dgC1fHsAunt6AMNtbgDGb3AAw3FyAMZwcQDGdXUAyHR1AMp3eADBeXkAxnt7AMB/fgDLensANLBSAEWf
|
||||
TgBBtFwAPMdnADHkdgDciiIAvoF/AISrdwDln0sA35lhAN2XfADgmmEA8LdlAO61cAArWPIALWT+AEh5
|
||||
+gDOf4AAfoCAAHiA1ABZv9wAZrnUAGK+2ABxnv4Ad6P/ADPX/QBw0OcAW+D7AIKEgwCPgoIAjI2NAJuC
|
||||
ggCUiIgAmYqKAJGSkgCjhIQAqoKCAKKLiwC+hIMAsoqKALaSgQCum5sAsZubALqqlQCdgr4Ar6ytALGh
|
||||
oAC6pKQAwoSDAMyBggDGiIYAyYiHAMWMigDMjIoA0ISFANKHiADUjIwA2Y6NAMCUjQDIk44A0JCPANaP
|
||||
kADHlZQAzpSSAMScmwDUkpIA2ZSVANWYlgDampcA2ZeYANWcnADam5sA4p2cAMChjwDeoJ4A5aCFAOaj
|
||||
jQDlpJoA2p6hAMOkowDOoaEAy62tANegoADdoqEA2aGpANGsrwDdq6kAwbG4ANGysQDdtLQA2ri3AOGk
|
||||
owDjqKYA66ylAOGnqADjq6oA6a2rAOOwrwDssK4A5K+wAOaztADttLIA57i2AO24tgDmurgA6rq6APC1
|
||||
swDyuLYA9Ly5APi+uwD1wL0A+cC9AKKMwACkk8QAqprMALSayACptsEAlaDkAOy/wACRxtQAgOv9AJnr
|
||||
9wDEwsoA5sbGAOzCwgDuyMcA7MzMAPPEwgDxy8oA9dPTAPja2gAAAAAAAAAAAP///wAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAoIJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAACYXODs4BCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
KTNDQ0M7OAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALllbYmJZQBcAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYYWNwcHBwWy8mAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFLanBwcHBwYz0eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAABpqcHBwcHBwZVkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl11w
|
||||
cHBwcHBwcGcSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIXdwcHBwcHBwcGkSAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPXBwcHBwcHBwd2wYAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAACXbnBwdXB5dXl0eW4hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAid3R5eXl5eXl5q6wzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9eXV5
|
||||
i7CxsbGxsblLKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABndYuwsbm8uby5vMFnHgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJt3q7G3vMHB1cLBwdWuEgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAeEhMSCiUAAAAAAAAAAEexsbm/1dXZ2dnZ1da5ZgwAAAAAAAAAAAAAAAAAAAAjEjNZaW5qXRMl
|
||||
AAAAAAAAADW5s7/V2N7i4uLi3dzZrQQPAAAAAAAAAAAAAAAAHxhZbm5uaWltd6ASAAAAAAAAAEmzvMLZ
|
||||
3uP29/fw4uTkuUAWCy0AAAAAAAAAAB4YYXd3gG13vbm5vb8zAAAAAAAAAE6xwdXd4/b6+/r38OTl1Vlc
|
||||
OAMIFAweFBQSM2mtrYB3vdXT0NXExNU1AAAAAAAAAE65wtXe8Pr7/Pz79+fn1WphZ25pXV1mbHetrXd3
|
||||
tdXT4vXw49nZ3NYgAAAAAAAAAEu3wdje9vv7/Pz79+fn34B3d2xtoHeud66uudXT4vD39/Dj49zk5G0A
|
||||
AAAAAAAAAD2xwcwoH0/L/Pukyenp5K27u7m5uczM0Nve4vb3+vr56OPl5eXl1igAAAAAAAAAADWxwQgB
|
||||
BQYNmveZK/Dp6cG/wcTV2eP3+vr6+/r6+ejm5ufn5+nkIgAAAAAAAAAAAJmruR4sjC2WLFCdDd3p6dXW
|
||||
1tXI3vn67pCO9Ojp6efo5+fm59wiAAAAAAAAAAAAAABLsZ0FmC0qKgHMRcjp6dzc1Y2KiO3RlfKTj+np
|
||||
5ubm5eXk1SIAAAAAAAAAAAAAAACdab/Lp5aWnEfV1cHm6ebk6pGSiabZ8fOU0uXl5eTk3NyuRQAAAAAA
|
||||
AAAAAAAAAAAAn0ux0KFTaMHBv7nC6efp3Ovv7OTm3OPl3Nzc3NfW1U6fAAAAAAAAAAAAAAAAAAAAAABF
|
||||
Wa25t7yxs7Gw5+fn5Obk18XG3NyBfHvD1cSgNQAAAAAAAAAAAAAAAAAAAAAAAAAAAFUzarGwsHl5sefn
|
||||
39zEgoZ/hL19fnqirj2jAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATj09ZXV0cLzn3NXChYeDub+1pbQ9
|
||||
VQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0rXj+rpInTBDcHCz5NW/ucG5u7GAM1QAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAADLytDi9tOemQAAAAAAUy9EecLEsa1uPTUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPj11Mme
|
||||
VakAAAAAAAAAAAAATS84M0akAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////
|
||||
AAD///////8AAP///////wAA//h/////AAD/4D////8AAP/AP////wAA/8A/////AAD/gB////8AAP8A
|
||||
H////wAA/wAf////AAD+AB////8AAP4AH////wAA/gAf////AAD8AB////8AAPwAH////wAA/AAP////
|
||||
AAD8AA////8AAPgAD//+BwAA+AAH//ADAAD4AAP/wAMAAPgAAP8AAwAA+AAAAAADAAD4AAAAAAMAAPgA
|
||||
AAAABwAA+AAAAAAHAAD4AAAAAA8AAPgAAAAAHwAA/AAAAAA/AAD8AAAAAH8AAP4AAAAA/wAA/4AAAAP/
|
||||
AAD/4AAAB/8AAP/4AAAf/wAA/8AAAH//AAD8A+AD//8AAPgP/A///wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
|
||||
AAAAAAAAAAAAAAABAAAAAQAAAAAAAFFNTQBRUlIAU1RUAGJHRwBiT08Aa0lIAGJTUwBrVlYAYllZAGZc
|
||||
XABpWloAb1xbAHNTUwB7V1YAc1hXAHFbWwBkZWUAaWFhAG5kZABpamkAcGFhAHlubgB2cHAAf3V1AH55
|
||||
eQB8fX0AgUpKAI1PTwCLWFcAhlhYAI9ZWQCKXFsAm1ZWAJJZWQCWWVgAmlpbAJtcWwCiXFwAl2BfAIBg
|
||||
YACAZ2YAgG9vAI9oaACWZWQAmGBhAJ5kZACcaWoAmm9vAIV0dACNcHAAiXZ2AIB8fACac3IAm3V0AJ51
|
||||
dQCZfHwAnHx8AKNmZgCnZmYAqmJiAK5jYwCvb24AtWVmALBtbgC5bW0AvmxtAKx+fQCxcnIAtHBwALZz
|
||||
dACydXQAtnd2ALlwcAC5dnYAt3p5ALh5eAC8fHsAun18ALx+fQDGb3AAxnBxAMdzdADAd3YAyHJzAMlz
|
||||
dADJdXYAynd4AMd/fwDMe3wAzXx9AHunbwBhvHIAYsN4ANuLOwC2hn4A4Zt5APC3ZABte9sAX47+AHWM
|
||||
5QAl0foAY+P8AIeDgwCFhoYAioSEAJOIiACWi4sAmpKRAKGCgQCmhYUAqYGBAKuDhACniooApYyMAKiO
|
||||
jQCyhYMAvoWEALeNjQCrj5AAr5eXALSVlAC9lJMAmbCEAK6RugDBgYAAwoSCAMWDhADChoQAxYeFAM6A
|
||||
gQDFiIYAxoqIAMqIiQDMi4oAy4yKAMiPjQDPj44A0ISFANKJigDUi4wA04+NANWNjgDKkY8A0JCOANud
|
||||
iQDWj5AAzJSTAM2XlgDGm5oA1pGSANOUkgDVl5EA1pOUANiVlgDYmJUA2ZeYANKenADbmpsA3pmYANuc
|
||||
mgDbn5wA1aacAN6gngDqqZoA3Z+gAMyjowDCra0AxqysAMqpqQDboaAA3qKiAN6logDbp6UA3aWkANer
|
||||
qgDWsbMA0rW0ANe0tADfs7IA4aSiAOGlpQDkp6UA46imAOWopgDsraIA6qimAOGoqADhrqwA6a2rAOqv
|
||||
rADpsK4A7LGuAOGzswDlsbEA7bKxAO+1sgDotrYA5rm3AO+4twDot7sA6bq5AOu9uwDrv70A8bazAPG2
|
||||
tADxuLUA9Lm2APC9uwD2vboA9L+9APi+uwD4v7wA8sC+APXAvgD5wL0AkILJAKqXzACsu8cAqr/LALLV
|
||||
3QDawMIA48XFAOvDwQDswMAA7cTDAO/ExQDgxsgA8cbEAPTGxADwyskA9MvJAPLNzQD21dYA+NjZAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAMEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqHCEcBQAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAayU9PSYbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdQlBSQiJpAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAM0pSUlJQPRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnUlJSUlJGFQAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAFJSUlJSUkoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzUlJSWVJZfxAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5XWYqKioqGDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASoqMkpqa
|
||||
mqAsAAAAAAAAAAAAAAAAAABoNAAAAAAAAACMjJyuvLy2toYHAAAAAAAAAAAAABcOIDouBgAAAAAAc4yc
|
||||
tsHKysPAriIKAAAAAAAAABYgRk1LTX+DEAAAAABukqXB4ejo4dHPQCIEChcXEwggTXV/k66unKMpAAAA
|
||||
AG6Srsro6ero0dN/Rk1NRk2Dg4STrsbh4cHAt2sAAAAAbpKuOXPe6ajW15KGg4OGk528yuHo5eHPz882
|
||||
AAAAAAB4jCkDAxSoMabXt5yjt8ro3ePo5dbT09HTdAAAAAAAAABGcBFoGgFwdtfDwHxi2dpmZcrX09HP
|
||||
z0MAAAAAAAAAAHh/qWwaOa6cz9PNZGPYsdzbzc3DwLk2AAAAAAAAAAAAAAAvhpKakoyg19HNyKS5wHtb
|
||||
orZ/cwAAAAAAAAAAAAAAAAAANkaKWVm5zb1gYV6cXVxfNgAAAAAAAAAAAAAAAAAAALGvlTIuP1K5tqCR
|
||||
l4xfLwAAAAAAAAAAAAAAAAAAsbPBenkAAAAAcCVYjE0scwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////+f///+D////A////wH
|
||||
///4B///+Af///gH///wB///8Af///AH/+fwA/8D4AH8AeAAAAHgAAAB4AAAA+AAAAfwAAAP8AAAH/wA
|
||||
AD//AAD//gAD//B4D////////////////////////////ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
|
||||
AAAAAAAAAAEAAAABAAAAAAAAWlJSAHBJSQB1SEgAe1dXAHdYWAB5WlkAel1dAGBiYgB1bGwAfWtrAHh2
|
||||
dgB9fn4Ag01NAIRXVwCIV1cAhV9eAItbWgCgX14ApV1dAJhgXwCNYGAAnWtqAJhtbQCCdnYAh3x8AI15
|
||||
eACeensAqGBgAKhoZwCga2oArGpqALNqagCzb28AtG1tALltbQCxb3AApnVzAKlzcwCqdHMApnp6AKd+
|
||||
fgCpensAq3x7ALZ3dgC8dHQAvH59AMZvcADGcHEAxXN0AMhycwDJdncAynh5AMx5egDNfn8Ajo1wAOek
|
||||
VgDGgH8A4p53AEZ2+gB8u4AAd8PaAIuEhACOh4cAjo6OAJ+DggCejo4Ao4SEAKSIiACsi4sAqo2MAK6P
|
||||
jgC+gYAAvoaGAL+KiACskJAAtJeXALWenQC5np4At6iOAKmyjgC9nroAwYSDAMaGhADOhoYAxomHAMiK
|
||||
iQDJjYwA0oeIANOOjwDUjY0A2ZiPANaPkADGkZEAx5eXAMySkADGnZwA1ZOSANeTlADWl5YA2JSVANGZ
|
||||
mADan50A3J6dAOCcmwDVoJ8A7K2fAMOtrQDXo6IA3aCgAN+kpADVq6oA3ay3AMu0tADPtrYA3L+/AOCi
|
||||
oQDhpqUA5KelAOinpgDlq6gA46usAOOvrQDqrqwA7LGuAOayswDjtrQA5re1AOqysQDts7EA57y6AO+8
|
||||
ugDrvL0A8LOwAPC1sgDwtrQA87q3APS6twD2vboA8b69APi/vAD2wb4A+cC9AJmTzwDHqMMAu8PMAIHf
|
||||
8QDByNAA7cLCAO3FwwDvxsQA5cjIAOzOzgDwxcQA9cbEAPPP0AD10tIAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
BQMJAAAAAAAAAAAAAAAAAAAAAAAAAAAPHBMNAAAAAAAAAAAAAAAAAAAAAAAAABojLy8TAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAB0wMDAiPgAAAAAAAAAAAAAAAAAAAAAAQjAwMDAtGAAAAAAAAAAAAAAAAAAAAAAAFzIy
|
||||
NTU5CgAAAAAAAAAAAAAAAAAAAAAAIjZYWFxcBwAAAAAAAAAAAAAAAAAAAAAANlxtdW11JQAAAAAAAAAA
|
||||
PgcRDgkAAAAAXG1/lISAZgMAAAAAABkVLC5SVhcAAABNY3WWnJuLfB8UBAcQHkhWaX91dSsAAABNY2BM
|
||||
mJeCiVJSVl9laX+WloSJgEIAAAAAXAEIC0tGjnR0dJaRk5qNjIyJQwAAAAAAJkNADBtdjIaPO1GSPYuJ
|
||||
hnVEAAAAAAAAAClISWRcd4xwkGp8UE90VwAAAAAAAAAAAAAAKSQ1NYZ7OjhbPDdGAAAAAAAAAAAAAHNv
|
||||
YGsAKyJoXFYmRwAAAAAAAAAAAAAAcnIAAAAAAAAATgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP//
|
||||
/wD///8A////APx//wD4f/8A8H//APA//wDgP/8A4D//AOA//wDgP8EA4B8BAMAAAQDAAAEA4AADAOAA
|
||||
BwDwAB8A/AA/APCA/wDn9/8A////AP///wD///8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
|
||||
AAAAAQAAAAEAAAAAAABjZGQAdmRjAHtpaQB/eHgAgU9PAKBaWgCFbm0AlWtqAKptbgCwZ2cAsGhoAKxw
|
||||
cACteHkAvnJyAMZvcADGcHEAy3l5AMx9fgCFmXQAwIB/ANeUfQDhoX8AlIqJAJWMjACYiIgAoIaGAK2K
|
||||
igCxh4cAvoGAALKKigC4iYgAuJWVAL2cnACss50AuqKhAL+mpgDLgoIAxImHAMeNjADLkI8AxpWTANCS
|
||||
kQDYlZUA1J6dANqZmgDdnp4A1J+oAMaiogDOr68AzLKyANi5uADhpaIA4qypAOWtqADrrqsA4bKwAOay
|
||||
sgDtuLYA57++AOy4uADxtLIA8be0APa9ugDswL4A9sG+ALCcxwC5ncIA06zBALnH0QC2ytQA7sPDAPLS
|
||||
0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAZBgUAAAAAAAAAAAAAAAAACw8KAAAAAAAAAAAAAAAAGhAQDgAAAAAAAAAAAAAAAAkRESUYAAAA
|
||||
AAAAAAAAAAAlKy4uBwAAAAAAAAcDAAAAKzlHPCYCAAAYCB0oKgAAAC0wSDs0FB0nLDlAOiwAAAANAQQb
|
||||
Pi9DRkVBPzUAAAAAJB4cKz5EQjMiNSkAAAAAAAAAHwwRNxYVEyQAAAAAAAAxMgAAACEgAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAD//wAA4/8AAOP/AADD/wAAwf8AAMH5
|
||||
AADAwQAAwAEAAMADAADABwAA8A8AAM5/AAD//wAA//8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAkAAAAJAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAUAAAAOAEBAVUAAABUAAAANQAAABAAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAkFBSUvGRl5TCkpwlYuLtxDJCTQFw0NmQAA
|
||||
AEkAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGAwMKE8rK6V6RET2klJR/5ZS
|
||||
U/+OT0//ZDc38B0QEJoAAAAyAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYDAwYVzAwoopP
|
||||
T/ygXVz/oFtb/55ZWf+bWFf/k1NT/1UvL9wGAwNcAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AARNKipxhk5O+adkY/+uZWX/tWdo/7VmZ/+qYWH/nltb/3hERPcfERGCAAAAFgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAADEZGS1zQ0LXqGdm/7ptbf/Fb3D/x3Bx/8hwcf/BbW7/q2Vl/4hPT/82HR2gAAAAIAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAB1gxMYyYXl3/vXFx/8Zwcf/HcHH/x3Bx/8dwcf/HcHH/uG1t/5NY
|
||||
V/9EJia2AAAAKQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPB8fNH1MS+K4cnH/x3Fy/8dwcf/HcHH/x3Bx/8dw
|
||||
cf/HcHH/wHBx/51gX/9PLCzGAAAAMwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACXjU1h6NnZv/Fc3T/x3Bx/8dw
|
||||
cf/HcHH/x3Bx/8dwcf/HcHH/w3Jz/6ZoZ/9ZMzPTAQAAPQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyFxccektK0b12
|
||||
dv/HcHH/x3Bx/8dwcf/HcHH/x3Bx/8dwcf/HcHH/xXR0/69wb/9jOjneBwMDSQAAAAUAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABNKSlNlmBf9sh3d//HcHH/x3Bx/8dwcf/HcHH/x3Bx/8dwcf/HcHH/xnd3/7Z4d/9sQUDnDgcHVQAA
|
||||
AAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABkOjqKsXFw/8lyc//HcXL/yHJz/8l0df/JdXb/yXV2/8l1dv/JdHX/ynt7/7+B
|
||||
f/94SknvFgsLZQAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAACILCxB7TUzDwXd3/8lyc//KdXb/y3h5/8x7fP/NfX7/zX5+/819
|
||||
fv/NfH3/zoOC/8iJiP+GVVX3Hg8QegAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMiIi+SXl3oynp7/8t4ef/NfX7/z4GC/9GE
|
||||
hf/Sh4j/04iJ/9KIiP/Rhof/04uK/8+RkP+XY2L9KxcXlwAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABwAA
|
||||
AA0AAAAPAAAACwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUvL1enbW37zn5+/85/
|
||||
gP/Rhob/1IuM/9aPkP/XkpP/2JOU/9iTlP/XkZH/15OT/9eZl/+rdHP/QSUlvAAAADwAAAAFAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAACQAA
|
||||
ABgAAAAvAgEBSwcDA2EFAgJoAAAAWAAAADYAAAARAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGU8
|
||||
O4W5eXn/0IKD/9KIif/Wj5D/2ZWW/9ubm//dnp//3qCg/92foP/cnZ3/3Jyc/9+in//CiYf/Zj8/4wYC
|
||||
AnAAAAAbAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAA
|
||||
AA4AAAAnCQQEUCISEoQ+IiKzVzEx1mU6OuZiOTnmRigo0hgNDZsAAABMAAAAEAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAABnVJSK/HhIP/04eI/9aQkf/amJn/3qCh/+Gmp//jq6v/5Kyt/+OsrP/iqan/4aal/+ap
|
||||
p//Umpj/nmxr/C8ZGboAAABXAAAAGAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAIAAAAOAQAALRkNDWY+IiKpZDo63YZRUfigZGP/sHBv/7V0c/+xcnH/oWZm/2k+PvEfEBCcAAAAMQAA
|
||||
AAMAAAAAAAAAAAAAAAAAAAAALhAQFIZXVs/RjIz/1Y2O/9qYmP/eoaL/46qr/+aysv/ot7f/6rm5/+m4
|
||||
uf/otbX/5q+v/+uvrf/jqab/wYeF/28/P/QhEhKvAAAAXwAAACgAAAANAAAABQAAAAMAAAACAAAAAwAA
|
||||
AAUAAAAKAAAAFQAAADAdDg9oSSkptHZHRu2dYmL+t3Z1/758e/+6enn/tnh3/7d5eP+8fn3/w4SD/7Z6
|
||||
ef9eODfbBgICTgAAAAgAAAAAAAAAAAAAAAAAAAAAPhwcJJVjYuPXkZH/2JOU/92fn//iqqr/57O0/+u8
|
||||
vP/uwsL/78XG/+/Exf/twMD/67i4/+60sv/wtrP/zZKQ/5taWv9xQED2MRsaxAgEBIcAAABaAAAAQQAA
|
||||
ADcAAAA2AAAAOwAAAEUEAgJZHA4OfUcnJ7l5SkntqGxr/8CAfv/DgoH/vH59/7p+ff/DiIb/zZGP/9GT
|
||||
kf/UlJP/1peV/9eZl/+GVlbuGQsLVwAAAAcAAAAAAAAAAAAAAAAAAAAARiIiLZ9rauvZk5P/2peY/+Ck
|
||||
pP/lsLD/6ru7/+/Fxf/yzMz/9NDQ//PPz//xycr/7sDA//K5tv/1u7j/36Kg/6dmZf+mZWX/j1ZW/WM6
|
||||
OutDJSXQNBwcvDAaGrQ0HBy1PiIivUwsLMtkPDzfh1VU9a1xcP/EhIP/xIWE/7+Cgf/Ch4b/zZST/9mk
|
||||
ov/grq3/4a6t/96lo//eoJ7/36Kg/+Cjof+IWVjnGwwMQwAAAAIAAAAAAAAAAAAAAAAAAAAARyQkL6Br
|
||||
auzZk5P/25qb/+GnqP/ntLT/7cDA//LLy//209T/+NjY//fX1//00ND/8cbG//W9u//4vrz/46ak/7d0
|
||||
c/+vb27/s3Jy/7d2df+ucXD/pWpp/6Npaf+nbWz/sHVz/7p9fP/EhYT/yImI/8WIhv/DiIb/ypGP/9eg
|
||||
n//hr63/57q5/+rCwP/rwsD/6bq4/+evrf/nq6n/6q6r/9qgnv9wRkbDBwAAHgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAASCQkLZ1nZuvYkpP/25uc/+Opqv/qtrf/7cHB//TOzv/52Nj/+tzc//na2v/xz9D/8MfH//fA
|
||||
vv/6wb7/6a6r/8OBgP/DgoD/vX58/7h7ev+8fn3/woOC/8aHhv/HiYj/xoqJ/8aLif/Ijoz/zZST/9eg
|
||||
nv/hrav/6Lm3/+zCwf/uyMf/78nH/+/Dwf/uvLr/7ba0/+60sf/vtLL/8ri1/7J+fflMKSltAAAABAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAQyEhI5JcXOPWj5D/3Juc/8qVlf+BZmb/bl5e/4l4eP/AqKj/8tPT//LO
|
||||
zv+5p6b/w6qq//fBv//7wr//8LWy/86Ojf/Ojoz/0ZGP/9GSkP/OkY//zpOR/9GamP/VoJ//2qel/+Gv
|
||||
rf/nt7X/6727/+3Dwf/wycf/8czL//LLyf/yxsT/8cC+//G7uf/yubf/87m3//S7uP/4vrv/1J6c/3JH
|
||||
RrAdCgsWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANRcXEYJNTcvPiIn/15aW/2VNTf85Ojr/Q0VF/0JF
|
||||
RP9dXFz/n5GR/+S/v/+bh4f/hXp6/+25uP/7wr//9bu4/9qcmv/Zmpj/252b/96gnf/ipKH/5q+s/+u+
|
||||
vP/vycf/8srI/+3Hxv/wysj/9c7M//TNy//0ysj/9MbE//TBv//1vrz/9r26//e9u//4vrv/+L+8//vB
|
||||
vv/hqqf/g1ZVzDwcHC4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW4+Ppq/env/05OT/2ZX
|
||||
V/9rbm7/fX9//3l6ev99f3//cHJy/5F9ff+ff3//XFhY/9eop//8wr//+L+8/+Wppv/ipaP/5qil/96i
|
||||
pP/Kmaz/1qi1//LGxP/tyMf/qb3J/23E3P9kw9//vMTN//jDwP/3wb//+MC9//i/vf/5v73/+b+8//i/
|
||||
vP/3vrv/+L68/92mo/+IWlnRRSMjOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFcv
|
||||
L0mbX1/y15GS/6GAgP9XV1b/iYuL/4CBgf98fX3/cnR0/1dPT/++j4//km9w/9Sfnv/6wL3/+cC9/+6z
|
||||
sP/ssK3/0Z+u/4OH1P9YffD/QGPs/7KYyv/Ct7z/Ytrz/3Ts//8s2f//cbvU//m+u//4v7z/+L67//e9
|
||||
uv/1vLn/9Lq3//O5tv/zuLX/0puZ/4RVVctGIyM4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAADIXFwdrPDySq2ts/diZmf/ApKT/sKur/4CBgP95enr/iYiI/49zdP/do6P/36Ch/96e
|
||||
nv/zuLX/+sK///W7uP/1ubT/qZC//2qY+/9tnf//MGT6/56FxP/esK//nMbS/57n8/9+z+T/ybG3//a6
|
||||
t//zubb/8re0//C1s//utLH/7rKw/+qvrP++iIb9dklJtkMgISoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHIyMSazw8kZ5hYvXNjI3/2aSk/7OMjP+bd3f/sIKC/9KV
|
||||
lv/cnJz/2peY/9aRkf/koqL/+sG+//nAvf/5v7z/4amw/6qZx/+aouP/qpvP/+mxtv/2urj/6rGv/+S6
|
||||
u//ptrX/466n/+Ovqf/ssK7/6q6s/+isqv/oq6n/2J2b/6JubfFoPT2NOxoaFwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOBoaCFowMFd7SEjAomZm9sWC
|
||||
gv/XkZL/25SV/9iSk//Wj5D/1IyN/9KHiP/UiIj/8bOx//rCv//3vbv/9ru4//O3s//xuLX/7q6e/+ej
|
||||
hf/npIn/7bCp/+Otp/+KsX3/ULdm/1WjWv+7oYz/5KWk/9uenP+4gH79glJRzVYuLlQgCAkGAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAA8HBwQVy4uS3FBQaCPV1fjsG5v/cmAgf/ShYb/0YKD/85+f//LeXr/2I2M//e8uf/1vLn/7rOx/+2y
|
||||
sP/lpJX/5qFY/+6xXP/djS3/35h9/86gl/9SwW7/Nd90/0WxXP+vlH//wYSE/49cW+VlOTmBQR4eHAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGk7OhqIWFd8oG5u8J5qav+eX2D/tmts/8Z0df/KdHX/yXJz/92T
|
||||
k//3vLn/7LGu/+Snpf/dm5L/4Z1q/+61dP/fmmX/15WM/9eYlv/Bm43/r6uR/6uNgP+WYWDtbkBAnUwn
|
||||
JzQVAQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiFJSBnhC
|
||||
QgpqNDQJWSUlB08dHQdfKisKfENDFJJWViinbGtRvYOCjtOcm8/pt7X157y6/7eOjfhxRUW7aTk5m4RK
|
||||
StehWlr6uGdo/8Zwcf/dkpH/8bSx/+OnpP/YmZj/1ZWT/9ealP/Vl5X/0JCP/8eIhv+zdnb/lFtc6nA/
|
||||
QKRSKio/JQwNBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADTn6AB2qioDMuUlCHBhYU8voCAWcCBgXTEhoaLzZGQqdeensngrKvn47Sz/NOop/+yiIfyi2Bgs2k+
|
||||
PlZXKysPAAAAAUYlJRxcMTFYcj4+pYpMTeWmXF3+xnl5/9+Zl//dnJr/z46M/8KCgf+vc3L/ll9e831L
|
||||
S8hlOTl/TigoMy0REQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABzQUIDnmprDriGhifHlpZMzp6eeNCgoZ7On5+2yJqaybuPj9WnfHzVj2RkunVJ
|
||||
SYNbLy8/PRQUCgAAAAAAAAAAAAAAAAAAAAAAAAAAKRUVBU0pKSphNDRtd0BAsotNTd2ZW1vrkVlY4HtJ
|
||||
Sb5lOTmCUysrQTsbGxEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWCwsA2Y4OA5xQkImdkhIRHhKSll0R0dibUBAWWI2
|
||||
NkNUKCgoOhISDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMhkZB0km
|
||||
Jh5LJiYsRSEhITATFAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP//
|
||||
/////wAA////////AAD///////8AAP///////wAA////////AAD/+H////8AAP/gH////wAA/8Af////
|
||||
AAD/gA////8AAP+AD////wAA/wAP////AAD/AA////8AAP4AB////wAA/gAH////AAD8AAf///8AAPwA
|
||||
B////wAA/AAH////AAD8AAf///8AAPgAB////wAA+AAH//4HAAD4AAP/8AEAAPgAAf/AAQAA8AAA/wAA
|
||||
AADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAEAAPAAAAAAAQAA8AAAAAADAADwAAAAAAcAAPAA
|
||||
AAAADwAA+AAAAAAfAAD4AAAAAD8AAPwAAAAAfwAA/gAAAAD/AAD/gAAAA/8AAP/gAAAH/wAAgAAAAB//
|
||||
AAAAAAAAf/8AAAAD4AP//wAAgB/8H///AAD///////8AAP///////wAA////////AAD///////8AAP//
|
||||
/////wAA////////AAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAYAAAAZAAAAGQAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAARCQkYOh8fb0ooKK80HByiCQUFTAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAIhERFmA2Np2ITUz3lVNT/4dLS/5IKCi9AAAALwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAANjODiBllhY+61kZP+vY2P/pV5e/3xHRvEhEhJfAAAAAgAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAASSgoN41VVeS6bW3/xW9w/8dwcf+9bG3/klZW/jogIIEAAAAGAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ1RkWcs2xs/8dxcv/HcHH/x3Bx/8Zwcf+iYWH/SSkpmAAA
|
||||
AAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUC0tMZtgX+fGcnP/x3Bx/8dwcf/HcHH/x3Fy/61q
|
||||
av9UMTGqAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABxRER1tm9v/8hxcv/HcHH/x3Bx/8dw
|
||||
cf/HcnP/tnRz/185OboAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAACIxXV7TEdHT/yHJz/8l1
|
||||
dv/Kd3j/ynd4/8p4eP/Bf37/bURDywAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNKysjo2Zm4Mt4
|
||||
ef/NfH3/z4GC/9GFhf/RhYb/0YWF/82Mi/9+UVHeCAICOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJAAAACwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAGc+
|
||||
Pkm1c3P30IGC/9OJiv/XkZL/2ZaW/9mWl//YlJX/2JmY/5hnZfMeEBBrAAAABwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA0FAgItHhAQWzAbG4IqFxeHDQcHWwAAABkAAAAAAAAAAAAA
|
||||
AAAAAAAAek1MdMN/f//VjI3/2piZ/9+io//hqKn/4qmp/+Clpf/jpqT/wImH/04xMLwAAAA6AAAABQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABEbDg5GRygokW5CQs+MVlbxnGJh/JdfXvxnPz7hHA8PbgAA
|
||||
AAwAAAAAAAAAAAAAAACMW1qbz4qK/9qXl//gpqb/5rKz/+q6u//rvLz/6La2/+qxr//epKL/j1lZ+DUc
|
||||
HLACAQFPAAAAHQAAAA8AAAAPAAAAEwAAACIbDg5MVDExnYZUU+SpbWz+uXl4/7x+fP/AgoD/xoeF/72A
|
||||
f/9fOzu1AAAAHAAAAAAAAAAAAAAABJhkZK/VkZH/3Z+g/+axsf/twMD/8svL//LNzf/vxcX/8Lq4/+6z
|
||||
sf+1dHP/j1VU+144N9g7IiKqMhwclDcfH5RGKSmiYTw7v4tZWOiydXT+woOC/8aKiP/Ol5X/2aWj/9ui
|
||||
of/cnpz/2pyb/35TUrgAAAAVAAAAAAAAAAAAAAAFmmVkstaTk//hpaX/7Lm6//TLy//419f/+NnZ//TP
|
||||
z//1wb//9Lq3/8aGhP+1dHP/s3Rz/6xwb/+pb27+rnNy/7Z7ev/BhIL/yY2L/8+WlP/apqT/5be2/+vB
|
||||
v//rvrz/6bKw/+uvrf/Um5n/bUVEgAAAAAMAAAAAAAAAAAAAAAOTXV2q1ZGR/9CYmP+dfX7/o4yM/9e8
|
||||
vP/z0tL/zLOz/+u8u//5v7z/1peV/8uLif/Ki4r/yoyL/86Ukv/TnJv/2qSi/+Gtq//nuLb/7cPB//DJ
|
||||
x//xxsT/8b+9//G6t//zubf/77az/6d1dM89Hx8lAAAAAAAAAAAAAAAAAAAAAIJOTojNiIn/jGlp/01O
|
||||
Tv9UVlb/dnNz/7uhof+Pfn7/xJ+e//zCv//lqKb/3J2b/+Chnv/hpaT/7Ly5/+vHxv/MxMn/0MjN//LK
|
||||
yf/1x8X/9sLA//a/vP/3vrv/+L+8//S7uP+5hoXhYTo5RwAAAAAAAAAAAAAAAAAAAAAAAAAAaTs7RrVz
|
||||
dPKmfn7/cXJx/4SGhv97fX3/b2Zm/516ev+7kJD/+sG+//C2s//lqqr/rpbA/3aB2/+ql83/tMHK/2jc
|
||||
9P9OzOz/2r3B//q/vP/3vrv/9ry6//a8uf/ss7D/tYGA32c+Pk0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAvEhIHg01Njbp9fvrCn5//nI+P/4R7ev+fgID/2Jyd/9ybnP/ytrT/+b+8/+ewtf+Mld3/ZI36/5eI
|
||||
zv/Ttrn/sNLc/6/Czv/stLT/8re0/++0sf/tsq//2qCe/6Rxb8phODg+AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABCIB8MeUZGbqRpata8gYH8x4mJ/9eTk//YkpP/04qL/+Cbmv/5wL3/9726/+Sw
|
||||
t//Zrrn/56qY/+2smf/lr6n/nLWJ/4Gtdf/Pppn/3qGf/7yEg/KJWViYTyoqIAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQh0dGXJAQGOXXl7NtnR1/8V7fP/MfH3/znt8/+il
|
||||
o//0urj/7LCu/+Whg//rq13/35VX/9Kek/9yvXz/ZbNv/6iCdfqYY2O/aj4+TCUJCgcAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAACcamsBjFRVB4FERAh9PT0JjU1ND6VnZx+/hINF0JqZiNOjoty0iIf2hFBQw5lX
|
||||
V8+wY2P4xXR0/+aioP/oq6j/2pqT/92fif/Vlor/yYqJ/7N8efiVZmPGdERFYkEfHxIAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAALiFhgXFkJEdx5CQSMqSknbNlZWbz5uaws2cnOXBlJPnqH18r4dc
|
||||
XFFULy8OSCUlFm07O0+FSUmeoV1d3sF9fPrGhoX/snZ295xkZNiFUlKbbD4+T0UdHxIAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc0JDA5FgYRKdbm46onR0Zp9ycnuWampzhFlZVmY6
|
||||
OikvDAwHAAAAAAAAAAAAAAAAAAAAAB0ODgRULCwhbjo7UXhERGVrPDxHTCYmGxAAAQMAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAP//////////////////////D////gf///wH///4A///+AP///AD///wA///8AP//+AD
|
||||
///gA//D4AH+AeAA+ADgAAAAwAAAAMAAAADAAAAB4AAAA+AAAAfgAAAP8AAAH/wAAD8AAAD/AAAD/wB4
|
||||
D//H////////////////////KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAABMAAAAtAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAgIO1cwMM1qOjrsHhAQmwAA
|
||||
ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAATCgogfUhI6ahgYP6lXV3+f0hI9wIBAT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsGBgFPLy6kuW1t/sZv
|
||||
cP/Gb3D/oF9e/hMKCmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4QECynZmX7xnBx/sdwcf/HcHH/tG1t/h8REYMAAAABAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAx
|
||||
MIzFc3T+xm9w/sdwcf7HcHH+vHR0/jAcHJkAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQ4OAYVSUtfIcnP/yXZ3/st5ef/LeHn/xoB//kQq
|
||||
KrEAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAJxYWGrNvb/7Nfn//0oeI/tSNjf/UjI3/1ZOS/mE+PtQAAAAXAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAIAAAARAAAALQAAADUAAAARAAAAAAAAAAAAAAAAQyYmUM6Ghv/Wj5D/3J2e/uCl
|
||||
pf/fpKT/4KOi/qRycPkHBARlAAAABQAAAAAAAAAAAAAAAAAAAAAAAAADAQAAJh8REYBYNTXMhVJR8XxM
|
||||
TO8gEhKeAAAAEAAAAAAAAAAAbUVEe9aPkP7doKD+5rKz/uu9vv7rvLz+6rKx/tqfnf5iNzfnCAQEcwAA
|
||||
ACoAAAAbAAAAIQIBATorGBiQhFNT67Z3dv68fn3+wYSD/siKiP6aZmX2AQAAKQAAAAAAAAAAd05Ni9eT
|
||||
lP/jq6z/7cLC/vXS0v/zz9D/8b69/uyxrv+samr/l15d+2tDQ+NkPz7bdkxL451nZve+gYD/yY2M/tWg
|
||||
n//jtrT/46+t/uOmpP+mdHPwBQMDFAAAAAAAAAAAdkpJh9iUlf7Hl5f+tJeX/uzOzv7lyMj+57y6/vS6
|
||||
t/7HhoX+xYaE/saJh/7MkpD+0ZmY/tejov7mt7X+7cXD/vDFxP7vvLr+8Le0/u2zsf5PMzOMDQcHAQAA
|
||||
AAAAAAAAYTg4X9OOj/9aUlL/YGJi/nh2dv+skJD/qo2M/vnAvf/dn53/4KKg/+Cnp/7vxsT/u8PM/sHI
|
||||
0P/1xsT/9sG+/ve+u//3vrv/87q3/ntVVLkkFhYIAAAAAAAAAAAAAAAAVC8wD6BkZOWjhIT/jo6O/n1+
|
||||
fv+eenv/xpGR/vi/vP/wtbL/mZPP/0Z2+v69nrr/gd/x/nfD2v/2vLr/9Lq3/vG2tP/lq6j/elJRrjQg
|
||||
IAoAAAAAAAAAAAAAAAAAAAAAAAAAAGc7OyeOWVnGv4eH/r2Fhf7YlZb+1Y6P/uinpv74v7z+3ay3/seo
|
||||
w/7srZ/+7LGv/qmyjv63qI7+5Kel/r2GhPZ1S0p1QCcmAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAd0pKOpReXtKxb3D/yXl6/sx5ev/ws7D/6q6s/+Ked/7npFb/2ZiP/ny7gP+OjW/9h1dWr2I7
|
||||
OiMAAAAAAAAAAAAAAAAAAAAAAAAAALSCggSqcXIbo2dnN61xcVS/h4eIzp2c2cKWle2OY2OGbz4+Y4xN
|
||||
Tr6zaWn84Jyb/9aXlv7Ji4r/p25t9INTUqZlPDw3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJg
|
||||
YASjcnMorH9/a6h7e4yabm6Df1NTU3VKSgwAAAAAAAAAAAAAAABgNDQgcj8/bntHR4ZnPDxTVTExDQAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////APx//wD4P/8A8D//AOA//wDgH/8A4B//AMAf
|
||||
/wDAH8EAwA8AAMAAAADAAAAAwAAAAMAAAQDAAAMA4AAHAPgAHwAAAH8AAcH/AP///wD///8A////ACgA
|
||||
AAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQc
|
||||
HA5LKSlUNBwcSAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsO
|
||||
DgV/SkqHm1hY+X5HR90tGRkuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAB4SEhCr2Zm7sZwcf+oYWL5UC8vUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAACnl9fnMRwcf/IcXL/tmxs/mI8PGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAa0NCGbRsbdbMenv/zn5//8R9ff9ySkmCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAA
|
||||
AAkAAAAAAAAAAItYWDvFfn/y2ZWW/92fn//anJv/jWFgvwAAAB0AAAAAAAAAAAAAAAIzHBwiYjs7a3pM
|
||||
S6pqQkKjLBoaMwAAAACeZ2dZ05KS/em0tP/vxMT/77u6/8CHhfpmPDyvRysqYlExMV1ySEiGnWdn07qB
|
||||
gPzLkI//w4iG/HJLS3YAAAAAomloXsyRkf/DoKD/48bG/+jAv//hpKL/vX17/7h/fPu/iYj7z5qZ/+Gw
|
||||
rv/rvLr/77q3/9ScmuR9U1I+AAAAAJZbWz2ndnbxdG9v/4yCgv+4lJP/77Wy/86erP+6nsH/tsXR/8PH
|
||||
0P/4wsD/9b26/+Cppu2peXdiAAAAAQAAAABYKCgHn2lqe6eCguSsgoL90pKS//Cxrv/TrcP/s5y+/8i3
|
||||
s/+quab/26mh/82UktSgbm1TBAAAAwAAAACud3cEvYGBC7N6ehyyfHtyt39+3bNub9vLgYH05qak/+Kg
|
||||
g//OlH39jZR04Zd0aYmDT1EiAAAAAAAAAAAAAAAAr3t7D7aCgki5h4Z8uImJgah+fUltPz8ajU1ORq1s
|
||||
bI6vdHOgm2RkaYxJUiZgCygCAAAAAAAAAAAAAAAAAAAAAGo9PQF9UVEHcEdHCTodHQIAAAAAAAAAAAAA
|
||||
AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AADh/wAAwf8AAMH/
|
||||
AACB/wAAgfkAAIDAAACAAAAAgAAAAIAAAACAAQAAAAcAAAAPAAAOfwAA//8AAA==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
|
@ -2,6 +2,7 @@
|
|||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
|
@ -66,7 +67,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SetMaxXY()
|
||||
{
|
||||
var video = BizHawk.Emulation.Common.VideoProviderGlue.VideoProvider(Global.Emulator);
|
||||
var video = Global.Emulator.AsVideoProvider(); // TODO: this is objectively wrong, these are core agnostic settings, why is the current core used here? Also this will crash on a core without a video provider
|
||||
XNumeric.Maximum = video.BufferWidth - 12;
|
||||
YNumeric.Maximum = video.BufferHeight - 12;
|
||||
PositionPanel.Size = new Size(video.BufferWidth + 2, video.BufferHeight + 2);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
return;
|
||||
}
|
||||
|
||||
string[] coresToHide = { "INTV", "C64" };
|
||||
string[] coresToHide = { "C64" };
|
||||
|
||||
foreach (var core in coresToHide)
|
||||
{
|
||||
|
|
After Width: | Height: | Size: 567 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 586 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 827 B |
After Width: | Height: | Size: 546 B |
After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 663 B |
After Width: | Height: | Size: 723 B |
After Width: | Height: | Size: 642 B |
After Width: | Height: | Size: 785 B |
After Width: | Height: | Size: 771 B |
|
@ -13,14 +13,18 @@ using BizHawk.Client.EmuHawk.WinFormExtensions;
|
|||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
// TODO - Allow relative paths in record textbox
|
||||
public partial class RecordMovie : Form
|
||||
{
|
||||
// TODO - Allow relative paths in record textbox
|
||||
public RecordMovie()
|
||||
private IEmulator Emulator;
|
||||
|
||||
public RecordMovie(IEmulator core)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
if (!Global.Emulator.HasSavestates())
|
||||
Emulator = core;
|
||||
|
||||
if (!Emulator.HasSavestates())
|
||||
{
|
||||
StartFromCombo.Items.Remove(
|
||||
StartFromCombo.Items
|
||||
|
@ -29,7 +33,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
.ToLower() == "now"));
|
||||
}
|
||||
|
||||
if (!Global.Emulator.HasSaveRam())
|
||||
if (!Emulator.HasSaveRam())
|
||||
{
|
||||
StartFromCombo.Items.Remove(
|
||||
StartFromCombo.Items
|
||||
|
@ -88,9 +92,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
Directory.CreateDirectory(fileInfo.DirectoryName);
|
||||
}
|
||||
|
||||
if (StartFromCombo.SelectedItem.ToString() == "Now" && Global.Emulator.HasSavestates())
|
||||
if (StartFromCombo.SelectedItem.ToString() == "Now" && Emulator.HasSavestates())
|
||||
{
|
||||
var core = Global.Emulator.AsStatable();
|
||||
var core = Emulator.AsStatable();
|
||||
|
||||
movieToRecord.StartsFromSavestate = true;
|
||||
movieToRecord.StartsFromSaveRam = false;
|
||||
|
@ -112,15 +116,15 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
// hack: some IMovies eat the framebuffer, so don't bother with them
|
||||
movieToRecord.SavestateFramebuffer = new int[0];
|
||||
if (movieToRecord.SavestateFramebuffer != null)
|
||||
if (movieToRecord.SavestateFramebuffer != null && Emulator.HasVideoProvider())
|
||||
{
|
||||
movieToRecord.SavestateFramebuffer = (int[])Global.Emulator.VideoProvider().GetVideoBuffer().Clone();
|
||||
movieToRecord.SavestateFramebuffer = (int[])Emulator.AsVideoProvider().GetVideoBuffer().Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (StartFromCombo.SelectedItem.ToString() == "SaveRam" && Global.Emulator.HasSaveRam())
|
||||
else if (StartFromCombo.SelectedItem.ToString() == "SaveRam" && Emulator.HasSaveRam())
|
||||
{
|
||||
var core = Global.Emulator.AsSaveRam();
|
||||
var core = Emulator.AsSaveRam();
|
||||
movieToRecord.StartsFromSavestate = false;
|
||||
movieToRecord.StartsFromSaveRam = true;
|
||||
movieToRecord.SaveRam = core.CloneSaveRam();
|
||||
|
|