Porting Tas Editor modules from win32. In work.
This commit is contained in:
parent
019c30b229
commit
f00613007b
|
@ -535,9 +535,12 @@ set(SRC_DRIVERS_SDL
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/avi/gwavi.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/TasEditorWindow.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/taseditor_config.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/markers_manager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/selection.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/splicer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/inputlog.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/laglog.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TasEditor/markers.cpp
|
||||
)
|
||||
|
||||
set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL})
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/TasEditor/TasEditorWindow.h"
|
||||
|
||||
TasEditorWindow *tasWin = NULL;
|
||||
MARKERS_MANAGER *markersManager = NULL;
|
||||
TasEditorWindow *tasWin = NULL;
|
||||
TASEDITOR_CONFIG *taseditorConfig = NULL;
|
||||
MARKERS_MANAGER *markersManager = NULL;
|
||||
SPLICER *splicer = NULL;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//---- Main TAS Editor Window
|
||||
|
|
|
@ -0,0 +1,664 @@
|
|||
/* ---------------------------------------------------------------------------------
|
||||
Implementation file of Greenzone class
|
||||
Copyright (c) 2011-2013 AnS
|
||||
|
||||
(The MIT License)
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------------
|
||||
Greenzone - Access zone
|
||||
[Single instance]
|
||||
|
||||
* stores array of savestates, used for faster movie navigation by Playback cursor
|
||||
* also stores LagLog of current movie Input
|
||||
* saves and loads the data from a project file. On error: truncates Greenzone to last successfully read savestate
|
||||
* regularly checks if there's a savestate of current emulation state, if there's no such savestate in array then creates one and updates lag info for previous frame
|
||||
* implements the working of "Auto-adjust Input according to lag" feature
|
||||
* regularly runs gradual cleaning of the savestates array (for memory saving), deleting oldest savestates
|
||||
* on demand: (when movie Input was changed) truncates the size of Greenzone, deleting savestates that became irrelevant because of new Input. After truncating it may also move Playback cursor (which must always reside within Greenzone) and may launch Playback seeking
|
||||
* stores resources: save id, properties of gradual cleaning, timing of cleaning
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
#include "taseditor_project.h"
|
||||
#include "state.h"
|
||||
#include "zlib.h"
|
||||
|
||||
extern TASEDITOR_CONFIG taseditorConfig;
|
||||
extern TASEDITOR_PROJECT project;
|
||||
extern PLAYBACK playback;
|
||||
extern HISTORY history;
|
||||
extern BOOKMARKS bookmarks;
|
||||
extern MARKERS_MANAGER markersManager;
|
||||
extern PIANO_ROLL pianoRoll;
|
||||
extern SELECTION selection;
|
||||
|
||||
extern char lagFlag;
|
||||
|
||||
char greenzone_save_id[GREENZONE_ID_LEN] = "GREENZONE";
|
||||
char greenzone_skipsave_id[GREENZONE_ID_LEN] = "GREENZONX";
|
||||
|
||||
GREENZONE::GREENZONE()
|
||||
{
|
||||
}
|
||||
|
||||
void GREENZONE::init()
|
||||
{
|
||||
reset();
|
||||
nextCleaningTime = clock() + TIME_BETWEEN_CLEANINGS;
|
||||
}
|
||||
void GREENZONE::free()
|
||||
{
|
||||
savestates.resize(0);
|
||||
greenzoneSize = 0;
|
||||
lagLog.reset();
|
||||
}
|
||||
void GREENZONE::reset()
|
||||
{
|
||||
free();
|
||||
}
|
||||
void GREENZONE::update()
|
||||
{
|
||||
// keep collecting savestates, this code must be executed at the end of every frame
|
||||
if (taseditorConfig.enableGreenzoning)
|
||||
{
|
||||
collectCurrentState();
|
||||
} else
|
||||
{
|
||||
// just update Greenzone upper limit
|
||||
if (greenzoneSize <= currFrameCounter)
|
||||
greenzoneSize = currFrameCounter + 1;
|
||||
}
|
||||
|
||||
// run cleaning from time to time
|
||||
if (clock() > nextCleaningTime)
|
||||
runGreenzoneCleaning();
|
||||
|
||||
// also log lag frames
|
||||
if (currFrameCounter > 0)
|
||||
{
|
||||
// lagFlag indicates that lag was in previous frame
|
||||
int old_lagFlag = lagLog.getLagInfoAtFrame(currFrameCounter - 1);
|
||||
// Auto-adjust Input according to lag
|
||||
if (taseditorConfig.autoAdjustInputAccordingToLag && old_lagFlag != LAGGED_UNKNOWN)
|
||||
{
|
||||
if ((old_lagFlag == LAGGED_YES) && !lagFlag)
|
||||
{
|
||||
// there's no more lag on previous frame - shift Input up 1 or more frames
|
||||
adjustUp();
|
||||
} else if ((old_lagFlag == LAGGED_NO) && lagFlag)
|
||||
{
|
||||
// there's new lag on previous frame - shift Input down 1 frame
|
||||
adjustDown();
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (lagFlag && (old_lagFlag != LAGGED_YES))
|
||||
{
|
||||
lagLog.setLagInfo(currFrameCounter - 1, true);
|
||||
// keep current snapshot laglog in touch
|
||||
history.getCurrentSnapshot().laglog.setLagInfo(currFrameCounter - 1, true);
|
||||
} else if (!lagFlag && old_lagFlag != LAGGED_NO)
|
||||
{
|
||||
lagLog.setLagInfo(currFrameCounter - 1, false);
|
||||
// keep current snapshot laglog in touch
|
||||
history.getCurrentSnapshot().laglog.setLagInfo(currFrameCounter - 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::collectCurrentState()
|
||||
{
|
||||
if ((int)savestates.size() <= currFrameCounter)
|
||||
savestates.resize(currFrameCounter + 1);
|
||||
// if frame is not saved - log savestate
|
||||
if (!savestates[currFrameCounter].size())
|
||||
{
|
||||
EMUFILE_MEMORY ms(&savestates[currFrameCounter]);
|
||||
FCEUSS_SaveMS(&ms, Z_DEFAULT_COMPRESSION);
|
||||
ms.trim();
|
||||
}
|
||||
if (greenzoneSize <= currFrameCounter)
|
||||
greenzoneSize = currFrameCounter + 1;
|
||||
}
|
||||
|
||||
bool GREENZONE::loadSavestateOfFrame(unsigned int frame)
|
||||
{
|
||||
if (frame >= savestates.size() || !savestates[frame].size())
|
||||
return false;
|
||||
EMUFILE_MEMORY ms(&savestates[frame]);
|
||||
return FCEUSS_LoadFP(&ms, SSLOADPARAM_NOBACKUP);
|
||||
}
|
||||
|
||||
void GREENZONE::runGreenzoneCleaning()
|
||||
{
|
||||
bool changed = false;
|
||||
int i = currFrameCounter - taseditorConfig.greenzoneCapacity;
|
||||
if (i <= 0) goto finish; // zeroth frame should not be cleaned
|
||||
int limit;
|
||||
// 2x of 1/2
|
||||
limit = i - 2 * taseditorConfig.greenzoneCapacity;
|
||||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if (i & 0x1)
|
||||
changed = changed | clearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 4x of 1/4
|
||||
limit = i - 4 * taseditorConfig.greenzoneCapacity;
|
||||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if (i & 0x3)
|
||||
changed = changed | clearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 8x of 1/8
|
||||
limit = i - 8 * taseditorConfig.greenzoneCapacity;
|
||||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if (i & 0x7)
|
||||
changed = changed | clearSavestateAndFreeMemory(i);
|
||||
}
|
||||
if (i < 0) goto finish;
|
||||
// 16x of 1/16
|
||||
limit = i - 16 * taseditorConfig.greenzoneCapacity;
|
||||
if (limit < 0) limit = 0;
|
||||
for (; i > limit; i--)
|
||||
{
|
||||
if (i & 0xF)
|
||||
changed = changed | clearSavestateAndFreeMemory(i);
|
||||
}
|
||||
// clear all remaining
|
||||
for (; i > 0; i--)
|
||||
{
|
||||
changed = changed | clearSavestateAndFreeMemory(i);
|
||||
}
|
||||
finish:
|
||||
if (changed)
|
||||
{
|
||||
pianoRoll.redraw();
|
||||
bookmarks.redrawBookmarksList();
|
||||
}
|
||||
// shedule next cleaning
|
||||
nextCleaningTime = clock() + TIME_BETWEEN_CLEANINGS;
|
||||
}
|
||||
|
||||
// returns true if actually cleared savestate data
|
||||
bool GREENZONE::clearSavestateOfFrame(unsigned int frame)
|
||||
{
|
||||
if (frame < savestates.size() && savestates[frame].size())
|
||||
{
|
||||
savestates[frame].resize(0);
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool GREENZONE::clearSavestateAndFreeMemory(unsigned int frame)
|
||||
{
|
||||
if (frame < savestates.size() && savestates[frame].size())
|
||||
{
|
||||
savestates[frame].swap(std::vector<uint8>());
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::ungreenzoneSelectedFrames()
|
||||
{
|
||||
RowsSelection* current_selection = selection.getCopyOfCurrentRowsSelection();
|
||||
if (current_selection->size() == 0) return;
|
||||
bool changed = false;
|
||||
int size = savestates.size();
|
||||
int start_index = *current_selection->begin();
|
||||
int end_index = *current_selection->rbegin();
|
||||
RowsSelection::reverse_iterator current_selection_rend = current_selection->rend();
|
||||
// degreenzone frames, going backwards
|
||||
for (RowsSelection::reverse_iterator it(current_selection->rbegin()); it != current_selection_rend; it++)
|
||||
changed = changed | clearSavestateAndFreeMemory(*it);
|
||||
if (changed)
|
||||
{
|
||||
pianoRoll.redraw();
|
||||
bookmarks.redrawBookmarksList();
|
||||
}
|
||||
}
|
||||
|
||||
void GREENZONE::save(EMUFILE *os, int save_type)
|
||||
{
|
||||
if (save_type != GREENZONE_SAVING_MODE_NO)
|
||||
{
|
||||
collectCurrentState(); // in case the project is being saved before the greenzone.update() was called within current frame
|
||||
runGreenzoneCleaning();
|
||||
if (greenzoneSize > (int)savestates.size())
|
||||
greenzoneSize = savestates.size();
|
||||
// write "GREENZONE" string
|
||||
os->fwrite(greenzone_save_id, GREENZONE_ID_LEN);
|
||||
// write LagLog
|
||||
lagLog.save(os);
|
||||
// write size
|
||||
write32le(greenzoneSize, os);
|
||||
// write Playback cursor position
|
||||
write32le(currFrameCounter, os);
|
||||
}
|
||||
int frame, size;
|
||||
int last_tick = 0;
|
||||
|
||||
switch (save_type)
|
||||
{
|
||||
case GREENZONE_SAVING_MODE_ALL:
|
||||
{
|
||||
// write savestates
|
||||
for (frame = 0; frame < greenzoneSize; ++frame)
|
||||
{
|
||||
// update TASEditor progressbar from time to time
|
||||
if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
|
||||
{
|
||||
playback.setProgressbar(frame, greenzoneSize);
|
||||
last_tick = frame / PROGRESSBAR_UPDATE_RATE;
|
||||
}
|
||||
if (!savestates[frame].size()) continue;
|
||||
write32le(frame, os);
|
||||
// write savestate
|
||||
size = savestates[frame].size();
|
||||
write32le(size, os);
|
||||
os->fwrite(&savestates[frame][0], size);
|
||||
}
|
||||
// write -1 as eof for greenzone
|
||||
write32le(-1, os);
|
||||
break;
|
||||
}
|
||||
case GREENZONE_SAVING_MODE_16TH:
|
||||
{
|
||||
// write savestates
|
||||
for (frame = 0; frame < greenzoneSize; ++frame)
|
||||
{
|
||||
if (!(frame & 0xF) || frame == currFrameCounter)
|
||||
{
|
||||
// update TASEditor progressbar from time to time
|
||||
if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
|
||||
{
|
||||
playback.setProgressbar(frame, greenzoneSize);
|
||||
last_tick = frame / PROGRESSBAR_UPDATE_RATE;
|
||||
}
|
||||
if (!savestates[frame].size()) continue;
|
||||
write32le(frame, os);
|
||||
// write savestate
|
||||
size = savestates[frame].size();
|
||||
write32le(size, os);
|
||||
os->fwrite(&savestates[frame][0], size);
|
||||
}
|
||||
}
|
||||
// write -1 as eof for greenzone
|
||||
write32le(-1, os);
|
||||
break;
|
||||
}
|
||||
case GREENZONE_SAVING_MODE_MARKED:
|
||||
{
|
||||
// write savestates
|
||||
for (frame = 0; frame < greenzoneSize; ++frame)
|
||||
{
|
||||
if (markersManager.getMarkerAtFrame(frame) || frame == currFrameCounter)
|
||||
{
|
||||
// update TASEditor progressbar from time to time
|
||||
if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
|
||||
{
|
||||
playback.setProgressbar(frame, greenzoneSize);
|
||||
last_tick = frame / PROGRESSBAR_UPDATE_RATE;
|
||||
}
|
||||
if (!savestates[frame].size()) continue;
|
||||
write32le(frame, os);
|
||||
// write savestate
|
||||
size = savestates[frame].size();
|
||||
write32le(size, os);
|
||||
os->fwrite(&savestates[frame][0], size);
|
||||
}
|
||||
}
|
||||
// write -1 as eof for greenzone
|
||||
write32le(-1, os);
|
||||
break;
|
||||
}
|
||||
case GREENZONE_SAVING_MODE_NO:
|
||||
{
|
||||
// write "GREENZONX" string
|
||||
os->fwrite(greenzone_skipsave_id, GREENZONE_ID_LEN);
|
||||
// write LagLog
|
||||
lagLog.save(os);
|
||||
// write Playback cursor position
|
||||
write32le(currFrameCounter, os);
|
||||
if (currFrameCounter > 0)
|
||||
{
|
||||
// write ONE savestate for currFrameCounter
|
||||
collectCurrentState();
|
||||
int size = savestates[currFrameCounter].size();
|
||||
write32le(size, os);
|
||||
os->fwrite(&savestates[currFrameCounter][0], size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// returns true if couldn't load
|
||||
bool GREENZONE::load(EMUFILE *is, unsigned int offset)
|
||||
{
|
||||
free();
|
||||
if (offset)
|
||||
{
|
||||
if (is->fseek(offset, SEEK_SET)) goto error;
|
||||
} else
|
||||
{
|
||||
reset();
|
||||
playback.restartPlaybackFromZeroGround(); // reset Playback cursor to frame 0
|
||||
return false;
|
||||
}
|
||||
int frame = 0, prev_frame = -1, size = 0;
|
||||
int last_tick = 0;
|
||||
// read "GREENZONE" string
|
||||
char save_id[GREENZONE_ID_LEN];
|
||||
if ((int)is->fread(save_id, GREENZONE_ID_LEN) < GREENZONE_ID_LEN) goto error;
|
||||
if (!strcmp(greenzone_skipsave_id, save_id))
|
||||
{
|
||||
// string says to skip loading Greenzone
|
||||
// read LagLog
|
||||
lagLog.load(is);
|
||||
// read Playback cursor position
|
||||
if (read32le(&frame, is))
|
||||
{
|
||||
currFrameCounter = frame;
|
||||
greenzoneSize = currFrameCounter + 1;
|
||||
savestates.resize(greenzoneSize);
|
||||
if (currFrameCounter)
|
||||
{
|
||||
// there must be one savestate in the file
|
||||
if (read32le(&size, is) && size >= 0)
|
||||
{
|
||||
savestates[frame].resize(size);
|
||||
if (is->fread(&savestates[frame][0], size) == size)
|
||||
{
|
||||
if (loadSavestateOfFrame(currFrameCounter))
|
||||
{
|
||||
FCEU_printf("No Greenzone in the file\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
// literally no Greenzone in the file, but this is still not a error
|
||||
reset();
|
||||
playback.restartPlaybackFromZeroGround(); // reset Playback cursor to frame 0
|
||||
FCEU_printf("No Greenzone in the file, Playback at frame 0\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (strcmp(greenzone_save_id, save_id)) goto error; // string is not valid
|
||||
// read LagLog
|
||||
lagLog.load(is);
|
||||
// read size
|
||||
if (read32le(&size, is) && size >= 0 && size <= currMovieData.getNumRecords())
|
||||
{
|
||||
greenzoneSize = size;
|
||||
savestates.resize(greenzoneSize);
|
||||
// read Playback cursor position
|
||||
if (read32le(&frame, is))
|
||||
{
|
||||
currFrameCounter = frame;
|
||||
int greenzone_tail_frame = currFrameCounter - taseditorConfig.greenzoneCapacity;
|
||||
int greenzone_tail_frame2 = greenzone_tail_frame - 2 * taseditorConfig.greenzoneCapacity;
|
||||
int greenzone_tail_frame4 = greenzone_tail_frame - 4 * taseditorConfig.greenzoneCapacity;
|
||||
int greenzone_tail_frame8 = greenzone_tail_frame - 8 * taseditorConfig.greenzoneCapacity;
|
||||
int greenzone_tail_frame16 = greenzone_tail_frame - 16 * taseditorConfig.greenzoneCapacity;
|
||||
// read savestates
|
||||
while(1)
|
||||
{
|
||||
if (!read32le(&frame, is)) break;
|
||||
if (frame < 0) break; // -1 = eof
|
||||
// update TASEditor progressbar from time to time
|
||||
if (frame / PROGRESSBAR_UPDATE_RATE > last_tick)
|
||||
{
|
||||
playback.setProgressbar(frame, greenzoneSize);
|
||||
last_tick = frame / PROGRESSBAR_UPDATE_RATE;
|
||||
}
|
||||
// read savestate
|
||||
if (!read32le(&size, is)) break;
|
||||
if (size < 0) break;
|
||||
if (frame <= greenzone_tail_frame16
|
||||
|| (frame <= greenzone_tail_frame8 && (frame & 0xF))
|
||||
|| (frame <= greenzone_tail_frame4 && (frame & 0x7))
|
||||
|| (frame <= greenzone_tail_frame2 && (frame & 0x3))
|
||||
|| (frame <= greenzone_tail_frame && (frame & 0x1)))
|
||||
{
|
||||
// skip loading this savestate
|
||||
if (is->fseek(size, SEEK_CUR) != 0) break;
|
||||
} else
|
||||
{
|
||||
// load this savestate
|
||||
if ((int)savestates.size() <= frame)
|
||||
savestates.resize(frame + 1);
|
||||
savestates[frame].resize(size);
|
||||
if ((int)is->fread(&savestates[frame][0], size) < size) break;
|
||||
prev_frame = frame; // successfully read one Greenzone frame info
|
||||
}
|
||||
}
|
||||
if (prev_frame+1 == greenzoneSize)
|
||||
{
|
||||
// everything went fine - load savestate at cursor position
|
||||
if (loadSavestateOfFrame(currFrameCounter))
|
||||
return false;
|
||||
}
|
||||
// uh, okay, but maybe we managed to read at least something useful from the file
|
||||
// first see if original position of currFrameCounter was read successfully
|
||||
if (loadSavestateOfFrame(currFrameCounter))
|
||||
{
|
||||
greenzoneSize = prev_frame+1; // cut greenZoneCount to last good frame
|
||||
FCEU_printf("Greenzone loaded partially\n");
|
||||
return false;
|
||||
}
|
||||
// then at least jump to some frame that was read successfully
|
||||
for (; prev_frame >= 0; prev_frame--)
|
||||
{
|
||||
if (loadSavestateOfFrame(prev_frame))
|
||||
{
|
||||
currFrameCounter = prev_frame;
|
||||
greenzoneSize = prev_frame+1; // cut greenZoneCount to this good frame
|
||||
FCEU_printf("Greenzone loaded partially, Playback moved to the end of greenzone\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
error:
|
||||
FCEU_printf("Error loading Greenzone\n");
|
||||
reset();
|
||||
playback.restartPlaybackFromZeroGround(); // reset Playback cursor to frame 0
|
||||
return true;
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
void GREENZONE::adjustUp()
|
||||
{
|
||||
int at = currFrameCounter - 1; // at = the frame above currFrameCounter
|
||||
// find how many consequent lag frames there are
|
||||
int num_frames_to_erase = 0;
|
||||
while (lagLog.getLagInfoAtFrame(at++) == LAGGED_YES)
|
||||
num_frames_to_erase++;
|
||||
|
||||
if (num_frames_to_erase > 0)
|
||||
{
|
||||
bool markers_changed = false;
|
||||
// delete these frames of lag
|
||||
currMovieData.eraseRecords(currFrameCounter - 1, num_frames_to_erase);
|
||||
lagLog.eraseFrame(currFrameCounter - 1, num_frames_to_erase);
|
||||
if (taseditorConfig.bindMarkersToInput)
|
||||
{
|
||||
if (markersManager.eraseMarker(currFrameCounter - 1, num_frames_to_erase))
|
||||
markers_changed = true;
|
||||
}
|
||||
// update movie data size, because Playback cursor must always be inside the movie
|
||||
// if movie length is less or equal to currFrame, pad it with empty frames
|
||||
if (((int)currMovieData.records.size() - 1) <= currFrameCounter)
|
||||
currMovieData.insertEmpty(-1, currFrameCounter - ((int)currMovieData.records.size() - 1));
|
||||
// update Piano Roll (reduce it if needed)
|
||||
pianoRoll.updateLinesCount();
|
||||
// register changes
|
||||
int first_input_changes = history.registerAdjustLag(currFrameCounter - 1, 0 - num_frames_to_erase);
|
||||
// if Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back)
|
||||
// also if the frame above currFrameCounter is lag frame then rewind 1 frame (invalidate Greenzone), because maybe this frame also needs lag removal
|
||||
if ((first_input_changes >= 0 && first_input_changes < currFrameCounter) || (lagLog.getLagInfoAtFrame(currFrameCounter - 1) != LAGGED_NO))
|
||||
{
|
||||
// custom invalidation procedure, not retriggering LostPosition/PauseFrame
|
||||
invalidate(first_input_changes);
|
||||
bool emu_was_paused = (FCEUI_EmulationPaused() != 0);
|
||||
int saved_pause_frame = playback.getPauseFrame();
|
||||
playback.ensurePlaybackIsInsideGreenzone();
|
||||
if (saved_pause_frame >= 0)
|
||||
playback.startSeekingToFrame(saved_pause_frame);
|
||||
if (emu_was_paused)
|
||||
playback.pauseEmulation();
|
||||
} else
|
||||
{
|
||||
// just invalidate Greenzone after currFrameCounter (this is necessary in order to force user to re-emulate everything after the point, because the lag log data after the currFrameCounter is now in unknown state and it should be collected again)
|
||||
invalidate(currFrameCounter);
|
||||
}
|
||||
if (markers_changed)
|
||||
selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true;
|
||||
}
|
||||
}
|
||||
void GREENZONE::adjustDown()
|
||||
{
|
||||
int at = currFrameCounter - 1;
|
||||
bool markers_changed = false;
|
||||
// clone frame and insert lag
|
||||
currMovieData.cloneRegion(at, 1);
|
||||
lagLog.insertFrame(at, true, 1);
|
||||
if (taseditorConfig.bindMarkersToInput)
|
||||
{
|
||||
if (markersManager.insertEmpty(at, 1))
|
||||
markers_changed = true;
|
||||
}
|
||||
// register changes
|
||||
int first_input_changes = history.registerAdjustLag(at, +1);
|
||||
// If Input in the frame above currFrameCounter has changed then invalidate Greenzone (rewind 1 frame back)
|
||||
// This should never actually happen, because we clone the frame, so the Input doesn't change
|
||||
// But the check should remain, in case we decide to insert blank frame instead of cloning
|
||||
if (first_input_changes >= 0 && first_input_changes < currFrameCounter)
|
||||
{
|
||||
// custom invalidation procedure, not retriggering LostPosition/PauseFrame
|
||||
invalidate(first_input_changes);
|
||||
bool emu_was_paused = (FCEUI_EmulationPaused() != 0);
|
||||
int saved_pause_frame = playback.getPauseFrame();
|
||||
playback.ensurePlaybackIsInsideGreenzone();
|
||||
if (saved_pause_frame >= 0)
|
||||
playback.startSeekingToFrame(saved_pause_frame);
|
||||
if (emu_was_paused)
|
||||
playback.pauseEmulation();
|
||||
} else
|
||||
{
|
||||
// just invalidate Greenzone after currFrameCounter
|
||||
invalidate(currFrameCounter);
|
||||
}
|
||||
if (markers_changed)
|
||||
selection.mustFindCurrentMarker = playback.mustFindCurrentMarker = true;
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// This version doesn't restore playback, may be used only by Branching, Recording and AdjustLag functions!
|
||||
void GREENZONE::invalidate(int after)
|
||||
{
|
||||
if (after >= 0)
|
||||
{
|
||||
if (after >= currMovieData.getNumRecords())
|
||||
after = currMovieData.getNumRecords() - 1;
|
||||
// clear all savestates that became irrelevant
|
||||
for (int i = savestates.size() - 1; i > after; i--)
|
||||
clearSavestateOfFrame(i);
|
||||
if (greenzoneSize > after + 1)
|
||||
{
|
||||
greenzoneSize = after + 1;
|
||||
FCEUMOV_IncrementRerecordCount();
|
||||
}
|
||||
}
|
||||
// redraw Piano Roll even if Greenzone didn't change
|
||||
pianoRoll.redraw();
|
||||
bookmarks.redrawBookmarksList();
|
||||
}
|
||||
// invalidate and restore playback
|
||||
void GREENZONE::invalidateAndUpdatePlayback(int after)
|
||||
{
|
||||
if (after >= 0)
|
||||
{
|
||||
if (after >= currMovieData.getNumRecords())
|
||||
after = currMovieData.getNumRecords() - 1;
|
||||
// clear all savestates that became irrelevant
|
||||
for (int i = savestates.size() - 1; i > after; i--)
|
||||
clearSavestateOfFrame(i);
|
||||
if (greenzoneSize > after + 1 || currFrameCounter > after)
|
||||
{
|
||||
greenzoneSize = after + 1;
|
||||
FCEUMOV_IncrementRerecordCount();
|
||||
// either set Playback cursor to be inside the Greenzone or run seeking to restore Playback cursor position
|
||||
if (currFrameCounter >= greenzoneSize)
|
||||
{
|
||||
if (playback.getPauseFrame() >= 0 && !FCEUI_EmulationPaused())
|
||||
{
|
||||
// emulator was running, so continue seeking, but don't follow the Playback cursor
|
||||
playback.jump(playback.getPauseFrame(), false, true, false);
|
||||
} else
|
||||
{
|
||||
playback.setLastPosition(currFrameCounter);
|
||||
if (taseditorConfig.autoRestoreLastPlaybackPosition)
|
||||
// start seeking to the green arrow, but don't follow the Playback cursor
|
||||
playback.jump(playback.getLastPosition(), false, true, false);
|
||||
else
|
||||
playback.ensurePlaybackIsInsideGreenzone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// redraw Piano Roll even if Greenzone didn't change
|
||||
pianoRoll.redraw();
|
||||
bookmarks.redrawBookmarksList();
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
int GREENZONE::findFirstGreenzonedFrame(int starting_index)
|
||||
{
|
||||
for (int i = starting_index; i < greenzoneSize; ++i)
|
||||
if (savestates[i].size()) return i;
|
||||
return -1; // error
|
||||
}
|
||||
|
||||
// getters
|
||||
int GREENZONE::getSize()
|
||||
{
|
||||
return greenzoneSize;
|
||||
}
|
||||
|
||||
// this should only be used by Bookmark Set procedure
|
||||
std::vector<uint8>& GREENZONE::getSavestateOfFrame(int frame)
|
||||
{
|
||||
return savestates[frame];
|
||||
}
|
||||
// this function should only be used by Bookmark Deploy procedure
|
||||
void GREENZONE::writeSavestateForFrame(int frame, std::vector<uint8>& savestate)
|
||||
{
|
||||
if ((int)savestates.size() <= frame)
|
||||
savestates.resize(frame + 1);
|
||||
savestates[frame] = savestate;
|
||||
if (greenzoneSize <= frame)
|
||||
greenzoneSize = frame + 1;
|
||||
}
|
||||
|
||||
bool GREENZONE::isSavestateEmpty(unsigned int frame)
|
||||
{
|
||||
if ((int)frame < greenzoneSize && frame < savestates.size() && savestates[frame].size())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Specification file for Greenzone class
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include "Qt/TasEditor/laglog.h"
|
||||
|
||||
#define GREENZONE_ID_LEN 10
|
||||
|
||||
#define TIME_BETWEEN_CLEANINGS 10000 // in milliseconds
|
||||
// Greenzone cleaning masks
|
||||
#define EVERY16TH 0xFFFFFFF0
|
||||
#define EVERY8TH 0xFFFFFFF8
|
||||
#define EVERY4TH 0xFFFFFFFC
|
||||
#define EVERY2ND 0xFFFFFFFE
|
||||
|
||||
#define PROGRESSBAR_UPDATE_RATE 1000 // progressbar is updated after every 1000 savestates loaded from FM3 file
|
||||
|
||||
class GREENZONE
|
||||
{
|
||||
public:
|
||||
GREENZONE();
|
||||
void init();
|
||||
void reset();
|
||||
void free();
|
||||
void update();
|
||||
|
||||
void save(EMUFILE *os, int save_type = GREENZONE_SAVING_MODE_ALL);
|
||||
bool load(EMUFILE *is, unsigned int offset);
|
||||
|
||||
bool loadSavestateOfFrame(unsigned int frame);
|
||||
|
||||
void runGreenzoneCleaning();
|
||||
|
||||
void ungreenzoneSelectedFrames();
|
||||
|
||||
void invalidate(int after);
|
||||
void invalidateAndUpdatePlayback(int after);
|
||||
|
||||
int findFirstGreenzonedFrame(int startingFrame = 0);
|
||||
|
||||
int getSize();
|
||||
std::vector<uint8_t>& getSavestateOfFrame(int frame);
|
||||
void writeSavestateForFrame(int frame, std::vector<uint8>& savestate);
|
||||
bool isSavestateEmpty(unsigned int frame);
|
||||
|
||||
// saved data
|
||||
LAGLOG lagLog;
|
||||
|
||||
private:
|
||||
void collectCurrentState();
|
||||
bool clearSavestateOfFrame(unsigned int frame);
|
||||
bool clearSavestateAndFreeMemory(unsigned int frame);
|
||||
|
||||
void adjustUp();
|
||||
void adjustDown();
|
||||
|
||||
// saved data
|
||||
int greenzoneSize;
|
||||
std::vector<std::vector<uint8_t>> savestates;
|
||||
|
||||
// not saved data
|
||||
int nextCleaningTime;
|
||||
|
||||
};
|
|
@ -25,7 +25,7 @@ InputLog - Log of Input
|
|||
#include "Qt/TasEditor/taseditor_project.h"
|
||||
|
||||
extern SELECTION selection;
|
||||
extern int getInputType(MovieData& md);
|
||||
//extern int getInputType(MovieData& md);
|
||||
|
||||
int joysticksPerFrame[INPUT_TYPES_TOTAL] = {1, 2, 4};
|
||||
|
||||
|
@ -36,9 +36,9 @@ INPUTLOG::INPUTLOG()
|
|||
void INPUTLOG::init(MovieData& md, bool hotchanges, int force_input_type)
|
||||
{
|
||||
hasHotChanges = hotchanges;
|
||||
if (force_input_type < 0)
|
||||
inputType = getInputType(md);
|
||||
else
|
||||
//if (force_input_type < 0)
|
||||
// inputType = getInputType(md);
|
||||
//else
|
||||
inputType = force_input_type;
|
||||
int num_joys = joysticksPerFrame[inputType];
|
||||
// retrieve Input data from movie data
|
||||
|
|
|
@ -15,9 +15,9 @@ Markers - Snapshot of Markers state
|
|||
* stores resources: max length of a Note
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
#include "../common.h"
|
||||
#include "markers.h"
|
||||
#include "zlib.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#include "Qt/TasEditor/markers.h"
|
||||
|
||||
MARKERS::MARKERS()
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "fceu.h"
|
||||
#define MAX_NOTE_LEN 100
|
||||
|
||||
class MARKERS
|
||||
|
|
|
@ -21,16 +21,18 @@ Markers_manager - Manager of Markers
|
|||
* stores resources: save id, properties of searching for similar Notes
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
#include "taseditor_project.h"
|
||||
#include <Shlwapi.h> // for StrStrI
|
||||
#include "fceu.h"
|
||||
#include "Qt/TasEditor/taseditor_project.h"
|
||||
#include "Qt/TasEditor/TasEditorWindow.h"
|
||||
//#include <Shlwapi.h> // for StrStrI
|
||||
|
||||
#pragma comment(lib, "Shlwapi.lib")
|
||||
//#pragma comment(lib, "Shlwapi.lib")
|
||||
|
||||
extern TASEDITOR_CONFIG taseditorConfig;
|
||||
extern TASEDITOR_WINDOW taseditorWindow;
|
||||
extern PLAYBACK playback;
|
||||
extern SELECTION selection;
|
||||
extern HISTORY history;
|
||||
//extern TASEDITOR_CONFIG taseditorConfig;
|
||||
//extern TASEDITOR_WINDOW taseditorWindow;
|
||||
//extern PLAYBACK playback;
|
||||
//extern SELECTION selection;
|
||||
//extern HISTORY history;
|
||||
|
||||
// resources
|
||||
char markers_save_id[MARKERS_ID_LEN] = "MARKERS";
|
||||
|
@ -177,7 +179,7 @@ int MARKERS_MANAGER::setMarkerAtFrame(int frame)
|
|||
|
||||
int marker_num = getMarkerAboveFrame(frame) + 1;
|
||||
markers.markersArray[frame] = marker_num;
|
||||
if (taseditorConfig.emptyNewMarkerNotes)
|
||||
if (taseditorConfig->emptyNewMarkerNotes)
|
||||
markers.notes.insert(markers.notes.begin() + marker_num, 1, "");
|
||||
else
|
||||
// copy previous Marker note
|
||||
|
@ -374,379 +376,379 @@ void MARKERS_MANAGER::findSimilarNote()
|
|||
}
|
||||
void MARKERS_MANAGER::findNextSimilarNote()
|
||||
{
|
||||
int i, t;
|
||||
int sourceMarker = playback.displayedMarkerNumber;
|
||||
char sourceNote[MAX_NOTE_LEN];
|
||||
strcpy(sourceNote, getNoteCopy(sourceMarker).c_str());
|
||||
|
||||
// check if playback_marker_text is empty
|
||||
if (!sourceNote[0])
|
||||
{
|
||||
MessageBox(taseditorWindow.hwndTASEditor, "Marker Note under Playback cursor is empty!", "Find Similar Note", MB_OK);
|
||||
return;
|
||||
}
|
||||
// check if there's at least one note (not counting zeroth note)
|
||||
if (markers.notes.size() <= 0)
|
||||
{
|
||||
MessageBox(taseditorWindow.hwndTASEditor, "This project doesn't have any Markers!", "Find Similar Note", MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// 0 - divide source string into keywords
|
||||
int totalSourceKeywords = 0;
|
||||
char sourceKeywords[MAX_NUM_KEYWORDS][MAX_NOTE_LEN] = {0};
|
||||
int current_line_pos = 0;
|
||||
char sourceKeywordsLine[MAX_NUM_KEYWORDS] = {0};
|
||||
char* pch;
|
||||
// divide into tokens
|
||||
pch = strtok(sourceNote, keywordDelimiters);
|
||||
while (pch != NULL)
|
||||
{
|
||||
if (strlen(pch) >= KEYWORD_MIN_LEN)
|
||||
{
|
||||
// check if same keyword already appeared in the string
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
if (!_stricmp(sourceKeywords[t], pch)) break;
|
||||
if (t < 0)
|
||||
{
|
||||
// save new keyword
|
||||
strcpy(sourceKeywords[totalSourceKeywords], pch);
|
||||
// also set its id into the line
|
||||
sourceKeywordsLine[current_line_pos++] = totalSourceKeywords + 1;
|
||||
totalSourceKeywords++;
|
||||
} else
|
||||
{
|
||||
// same keyword found
|
||||
sourceKeywordsLine[current_line_pos++] = t + 1;
|
||||
}
|
||||
}
|
||||
pch = strtok(NULL, keywordDelimiters);
|
||||
}
|
||||
// we found the line (sequence) of keywords
|
||||
sourceKeywordsLine[current_line_pos] = 0;
|
||||
|
||||
if (!totalSourceKeywords)
|
||||
{
|
||||
MessageBox(taseditorWindow.hwndTASEditor, "Marker Note under Playback cursor doesn't have keywords!", "Find Similar Note", MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1 - find how frequently each keyword appears in notes
|
||||
std::vector<int> keywordFound(totalSourceKeywords);
|
||||
char checkedNote[MAX_NOTE_LEN];
|
||||
for (i = markers.notes.size() - 1; i > 0; i--)
|
||||
{
|
||||
if (i != sourceMarker)
|
||||
{
|
||||
strcpy(checkedNote, markers.notes[i].c_str());
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
if (StrStrI(checkedNote, sourceKeywords[t]))
|
||||
keywordFound[t]++;
|
||||
}
|
||||
}
|
||||
// findmax
|
||||
int maxFound = 0;
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
if (maxFound < keywordFound[t])
|
||||
maxFound = keywordFound[t];
|
||||
// and then calculate weight of each keyword: the more often it appears in Markers, the less weight it has
|
||||
std::vector<double> keywordWeight(totalSourceKeywords);
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
keywordWeight[t] = KEYWORD_WEIGHT_BASE + KEYWORD_WEIGHT_FACTOR * (keywordFound[t] / (double)maxFound);
|
||||
|
||||
// start accumulating priorities
|
||||
std::vector<std::pair<int, double>> notePriority(markers.notes.size());
|
||||
|
||||
// 2 - find keywords in notes (including cases when keyword appears inside another word)
|
||||
for (i = notePriority.size() - 1; i > 0; i--)
|
||||
{
|
||||
notePriority[i].first = i;
|
||||
if (i != sourceMarker)
|
||||
{
|
||||
strcpy(checkedNote, markers.notes[i].c_str());
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
{
|
||||
if (StrStrI(checkedNote, sourceKeywords[t]))
|
||||
notePriority[i].second += KEYWORD_CASEINSENTITIVE_BONUS_PER_CHAR * keywordWeight[t] * strlen(sourceKeywords[t]);
|
||||
if (strstr(checkedNote, sourceKeywords[t]))
|
||||
notePriority[i].second += KEYWORD_CASESENTITIVE_BONUS_PER_CHAR * keywordWeight[t] * strlen(sourceKeywords[t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3 - search sequences of keywords from all other notes
|
||||
current_line_pos = 0;
|
||||
char checkedKeywordsLine[MAX_NUM_KEYWORDS] = {0};
|
||||
int keyword_id;
|
||||
for (i = markers.notes.size() - 1; i > 0; i--)
|
||||
{
|
||||
if (i != sourceMarker)
|
||||
{
|
||||
strcpy(checkedNote, markers.notes[i].c_str());
|
||||
// divide into tokens
|
||||
pch = strtok(checkedNote, keywordDelimiters);
|
||||
while (pch != NULL)
|
||||
{
|
||||
if (strlen(pch) >= KEYWORD_MIN_LEN)
|
||||
{
|
||||
// check if the keyword is one of sourceKeywords
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
if (!_stricmp(sourceKeywords[t], pch)) break;
|
||||
if (t >= 0)
|
||||
{
|
||||
// the keyword is one of sourceKeywords - set its id into the line
|
||||
checkedKeywordsLine[current_line_pos++] = t + 1;
|
||||
} else
|
||||
{
|
||||
// found keyword that doesn't appear in sourceNote, give penalty
|
||||
notePriority[i].second -= KEYWORD_PENALTY_FOR_STRANGERS * strlen(pch);
|
||||
// since the keyword breaks our sequence of coincident keywords, check if that sequence is similar to sourceKeywordsLine
|
||||
if (current_line_pos >= KEYWORDS_LINE_MIN_SEQUENCE)
|
||||
{
|
||||
checkedKeywordsLine[current_line_pos] = 0;
|
||||
// search checkedKeywordsLine in sourceKeywordsLine
|
||||
if (strstr(sourceKeywordsLine, checkedKeywordsLine))
|
||||
{
|
||||
// found same sequence of keywords! add priority to this checkedNote
|
||||
for (t = current_line_pos - 1; t >= 0; t--)
|
||||
{
|
||||
// add bonus for every keyword in the sequence
|
||||
keyword_id = checkedKeywordsLine[t] - 1;
|
||||
notePriority[i].second += current_line_pos * KEYWORD_SEQUENCE_BONUS_PER_CHAR * keywordWeight[keyword_id] * strlen(sourceKeywords[keyword_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear checkedKeywordsLine
|
||||
memset(checkedKeywordsLine, 0, MAX_NUM_KEYWORDS);
|
||||
current_line_pos = 0;
|
||||
}
|
||||
}
|
||||
pch = strtok(NULL, keywordDelimiters);
|
||||
}
|
||||
// finished dividing into tokens
|
||||
if (current_line_pos >= KEYWORDS_LINE_MIN_SEQUENCE)
|
||||
{
|
||||
checkedKeywordsLine[current_line_pos] = 0;
|
||||
// search checkedKeywordsLine in sourceKeywordsLine
|
||||
if (strstr(sourceKeywordsLine, checkedKeywordsLine))
|
||||
{
|
||||
// found same sequence of keywords! add priority to this checkedNote
|
||||
for (t = current_line_pos - 1; t >= 0; t--)
|
||||
{
|
||||
// add bonus for every keyword in the sequence
|
||||
keyword_id = checkedKeywordsLine[t] - 1;
|
||||
notePriority[i].second += current_line_pos * KEYWORD_SEQUENCE_BONUS_PER_CHAR * keywordWeight[keyword_id] * strlen(sourceKeywords[keyword_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear checkedKeywordsLine
|
||||
memset(checkedKeywordsLine, 0, MAX_NUM_KEYWORDS);
|
||||
current_line_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 4 - sort notePriority by second member of the pair
|
||||
std::sort(notePriority.begin(), notePriority.end(), ordering);
|
||||
|
||||
/*
|
||||
// debug trace
|
||||
FCEU_printf("\n\n\n\n\n\n\n\n\n\n");
|
||||
for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
FCEU_printf("Keyword: %s, %d, %f\n", sourceKeywords[t], keywordFound[t], keywordWeight[t]);
|
||||
for (i = notePriority.size() - 1; i > 0; i--)
|
||||
{
|
||||
int marker_id = notePriority[i].first;
|
||||
FCEU_printf("Result: %s, %d, %f\n", notes[marker_id].c_str(), marker_id, notePriority[i].second);
|
||||
}
|
||||
*/
|
||||
|
||||
// Send Selection to the Marker found
|
||||
int index = notePriority.size()-1 - currentIterationOfFindSimilar;
|
||||
if (index >= 0 && notePriority[index].second >= MIN_PRIORITY_TRESHOLD)
|
||||
{
|
||||
int marker_id = notePriority[index].first;
|
||||
int frame = getMarkerFrameNumber(marker_id);
|
||||
if (frame >= 0)
|
||||
selection.jumpToFrame(frame);
|
||||
} else
|
||||
{
|
||||
if (currentIterationOfFindSimilar)
|
||||
MessageBox(taseditorWindow.hwndTASEditor, "Could not find more Notes similar to Marker Note under Playback cursor!", "Find Similar Note", MB_OK);
|
||||
else
|
||||
MessageBox(taseditorWindow.hwndTASEditor, "Could not find anything similar to Marker Note under Playback cursor!", "Find Similar Note", MB_OK);
|
||||
}
|
||||
|
||||
// increase currentIterationOfFindSimilar so that next time we'll find another note
|
||||
currentIterationOfFindSimilar++;
|
||||
// int i, t;
|
||||
// int sourceMarker = playback.displayedMarkerNumber;
|
||||
// char sourceNote[MAX_NOTE_LEN];
|
||||
// strcpy(sourceNote, getNoteCopy(sourceMarker).c_str());
|
||||
//
|
||||
// // check if playback_marker_text is empty
|
||||
// if (!sourceNote[0])
|
||||
// {
|
||||
// MessageBox(taseditorWindow.hwndTASEditor, "Marker Note under Playback cursor is empty!", "Find Similar Note", MB_OK);
|
||||
// return;
|
||||
// }
|
||||
// // check if there's at least one note (not counting zeroth note)
|
||||
// if (markers.notes.size() <= 0)
|
||||
// {
|
||||
// MessageBox(taseditorWindow.hwndTASEditor, "This project doesn't have any Markers!", "Find Similar Note", MB_OK);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 0 - divide source string into keywords
|
||||
// int totalSourceKeywords = 0;
|
||||
// char sourceKeywords[MAX_NUM_KEYWORDS][MAX_NOTE_LEN] = {0};
|
||||
// int current_line_pos = 0;
|
||||
// char sourceKeywordsLine[MAX_NUM_KEYWORDS] = {0};
|
||||
// char* pch;
|
||||
// // divide into tokens
|
||||
// pch = strtok(sourceNote, keywordDelimiters);
|
||||
// while (pch != NULL)
|
||||
// {
|
||||
// if (strlen(pch) >= KEYWORD_MIN_LEN)
|
||||
// {
|
||||
// // check if same keyword already appeared in the string
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// if (!_stricmp(sourceKeywords[t], pch)) break;
|
||||
// if (t < 0)
|
||||
// {
|
||||
// // save new keyword
|
||||
// strcpy(sourceKeywords[totalSourceKeywords], pch);
|
||||
// // also set its id into the line
|
||||
// sourceKeywordsLine[current_line_pos++] = totalSourceKeywords + 1;
|
||||
// totalSourceKeywords++;
|
||||
// } else
|
||||
// {
|
||||
// // same keyword found
|
||||
// sourceKeywordsLine[current_line_pos++] = t + 1;
|
||||
// }
|
||||
// }
|
||||
// pch = strtok(NULL, keywordDelimiters);
|
||||
// }
|
||||
// // we found the line (sequence) of keywords
|
||||
// sourceKeywordsLine[current_line_pos] = 0;
|
||||
//
|
||||
// if (!totalSourceKeywords)
|
||||
// {
|
||||
// MessageBox(taseditorWindow.hwndTASEditor, "Marker Note under Playback cursor doesn't have keywords!", "Find Similar Note", MB_OK);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 1 - find how frequently each keyword appears in notes
|
||||
// std::vector<int> keywordFound(totalSourceKeywords);
|
||||
// char checkedNote[MAX_NOTE_LEN];
|
||||
// for (i = markers.notes.size() - 1; i > 0; i--)
|
||||
// {
|
||||
// if (i != sourceMarker)
|
||||
// {
|
||||
// strcpy(checkedNote, markers.notes[i].c_str());
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// if (StrStrI(checkedNote, sourceKeywords[t]))
|
||||
// keywordFound[t]++;
|
||||
// }
|
||||
// }
|
||||
// // findmax
|
||||
// int maxFound = 0;
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// if (maxFound < keywordFound[t])
|
||||
// maxFound = keywordFound[t];
|
||||
// // and then calculate weight of each keyword: the more often it appears in Markers, the less weight it has
|
||||
// std::vector<double> keywordWeight(totalSourceKeywords);
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// keywordWeight[t] = KEYWORD_WEIGHT_BASE + KEYWORD_WEIGHT_FACTOR * (keywordFound[t] / (double)maxFound);
|
||||
//
|
||||
// // start accumulating priorities
|
||||
// std::vector<std::pair<int, double>> notePriority(markers.notes.size());
|
||||
//
|
||||
// // 2 - find keywords in notes (including cases when keyword appears inside another word)
|
||||
// for (i = notePriority.size() - 1; i > 0; i--)
|
||||
// {
|
||||
// notePriority[i].first = i;
|
||||
// if (i != sourceMarker)
|
||||
// {
|
||||
// strcpy(checkedNote, markers.notes[i].c_str());
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// {
|
||||
// if (StrStrI(checkedNote, sourceKeywords[t]))
|
||||
// notePriority[i].second += KEYWORD_CASEINSENTITIVE_BONUS_PER_CHAR * keywordWeight[t] * strlen(sourceKeywords[t]);
|
||||
// if (strstr(checkedNote, sourceKeywords[t]))
|
||||
// notePriority[i].second += KEYWORD_CASESENTITIVE_BONUS_PER_CHAR * keywordWeight[t] * strlen(sourceKeywords[t]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 3 - search sequences of keywords from all other notes
|
||||
// current_line_pos = 0;
|
||||
// char checkedKeywordsLine[MAX_NUM_KEYWORDS] = {0};
|
||||
// int keyword_id;
|
||||
// for (i = markers.notes.size() - 1; i > 0; i--)
|
||||
// {
|
||||
// if (i != sourceMarker)
|
||||
// {
|
||||
// strcpy(checkedNote, markers.notes[i].c_str());
|
||||
// // divide into tokens
|
||||
// pch = strtok(checkedNote, keywordDelimiters);
|
||||
// while (pch != NULL)
|
||||
// {
|
||||
// if (strlen(pch) >= KEYWORD_MIN_LEN)
|
||||
// {
|
||||
// // check if the keyword is one of sourceKeywords
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// if (!_stricmp(sourceKeywords[t], pch)) break;
|
||||
// if (t >= 0)
|
||||
// {
|
||||
// // the keyword is one of sourceKeywords - set its id into the line
|
||||
// checkedKeywordsLine[current_line_pos++] = t + 1;
|
||||
// } else
|
||||
// {
|
||||
// // found keyword that doesn't appear in sourceNote, give penalty
|
||||
// notePriority[i].second -= KEYWORD_PENALTY_FOR_STRANGERS * strlen(pch);
|
||||
// // since the keyword breaks our sequence of coincident keywords, check if that sequence is similar to sourceKeywordsLine
|
||||
// if (current_line_pos >= KEYWORDS_LINE_MIN_SEQUENCE)
|
||||
// {
|
||||
// checkedKeywordsLine[current_line_pos] = 0;
|
||||
// // search checkedKeywordsLine in sourceKeywordsLine
|
||||
// if (strstr(sourceKeywordsLine, checkedKeywordsLine))
|
||||
// {
|
||||
// // found same sequence of keywords! add priority to this checkedNote
|
||||
// for (t = current_line_pos - 1; t >= 0; t--)
|
||||
// {
|
||||
// // add bonus for every keyword in the sequence
|
||||
// keyword_id = checkedKeywordsLine[t] - 1;
|
||||
// notePriority[i].second += current_line_pos * KEYWORD_SEQUENCE_BONUS_PER_CHAR * keywordWeight[keyword_id] * strlen(sourceKeywords[keyword_id]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // clear checkedKeywordsLine
|
||||
// memset(checkedKeywordsLine, 0, MAX_NUM_KEYWORDS);
|
||||
// current_line_pos = 0;
|
||||
// }
|
||||
// }
|
||||
// pch = strtok(NULL, keywordDelimiters);
|
||||
// }
|
||||
// // finished dividing into tokens
|
||||
// if (current_line_pos >= KEYWORDS_LINE_MIN_SEQUENCE)
|
||||
// {
|
||||
// checkedKeywordsLine[current_line_pos] = 0;
|
||||
// // search checkedKeywordsLine in sourceKeywordsLine
|
||||
// if (strstr(sourceKeywordsLine, checkedKeywordsLine))
|
||||
// {
|
||||
// // found same sequence of keywords! add priority to this checkedNote
|
||||
// for (t = current_line_pos - 1; t >= 0; t--)
|
||||
// {
|
||||
// // add bonus for every keyword in the sequence
|
||||
// keyword_id = checkedKeywordsLine[t] - 1;
|
||||
// notePriority[i].second += current_line_pos * KEYWORD_SEQUENCE_BONUS_PER_CHAR * keywordWeight[keyword_id] * strlen(sourceKeywords[keyword_id]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // clear checkedKeywordsLine
|
||||
// memset(checkedKeywordsLine, 0, MAX_NUM_KEYWORDS);
|
||||
// current_line_pos = 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 4 - sort notePriority by second member of the pair
|
||||
// std::sort(notePriority.begin(), notePriority.end(), ordering);
|
||||
//
|
||||
// /*
|
||||
// // debug trace
|
||||
// FCEU_printf("\n\n\n\n\n\n\n\n\n\n");
|
||||
// for (t = totalSourceKeywords - 1; t >= 0; t--)
|
||||
// FCEU_printf("Keyword: %s, %d, %f\n", sourceKeywords[t], keywordFound[t], keywordWeight[t]);
|
||||
// for (i = notePriority.size() - 1; i > 0; i--)
|
||||
// {
|
||||
// int marker_id = notePriority[i].first;
|
||||
// FCEU_printf("Result: %s, %d, %f\n", notes[marker_id].c_str(), marker_id, notePriority[i].second);
|
||||
// }
|
||||
// */
|
||||
//
|
||||
// // Send Selection to the Marker found
|
||||
// int index = notePriority.size()-1 - currentIterationOfFindSimilar;
|
||||
// if (index >= 0 && notePriority[index].second >= MIN_PRIORITY_TRESHOLD)
|
||||
// {
|
||||
// int marker_id = notePriority[index].first;
|
||||
// int frame = getMarkerFrameNumber(marker_id);
|
||||
// if (frame >= 0)
|
||||
// selection.jumpToFrame(frame);
|
||||
// } else
|
||||
// {
|
||||
// if (currentIterationOfFindSimilar)
|
||||
// MessageBox(taseditorWindow.hwndTASEditor, "Could not find more Notes similar to Marker Note under Playback cursor!", "Find Similar Note", MB_OK);
|
||||
// else
|
||||
// MessageBox(taseditorWindow.hwndTASEditor, "Could not find anything similar to Marker Note under Playback cursor!", "Find Similar Note", MB_OK);
|
||||
// }
|
||||
//
|
||||
// // increase currentIterationOfFindSimilar so that next time we'll find another note
|
||||
// currentIterationOfFindSimilar++;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------
|
||||
void MARKERS_MANAGER::updateEditedMarkerNote()
|
||||
{
|
||||
if (!markerNoteEditMode) return;
|
||||
char new_text[MAX_NOTE_LEN];
|
||||
if (markerNoteEditMode == MARKER_NOTE_EDIT_UPPER)
|
||||
{
|
||||
int len = SendMessage(playback.hwndPlaybackMarkerEditField, WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)new_text);
|
||||
new_text[len] = 0;
|
||||
// check changes
|
||||
if (strcmp(getNoteCopy(playback.displayedMarkerNumber).c_str(), new_text))
|
||||
{
|
||||
setNote(playback.displayedMarkerNumber, new_text);
|
||||
if (playback.displayedMarkerNumber)
|
||||
history.registerMarkersChange(MODTYPE_MARKER_RENAME, getMarkerFrameNumber(playback.displayedMarkerNumber), -1, new_text);
|
||||
else
|
||||
// zeroth Marker - just assume it's set on frame 0
|
||||
history.registerMarkersChange(MODTYPE_MARKER_RENAME, 0, -1, new_text);
|
||||
// notify Selection to change text in the lower Marker (in case both are showing same Marker)
|
||||
selection.mustFindCurrentMarker = true;
|
||||
}
|
||||
} else if (markerNoteEditMode == MARKER_NOTE_EDIT_LOWER)
|
||||
{
|
||||
int len = SendMessage(selection.hwndSelectionMarkerEditField, WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)new_text);
|
||||
new_text[len] = 0;
|
||||
// check changes
|
||||
if (strcmp(getNoteCopy(selection.displayedMarkerNumber).c_str(), new_text))
|
||||
{
|
||||
setNote(selection.displayedMarkerNumber, new_text);
|
||||
if (selection.displayedMarkerNumber)
|
||||
history.registerMarkersChange(MODTYPE_MARKER_RENAME, getMarkerFrameNumber(selection.displayedMarkerNumber), -1, new_text);
|
||||
else
|
||||
// zeroth Marker - just assume it's set on frame 0
|
||||
history.registerMarkersChange(MODTYPE_MARKER_RENAME, 0, -1, new_text);
|
||||
// notify Playback to change text in upper Marker (in case both are showing same Marker)
|
||||
playback.mustFindCurrentMarker = true;
|
||||
}
|
||||
}
|
||||
// if (!markerNoteEditMode) return;
|
||||
// char new_text[MAX_NOTE_LEN];
|
||||
// if (markerNoteEditMode == MARKER_NOTE_EDIT_UPPER)
|
||||
// {
|
||||
// int len = SendMessage(playback.hwndPlaybackMarkerEditField, WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)new_text);
|
||||
// new_text[len] = 0;
|
||||
// // check changes
|
||||
// if (strcmp(getNoteCopy(playback.displayedMarkerNumber).c_str(), new_text))
|
||||
// {
|
||||
// setNote(playback.displayedMarkerNumber, new_text);
|
||||
// if (playback.displayedMarkerNumber)
|
||||
// history.registerMarkersChange(MODTYPE_MARKER_RENAME, getMarkerFrameNumber(playback.displayedMarkerNumber), -1, new_text);
|
||||
// else
|
||||
// // zeroth Marker - just assume it's set on frame 0
|
||||
// history.registerMarkersChange(MODTYPE_MARKER_RENAME, 0, -1, new_text);
|
||||
// // notify Selection to change text in the lower Marker (in case both are showing same Marker)
|
||||
// selection.mustFindCurrentMarker = true;
|
||||
// }
|
||||
// } else if (markerNoteEditMode == MARKER_NOTE_EDIT_LOWER)
|
||||
// {
|
||||
// int len = SendMessage(selection.hwndSelectionMarkerEditField, WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)new_text);
|
||||
// new_text[len] = 0;
|
||||
// // check changes
|
||||
// if (strcmp(getNoteCopy(selection.displayedMarkerNumber).c_str(), new_text))
|
||||
// {
|
||||
// setNote(selection.displayedMarkerNumber, new_text);
|
||||
// if (selection.displayedMarkerNumber)
|
||||
// history.registerMarkersChange(MODTYPE_MARKER_RENAME, getMarkerFrameNumber(selection.displayedMarkerNumber), -1, new_text);
|
||||
// else
|
||||
// // zeroth Marker - just assume it's set on frame 0
|
||||
// history.registerMarkersChange(MODTYPE_MARKER_RENAME, 0, -1, new_text);
|
||||
// // notify Playback to change text in upper Marker (in case both are showing same Marker)
|
||||
// playback.mustFindCurrentMarker = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// ------------------------------------------------------------------------------------
|
||||
INT_PTR CALLBACK findNoteWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
extern MARKERS_MANAGER markersManager;
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
if (taseditorConfig.findnoteWindowX == -32000) taseditorConfig.findnoteWindowX = 0; //Just in case
|
||||
if (taseditorConfig.findnoteWindowY == -32000) taseditorConfig.findnoteWindowY = 0;
|
||||
SetWindowPos(hwndDlg, 0, taseditorConfig.findnoteWindowX, taseditorConfig.findnoteWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
|
||||
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase ? BST_CHECKED : BST_UNCHECKED);
|
||||
if (taseditorConfig.findnoteSearchUp)
|
||||
Button_SetCheck(GetDlgItem(hwndDlg, IDC_RADIO_UP), BST_CHECKED);
|
||||
else
|
||||
Button_SetCheck(GetDlgItem(hwndDlg, IDC_RADIO_DOWN), BST_CHECKED);
|
||||
HWND hwndEdit = GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND);
|
||||
SendMessage(hwndEdit, EM_SETLIMITTEXT, MAX_NOTE_LEN - 1, 0);
|
||||
SetWindowText(hwndEdit, markersManager.findNoteString);
|
||||
if (GetDlgCtrlID((HWND)wParam) != IDC_NOTE_TO_FIND)
|
||||
{
|
||||
SetFocus(hwndEdit);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case WM_MOVE:
|
||||
{
|
||||
if (!IsIconic(hwndDlg))
|
||||
{
|
||||
RECT wrect;
|
||||
GetWindowRect(hwndDlg, &wrect);
|
||||
taseditorConfig.findnoteWindowX = wrect.left;
|
||||
taseditorConfig.findnoteWindowY = wrect.top;
|
||||
WindowBoundsCheckNoResize(taseditorConfig.findnoteWindowX, taseditorConfig.findnoteWindowY, wrect.right);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
{
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_NOTE_TO_FIND:
|
||||
{
|
||||
if (HIWORD(wParam) == EN_CHANGE)
|
||||
{
|
||||
if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND)))
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
|
||||
else
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDOK), false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDC_RADIO_UP:
|
||||
taseditorConfig.findnoteSearchUp = true;
|
||||
break;
|
||||
case IDC_RADIO_DOWN:
|
||||
taseditorConfig.findnoteSearchUp = false;
|
||||
break;
|
||||
case IDC_MATCH_CASE:
|
||||
taseditorConfig.findnoteMatchCase ^= 1;
|
||||
CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase? BST_CHECKED : BST_UNCHECKED);
|
||||
break;
|
||||
case IDOK:
|
||||
{
|
||||
int len = SendMessage(GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND), WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)markersManager.findNoteString);
|
||||
markersManager.findNoteString[len] = 0;
|
||||
// scan frames from current Selection to the border
|
||||
int cur_marker = 0;
|
||||
bool result;
|
||||
int movie_size = currMovieData.getNumRecords();
|
||||
int current_frame = selection.getCurrentRowsSelectionBeginning();
|
||||
if (current_frame < 0 && taseditorConfig.findnoteSearchUp)
|
||||
current_frame = movie_size;
|
||||
while (true)
|
||||
{
|
||||
// move forward
|
||||
if (taseditorConfig.findnoteSearchUp)
|
||||
{
|
||||
current_frame--;
|
||||
if (current_frame < 0)
|
||||
{
|
||||
MessageBox(taseditorWindow.hwndFindNote, "Nothing was found.", "Find Note", MB_OK);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
current_frame++;
|
||||
if (current_frame >= movie_size)
|
||||
{
|
||||
MessageBox(taseditorWindow.hwndFindNote, "Nothing was found!", "Find Note", MB_OK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// scan marked frames
|
||||
cur_marker = markersManager.getMarkerAtFrame(current_frame);
|
||||
if (cur_marker)
|
||||
{
|
||||
if (taseditorConfig.findnoteMatchCase)
|
||||
result = (strstr(markersManager.getNoteCopy(cur_marker).c_str(), markersManager.findNoteString) != 0);
|
||||
else
|
||||
result = (StrStrI(markersManager.getNoteCopy(cur_marker).c_str(), markersManager.findNoteString) != 0);
|
||||
if (result)
|
||||
{
|
||||
// found note containing searched string - jump there
|
||||
selection.jumpToFrame(current_frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
DestroyWindow(taseditorWindow.hwndFindNote);
|
||||
taseditorWindow.hwndFindNote = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_CLOSE:
|
||||
case WM_QUIT:
|
||||
{
|
||||
DestroyWindow(taseditorWindow.hwndFindNote);
|
||||
taseditorWindow.hwndFindNote = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
//INT_PTR CALLBACK findNoteWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
//{
|
||||
// extern MARKERS_MANAGER markersManager;
|
||||
// switch (message)
|
||||
// {
|
||||
// case WM_INITDIALOG:
|
||||
// {
|
||||
// if (taseditorConfig.findnoteWindowX == -32000) taseditorConfig.findnoteWindowX = 0; //Just in case
|
||||
// if (taseditorConfig.findnoteWindowY == -32000) taseditorConfig.findnoteWindowY = 0;
|
||||
// SetWindowPos(hwndDlg, 0, taseditorConfig.findnoteWindowX, taseditorConfig.findnoteWindowY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
//
|
||||
// CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase ? BST_CHECKED : BST_UNCHECKED);
|
||||
// if (taseditorConfig.findnoteSearchUp)
|
||||
// Button_SetCheck(GetDlgItem(hwndDlg, IDC_RADIO_UP), BST_CHECKED);
|
||||
// else
|
||||
// Button_SetCheck(GetDlgItem(hwndDlg, IDC_RADIO_DOWN), BST_CHECKED);
|
||||
// HWND hwndEdit = GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND);
|
||||
// SendMessage(hwndEdit, EM_SETLIMITTEXT, MAX_NOTE_LEN - 1, 0);
|
||||
// SetWindowText(hwndEdit, markersManager.findNoteString);
|
||||
// if (GetDlgCtrlID((HWND)wParam) != IDC_NOTE_TO_FIND)
|
||||
// {
|
||||
// SetFocus(hwndEdit);
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// case WM_MOVE:
|
||||
// {
|
||||
// if (!IsIconic(hwndDlg))
|
||||
// {
|
||||
// RECT wrect;
|
||||
// GetWindowRect(hwndDlg, &wrect);
|
||||
// taseditorConfig.findnoteWindowX = wrect.left;
|
||||
// taseditorConfig.findnoteWindowY = wrect.top;
|
||||
// WindowBoundsCheckNoResize(taseditorConfig.findnoteWindowX, taseditorConfig.findnoteWindowY, wrect.right);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case WM_COMMAND:
|
||||
// {
|
||||
// switch (LOWORD(wParam))
|
||||
// {
|
||||
// case IDC_NOTE_TO_FIND:
|
||||
// {
|
||||
// if (HIWORD(wParam) == EN_CHANGE)
|
||||
// {
|
||||
// if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND)))
|
||||
// EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
|
||||
// else
|
||||
// EnableWindow(GetDlgItem(hwndDlg, IDOK), false);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case IDC_RADIO_UP:
|
||||
// taseditorConfig.findnoteSearchUp = true;
|
||||
// break;
|
||||
// case IDC_RADIO_DOWN:
|
||||
// taseditorConfig.findnoteSearchUp = false;
|
||||
// break;
|
||||
// case IDC_MATCH_CASE:
|
||||
// taseditorConfig.findnoteMatchCase ^= 1;
|
||||
// CheckDlgButton(hwndDlg, IDC_MATCH_CASE, taseditorConfig.findnoteMatchCase? BST_CHECKED : BST_UNCHECKED);
|
||||
// break;
|
||||
// case IDOK:
|
||||
// {
|
||||
// int len = SendMessage(GetDlgItem(hwndDlg, IDC_NOTE_TO_FIND), WM_GETTEXT, MAX_NOTE_LEN, (LPARAM)markersManager.findNoteString);
|
||||
// markersManager.findNoteString[len] = 0;
|
||||
// // scan frames from current Selection to the border
|
||||
// int cur_marker = 0;
|
||||
// bool result;
|
||||
// int movie_size = currMovieData.getNumRecords();
|
||||
// int current_frame = selection.getCurrentRowsSelectionBeginning();
|
||||
// if (current_frame < 0 && taseditorConfig.findnoteSearchUp)
|
||||
// current_frame = movie_size;
|
||||
// while (true)
|
||||
// {
|
||||
// // move forward
|
||||
// if (taseditorConfig.findnoteSearchUp)
|
||||
// {
|
||||
// current_frame--;
|
||||
// if (current_frame < 0)
|
||||
// {
|
||||
// MessageBox(taseditorWindow.hwndFindNote, "Nothing was found.", "Find Note", MB_OK);
|
||||
// break;
|
||||
// }
|
||||
// } else
|
||||
// {
|
||||
// current_frame++;
|
||||
// if (current_frame >= movie_size)
|
||||
// {
|
||||
// MessageBox(taseditorWindow.hwndFindNote, "Nothing was found!", "Find Note", MB_OK);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// // scan marked frames
|
||||
// cur_marker = markersManager.getMarkerAtFrame(current_frame);
|
||||
// if (cur_marker)
|
||||
// {
|
||||
// if (taseditorConfig.findnoteMatchCase)
|
||||
// result = (strstr(markersManager.getNoteCopy(cur_marker).c_str(), markersManager.findNoteString) != 0);
|
||||
// else
|
||||
// result = (StrStrI(markersManager.getNoteCopy(cur_marker).c_str(), markersManager.findNoteString) != 0);
|
||||
// if (result)
|
||||
// {
|
||||
// // found note containing searched string - jump there
|
||||
// selection.jumpToFrame(current_frame);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return TRUE;
|
||||
// }
|
||||
// case IDCANCEL:
|
||||
// DestroyWindow(taseditorWindow.hwndFindNote);
|
||||
// taseditorWindow.hwndFindNote = 0;
|
||||
// return TRUE;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// case WM_CLOSE:
|
||||
// case WM_QUIT:
|
||||
// {
|
||||
// DestroyWindow(taseditorWindow.hwndFindNote);
|
||||
// taseditorWindow.hwndFindNote = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// return FALSE;
|
||||
//}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue