* Taseditor: Config->Deselect on doubleclick
* Taseditor: checking ROM checksum when saving/loading projects * more correct way to launch TAS Editor when trying to rerecord a fm3 * TAS Editor can have mouse wheel input even when keyboard focus is on FCEUX window * disabled FCEUX context menu when TAS Editor is engaged * added SoundDisplay2.lua
This commit is contained in:
parent
9722ac44c7
commit
0638d88ff9
|
@ -0,0 +1,312 @@
|
|||
-- feos, 2012
|
||||
-- gui.box frame simulates transparency
|
||||
|
||||
print("Hi-hat and keys may glitch if you produce sound effects.")
|
||||
print("Leftclick over the displays: channel names to hide the volumes, notes to hide the keyboard.")
|
||||
print(" ")
|
||||
print("And praise Gocha!")
|
||||
|
||||
iterator = 15
|
||||
kb = {x=9, y=154, on=true}
|
||||
prev_keys = input.get()
|
||||
semitones = {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"}
|
||||
|
||||
volumes = {
|
||||
S1V = {0}, S1C = {},
|
||||
S2V = {0}, S2C = {},
|
||||
TV = {0},
|
||||
NV = {0},
|
||||
DPCMV = {0}
|
||||
}
|
||||
|
||||
function Draw()
|
||||
snd = sound.get()
|
||||
keys = input.get()
|
||||
|
||||
-- do only at the first frame
|
||||
if #volumes.S1V == 1 then
|
||||
channels = {
|
||||
Square1 = {x=1, y=9, vol=volumes.S1V, color=volumes.S1C, duty=0, midi=0, semitone=0, octave=0, prev_semitone=0, float = {}},
|
||||
Square2 = {x=1+45*1, y=9, vol=volumes.S2V, color=volumes.S2C, duty=0, midi=0, semitone=0, octave=0, prev_semitone=0, float = {}},
|
||||
Triangle = {x=1+45*2, y=9, vol=volumes.TV, midi=0, semitone=0, octave=0, prev_semitone=0, float = {}},
|
||||
Noise = {x=1+45*3, y=9, vol=volumes.NV, midi=0, semitone=0, octave=0},
|
||||
DPCM = {x=1+45*4, y=9, vol=volumes.DPCMV}
|
||||
}
|
||||
end
|
||||
|
||||
-- update the first indices for volume tables
|
||||
-- shift the previous ones farther
|
||||
table.insert(channels.Square1.vol, 1, snd.rp2a03.square1.volume*15)
|
||||
table.insert(channels.Square2.vol, 1, snd.rp2a03.square2.volume*15)
|
||||
table.insert(channels.Triangle.vol, 1, snd.rp2a03.triangle.volume*15)
|
||||
table.insert(channels.Noise.vol, 1, snd.rp2a03.noise.volume*15)
|
||||
table.insert(channels.DPCM.vol, 1, snd.rp2a03.dpcm.volume*15)
|
||||
|
||||
-- get duty and midikey for proper channels
|
||||
channels.Square1.duty = snd.rp2a03.square1.duty
|
||||
channels.Square2.duty = snd.rp2a03.square2.duty
|
||||
|
||||
channels.Square1.midi = snd.rp2a03.square1.midikey
|
||||
channels.Square2.midi = snd.rp2a03.square2.midikey
|
||||
channels.Triangle.midi = snd.rp2a03.triangle.midikey
|
||||
channels.Noise.midi = snd.rp2a03.noise.midikey
|
||||
|
||||
-- guess notes
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" or name == "Triangle" or name == "Noise" then
|
||||
if chan.vol[1] > 0 then
|
||||
chan.octave = math.floor((chan.midi - 12) / 12)
|
||||
chan.semitone = tostring(semitones[math.floor((chan.midi - 21) % 12) + 1])
|
||||
else chan.semitone = "--"; chan.octave = "-"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- notes display
|
||||
gui.text(kb.x+203, kb.y, "S1: "..channels.Square1.semitone..channels.Square1.octave, "#ff0000ff", "#000000ff")
|
||||
gui.text(kb.x+203, kb.y+9, "S2: "..channels.Square2.semitone..channels.Square2.octave, "#aa00ccff", "#000000ff")
|
||||
gui.text(kb.x+204, kb.y+18, "Tr: "..channels.Triangle.semitone..channels.Triangle.octave, "#00aaffff", "#000000ff")
|
||||
gui.text(kb.x+204, kb.y+27, "Ns: "..channels.Noise.semitone..channels.Noise.octave, "#ffffffff", "#000000ff")
|
||||
|
||||
-----------------
|
||||
-- Draw hi-hat --
|
||||
-----------------
|
||||
|
||||
xhh1 = 227
|
||||
yhh1 = 18
|
||||
xhh2 = 227
|
||||
yhh2 = 18
|
||||
|
||||
if channels.Noise.vol[1] > 0 then
|
||||
if channels.Noise.octave >= 8 and channels.Noise.octave <= 13 then
|
||||
colorhh = "#ffaa00"
|
||||
if channels.Noise.vol[2] - channels.Noise.vol[1] < 4
|
||||
and channels.Noise.vol[2] > 0
|
||||
then yhh1 = 15
|
||||
end
|
||||
end
|
||||
else colorhh = "#00000000"
|
||||
end
|
||||
|
||||
gui.line(xhh1-1, yhh1, xhh1+28, yhh1, "#00000088")
|
||||
gui.line(xhh1-1, yhh1-1, xhh1+28, yhh1-1, "#00000088")
|
||||
gui.line(xhh1-1, yhh1-2, xhh1+28, yhh1-2, "#00000088")
|
||||
gui.line(xhh1+3, yhh1-3, xhh1+24, yhh1-3, "#00000088")
|
||||
gui.line(xhh1+8, yhh1-4, xhh1+19, yhh1-4, "#00000088")
|
||||
gui.line(xhh1+11, yhh1-5, xhh1+16, yhh1-5, "#00000088")
|
||||
gui.line(xhh1+12, yhh1-6, xhh1+15, yhh1-6, "#00000088")
|
||||
gui.line(xhh2-1, yhh2, xhh2+28, yhh2, "#00000088")
|
||||
gui.line(xhh2-1, yhh2+1, xhh2+28, yhh2+1, "#00000088")
|
||||
gui.line(xhh2-1, yhh2+2, xhh2+28, yhh2+2, "#00000088")
|
||||
gui.line(xhh2+3, yhh2+3, xhh2+24, yhh2+3, "#00000088")
|
||||
gui.line(xhh2+8, yhh2+4, xhh2+19, yhh2+4, "#00000088")
|
||||
gui.line(xhh2+11, yhh2+5, xhh2+16, yhh2+5, "#00000088")
|
||||
gui.line(xhh2+12, yhh2+6, xhh2+15, yhh2+6, "#00000088")
|
||||
|
||||
gui.line(xhh1, yhh1-1, xhh1+27, yhh1-1, colorhh)
|
||||
gui.line(xhh1+4, yhh1-2, xhh1+23, yhh1-2, colorhh)
|
||||
gui.line(xhh1+9, yhh1-3, xhh1+18, yhh1-3, colorhh)
|
||||
gui.line(xhh1+12, yhh1-4, xhh1+15, yhh1-4, colorhh)
|
||||
gui.line(xhh1+13, yhh1-5, xhh1+14, yhh1-5, colorhh)
|
||||
gui.line(xhh2, yhh2+1, xhh2+27, yhh2+1, colorhh)
|
||||
gui.line(xhh2+4, yhh2+2, xhh2+23, yhh2+2, colorhh)
|
||||
gui.line(xhh2+9, yhh2+3, xhh2+18, yhh2+3, colorhh)
|
||||
gui.line(xhh2+12, yhh2+4, xhh2+15, yhh2+4, colorhh)
|
||||
gui.line(xhh2+13, yhh2+5, xhh2+14, yhh2+5, colorhh)
|
||||
|
||||
--------------------
|
||||
-- Keyboard stuff --
|
||||
--------------------
|
||||
|
||||
if (kb.on) then
|
||||
-- capture leftclicks
|
||||
if keys.xmouse <= 256 and keys.xmouse >= 205 and keys.ymouse >= 154 and keys.ymouse <= 181 then
|
||||
if keys["leftclick"] and not prev_keys["leftclick"] then kb.on = false end
|
||||
end
|
||||
-- draw the kayboard
|
||||
gui.box(kb.x-8, kb.y, kb.x+200, kb.y+16, "#ffffffff") -- white solid box
|
||||
for a = -2, 49 do gui.box(kb.x+4*a, kb.y, kb.x+4*a, kb.y+16, "#00000000") end -- black lines
|
||||
-- draw colored boxes as clean notes
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" or name == "Triangle" then
|
||||
if name == "Triangle" then color = "#00aaffff"
|
||||
elseif name == "Square1" then color = "#ff0000ff"
|
||||
else color = "#aa00ccff"
|
||||
end
|
||||
|
||||
if chan.semitone == "C" then gui.box(kb.x+1 +28*(chan.octave-1), kb.y, kb.x+3 +28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "D" then gui.box(kb.x+5 +28*(chan.octave-1), kb.y, kb.x+7 +28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "E" then gui.box(kb.x+9 +28*(chan.octave-1), kb.y, kb.x+11+28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "F" then gui.box(kb.x+13+28*(chan.octave-1), kb.y, kb.x+15+28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "G" then gui.box(kb.x+17+28*(chan.octave-1), kb.y, kb.x+19+28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "A" then gui.box(kb.x+21+28*(chan.octave-1), kb.y, kb.x+23+28*(chan.octave-1), kb.y+16, color)
|
||||
elseif chan.semitone == "B" then gui.box(kb.x+25+28*(chan.octave-1), kb.y, kb.x+27+28*(chan.octave-1), kb.y+16, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- draw accidental keys
|
||||
gui.box(kb.x-3, kb.y, kb.x-5, kb.y+10, "#00000000")
|
||||
for oct = 0, 6 do
|
||||
gui.box(kb.x+3+28*oct, kb.y, kb.x+5+28*oct, kb.y+10, "#00000000")
|
||||
gui.box(kb.x+7+28*oct, kb.y, kb.x+9+28*oct, kb.y+10, "#00000000")
|
||||
gui.box(kb.x+15+28*oct, kb.y, kb.x+17+28*oct, kb.y+10, "#00000000")
|
||||
gui.box(kb.x+19+28*oct, kb.y, kb.x+21+28*oct, kb.y+10, "#00000000")
|
||||
gui.box(kb.x+23+28*oct, kb.y, kb.x+25+28*oct, kb.y+10, "#00000000")
|
||||
end
|
||||
-- draw colored boxes over accidental keys
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" or name == "Triangle" then
|
||||
if name == "Triangle" then color = "#00aaffff"
|
||||
elseif name == "Square1" then color = "#ff0000ff"
|
||||
else color = "#aa00ccff"
|
||||
end
|
||||
|
||||
if chan.semitone == "C#" then gui.box(kb.x+3 +28*(chan.octave-1), kb.y, kb.x+5 +28*(chan.octave-1), kb.y+10, color)
|
||||
elseif chan.semitone == "D#" then gui.box(kb.x+7 +28*(chan.octave-1), kb.y, kb.x+9 +28*(chan.octave-1), kb.y+10, color)
|
||||
elseif chan.semitone == "F#" then gui.box(kb.x+15+28*(chan.octave-1), kb.y, kb.x+17+28*(chan.octave-1), kb.y+10, color)
|
||||
elseif chan.semitone == "G#" then gui.box(kb.x+19+28*(chan.octave-1), kb.y, kb.x+21+28*(chan.octave-1), kb.y+10, color)
|
||||
elseif chan.semitone == "A#" then gui.box(kb.x+23+28*(chan.octave-1), kb.y, kb.x+25+28*(chan.octave-1), kb.y+10, color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
grey = "#aaaaaaaa"
|
||||
for oct = 0, 6 do
|
||||
gui.line(kb.x+3+28*oct, kb.y+10, kb.x+5+28*oct, kb.y+10, grey)
|
||||
gui.line(kb.x+7+28*oct, kb.y+10, kb.x+9+28*oct, kb.y+10, grey)
|
||||
gui.line(kb.x+15+28*oct, kb.y+10, kb.x+17+28*oct, kb.y+10, grey)
|
||||
gui.line(kb.x+19+28*oct, kb.y+10, kb.x+21+28*oct, kb.y+10, grey)
|
||||
gui.line(kb.x+23+28*oct, kb.y+10, kb.x+25+28*oct, kb.y+10, grey)
|
||||
end
|
||||
gui.line(kb.x-3, kb.y+10, kb.x-5, kb.y+10, grey)
|
||||
gui.line(kb.x-8, kb.y, kb.x+200, kb.y, "#00000088")
|
||||
gui.line(kb.x-8, kb.y+16, kb.x+200, kb.y+16, "#00000088")
|
||||
gui.line(kb.x-8, kb.y, kb.x-8, kb.y+16, "#00000088")
|
||||
gui.line(kb.x+200, kb.y, kb.x+200, kb.y+16, "#00000088")
|
||||
else
|
||||
-- capture leftclicks
|
||||
if keys.xmouse <= 256 and keys.xmouse >= 205 and keys.ymouse >= 154 and keys.ymouse <= 181 then
|
||||
if keys["leftclick"] and not prev_keys["leftclick"] then kb.on = true end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------
|
||||
-- Floating notes --
|
||||
--------------------
|
||||
|
||||
if (kb.on) then
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" or name == "Triangle" then
|
||||
|
||||
if chan.prev_semitone ~= chan.semitone then
|
||||
if chan.semitone == "C" then table.insert(chan.float, 1, kb.x+1 +28*(chan.octave-1))
|
||||
elseif chan.semitone == "D" then table.insert(chan.float, 1, kb.x+5 +28*(chan.octave-1))
|
||||
elseif chan.semitone == "E" then table.insert(chan.float, 1, kb.x+9 +28*(chan.octave-1))
|
||||
elseif chan.semitone == "F" then table.insert(chan.float, 1, kb.x+13+28*(chan.octave-1))
|
||||
elseif chan.semitone == "G" then table.insert(chan.float, 1, kb.x+17+28*(chan.octave-1))
|
||||
elseif chan.semitone == "A" then table.insert(chan.float, 1, kb.x+21+28*(chan.octave-1))
|
||||
elseif chan.semitone == "B" then table.insert(chan.float, 1, kb.x+25+28*(chan.octave-1))
|
||||
elseif chan.semitone == "C#" then table.insert(chan.float, 1, kb.x+3 +28*(chan.octave-1))
|
||||
elseif chan.semitone == "D#" then table.insert(chan.float, 1, kb.x+7 +28*(chan.octave-1))
|
||||
elseif chan.semitone == "F#" then table.insert(chan.float, 1, kb.x+15+28*(chan.octave-1))
|
||||
elseif chan.semitone == "G#" then table.insert(chan.float, 1, kb.x+19+28*(chan.octave-1))
|
||||
elseif chan.semitone == "A#" then table.insert(chan.float, 1, kb.x+23+28*(chan.octave-1))
|
||||
end
|
||||
end
|
||||
|
||||
if name == "Triangle" then color = "#00aaffff"
|
||||
elseif name == "Square1" then color = "#ff0000ff"
|
||||
else color = "#aa00ccff"
|
||||
end
|
||||
|
||||
if #chan.float < 13 then
|
||||
for i = 2, #chan.float do
|
||||
if movie.framecount()%2 == 0 then gui.box(chan.float[i]-1, 161+i*5, chan.float[i]+3, 165+i*5, "#eedd2200") end
|
||||
gui.box(chan.float[i], 162+i*5, chan.float[i]+2, 164+i*5, color)
|
||||
end
|
||||
else
|
||||
for i = 2, 13 do
|
||||
if movie.framecount()%2 == 0 then gui.box(chan.float[i]-1, 161+i*5, chan.float[i]+3, 165+i*5, "#eedd2200") end
|
||||
gui.box(chan.float[i], 162+i*5, chan.float[i]+2, 164+i*5, color)
|
||||
end
|
||||
table.remove(chan.float, 14)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---------------------
|
||||
-- Volumes display --
|
||||
---------------------
|
||||
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" then
|
||||
-- set color for each duty value
|
||||
if chan.duty == 0 then table.insert(chan.color,1,"#aaff00ff")
|
||||
elseif chan.duty == 1 then table.insert(chan.color,1,"#00ff00ff")
|
||||
elseif chan.duty == 2 then table.insert(chan.color,1,"#00bb00ff")
|
||||
else table.insert(chan.color,1,"#008800ff")
|
||||
end
|
||||
end
|
||||
-- capture leftclicks
|
||||
if iterator == 15 then
|
||||
if keys.ymouse <= 24 and keys.ymouse >= 0 then
|
||||
if keys["leftclick"] and not prev_keys["leftclick"] then iterator = 1 end
|
||||
end
|
||||
else
|
||||
if keys.ymouse <= 24 and keys.ymouse >= 0 then
|
||||
if keys["leftclick"] and not prev_keys["leftclick"] then iterator = 15 end
|
||||
end
|
||||
end
|
||||
-- draw volumes
|
||||
gui.text(chan.x, 9, name, "#ffffffff", "#000000ff")
|
||||
if iterator <=14 then
|
||||
-- draw just first volume values
|
||||
gui.text(chan.x, chan.y+9+1, chan.vol[1])
|
||||
if tonumber(chan.vol[1]) > 0 then
|
||||
for j = 0, chan.vol[1]-1 do
|
||||
gui.box(chan.x+13+j*2, chan.y+9, chan.x+15+j*2, chan.y+8+9, "#000000ff")
|
||||
gui.line(chan.x+14+j*2, chan.y+1+9, chan.x+14+j*2, chan.y+7+9, "#00ff00ff")
|
||||
if name == "Square1" or name == "Square2" then
|
||||
-- color comes from duty
|
||||
gui.text(chan.x+38, chan.y, chan.duty, chan.color[1], "#000000ff")
|
||||
gui.line(chan.x+14+j*2, chan.y+1+9, chan.x+14+j*2, chan.y+7+9, chan.color[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- draw all 15 volume values
|
||||
for i = 1, #chan.vol do
|
||||
gui.text(chan.x, chan.y+i*9+1, chan.vol[i])
|
||||
if tonumber(chan.vol[i]) > 0 then
|
||||
for j = 0, chan.vol[i]-1 do
|
||||
gui.box(chan.x+13+j*2, chan.y+i*9, chan.x+15+j*2, chan.y+8+i*9, "#000000ff")
|
||||
gui.line(chan.x+14+j*2, chan.y+1+i*9, chan.x+14+j*2, chan.y+7+i*9, "#00ff00ff")
|
||||
if name == "Square1" or name == "Square2" then
|
||||
-- color comes from duty
|
||||
gui.text(chan.x+38, chan.y, chan.duty, chan.color[1], "#000000ff")
|
||||
gui.line(chan.x+14+j*2, chan.y+1+i*9, chan.x+14+j*2, chan.y+7+i*9, chan.color[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- keep the table limited
|
||||
table.remove(chan.vol, 15)
|
||||
|
||||
-- highlight the first values
|
||||
-- 30 Hz blinking, works properly if your monitor is set to 60 Hz
|
||||
if chan.vol[1] > 0 and movie.framecount()%2 == 0 then
|
||||
gui.box(chan.x+12, chan.y+8, chan.x+14+chan.vol[1]*2, chan.y+18, "#ffcc0000")
|
||||
end
|
||||
end
|
||||
|
||||
for name, chan in pairs(channels) do
|
||||
if name == "Square1" or name == "Square2" or name == "Triangle" then
|
||||
chan.prev_semitone = chan.semitone
|
||||
end
|
||||
end
|
||||
|
||||
prev_keys = keys
|
||||
end
|
||||
emu.registerafter(Draw);
|
|
@ -347,6 +347,7 @@ static CFGSTRUCT fceuconfig[] = {
|
|||
AC(taseditor_config.savecompact_selection),
|
||||
AC(taseditor_config.findnote_matchcase),
|
||||
AC(taseditor_config.findnote_search_up),
|
||||
AC(taseditor_config.deselect_on_doubleclick),
|
||||
AC(taseditor_config.silent_autosave),
|
||||
AC(taseditor_config.tooltips),
|
||||
AC(taseditor_config.current_pattern),
|
||||
|
|
|
@ -289,7 +289,9 @@ BEGIN
|
|||
MENUITEM "Use Input keys for Column Set", ID_CONFIG_USEINPUTKEYSFORCOLUMNSET,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Allow keyboard controls in Piano Roll", ID_CONFIG_KEYBOARDCONTROLSINPIANOROLL,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Superimpose affects copy/paste", ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM MFT_SEPARATOR
|
||||
MENUITEM "Autofire Pattern skips Lag", ID_CONFIG_COLUMNSETPATTERNSKIPSLAG,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Deselect on doubleclick", ID_CONFIG_DESELECTONDOUBLECLICK,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM MFT_SEPARATOR
|
||||
MENUITEM "Silent Autosave", ID_CONFIG_SILENTAUTOSAVE,MFT_STRING,MFS_ENABLED
|
||||
MENUITEM "Mute Turbo", ID_CONFIG_MUTETURBO,MFT_STRING,MFS_ENABLED
|
||||
|
@ -1451,7 +1453,7 @@ BEGIN
|
|||
LTEXT "TAS Editor",IDC_TASEDITOR_NAME,43,8,83,13
|
||||
LTEXT "Version 1.0",IDC_STATIC,63,25,37,8
|
||||
LTEXT "Created by AnS",IDC_STATIC,138,12,52,8
|
||||
LTEXT "Based on TASEdit v0.1",IDC_STATIC,138,25,83,9,SS_NOPREFIX
|
||||
LTEXT "Originated from TASEdit",IDC_STATIC,138,25,83,9,SS_NOPREFIX
|
||||
LTEXT "made by zeromus & adelikat",IDC_STATIC,138,35,96,9,SS_NOPREFIX
|
||||
END
|
||||
|
||||
|
|
|
@ -994,6 +994,7 @@
|
|||
#define ID_CONFIG_COLUMNSETPATTERNSKIPSLAG 40535
|
||||
#define ID_EDIT_DESELECT 40536
|
||||
#define ID_SELECTED_DESELECT 40537
|
||||
#define ID_CONFIG_DESELECTONDOUBLECLICK 40538
|
||||
#define IDC_DEBUGGER_ICONTRAY 55535
|
||||
#define MW_ValueLabel2 65423
|
||||
#define MW_ValueLabel1 65426
|
||||
|
@ -1003,7 +1004,7 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 206
|
||||
#define _APS_NEXT_COMMAND_VALUE 40538
|
||||
#define _APS_NEXT_COMMAND_VALUE 40539
|
||||
#define _APS_NEXT_CONTROL_VALUE 1281
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
@ -23,11 +23,11 @@ Main - Logical center of the program
|
|||
#include "utils/xstring.h"
|
||||
#include "main.h" // for GetRomName
|
||||
#include "taseditor.h"
|
||||
#include "version.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TAS Editor data
|
||||
bool emulator_must_run_taseditor = false;
|
||||
bool Taseditor_rewind_now = false;
|
||||
bool must_call_manual_lua_function = false;
|
||||
std::vector<std::string> autofire_patterns_names;
|
||||
|
@ -193,7 +193,6 @@ bool EnterTasEditor()
|
|||
}
|
||||
FCEUI_StopMovie();
|
||||
movieMode = MOVIEMODE_TASEDITOR;
|
||||
currMovieData.emuVersion = FCEU_VERSION_NUMERIC;
|
||||
}
|
||||
// ensure that movie has correct set of ports/fourscore
|
||||
SetInputType(currMovieData, GetInputType(currMovieData));
|
||||
|
@ -278,6 +277,14 @@ void UpdateTasEditor()
|
|||
{
|
||||
// TAS Editor is not engaged... but we still should run Lua auto function
|
||||
TaseditorAutoFunction();
|
||||
if (emulator_must_run_taseditor)
|
||||
{
|
||||
char fullname[512];
|
||||
strcpy(fullname, curMovieFilename);
|
||||
if (EnterTasEditor())
|
||||
LoadProject(fullname);
|
||||
emulator_must_run_taseditor = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -514,10 +521,14 @@ bool SaveProjectAs()
|
|||
}
|
||||
bool SaveProject()
|
||||
{
|
||||
if (!project.save())
|
||||
if (project.GetProjectFile().empty())
|
||||
{
|
||||
return SaveProjectAs();
|
||||
else
|
||||
} else
|
||||
{
|
||||
project.save();
|
||||
taseditor_window.UpdateCaption();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -628,9 +639,7 @@ void SaveCompact()
|
|||
ofn.lpstrInitialDir = initdir.c_str();
|
||||
|
||||
if(GetSaveFileName(&ofn)) //If it is a valid filename
|
||||
{
|
||||
project.save_compact(nameo, taseditor_config.savecompact_binary, taseditor_config.savecompact_markers, taseditor_config.savecompact_bookmarks, taseditor_config.savecompact_greenzone, taseditor_config.savecompact_history, taseditor_config.savecompact_piano_roll, taseditor_config.savecompact_selection);
|
||||
}
|
||||
project.save(nameo, taseditor_config.savecompact_binary, taseditor_config.savecompact_markers, taseditor_config.savecompact_bookmarks, taseditor_config.savecompact_greenzone, taseditor_config.savecompact_history, taseditor_config.savecompact_piano_roll, taseditor_config.savecompact_selection);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -344,9 +344,13 @@ void BOOKMARKS::set(int slot)
|
|||
// save time of this slot before rewriting it
|
||||
char saved_time[TIME_DESC_LENGTH];
|
||||
if (bookmarks_array[slot].not_empty)
|
||||
strncpy(saved_time, bookmarks_array[slot].snapshot.description, TIME_DESC_LENGTH-1);
|
||||
else
|
||||
{
|
||||
strncpy(saved_time, bookmarks_array[slot].snapshot.description, TIME_DESC_LENGTH - 1);
|
||||
saved_time[TIME_DESC_LENGTH - 1] = 0;
|
||||
} else
|
||||
{
|
||||
saved_time[0] = 0;
|
||||
}
|
||||
|
||||
bookmarks_array[slot].set();
|
||||
|
||||
|
@ -369,7 +373,7 @@ void BOOKMARKS::set(int slot)
|
|||
break;
|
||||
}
|
||||
if (i >= TOTAL_BOOKMARKS)
|
||||
// didn't find another child of cloud
|
||||
// didn't find another child of cloud, change cloud's time, sice "root" has shifted
|
||||
strcpy(cloud_time, saved_time);
|
||||
}
|
||||
// before disconnecting from old parent, connect all childs to the old parent
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#define GREENZONE_ID_LEN 10
|
||||
|
||||
#define TIME_BETWEEN_CLEANINGS 10000 // in milliseconds
|
||||
#define TIME_BETWEEN_CLEANINGS 15000 // in milliseconds
|
||||
// greenzone cleaning masks
|
||||
#define EVERY16TH 0xFFFFFFF0
|
||||
#define EVERY8TH 0xFFFFFFF8
|
||||
|
|
|
@ -619,8 +619,14 @@ LONG PIANO_ROLL::CustomDraw(NMLVCUSTOMDRAW* msg)
|
|||
} else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 0 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 2)
|
||||
{
|
||||
// pad 1 or 3
|
||||
// font
|
||||
// font: empty cells have "SelectFont", non-empty have normal font
|
||||
int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
|
||||
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
|
||||
if ((int)currMovieData.records.size() <= cell_y ||
|
||||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
|
||||
SelectObject(msg->nmcd.hdc, hMainListFont);
|
||||
else
|
||||
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
|
||||
// bg
|
||||
if (cell_y == history.GetUndoHint())
|
||||
{
|
||||
|
@ -652,8 +658,14 @@ LONG PIANO_ROLL::CustomDraw(NMLVCUSTOMDRAW* msg)
|
|||
} else if((cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 1 || (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS == 3)
|
||||
{
|
||||
// pad 2 or 4
|
||||
// font
|
||||
// font: empty cells have "SelectFont", non-empty have normal font
|
||||
int joy = (cell_x - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
|
||||
int bit = (cell_x - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
|
||||
if ((int)currMovieData.records.size() <= cell_y ||
|
||||
((currMovieData.records[cell_y].joysticks[joy]) & (1<<bit)) )
|
||||
SelectObject(msg->nmcd.hdc, hMainListFont);
|
||||
else
|
||||
SelectObject(msg->nmcd.hdc, hMainListSelectFont);
|
||||
// bg
|
||||
if (cell_y == history.GetUndoHint())
|
||||
{
|
||||
|
@ -1092,7 +1104,6 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if(column_index == COLUMN_ICONS)
|
||||
{
|
||||
// click on the "icons" column - jump to the frame
|
||||
selection.ClearSelection();
|
||||
playback.jump(row_index);
|
||||
} else if(column_index == COLUMN_FRAMENUM || column_index == COLUMN_FRAMENUM2)
|
||||
{
|
||||
|
@ -1100,6 +1111,7 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if (msg == WM_LBUTTONDBLCLK && !alt_pressed)
|
||||
{
|
||||
// doubleclick - jump to the frame
|
||||
if (taseditor_config.deselect_on_doubleclick)
|
||||
selection.ClearSelection();
|
||||
playback.jump(row_index);
|
||||
} else
|
||||
|
|
|
@ -181,6 +181,9 @@ void RECORDER::update()
|
|||
}
|
||||
// call ColumnSet if needed
|
||||
if (taseditor_config.columnset_by_keys && movie_readonly && taseditor_window.TASEditor_focus)
|
||||
{
|
||||
// if Ctrl or Shift is held, do not call ColumnSet, because maybe this is accelerator
|
||||
if ((GetAsyncKeyState(VK_CONTROL) >= 0) && (GetAsyncKeyState(VK_SHIFT) >= 0))
|
||||
{
|
||||
bool alt_pressed = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0);
|
||||
for (int joy = 0; joy < num_joys; ++joy)
|
||||
|
@ -193,6 +196,7 @@ void RECORDER::update()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------
|
||||
void RECORDER::UncheckRecordingRadioButtons()
|
||||
|
|
|
@ -463,7 +463,8 @@ void SELECTION::EnforceSelectionToList()
|
|||
|
||||
void SELECTION::SelectAll()
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, -1, LVIS_SELECTED, LVIS_SELECTED);
|
||||
// select all, but remove "focused" from all
|
||||
ListView_SetItemState(piano_roll.hwndList, -1, LVIS_FOCUSED|LVIS_SELECTED, LVIS_SELECTED);
|
||||
}
|
||||
void SELECTION::SetRowSelection(int index)
|
||||
{
|
||||
|
@ -472,7 +473,7 @@ void SELECTION::SetRowSelection(int index)
|
|||
void SELECTION::SetRegionSelection(int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; ++i)
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
void SELECTION::SelectBetweenMarkers()
|
||||
{
|
||||
|
@ -510,7 +511,7 @@ void SELECTION::SelectBetweenMarkers()
|
|||
// default: select all between markers
|
||||
for (int i = upper_marker+1; i < lower_marker; ++i)
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
} else if (upper_border == upper_marker+1 && lower_border == lower_marker-1)
|
||||
{
|
||||
|
@ -519,14 +520,14 @@ void SELECTION::SelectBetweenMarkers()
|
|||
if (lower_marker >= movie_size) lower_marker = movie_size - 1;
|
||||
for (int i = upper_marker; i <= lower_marker; ++i)
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
} else if (upper_border <= upper_marker && lower_border >= lower_marker)
|
||||
{
|
||||
// selected all between markers and both markers selected too - now deselect lower marker
|
||||
for (int i = upper_marker; i < lower_marker; ++i)
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
} else if (upper_border == upper_marker && lower_border == lower_marker-1)
|
||||
{
|
||||
|
@ -534,14 +535,14 @@ void SELECTION::SelectBetweenMarkers()
|
|||
if (lower_marker >= movie_size) lower_marker = movie_size - 1;
|
||||
for (int i = upper_marker+1; i <= lower_marker; ++i)
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
} else if (upper_border == upper_marker+1 && lower_border == lower_marker)
|
||||
{
|
||||
// selected all between markers and lower marker selected too - now deselect lower marker (return to "selected all between markers")
|
||||
for (int i = upper_marker + 1; i < lower_marker; ++i)
|
||||
{
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
ListView_SetItemState(piano_roll.hwndList, i, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -547,6 +547,9 @@ bool SPLICER::Paste()
|
|||
}
|
||||
}
|
||||
result = true;
|
||||
} else
|
||||
{
|
||||
SetWindowText(hwndTextClipboard, clipboardEmptyText);
|
||||
}
|
||||
GlobalUnlock(hGlobal);
|
||||
}
|
||||
|
@ -664,6 +667,9 @@ bool SPLICER::PasteInsert()
|
|||
}
|
||||
}
|
||||
result = true;
|
||||
} else
|
||||
{
|
||||
SetWindowText(hwndTextClipboard, clipboardEmptyText);
|
||||
}
|
||||
GlobalUnlock(hGlobal);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
|
|||
findnote_matchcase = false;
|
||||
findnote_search_up = false;
|
||||
enable_auto_function = true;
|
||||
deselect_on_doubleclick = true;
|
||||
silent_autosave = true;
|
||||
tooltips = true;
|
||||
current_pattern = 0;
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
bool findnote_matchcase;
|
||||
bool findnote_search_up;
|
||||
bool enable_auto_function;
|
||||
bool deselect_on_doubleclick;
|
||||
bool silent_autosave;
|
||||
bool tooltips;
|
||||
int current_pattern;
|
||||
|
|
|
@ -179,7 +179,7 @@ void TASEDITOR_LUA::setnote(int index, const char* newtext)
|
|||
strncpy(text, newtext, MAX_NOTE_LEN - 1);
|
||||
if (strcmp(markers_manager.GetNote(index).c_str(), text))
|
||||
{
|
||||
// text differs from old note - rename
|
||||
// text differs from old Note - rename
|
||||
markers_manager.SetNote(index, text);
|
||||
history.RegisterMarkersChange(MODTYPE_LUA_MARKER_RENAME, markers_manager.GetMarkerFrame(index), -1, text);
|
||||
selection.must_find_current_marker = playback.must_find_current_marker = true;
|
||||
|
|
|
@ -33,6 +33,8 @@ extern PIANO_ROLL piano_roll;
|
|||
extern SELECTION selection;
|
||||
extern SPLICER splicer;
|
||||
|
||||
extern FCEUGI *GameInfo;
|
||||
|
||||
extern void FCEU_PrintError(char *format, ...);
|
||||
extern bool SaveProject();
|
||||
extern bool SaveProjectAs();
|
||||
|
@ -70,39 +72,60 @@ void TASEDITOR_PROJECT::update()
|
|||
|
||||
}
|
||||
|
||||
bool TASEDITOR_PROJECT::save()
|
||||
bool TASEDITOR_PROJECT::save(const char* different_name, bool save_binary, bool save_markers, bool save_bookmarks, bool save_greenzone, bool save_history, bool save_piano_roll, bool save_selection)
|
||||
{
|
||||
std::string PFN = GetProjectFile();
|
||||
if (PFN.empty()) return false;
|
||||
const char* filename = PFN.c_str();
|
||||
EMUFILE_FILE* ofs = FCEUD_UTF8_fstream(filename, "wb");
|
||||
|
||||
currMovieData.loadFrameCount = currMovieData.records.size();
|
||||
currMovieData.dump(ofs, true);
|
||||
|
||||
// save all modules
|
||||
unsigned int saved_stuff = ALL_SAVED;
|
||||
write32le(saved_stuff, ofs);
|
||||
markers_manager.save(ofs);
|
||||
bookmarks.save(ofs);
|
||||
greenzone.save(ofs);
|
||||
history.save(ofs);
|
||||
piano_roll.save(ofs);
|
||||
selection.save(ofs);
|
||||
|
||||
delete ofs;
|
||||
|
||||
playback.updateProgressbar();
|
||||
this->reset();
|
||||
return true;
|
||||
}
|
||||
bool TASEDITOR_PROJECT::save_compact(char* filename, bool save_binary, bool save_markers, bool save_bookmarks, bool save_greenzone, bool save_history, bool save_piano_roll, bool save_selection)
|
||||
{
|
||||
EMUFILE_FILE* ofs = FCEUD_UTF8_fstream(filename, "wb");
|
||||
if (!different_name && GetProjectFile().empty())
|
||||
// no different name specified, and there's no current filename of the project
|
||||
return false;
|
||||
|
||||
// check MD5
|
||||
char md5_movie[256];
|
||||
char md5_rom[256];
|
||||
strcpy(md5_movie, md5_asciistr(currMovieData.romChecksum));
|
||||
strcpy(md5_rom, md5_asciistr(GameInfo->MD5));
|
||||
if(strcmp(md5_movie, md5_rom))
|
||||
{
|
||||
// checksums mismatch, check if they both aren't zero
|
||||
unsigned int k, count1 = 0, count2 = 0;
|
||||
for(k = 0; k < strlen(md5_movie); k++) count1 += md5_movie[k] - '0';
|
||||
for(k = 0; k < strlen(md5_rom); k++) count2 += md5_rom[k] - '0';
|
||||
if(count1 && count2)
|
||||
{
|
||||
// ask user if he wants to fix the checksum before saving
|
||||
char message[2048];
|
||||
strcpy(message, "Movie ROM:\n");
|
||||
strncat(message, currMovieData.romFilename.c_str(), 2047 - strlen(message));
|
||||
strncat(message, "\nMD5: ", 2047 - strlen(message));
|
||||
strncat(message, md5_movie, 2047 - strlen(message));
|
||||
strncat(message, "\n\nCurrent ROM: \n", 2047 - strlen(message));
|
||||
strncat(message, GameInfo->filename, 2047 - strlen(message));
|
||||
strncat(message, "\nMD5: ", 2047 - strlen(message));
|
||||
strncat(message, md5_rom, 2047 - strlen(message));
|
||||
strncat(message, "\n\nFix the movie header before saving? ", 2047 - strlen(message));
|
||||
int answer = MessageBox(taseditor_window.hwndTasEditor, message, "ROM Checksum Mismatch", MB_YESNOCANCEL);
|
||||
if (answer == IDCANCEL)
|
||||
{
|
||||
// cancel saving
|
||||
return false;
|
||||
} else if (answer == IDYES)
|
||||
{
|
||||
// change ROM data in the movie to current ROM
|
||||
currMovieData.romFilename = GameInfo->filename;
|
||||
currMovieData.romChecksum = GameInfo->MD5;
|
||||
}
|
||||
}
|
||||
}
|
||||
// open file for write
|
||||
EMUFILE_FILE* ofs = 0;
|
||||
if (different_name)
|
||||
ofs = FCEUD_UTF8_fstream(different_name, "wb");
|
||||
else
|
||||
ofs = FCEUD_UTF8_fstream(GetProjectFile().c_str(), "wb");
|
||||
if (ofs)
|
||||
{
|
||||
currMovieData.loadFrameCount = currMovieData.records.size();
|
||||
currMovieData.emuVersion = FCEU_VERSION_NUMERIC;
|
||||
currMovieData.dump(ofs, save_binary);
|
||||
|
||||
// save specified modules
|
||||
unsigned int saved_stuff = 0;
|
||||
if (save_markers) saved_stuff |= MARKERS_SAVED;
|
||||
|
@ -118,11 +141,16 @@ bool TASEDITOR_PROJECT::save_compact(char* filename, bool save_binary, bool save
|
|||
history.save(ofs, save_history);
|
||||
piano_roll.save(ofs, save_piano_roll);
|
||||
selection.save(ofs, save_selection);
|
||||
|
||||
delete ofs;
|
||||
|
||||
playback.updateProgressbar();
|
||||
// also reset autosave period if we saved the project to its current filename
|
||||
if (!different_name)
|
||||
this->reset();
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool TASEDITOR_PROJECT::load(char* fullname)
|
||||
{
|
||||
|
@ -134,14 +162,43 @@ bool TASEDITOR_PROJECT::load(char* fullname)
|
|||
return false;
|
||||
}
|
||||
|
||||
FCEU_printf("\nLoading TAS Editor project %s...\n", fullname);
|
||||
|
||||
MovieData tempMovieData = MovieData();
|
||||
extern bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader);
|
||||
if (LoadFM2(tempMovieData, &ifs, ifs.size(), false))
|
||||
{
|
||||
// check MD5
|
||||
char md5_original[256];
|
||||
char md5_current[256];
|
||||
strcpy(md5_original, md5_asciistr(tempMovieData.romChecksum));
|
||||
strcpy(md5_current, md5_asciistr(GameInfo->MD5));
|
||||
if(strcmp(md5_original, md5_current))
|
||||
{
|
||||
// checksums mismatch, check if they both aren't zero
|
||||
unsigned int k, count1 = 0, count2 = 0;
|
||||
for(k = 0; k < strlen(md5_original); k++) count1 += md5_original[k] - '0';
|
||||
for(k = 0; k < strlen(md5_current); k++) count2 += md5_current[k] - '0';
|
||||
if(count1 && count2)
|
||||
{
|
||||
// ask user if he really wants to load the project
|
||||
char message[2048];
|
||||
strcpy(message, "This project was made using different ROM!\n\n");
|
||||
strcat(message, "Original ROM:\n");
|
||||
strncat(message, tempMovieData.romFilename.c_str(), 2047 - strlen(message));
|
||||
strncat(message, "\nMD5: ", 2047 - strlen(message));
|
||||
strncat(message, md5_original, 2047 - strlen(message));
|
||||
strncat(message, "\n\nCurrent ROM: \n", 2047 - strlen(message));
|
||||
strncat(message, GameInfo->filename, 2047 - strlen(message));
|
||||
strncat(message, "\nMD5: ", 2047 - strlen(message));
|
||||
strncat(message, md5_current, 2047 - strlen(message));
|
||||
strncat(message, "\n\nLoad the project anyway? ", 2047 - strlen(message));
|
||||
int answer = MessageBox(taseditor_window.hwndTasEditor, message, "ROM Checksum Mismatch", MB_YESNO);
|
||||
if(answer == IDNO)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
FCEU_printf("\nLoading TAS Editor project %s...\n", fullname);
|
||||
// save data to currMovieData and continue loading
|
||||
currMovieData = tempMovieData;
|
||||
currMovieData.emuVersion = FCEU_VERSION_NUMERIC;
|
||||
LoadSubtitles(currMovieData);
|
||||
} else
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#define HISTORY_SAVED 8
|
||||
#define PIANO_ROLL_SAVED 16
|
||||
#define SELECTION_SAVED 32
|
||||
#define ALL_SAVED MARKERS_SAVED|BOOKMARKS_SAVED|GREENZONE_SAVED|HISTORY_SAVED|PIANO_ROLL_SAVED|SELECTION_SAVED
|
||||
|
||||
class TASEDITOR_PROJECT
|
||||
{
|
||||
|
@ -36,8 +35,7 @@ public:
|
|||
void reset();
|
||||
void update();
|
||||
|
||||
bool save();
|
||||
bool save_compact(char* filename, bool save_binary, bool save_markers, bool save_bookmarks, bool save_greenzone, bool save_history, bool save_piano_roll, bool save_selection);
|
||||
bool save(const char* different_name = 0, bool save_binary = true, bool save_markers = true, bool save_bookmarks = true, bool save_greenzone = true, bool save_history = true, bool save_piano_roll = true, bool save_selection = true);
|
||||
bool load(char* fullname);
|
||||
|
||||
void RenameProject(char* new_fullname);
|
||||
|
|
|
@ -441,10 +441,10 @@ void TASEDITOR_WINDOW::UpdateCheckedItems()
|
|||
CheckMenuItem(hmenu, ID_CONFIG_KEYBOARDCONTROLSINPIANOROLL, taseditor_config.keyboard_for_piano_roll?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE, taseditor_config.superimpose_affects_paste?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_COLUMNSETPATTERNSKIPSLAG, taseditor_config.pattern_skips_lag?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_DESELECTONDOUBLECLICK, taseditor_config.deselect_on_doubleclick?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_SILENTAUTOSAVE, taseditor_config.silent_autosave?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_MUTETURBO, muteTurbo?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_HELP_TOOLTIPS, taseditor_config.tooltips?MF_CHECKED : MF_UNCHECKED);
|
||||
|
||||
}
|
||||
|
||||
void TASEDITOR_WINDOW::SetTaseditorInput()
|
||||
|
@ -1053,6 +1053,10 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
taseditor_config.pattern_skips_lag ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_DESELECTONDOUBLECLICK:
|
||||
taseditor_config.deselect_on_doubleclick ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_SILENTAUTOSAVE:
|
||||
taseditor_config.silent_autosave ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
|
|
|
@ -73,6 +73,9 @@
|
|||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
#include "taseditor/taseditor_window.h"
|
||||
extern TASEDITOR_WINDOW taseditor_window;
|
||||
|
||||
using namespace std;
|
||||
|
||||
//----Context Menu - Some dynamically added menu items
|
||||
|
@ -1225,51 +1228,47 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
mouseb=wParam;
|
||||
goto proco;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
// send the message to TAS Editor
|
||||
if (taseditor_window.hwndTasEditor)
|
||||
SendMessage(taseditor_window.hwndTasEditor, msg, wParam, lParam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
// If TAS Editor is engaged, rightclick shouldn't popup menus, because right button is used with wheel input for TAS Editor's own purposes
|
||||
if (!FCEUMOV_Mode(MOVIEMODE_TASEDITOR))
|
||||
{
|
||||
if (rightClickEnabled)
|
||||
{
|
||||
hfceuxcontext = LoadMenu(fceu_hInstance,"FCEUCONTEXTMENUS");
|
||||
|
||||
//If There is a movie loaded in read only
|
||||
if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && movie_readonly)
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,0);
|
||||
whichContext = 0; // Game+Movie+readonly
|
||||
}
|
||||
|
||||
//If there is a movie loaded in read+write
|
||||
else if (GameInfo && FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED) && !movie_readonly)
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,3);
|
||||
whichContext = 3; // Game+Movie+readwrite
|
||||
}
|
||||
|
||||
|
||||
//If there is a ROM loaded but no movie
|
||||
else if (GameInfo)
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,1);
|
||||
whichContext = 1; // Game+NoMovie
|
||||
}
|
||||
|
||||
//Else no ROM
|
||||
else
|
||||
{
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext,2);
|
||||
whichContext = 2; // NoGame
|
||||
}
|
||||
|
||||
hfceuxcontext = LoadMenu(fceu_hInstance,"FCEUCONTEXTMENUS");
|
||||
hfceuxcontextsub = GetSubMenu(hfceuxcontext, whichContext);
|
||||
UpdateContextMenuItems(hfceuxcontextsub, whichContext);
|
||||
pt.x = LOWORD(lParam); //Get mouse x in terms of client area
|
||||
pt.y = HIWORD(lParam); //Get mouse y in terms of client area
|
||||
ClientToScreen(hAppWnd, (LPPOINT) &pt); //Convert client area x,y to screen x,y
|
||||
TrackPopupMenu(hfceuxcontextsub,TPM_RIGHTBUTTON,(pt.x),(pt.y),0,hWnd,0); //Create menu
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
mouseb=wParam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case WM_MOVE:
|
||||
{
|
||||
|
|
|
@ -250,7 +250,8 @@ public:
|
|||
void set_len(s32 length)
|
||||
{
|
||||
len = length;
|
||||
if(pos>length) pos=length;
|
||||
if(pos > length)
|
||||
pos = length;
|
||||
}
|
||||
void trim()
|
||||
{
|
||||
|
|
|
@ -44,7 +44,7 @@ extern void AddRecentMovieFile(const char *filename);
|
|||
#include "./drivers/win/taseditor/recorder.h"
|
||||
extern PLAYBACK playback;
|
||||
extern RECORDER recorder;
|
||||
|
||||
extern bool emulator_must_run_taseditor;
|
||||
extern bool TaseditorIsRecording();
|
||||
#endif
|
||||
|
||||
|
@ -1195,20 +1195,13 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
|
|||
{
|
||||
if (currMovieData.loadFrameCount >= 0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32
|
||||
int result = MessageBox(hAppWnd, "This movie is a TAS Editor project file.\nIt can be modified in TAS Editor only.\n\nOpen it in TAS Editor now?", "Movie Replay", MB_YESNO);
|
||||
if (result == IDYES)
|
||||
{
|
||||
extern bool EnterTasEditor();
|
||||
extern bool LoadProject(char* fullname);
|
||||
char fullname[512];
|
||||
strcpy(fullname, curMovieFilename);
|
||||
if (EnterTasEditor())
|
||||
LoadProject(fullname);
|
||||
}
|
||||
#else
|
||||
emulator_must_run_taseditor = true;
|
||||
#else
|
||||
FCEUI_printf("This movie is a TAS Editor project file! It can be modified in TAS Editor only.\nMovie is now Read-Only.\n");
|
||||
#endif
|
||||
#endif
|
||||
movie_readonly = true;
|
||||
}
|
||||
if (FCEU_isFileInArchive(curMovieFilename))
|
||||
|
|
|
@ -360,8 +360,10 @@ extern int geniestage;
|
|||
|
||||
bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
{
|
||||
// reset memory_savestate
|
||||
memory_savestate.set_len(0);
|
||||
// reinit memory_savestate
|
||||
// memory_savestate is global variable which already has its vector of bytes, so no need to allocate memory every time we use save/loadstate
|
||||
memory_savestate.set_len(0); // this also seeks to the beginning
|
||||
memory_savestate.unfail();
|
||||
|
||||
EMUFILE* os = &memory_savestate;
|
||||
|
||||
|
@ -648,10 +650,12 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
|||
int stateversion = FCEU_de32lsb(header + 8);
|
||||
int comprlen = FCEU_de32lsb(header + 12);
|
||||
|
||||
// memory_savestate is global variable which already has its vector of bytes
|
||||
// reinit memory_savestate
|
||||
// memory_savestate is global variable which already has its vector of bytes, so no need to allocate memory every time we use save/loadstate
|
||||
if ((int)(memory_savestate.get_vec())->size() < totalsize)
|
||||
(memory_savestate.get_vec())->resize(totalsize);
|
||||
memory_savestate.set_len(totalsize);
|
||||
memory_savestate.unfail();
|
||||
memory_savestate.fseek(0, SEEK_SET);
|
||||
|
||||
if(comprlen != -1)
|
||||
|
|
Loading…
Reference in New Issue