* Taseditor: Config->Combine consecutive Recordings/Draws
* Taseditor: rightclick menu appears only after click on selected row * Taseditor: refactoring
This commit is contained in:
parent
eca6e6e279
commit
66504dc115
|
@ -1,5 +1,31 @@
|
|||
|
||||
22-Mar-2012 - AnS - Config->Combine consecutive Recordings/Draws
|
||||
18-Mar-2012 - AnS - new hotkey "Cancel Seeking (TAS Editor)" (Esc)
|
||||
18-Mar-2012 - AnS - Taseditor: Config->Autopause at the end of Movie
|
||||
17-Mar-2012 - CaH4e3 - varous bugfixes, xstring trimming functions logic bugs, etc
|
||||
17-Mar-2012 - AnS - Taseditor: showing row_last_clicked when Shift or Alt is held
|
||||
17-Mar-2012 - AnS - Taseditor: no more "allow keys in Piano Roll"; new accelerators: Ctrl + arrows, Shift + arrows, Home/End/Page Up/Page Down, Ctrl + Home/End, Shift + Home/End
|
||||
17-Mar-2012 - AnS - Taseditor: selection by dragging from Frame#
|
||||
17-Mar-2012 - AnS - Taseditor: set/pick Markers by doubleclick, throw Markers away
|
||||
14-Mar-2012 - AnS - Taseditor: drawing input; holding Shift when drawing
|
||||
14-Mar-2012 - AnS - Taseditor: fixed known WinXP bug with scrollbar arrows
|
||||
14-Mar-2012 - AnS - Taseditor: moving Markers by drag'n'drop, "Marker Drag" and "Marker Swap" operations
|
||||
14-Mar-2012 - AnS - Taseditor: dragging blue arrow (moving Playback cursor)
|
||||
14-Mar-2012 - AnS - Taseditor: observing Piano Roll by dragging cursor outside
|
||||
11-Mar-2012 - AnS - Taseditor: double-tapping Shift/Ctrl scrolls Piano Roll to respective cursor
|
||||
09-Mar-2012 - AnS - Taseditor: Config->Deselect on doubleclick
|
||||
09-Mar-2012 - AnS - Taseditor: checking ROM checksum when saving/loading projects
|
||||
09-Mar-2012 - AnS - Taseditor: TAS Editor can have mouse wheel input even when keyboard focus is on FCEUX window
|
||||
09-Mar-2012 - AnS - disabled FCEUX context menu when TAS Editor is engaged
|
||||
06-mar-2012 - prg - fceux no longer segfaults when opening gamepadconfig with GTK < 2.24 - a message is printed to the console
|
||||
06-mar-2012 - prg - supports loading of configuration files in $FCEUXDIR/cfg.d/*
|
||||
01-Mar-2012 - AnS - Taseditor: changing history size doesn't reset history
|
||||
28-feb-2012 - AnS - Taseditor: "Deselect" option in menus
|
||||
26-feb-2012 - AnS - Small save/load state speedup, noticeable only in TAS Editor or lua bots
|
||||
21-feb-2012 - AnS - Taseditor: header lights on mouseover
|
||||
21-feb-2012 - AnS - Taseditor: registering click at buttondown; Alt+click on input = set pattern
|
||||
20-feb-2012 - AnS - Taseditor: Right button + wheel = Playback rewind/forward; Shift/Ctrl + wheel = jump via Markers with Playback/Selection cursor
|
||||
20-feb-2012 - AnS - Taseditor: middle button pauses/unpauses emulation
|
||||
18-feb-2012 - AnS - PATTERNS menu, loading data from "tools\taseditor_patterns.txt"
|
||||
18-feb-2012 - AnS - "Use pattern" checkbox in Recorder; Config->ColumnSet Pattern skips Lag
|
||||
18-feb-2012 - AnS - Taseditor: "Frame#" lights when Alt key is being held, not entering menu by Alt
|
||||
|
|
|
@ -318,7 +318,7 @@ static CFGSTRUCT fceuconfig[] = {
|
|||
AC(taseditor_config.show_branch_descr),
|
||||
AC(taseditor_config.bind_markers),
|
||||
AC(taseditor_config.empty_marker_notes),
|
||||
AC(taseditor_config.combine_consecutive_rec),
|
||||
AC(taseditor_config.combine_consecutive),
|
||||
AC(taseditor_config.use_1p_rec),
|
||||
AC(taseditor_config.columnset_by_keys),
|
||||
AC(taseditor_config.superimpose_affects_paste),
|
||||
|
|
|
@ -39,6 +39,7 @@ RECORDER recorder;
|
|||
GREENZONE greenzone;
|
||||
MARKERS_MANAGER markers_manager;
|
||||
BOOKMARKS bookmarks;
|
||||
BRANCHES branches;
|
||||
POPUP_DISPLAY popup_display;
|
||||
PIANO_ROLL piano_roll;
|
||||
TASEDITOR_LUA taseditor_lua;
|
||||
|
@ -94,6 +95,7 @@ bool EnterTasEditor()
|
|||
markers_manager.init();
|
||||
project.init();
|
||||
bookmarks.init();
|
||||
branches.init();
|
||||
popup_display.init();
|
||||
history.init();
|
||||
taseditor_lua.init();
|
||||
|
@ -150,6 +152,7 @@ bool ExitTasEditor()
|
|||
markers_manager.free();
|
||||
greenzone.free();
|
||||
bookmarks.free();
|
||||
branches.free();
|
||||
popup_display.free();
|
||||
history.free();
|
||||
playback.SeekingStop();
|
||||
|
@ -194,6 +197,7 @@ void UpdateTasEditor()
|
|||
markers_manager.update();
|
||||
playback.update();
|
||||
bookmarks.update();
|
||||
branches.update();
|
||||
popup_display.update();
|
||||
selection.update();
|
||||
splicer.update();
|
||||
|
@ -317,6 +321,7 @@ void NewProject()
|
|||
playback.reset();
|
||||
playback.StartFromZero();
|
||||
bookmarks.reset();
|
||||
branches.reset();
|
||||
history.reset();
|
||||
piano_roll.reset();
|
||||
selection.reset();
|
||||
|
|
|
@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
------------------------------------------------------------------------------------
|
||||
Bookmark - Single Bookmark data
|
||||
|
||||
* stores all info of one specific Bookmark-Branch: movie snapshot, a savestate of 1 frame, a screenshot of the frame, an info about relations of this Branch, a state of flashing for this Bookmark's row
|
||||
* stores all info of one specific Bookmark: movie snapshot, a savestate of 1 frame, a screenshot of the frame, a state of flashing for this Bookmark's row
|
||||
* saves and loads the data from a project file. On error: sends warning to caller
|
||||
* implements procedure of "Bookmark set": creating movie snapshot, setting key frame on current Playback position, copying savestate from Greenzone, making and compressing screenshot, launching flashing animation
|
||||
* launches respective flashings for "Bookmark jump" and "Branch deploy"
|
||||
|
@ -34,7 +34,6 @@ void BOOKMARK::init()
|
|||
not_empty = false;
|
||||
flash_type = flash_phase = 0;
|
||||
snapshot.jump_frame = -1;
|
||||
parent_branch = -1; // -1 = root (cloud)
|
||||
}
|
||||
|
||||
void BOOKMARK::set()
|
||||
|
@ -78,8 +77,6 @@ void BOOKMARK::save(EMUFILE *os)
|
|||
if (not_empty)
|
||||
{
|
||||
write8le(1, os);
|
||||
// write parent_branch
|
||||
write32le(parent_branch, os);
|
||||
// write snapshot
|
||||
snapshot.save(os);
|
||||
// write savestate
|
||||
|
@ -100,8 +97,6 @@ bool BOOKMARK::load(EMUFILE *is)
|
|||
not_empty = tmp != 0;
|
||||
if (not_empty)
|
||||
{
|
||||
// read parent_branch
|
||||
if (!read32le(&parent_branch, is)) return true;
|
||||
// read snapshot
|
||||
if (snapshot.load(is)) return true;
|
||||
// read savestate
|
||||
|
|
|
@ -30,7 +30,8 @@ public:
|
|||
SNAPSHOT snapshot;
|
||||
std::vector<uint8> savestate;
|
||||
std::vector<uint8> saved_screenshot;
|
||||
int parent_branch;
|
||||
|
||||
//int parent_branch;
|
||||
|
||||
// not saved vars
|
||||
int flash_phase;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,83 +17,15 @@ enum COMMANDS
|
|||
COMMAND_JUMP = 1,
|
||||
COMMAND_DEPLOY = 2,
|
||||
COMMAND_DELETE = 3, // not implemented, probably useless
|
||||
|
||||
TOTAL_COMMANDS
|
||||
};
|
||||
|
||||
#define ITEM_UNDER_MOUSE_NONE -2
|
||||
#define ITEM_UNDER_MOUSE_CLOUD -1
|
||||
|
||||
#define BOOKMARKS_FLASH_TICK 100 // in milliseconds
|
||||
#define BRANCHES_ANIMATION_TICK 50 // animate at 20FPS
|
||||
#define BRANCHES_TRANSITION_MAX 8
|
||||
|
||||
// branches bitmap
|
||||
#define BRANCHES_BITMAP_WIDTH 170
|
||||
#define BRANCHES_BITMAP_HEIGHT 145
|
||||
#define BRANCHES_ANIMATION_FRAMES 12
|
||||
#define BRANCHES_BITMAP_FRAMENUM_X 2
|
||||
#define BRANCHES_BITMAP_FRAMENUM_Y 1
|
||||
#define BRANCHES_BITMAP_TIME_X 2
|
||||
#define BRANCHES_BITMAP_TIME_Y BRANCHES_BITMAP_HEIGHT - 17
|
||||
#define BRANCHES_TEXT_SHADOW_COLOR 0xFFFFFF
|
||||
#define BRANCHES_TEXT_COLOR 0x7F0000
|
||||
// constants for drawing branches tree
|
||||
#define BRANCHES_CANVAS_WIDTH 146
|
||||
#define BRANCHES_CANVAS_HEIGHT 130
|
||||
#define BRANCHES_CLOUD_X 14
|
||||
#define BRANCHES_CLOUD_Y 72
|
||||
#define BRANCHES_GRID_MIN_WIDTH 14
|
||||
#define BRANCHES_GRID_MAX_WIDTH 30
|
||||
#define MIN_CLOUD_LINE_LENGTH 19
|
||||
#define BRANCHES_GRID_MIN_HALFHEIGHT 8
|
||||
#define BRANCHES_GRID_MAX_HALFHEIGHT 12
|
||||
#define EMPTY_BRANCHES_X -6
|
||||
#define EMPTY_BRANCHES_Y_BASE 8
|
||||
#define EMPTY_BRANCHES_Y_FACTOR 14
|
||||
#define MAX_NUM_CHILDREN_ON_CANVAS_HEIGHT 9
|
||||
#define MAX_CHAIN_LEN 10
|
||||
#define MAX_GRID_Y_POS 8
|
||||
// spritesheet
|
||||
#define DIGIT_BITMAP_WIDTH 9
|
||||
#define DIGIT_BITMAP_HALFWIDTH DIGIT_BITMAP_WIDTH/2
|
||||
#define DIGIT_BITMAP_HEIGHT 13
|
||||
#define DIGIT_BITMAP_HALFHEIGHT DIGIT_BITMAP_HEIGHT/2
|
||||
#define BLUE_DIGITS_SPRITESHEET_DX DIGIT_BITMAP_WIDTH*TOTAL_BOOKMARKS
|
||||
#define MOUSEOVER_DIGITS_SPRITESHEET_DY DIGIT_BITMAP_HEIGHT
|
||||
#define DIGIT_RECT_WIDTH 11
|
||||
#define DIGIT_RECT_WIDTH_COLLISION (DIGIT_RECT_WIDTH + 2)
|
||||
#define DIGIT_RECT_HALFWIDTH DIGIT_RECT_WIDTH/2
|
||||
#define DIGIT_RECT_HALFWIDTH_COLLISION (DIGIT_RECT_HALFWIDTH + 1)
|
||||
#define DIGIT_RECT_HEIGHT 15
|
||||
#define DIGIT_RECT_HEIGHT_COLLISION (DIGIT_RECT_HEIGHT + 2)
|
||||
#define DIGIT_RECT_HALFHEIGHT DIGIT_RECT_HEIGHT/2
|
||||
#define DIGIT_RECT_HALFHEIGHT_COLLISION (DIGIT_RECT_HALFHEIGHT + 1)
|
||||
#define BRANCHES_CLOUD_WIDTH 26
|
||||
#define BRANCHES_CLOUD_HALFWIDTH BRANCHES_CLOUD_WIDTH/2
|
||||
#define BRANCHES_CLOUD_HEIGHT 15
|
||||
#define BRANCHES_CLOUD_HALFHEIGHT BRANCHES_CLOUD_HEIGHT/2
|
||||
#define BRANCHES_CLOUD_SPRITESHEET_X 180
|
||||
#define BRANCHES_CLOUD_SPRITESHEET_Y 0
|
||||
#define BRANCHES_FIREBALL_WIDTH 10
|
||||
#define BRANCHES_FIREBALL_HALFWIDTH BRANCHES_FIREBALL_WIDTH/2
|
||||
#define BRANCHES_FIREBALL_HEIGHT 10
|
||||
#define BRANCHES_FIREBALL_HALFHEIGHT BRANCHES_FIREBALL_HEIGHT/2
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_X 0
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_Y 26
|
||||
#define BRANCHES_FIREBALL_MAX_SIZE 5
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_END_X 160
|
||||
#define BRANCHES_CORNER_WIDTH 7
|
||||
#define BRANCHES_CORNER_HALFWIDTH BRANCHES_CORNER_WIDTH/2
|
||||
#define BRANCHES_CORNER_HEIGHT 7
|
||||
#define BRANCHES_CORNER_HALFHEIGHT BRANCHES_CORNER_HEIGHT/2
|
||||
#define BRANCHES_CORNER1_SPRITESHEET_X 206
|
||||
#define BRANCHES_CORNER1_SPRITESHEET_Y 0
|
||||
#define BRANCHES_CORNER2_SPRITESHEET_X 213
|
||||
#define BRANCHES_CORNER2_SPRITESHEET_Y 0
|
||||
#define BRANCHES_CORNER3_SPRITESHEET_X 206
|
||||
#define BRANCHES_CORNER3_SPRITESHEET_Y 7
|
||||
#define BRANCHES_CORNER4_SPRITESHEET_X 213
|
||||
#define BRANCHES_CORNER4_SPRITESHEET_Y 7
|
||||
#define BRANCHES_CORNER_BASE_SHIFT 6
|
||||
// listview columns
|
||||
enum
|
||||
{
|
||||
|
@ -120,7 +52,7 @@ public:
|
|||
void save(EMUFILE *os, bool really_save = true);
|
||||
bool load(EMUFILE *is);
|
||||
|
||||
void command(int command_id, int slot);
|
||||
void command(int command_id, int slot = -1);
|
||||
|
||||
void GetDispInfo(NMLVDISPINFO* nmlvDispInfo);
|
||||
LONG CustomDraw(NMLVCUSTOMDRAW* msg);
|
||||
|
@ -128,85 +60,40 @@ public:
|
|||
void RightClick(int column_index, int row_index);
|
||||
|
||||
int FindBookmarkAtFrame(int frame);
|
||||
int GetCurrentBranch();
|
||||
|
||||
void RedrawBookmarksCaption();
|
||||
void RedrawBookmarksList();
|
||||
void RedrawChangedBookmarks(int frame);
|
||||
void RedrawBookmarksRow(int index);
|
||||
|
||||
void RedrawBranchesTree();
|
||||
void PaintBranchesBitmap(HDC hdc);
|
||||
|
||||
void MouseMove(int new_x, int new_y);
|
||||
void CheckMousePos();
|
||||
|
||||
void ChangesMadeSinceBranch();
|
||||
|
||||
void RecalculateBranchesTree();
|
||||
void RecursiveAddHeight(int branch_num, int amount);
|
||||
void RecursiveSetYPos(int parent, int parentY);
|
||||
void FindItemUnderMouse();
|
||||
|
||||
// saved vars
|
||||
std::vector<BOOKMARK> bookmarks_array;
|
||||
|
||||
// not saved vars
|
||||
int branch_row_top;
|
||||
int branch_row_left;
|
||||
int branch_row_height;
|
||||
int edit_mode;
|
||||
bool must_check_item_under_mouse;
|
||||
bool mouse_over_bitmap, mouse_over_bookmarkslist;
|
||||
int item_under_mouse;
|
||||
TRACKMOUSEEVENT tme, list_tme;
|
||||
HWND hwndBookmarksList, hwndBranchesBitmap, hwndBookmarks;
|
||||
|
||||
private:
|
||||
void set(int slot);
|
||||
void jump(int slot);
|
||||
void deploy(int slot);
|
||||
|
||||
void SetCurrentPosTime();
|
||||
|
||||
// also saved vars
|
||||
int current_branch;
|
||||
bool changes_since_current_branch;
|
||||
char cloud_time[TIME_DESC_LENGTH];
|
||||
char current_pos_time[TIME_DESC_LENGTH];
|
||||
|
||||
// not saved vars
|
||||
std::vector<int> commands;
|
||||
int check_flash_shedule;
|
||||
int edit_mode;
|
||||
int animation_frame;
|
||||
int next_animation_time;
|
||||
bool must_check_item_under_mouse;
|
||||
bool must_redraw_branches_tree;
|
||||
bool must_recalculate_branches_tree;
|
||||
std::vector<int> BranchX; // in pixels
|
||||
std::vector<int> BranchY;
|
||||
std::vector<int> BranchPrevX;
|
||||
std::vector<int> BranchPrevY;
|
||||
std::vector<int> BranchCurrX;
|
||||
std::vector<int> BranchCurrY;
|
||||
int CloudX, CloudPrevX, cloud_x;
|
||||
int CursorX, CursorPrevX, CursorY, CursorPrevY;
|
||||
int transition_phase;
|
||||
int fireball_size;
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
HWND hwndBookmarksList, hwndBookmarks;
|
||||
HWND hwndBranchesBitmap;
|
||||
int list_row_top;
|
||||
int list_row_left;
|
||||
int list_row_height;
|
||||
|
||||
// GDI stuff
|
||||
HFONT hBookmarksFont;
|
||||
HBRUSH normal_brush;
|
||||
RECT temp_rect;
|
||||
HPEN normal_pen, select_pen;
|
||||
HBITMAP branches_hbitmap, hOldBitmap, buffer_hbitmap, hOldBitmap1, branchesSpritesheet, hOldBitmap2;
|
||||
HDC hBitmapDC, hBufferDC, hSpritesheetDC;
|
||||
|
||||
// temps
|
||||
std::vector<int> GridX; // in grid units
|
||||
std::vector<int> GridY;
|
||||
std::vector<int> GridHeight;
|
||||
std::vector<std::vector<uint8>> Children;
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,944 @@
|
|||
/* ---------------------------------------------------------------------------------
|
||||
Implementation file of Branches class
|
||||
Copyright (c) 2011-2012 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.
|
||||
------------------------------------------------------------------------------------
|
||||
Branches - Manager of Branches
|
||||
[Singleton]
|
||||
|
||||
* stores info about Branches (relations of Bookmarks) and the id of current Branch
|
||||
* also stores the time of the last modification (see fireball) and the time of the root of Branches Tree (see cloudlet)
|
||||
* finds best place for every new Bookmark in the Branches Tree
|
||||
* saves and loads the data from a project file. On error: sends warning to caller
|
||||
* implements the working of Branches Tree: creating, recalculating relations, animating, redrawing, mouseover
|
||||
* on demand: reacts on project changes and recalculates Branches Tree
|
||||
* regularly updates animations in Branches Tree
|
||||
* stores resources: coordinates for building Branches Tree, animation timings
|
||||
------------------------------------------------------------------------------------ */
|
||||
|
||||
#include "taseditor_project.h"
|
||||
#include "utils/xstring.h"
|
||||
#include "zlib.h"
|
||||
|
||||
#pragma comment(lib, "msimg32.lib")
|
||||
|
||||
LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
WNDPROC hwndBranchesBitmap_oldWndProc;
|
||||
|
||||
extern TASEDITOR_CONFIG taseditor_config;
|
||||
extern TASEDITOR_WINDOW taseditor_window;
|
||||
extern POPUP_DISPLAY popup_display;
|
||||
extern PLAYBACK playback;
|
||||
extern SELECTION selection;
|
||||
extern GREENZONE greenzone;
|
||||
extern TASEDITOR_PROJECT project;
|
||||
extern HISTORY history;
|
||||
extern PIANO_ROLL piano_roll;
|
||||
extern MARKERS_MANAGER markers_manager;
|
||||
extern BOOKMARKS bookmarks;
|
||||
|
||||
extern COLORREF bookmark_flash_colors[TOTAL_COMMANDS][FLASH_PHASE_MAX+1];
|
||||
|
||||
// resources
|
||||
// corners cursor animation
|
||||
int corners_cursor_shift[BRANCHES_ANIMATION_FRAMES] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0 };
|
||||
|
||||
BRANCHES::BRANCHES()
|
||||
{
|
||||
}
|
||||
|
||||
void BRANCHES::init()
|
||||
{
|
||||
free();
|
||||
|
||||
// subclass BranchesBitmap
|
||||
hwndBranchesBitmap_oldWndProc = (WNDPROC)SetWindowLong(bookmarks.hwndBranchesBitmap, GWL_WNDPROC, (LONG)BranchesBitmapWndProc);
|
||||
|
||||
// init arrays
|
||||
BranchX.resize(TOTAL_BOOKMARKS+1);
|
||||
BranchY.resize(TOTAL_BOOKMARKS+1);
|
||||
BranchPrevX.resize(TOTAL_BOOKMARKS+1);
|
||||
BranchPrevY.resize(TOTAL_BOOKMARKS+1);
|
||||
BranchCurrX.resize(TOTAL_BOOKMARKS+1);
|
||||
BranchCurrY.resize(TOTAL_BOOKMARKS+1);
|
||||
|
||||
// init GDI stuff
|
||||
HDC win_hdc = GetWindowDC(bookmarks.hwndBranchesBitmap);
|
||||
hBitmapDC = CreateCompatibleDC(win_hdc);
|
||||
branches_hbitmap = CreateCompatibleBitmap(win_hdc, BRANCHES_BITMAP_WIDTH, BRANCHES_BITMAP_WIDTH);
|
||||
hOldBitmap = (HBITMAP)SelectObject(hBitmapDC, branches_hbitmap);
|
||||
hBufferDC = CreateCompatibleDC(win_hdc);
|
||||
buffer_hbitmap = CreateCompatibleBitmap(win_hdc, BRANCHES_BITMAP_WIDTH, BRANCHES_BITMAP_WIDTH);
|
||||
hOldBitmap1 = (HBITMAP)SelectObject(hBufferDC, buffer_hbitmap);
|
||||
normal_brush = CreateSolidBrush(0x000000);
|
||||
// prepare branches spritesheet
|
||||
branchesSpritesheet = LoadBitmap(fceu_hInstance, MAKEINTRESOURCE(IDB_BRANCH_SPRITESHEET));
|
||||
hSpritesheetDC = CreateCompatibleDC(win_hdc);
|
||||
hOldBitmap2 = (HBITMAP)SelectObject(hSpritesheetDC, branchesSpritesheet);
|
||||
// create pens
|
||||
normal_pen = CreatePen(PS_SOLID, 1, 0x0);
|
||||
select_pen = CreatePen(PS_SOLID, 2, 0xFF9080);
|
||||
|
||||
reset();
|
||||
next_animation_time = 0;
|
||||
|
||||
update();
|
||||
}
|
||||
void BRANCHES::free()
|
||||
{
|
||||
parents.resize(0);
|
||||
BranchX.resize(0);
|
||||
BranchY.resize(0);
|
||||
BranchPrevX.resize(0);
|
||||
BranchPrevY.resize(0);
|
||||
BranchCurrX.resize(0);
|
||||
BranchCurrY.resize(0);
|
||||
// free GDI stuff
|
||||
if (hOldBitmap && hBitmapDC)
|
||||
{
|
||||
SelectObject(hBitmapDC, hOldBitmap);
|
||||
DeleteDC(hBitmapDC);
|
||||
hBitmapDC = NULL;
|
||||
}
|
||||
if (branches_hbitmap)
|
||||
{
|
||||
DeleteObject(branches_hbitmap);
|
||||
branches_hbitmap = NULL;
|
||||
}
|
||||
if (hOldBitmap1 && hBufferDC)
|
||||
{
|
||||
SelectObject(hBufferDC, hOldBitmap1);
|
||||
DeleteDC(hBufferDC);
|
||||
hBufferDC = NULL;
|
||||
}
|
||||
if (buffer_hbitmap)
|
||||
{
|
||||
DeleteObject(buffer_hbitmap);
|
||||
buffer_hbitmap = NULL;
|
||||
}
|
||||
if (hOldBitmap2 && hSpritesheetDC)
|
||||
{
|
||||
SelectObject(hSpritesheetDC, hOldBitmap2);
|
||||
DeleteDC(hSpritesheetDC);
|
||||
hSpritesheetDC = NULL;
|
||||
}
|
||||
if (branchesSpritesheet)
|
||||
{
|
||||
DeleteObject(branchesSpritesheet);
|
||||
branchesSpritesheet = NULL;
|
||||
}
|
||||
}
|
||||
void BRANCHES::reset()
|
||||
{
|
||||
parents.resize(TOTAL_BOOKMARKS);
|
||||
for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--)
|
||||
parents[i] = ITEM_UNDER_MOUSE_CLOUD;
|
||||
|
||||
// set positions of slots to default coordinates
|
||||
for (int i = TOTAL_BOOKMARKS; i >= 0; i--)
|
||||
{
|
||||
BranchX[i] = BranchPrevX[i] = BranchCurrX[i] = EMPTY_BRANCHES_X;
|
||||
BranchY[i] = BranchPrevY[i] = BranchCurrY[i] = EMPTY_BRANCHES_Y_BASE + EMPTY_BRANCHES_Y_FACTOR * ((i + TOTAL_BOOKMARKS - 1) % TOTAL_BOOKMARKS);
|
||||
}
|
||||
CursorX = CursorPrevX = CloudX = CloudPrevX = BRANCHES_CLOUD_X;
|
||||
CursorY = CursorPrevY = BRANCHES_CLOUD_Y;
|
||||
|
||||
reset_vars();
|
||||
|
||||
current_branch = ITEM_UNDER_MOUSE_CLOUD;
|
||||
changes_since_current_branch = false;
|
||||
fireball_size = 0;
|
||||
|
||||
// set cloud_time and current_pos_time
|
||||
SetCurrentPosTime();
|
||||
strcpy(cloud_time, current_pos_time);
|
||||
}
|
||||
void BRANCHES::reset_vars()
|
||||
{
|
||||
transition_phase = animation_frame = 0;
|
||||
must_recalculate_branches_tree = must_redraw_branches_tree = true;
|
||||
next_animation_time = clock() + BRANCHES_ANIMATION_TICK;
|
||||
}
|
||||
|
||||
void BRANCHES::update()
|
||||
{
|
||||
if (must_recalculate_branches_tree)
|
||||
RecalculateBranchesTree();
|
||||
|
||||
// once per 50 milliseconds update branches_bitmap
|
||||
if (clock() > next_animation_time)
|
||||
{
|
||||
// animate branches_bitmap
|
||||
next_animation_time = clock() + BRANCHES_ANIMATION_TICK;
|
||||
animation_frame = (animation_frame + 1) % BRANCHES_ANIMATION_FRAMES;
|
||||
if (bookmarks.edit_mode == EDIT_MODE_BRANCHES)
|
||||
{
|
||||
// grow or shrink fireball size
|
||||
if (changes_since_current_branch)
|
||||
{
|
||||
fireball_size++;
|
||||
if (fireball_size > BRANCHES_FIREBALL_MAX_SIZE) fireball_size = BRANCHES_FIREBALL_MAX_SIZE;
|
||||
} else
|
||||
{
|
||||
fireball_size--;
|
||||
if (fireball_size < 0) fireball_size = 0;
|
||||
}
|
||||
// also update transition from old to new tree
|
||||
if (transition_phase)
|
||||
{
|
||||
transition_phase--;
|
||||
// recalculate current positions of branch items
|
||||
for (int i = 0; i <= TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
BranchCurrX[i] = (BranchX[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevX[i] * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
BranchCurrY[i] = (BranchY[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevY[i] * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
}
|
||||
cloud_x = (CloudX * (BRANCHES_TRANSITION_MAX - transition_phase) + CloudPrevX * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
must_redraw_branches_tree = true;
|
||||
bookmarks.must_check_item_under_mouse = true;
|
||||
} else if (!must_redraw_branches_tree)
|
||||
{
|
||||
// just update sprites
|
||||
InvalidateRect(bookmarks.hwndBranchesBitmap, 0, FALSE);
|
||||
}
|
||||
if (must_redraw_branches_tree)
|
||||
RedrawBranchesTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BRANCHES::save(EMUFILE *os)
|
||||
{
|
||||
// write cloud time
|
||||
os->fwrite(cloud_time, TIME_DESC_LENGTH);
|
||||
// write current branch and flag of changes since it
|
||||
write32le(current_branch, os);
|
||||
if (changes_since_current_branch)
|
||||
write8le((uint8)1, os);
|
||||
else
|
||||
write8le((uint8)0, os);
|
||||
// write current_position time
|
||||
os->fwrite(current_pos_time, TIME_DESC_LENGTH);
|
||||
// write all 10 parents
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
write32le(parents[i], os);
|
||||
}
|
||||
// returns true if couldn't load
|
||||
bool BRANCHES::load(EMUFILE *is)
|
||||
{
|
||||
// read cloud time
|
||||
if ((int)is->fread(cloud_time, TIME_DESC_LENGTH) < TIME_DESC_LENGTH) goto error;
|
||||
// read current branch and flag of changes since it
|
||||
uint8 tmp;
|
||||
if (!read32le(¤t_branch, is)) goto error;
|
||||
if (!read8le(&tmp, is)) goto error;
|
||||
changes_since_current_branch = (tmp != 0);
|
||||
// read current_position time
|
||||
if ((int)is->fread(current_pos_time, TIME_DESC_LENGTH) < TIME_DESC_LENGTH) goto error;
|
||||
// read all 10 parents
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
if (!read32le(&parents[i], is)) goto error;
|
||||
// all ok
|
||||
reset_vars();
|
||||
return false;
|
||||
error:
|
||||
FCEU_printf("Error loading branches\n");
|
||||
return true;
|
||||
}
|
||||
// ----------------------------------------------------------
|
||||
void BRANCHES::RedrawBranchesTree()
|
||||
{
|
||||
// draw background gradient
|
||||
TRIVERTEX vertex[2] ;
|
||||
vertex[0].x = 0;
|
||||
vertex[0].y = 0;
|
||||
vertex[0].Red = 0xC700;
|
||||
vertex[0].Green = 0xE700;
|
||||
vertex[0].Blue = 0xF300;
|
||||
vertex[0].Alpha = 0x0000;
|
||||
vertex[1].x = BRANCHES_BITMAP_WIDTH;
|
||||
vertex[1].y = BRANCHES_BITMAP_HEIGHT;
|
||||
vertex[1].Red = 0xEB00;
|
||||
vertex[1].Green = 0xFA00;
|
||||
vertex[1].Blue = 0xF800;
|
||||
vertex[1].Alpha = 0x0000;
|
||||
GRADIENT_RECT gRect;
|
||||
gRect.UpperLeft = 0;
|
||||
gRect.LowerRight = 1;
|
||||
GradientFill(hBitmapDC, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H);
|
||||
|
||||
// lines
|
||||
int branch_x, branch_y, parent_x, parent_y, child_id;
|
||||
SelectObject(hBitmapDC, normal_pen);
|
||||
for (int t = Children.size() - 1; t >= 0; t--)
|
||||
{
|
||||
if (t > 0)
|
||||
{
|
||||
parent_x = BranchCurrX[t-1];
|
||||
parent_y = BranchCurrY[t-1];
|
||||
} else
|
||||
{
|
||||
parent_x = cloud_x;
|
||||
parent_y = BRANCHES_CLOUD_Y;
|
||||
}
|
||||
for (int i = Children[t].size() - 1; i >= 0; i--)
|
||||
{
|
||||
child_id = Children[t][i];
|
||||
if (child_id < TOTAL_BOOKMARKS)
|
||||
{
|
||||
MoveToEx(hBitmapDC, parent_x, parent_y, 0);
|
||||
LineTo(hBitmapDC, BranchCurrX[child_id], BranchCurrY[child_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// lines for item under mouse
|
||||
SelectObject(hBitmapDC, select_pen);
|
||||
int branch = bookmarks.item_under_mouse;
|
||||
if (branch == TOTAL_BOOKMARKS)
|
||||
branch = current_branch;
|
||||
while (branch >= 0)
|
||||
{
|
||||
branch_x = BranchCurrX[branch];
|
||||
branch_y = BranchCurrY[branch];
|
||||
MoveToEx(hBitmapDC, branch_x, branch_y, 0);
|
||||
branch = parents[branch];
|
||||
if (branch >= 0)
|
||||
{
|
||||
branch_x = BranchCurrX[branch];
|
||||
branch_y = BranchCurrY[branch];
|
||||
} else
|
||||
{
|
||||
branch_x = cloud_x;
|
||||
branch_y = BRANCHES_CLOUD_Y;
|
||||
}
|
||||
LineTo(hBitmapDC, branch_x, branch_y);
|
||||
}
|
||||
if (changes_since_current_branch)
|
||||
{
|
||||
if (bookmarks.item_under_mouse != TOTAL_BOOKMARKS)
|
||||
SelectObject(hBitmapDC, normal_pen);
|
||||
if (current_branch >= 0)
|
||||
{
|
||||
parent_x = BranchCurrX[current_branch];
|
||||
parent_y = BranchCurrY[current_branch];
|
||||
} else
|
||||
{
|
||||
parent_x = cloud_x;
|
||||
parent_y = BRANCHES_CLOUD_Y;
|
||||
}
|
||||
MoveToEx(hBitmapDC, parent_x, parent_y, 0);
|
||||
branch_x = BranchCurrX[TOTAL_BOOKMARKS];
|
||||
branch_y = BranchCurrY[TOTAL_BOOKMARKS];
|
||||
LineTo(hBitmapDC, branch_x, branch_y);
|
||||
}
|
||||
|
||||
// cloud
|
||||
TransparentBlt(hBitmapDC, cloud_x - BRANCHES_CLOUD_HALFWIDTH, BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT, BRANCHES_CLOUD_WIDTH, BRANCHES_CLOUD_HEIGHT, hSpritesheetDC, BRANCHES_CLOUD_SPRITESHEET_X, BRANCHES_CLOUD_SPRITESHEET_Y, BRANCHES_CLOUD_WIDTH, BRANCHES_CLOUD_HEIGHT, 0x00FF00);
|
||||
|
||||
// branches rectangles
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
temp_rect.left = BranchCurrX[i] - DIGIT_RECT_HALFWIDTH;
|
||||
temp_rect.top = BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT;
|
||||
temp_rect.right = temp_rect.left + DIGIT_RECT_WIDTH;
|
||||
temp_rect.bottom = temp_rect.top + DIGIT_RECT_HEIGHT;
|
||||
if (bookmarks.bookmarks_array[i].flash_phase)
|
||||
{
|
||||
// draw colored rect
|
||||
HBRUSH color_brush = CreateSolidBrush(bookmark_flash_colors[bookmarks.bookmarks_array[i].flash_type][bookmarks.bookmarks_array[i].flash_phase]);
|
||||
FillRect(hBitmapDC, &temp_rect, color_brush);
|
||||
DeleteObject(color_brush);
|
||||
} else
|
||||
{
|
||||
// draw black rect
|
||||
FillRect(hBitmapDC, &temp_rect, normal_brush);
|
||||
}
|
||||
}
|
||||
// digits
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
branch_x = BranchCurrX[i] - DIGIT_BITMAP_HALFWIDTH;
|
||||
branch_y = BranchCurrY[i] - DIGIT_BITMAP_HALFHEIGHT;
|
||||
if(i == current_branch)
|
||||
{
|
||||
if (i == bookmarks.item_under_mouse)
|
||||
BitBlt(hBitmapDC, branch_x, branch_y, DIGIT_BITMAP_WIDTH, DIGIT_BITMAP_HEIGHT, hSpritesheetDC, i * DIGIT_BITMAP_WIDTH + BLUE_DIGITS_SPRITESHEET_DX, MOUSEOVER_DIGITS_SPRITESHEET_DY, SRCCOPY);
|
||||
else
|
||||
BitBlt(hBitmapDC, branch_x, branch_y, DIGIT_BITMAP_WIDTH, DIGIT_BITMAP_HEIGHT, hSpritesheetDC, i * DIGIT_BITMAP_WIDTH + BLUE_DIGITS_SPRITESHEET_DX, 0, SRCCOPY);
|
||||
} else
|
||||
{
|
||||
if (i == bookmarks.item_under_mouse)
|
||||
BitBlt(hBitmapDC, branch_x, branch_y, DIGIT_BITMAP_WIDTH, DIGIT_BITMAP_HEIGHT, hSpritesheetDC, i * DIGIT_BITMAP_WIDTH, MOUSEOVER_DIGITS_SPRITESHEET_DY, SRCCOPY);
|
||||
else
|
||||
BitBlt(hBitmapDC, branch_x, branch_y, DIGIT_BITMAP_WIDTH, DIGIT_BITMAP_HEIGHT, hSpritesheetDC, i * DIGIT_BITMAP_WIDTH, 0, SRCCOPY);
|
||||
}
|
||||
}
|
||||
SetBkMode(hBitmapDC, TRANSPARENT);
|
||||
// jump_frame of item under cursor (except cloud - it doesn't have particular frame)
|
||||
if (bookmarks.item_under_mouse > ITEM_UNDER_MOUSE_CLOUD)
|
||||
{
|
||||
char framenum_string[DIGITS_IN_FRAMENUM+1] = {0};
|
||||
if (bookmarks.item_under_mouse < TOTAL_BOOKMARKS)
|
||||
U32ToDecStr(framenum_string, bookmarks.bookmarks_array[bookmarks.item_under_mouse].snapshot.jump_frame, DIGITS_IN_FRAMENUM);
|
||||
else
|
||||
U32ToDecStr(framenum_string, currFrameCounter, DIGITS_IN_FRAMENUM);
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_SHADOW_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_FRAMENUM_X + 1, BRANCHES_BITMAP_FRAMENUM_Y + 1, (LPCSTR)framenum_string, DIGITS_IN_FRAMENUM);
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_FRAMENUM_X, BRANCHES_BITMAP_FRAMENUM_Y, (LPCSTR)framenum_string, DIGITS_IN_FRAMENUM);
|
||||
}
|
||||
// time of item under cursor
|
||||
if (bookmarks.item_under_mouse > ITEM_UNDER_MOUSE_NONE)
|
||||
{
|
||||
if (bookmarks.item_under_mouse == ITEM_UNDER_MOUSE_CLOUD)
|
||||
{
|
||||
// draw shadow of text
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_SHADOW_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X + 1, BRANCHES_BITMAP_TIME_Y + 1, (LPCSTR)cloud_time, TIME_DESC_LENGTH-1);
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X, BRANCHES_BITMAP_TIME_Y, (LPCSTR)cloud_time, TIME_DESC_LENGTH-1);
|
||||
} else if (bookmarks.item_under_mouse < TOTAL_BOOKMARKS)
|
||||
{
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_SHADOW_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X + 1, BRANCHES_BITMAP_TIME_Y + 1, (LPCSTR)bookmarks.bookmarks_array[bookmarks.item_under_mouse].snapshot.description, TIME_DESC_LENGTH-1);
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X, BRANCHES_BITMAP_TIME_Y, (LPCSTR)bookmarks.bookmarks_array[bookmarks.item_under_mouse].snapshot.description, TIME_DESC_LENGTH-1);
|
||||
} else // fireball - current_pos_time
|
||||
{
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_SHADOW_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X + 1, BRANCHES_BITMAP_TIME_Y + 1, (LPCSTR)current_pos_time, TIME_DESC_LENGTH-1);
|
||||
SetTextColor(hBitmapDC, BRANCHES_TEXT_COLOR);
|
||||
TextOut(hBitmapDC, BRANCHES_BITMAP_TIME_X, BRANCHES_BITMAP_TIME_Y, (LPCSTR)current_pos_time, TIME_DESC_LENGTH-1);
|
||||
}
|
||||
}
|
||||
// finished
|
||||
must_redraw_branches_tree = false;
|
||||
InvalidateRect(bookmarks.hwndBranchesBitmap, 0, FALSE);
|
||||
}
|
||||
|
||||
// this is called by wndproc on WM_PAINT
|
||||
void BRANCHES::PaintBranchesBitmap(HDC hdc)
|
||||
{
|
||||
int branch_x, branch_y;
|
||||
// "bg"
|
||||
BitBlt(hBufferDC, 0, 0, BRANCHES_BITMAP_WIDTH, BRANCHES_BITMAP_HEIGHT, hBitmapDC, 0, 0, SRCCOPY);
|
||||
// "sprites"
|
||||
// fireball
|
||||
if (fireball_size)
|
||||
{
|
||||
branch_x = BranchCurrX[TOTAL_BOOKMARKS] - BRANCHES_FIREBALL_HALFWIDTH;
|
||||
branch_y = BranchCurrY[TOTAL_BOOKMARKS] - BRANCHES_FIREBALL_HALFHEIGHT;
|
||||
if (fireball_size >= BRANCHES_FIREBALL_MAX_SIZE)
|
||||
{
|
||||
TransparentBlt(hBufferDC, branch_x, branch_y, BRANCHES_FIREBALL_WIDTH, BRANCHES_FIREBALL_HEIGHT, hSpritesheetDC, animation_frame * BRANCHES_FIREBALL_WIDTH + BRANCHES_FIREBALL_SPRITESHEET_X, BRANCHES_FIREBALL_SPRITESHEET_Y, BRANCHES_FIREBALL_WIDTH, BRANCHES_FIREBALL_HEIGHT, 0x00FF00);
|
||||
} else
|
||||
{
|
||||
TransparentBlt(hBufferDC, branch_x, branch_y, BRANCHES_FIREBALL_WIDTH, BRANCHES_FIREBALL_HEIGHT, hSpritesheetDC, BRANCHES_FIREBALL_SPRITESHEET_END_X - fireball_size * BRANCHES_FIREBALL_WIDTH, BRANCHES_FIREBALL_SPRITESHEET_Y, BRANCHES_FIREBALL_WIDTH, BRANCHES_FIREBALL_HEIGHT, 0x00FF00);
|
||||
}
|
||||
}
|
||||
// corners cursor
|
||||
branch_x = (CursorX * (BRANCHES_TRANSITION_MAX - transition_phase) + CursorPrevX * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
branch_y = (CursorY * (BRANCHES_TRANSITION_MAX - transition_phase) + CursorPrevY * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
int current_corners_cursor_shift = BRANCHES_CORNER_BASE_SHIFT + corners_cursor_shift[animation_frame];
|
||||
int corner_x, corner_y;
|
||||
// upper left
|
||||
corner_x = branch_x - current_corners_cursor_shift - BRANCHES_CORNER_HALFWIDTH;
|
||||
corner_y = branch_y - current_corners_cursor_shift - BRANCHES_CORNER_HALFHEIGHT;
|
||||
TransparentBlt(hBufferDC, corner_x, corner_y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, hSpritesheetDC, BRANCHES_CORNER1_SPRITESHEET_X, BRANCHES_CORNER1_SPRITESHEET_Y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, 0x00FF00);
|
||||
// upper right
|
||||
corner_x = branch_x + current_corners_cursor_shift - BRANCHES_CORNER_HALFWIDTH;
|
||||
corner_y = branch_y - current_corners_cursor_shift - BRANCHES_CORNER_HALFHEIGHT;
|
||||
TransparentBlt(hBufferDC, corner_x, corner_y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, hSpritesheetDC, BRANCHES_CORNER2_SPRITESHEET_X, BRANCHES_CORNER2_SPRITESHEET_Y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, 0x00FF00);
|
||||
// lower left
|
||||
corner_x = branch_x - current_corners_cursor_shift - BRANCHES_CORNER_HALFWIDTH;
|
||||
corner_y = branch_y + current_corners_cursor_shift - BRANCHES_CORNER_HALFHEIGHT;
|
||||
TransparentBlt(hBufferDC, corner_x, corner_y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, hSpritesheetDC, BRANCHES_CORNER3_SPRITESHEET_X, BRANCHES_CORNER3_SPRITESHEET_Y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, 0x00FF00);
|
||||
// lower right
|
||||
corner_x = branch_x + current_corners_cursor_shift - BRANCHES_CORNER_HALFWIDTH;
|
||||
corner_y = branch_y + current_corners_cursor_shift - BRANCHES_CORNER_HALFHEIGHT;
|
||||
TransparentBlt(hBufferDC, corner_x, corner_y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, hSpritesheetDC, BRANCHES_CORNER4_SPRITESHEET_X, BRANCHES_CORNER4_SPRITESHEET_Y, BRANCHES_CORNER_WIDTH, BRANCHES_CORNER_HEIGHT, 0x00FF00);
|
||||
// finish - paste buffer bitmap to screen
|
||||
BitBlt(hdc, 0, 0, BRANCHES_BITMAP_WIDTH, BRANCHES_BITMAP_HEIGHT, hBufferDC, 0, 0, SRCCOPY);
|
||||
}
|
||||
// ----------------------------------------------------------------------------------------
|
||||
int BRANCHES::GetCurrentBranch()
|
||||
{
|
||||
return current_branch;
|
||||
}
|
||||
|
||||
// this function finds best place for a new Bookmark in the Branches Tree
|
||||
void BRANCHES::HandleBookmarkSet(int slot, char* slot_time)
|
||||
{
|
||||
if (slot != current_branch)
|
||||
{
|
||||
// inherit current branch, forget previous parent
|
||||
int parent = parents[slot];
|
||||
if (parent == ITEM_UNDER_MOUSE_CLOUD && slot_time[0])
|
||||
{
|
||||
// check if this was the only child of cloud parent, if so then set cloud time to the saved_time
|
||||
int i = 0;
|
||||
for (; i < TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
if (bookmarks.bookmarks_array[i].not_empty && parents[i] == ITEM_UNDER_MOUSE_CLOUD && i != slot)
|
||||
break;
|
||||
}
|
||||
if (i >= TOTAL_BOOKMARKS)
|
||||
// didn't find another child of cloud, so after this slot disconnects, cloud will have 0 children
|
||||
// it will mean that old cloud disappears and new cloud is formed where the slot was
|
||||
strcpy(cloud_time, slot_time);
|
||||
}
|
||||
// before disconnecting from old parent, connect all childs to the old parent
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
if (bookmarks.bookmarks_array[i].not_empty && parents[i] == slot)
|
||||
parents[i] = parent;
|
||||
}
|
||||
parents[slot] = current_branch;
|
||||
}
|
||||
|
||||
// if parent is invalid (first_change < parent.jump_frame) then find better parent
|
||||
int factor = 0;
|
||||
// also if parent == cloud, then try to find better parent
|
||||
int parent = parents[slot];
|
||||
if (parent != ITEM_UNDER_MOUSE_CLOUD)
|
||||
factor = bookmarks.bookmarks_array[slot].snapshot.findFirstChange(bookmarks.bookmarks_array[parent].snapshot);
|
||||
if (parent == ITEM_UNDER_MOUSE_CLOUD || (factor >= 0 && factor < bookmarks.bookmarks_array[parent].snapshot.jump_frame))
|
||||
{
|
||||
// find highest frame of change
|
||||
std::vector<int> DecisiveFactor(TOTAL_BOOKMARKS);
|
||||
int best_branch = ITEM_UNDER_MOUSE_CLOUD;
|
||||
for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--)
|
||||
{
|
||||
if (i != slot && i != parent && bookmarks.bookmarks_array[i].not_empty && bookmarks.bookmarks_array[slot].snapshot.size >= bookmarks.bookmarks_array[i].snapshot.jump_frame)
|
||||
{
|
||||
factor = bookmarks.bookmarks_array[slot].snapshot.findFirstChange(bookmarks.bookmarks_array[i].snapshot);
|
||||
if (factor < 0)
|
||||
{
|
||||
// this branch is identical to this slot
|
||||
DecisiveFactor[i] = 2 * bookmarks.bookmarks_array[i].snapshot.size;
|
||||
} else if (factor >= bookmarks.bookmarks_array[i].snapshot.jump_frame)
|
||||
{
|
||||
// hey, this branch could be our new parent...
|
||||
DecisiveFactor[i] = 2 * factor;
|
||||
} else
|
||||
DecisiveFactor[i] = 0;
|
||||
} else
|
||||
{
|
||||
DecisiveFactor[i] = 0;
|
||||
}
|
||||
}
|
||||
// add +1 as a bonus to current parents and grandparents (a bit of nepotism here)
|
||||
while (parent >= 0)
|
||||
{
|
||||
if (DecisiveFactor[parent])
|
||||
DecisiveFactor[parent]++;
|
||||
parent = parents[parent];
|
||||
}
|
||||
// find max
|
||||
factor = 0;
|
||||
for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--)
|
||||
{
|
||||
if (DecisiveFactor[i] && DecisiveFactor[i] > factor)
|
||||
{
|
||||
factor = DecisiveFactor[i];
|
||||
best_branch = i;
|
||||
}
|
||||
}
|
||||
parent = parents[slot];
|
||||
if (parent != best_branch)
|
||||
{
|
||||
// before disconnecting from old parent, connect all childs to the old parent
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
{
|
||||
if (bookmarks.bookmarks_array[i].not_empty && parents[i] == slot)
|
||||
parents[i] = parent;
|
||||
}
|
||||
// found new parent
|
||||
parents[slot] = best_branch;
|
||||
must_recalculate_branches_tree = true;
|
||||
}
|
||||
}
|
||||
// switch current branch to this branch
|
||||
if (slot != current_branch || changes_since_current_branch)
|
||||
must_recalculate_branches_tree = true;
|
||||
current_branch = slot;
|
||||
changes_since_current_branch = false;
|
||||
}
|
||||
void BRANCHES::HandleBookmarkDeploy(int slot)
|
||||
{
|
||||
current_branch = slot;
|
||||
changes_since_current_branch = false;
|
||||
must_recalculate_branches_tree = true;
|
||||
}
|
||||
|
||||
void BRANCHES::ChangesMadeSinceBranch()
|
||||
{
|
||||
bool prev_changes_since_current_branch = changes_since_current_branch;
|
||||
changes_since_current_branch = true;
|
||||
SetCurrentPosTime();
|
||||
// recalculate branch tree if previous_changes = false
|
||||
if (!prev_changes_since_current_branch)
|
||||
must_recalculate_branches_tree = true;
|
||||
else if (bookmarks.item_under_mouse == TOTAL_BOOKMARKS)
|
||||
must_redraw_branches_tree = true; // to redraw fireball's time
|
||||
}
|
||||
|
||||
void BRANCHES::FindItemUnderMouse(int mouse_x, int mouse_y)
|
||||
{
|
||||
int prev_item_under_mouse = bookmarks.item_under_mouse;
|
||||
bookmarks.item_under_mouse = ITEM_UNDER_MOUSE_NONE;
|
||||
for (int i = 0; i < TOTAL_BOOKMARKS; ++i)
|
||||
if (bookmarks.item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= BranchCurrX[i] - DIGIT_RECT_HALFWIDTH_COLLISION && mouse_x < BranchCurrX[i] - DIGIT_RECT_HALFWIDTH_COLLISION + DIGIT_RECT_WIDTH_COLLISION && mouse_y >= BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT_COLLISION && mouse_y < BranchCurrY[i] - DIGIT_RECT_HALFHEIGHT_COLLISION + DIGIT_RECT_HEIGHT_COLLISION)
|
||||
bookmarks.item_under_mouse = i;
|
||||
if (bookmarks.item_under_mouse == ITEM_UNDER_MOUSE_NONE && mouse_x >= cloud_x - BRANCHES_CLOUD_HALFWIDTH && mouse_x < cloud_x - BRANCHES_CLOUD_HALFWIDTH + BRANCHES_CLOUD_WIDTH && mouse_y >= BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT && mouse_y < BRANCHES_CLOUD_Y - BRANCHES_CLOUD_HALFHEIGHT + BRANCHES_CLOUD_HEIGHT)
|
||||
bookmarks.item_under_mouse = ITEM_UNDER_MOUSE_CLOUD;
|
||||
if (bookmarks.item_under_mouse == ITEM_UNDER_MOUSE_NONE && changes_since_current_branch && mouse_x >= BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH_COLLISION && mouse_x < BranchCurrX[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFWIDTH_COLLISION + DIGIT_RECT_WIDTH_COLLISION && mouse_y >= BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT_COLLISION && mouse_y < BranchCurrY[TOTAL_BOOKMARKS] - DIGIT_RECT_HALFHEIGHT_COLLISION + DIGIT_RECT_HEIGHT_COLLISION)
|
||||
bookmarks.item_under_mouse = TOTAL_BOOKMARKS;
|
||||
if (prev_item_under_mouse != bookmarks.item_under_mouse)
|
||||
must_redraw_branches_tree = true;
|
||||
}
|
||||
|
||||
void BRANCHES::SetCurrentPosTime()
|
||||
{
|
||||
time_t raw_time;
|
||||
time(&raw_time);
|
||||
struct tm * timeinfo = localtime(&raw_time);
|
||||
strftime(current_pos_time, TIME_DESC_LENGTH, "%H:%M:%S", timeinfo);
|
||||
}
|
||||
|
||||
void BRANCHES::RecalculateBranchesTree()
|
||||
{
|
||||
// save previous values
|
||||
for (int i = TOTAL_BOOKMARKS; i >= 0; i--)
|
||||
{
|
||||
BranchPrevX[i] = (BranchX[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevX[i] * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
BranchPrevY[i] = (BranchY[i] * (BRANCHES_TRANSITION_MAX - transition_phase) + BranchPrevY[i] * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
}
|
||||
CloudPrevX = (CloudX * (BRANCHES_TRANSITION_MAX - transition_phase) + CloudPrevX * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
CursorPrevX = (CursorX * (BRANCHES_TRANSITION_MAX - transition_phase) + CursorPrevX * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
CursorPrevY = (CursorY * (BRANCHES_TRANSITION_MAX - transition_phase) + CursorPrevY * transition_phase) / BRANCHES_TRANSITION_MAX;
|
||||
transition_phase = BRANCHES_TRANSITION_MAX;
|
||||
|
||||
// 0. Prepare arrays
|
||||
GridX.resize(0);
|
||||
GridY.resize(0);
|
||||
Children.resize(0);
|
||||
GridHeight.resize(0);
|
||||
GridX.resize(TOTAL_BOOKMARKS+1);
|
||||
GridY.resize(TOTAL_BOOKMARKS+1);
|
||||
Children.resize(TOTAL_BOOKMARKS+2); // 0th subvector is for cloud's children
|
||||
GridHeight.resize(TOTAL_BOOKMARKS+1);
|
||||
for (int i = TOTAL_BOOKMARKS; i >= 0; i--)
|
||||
GridHeight[i] = 1;
|
||||
|
||||
// 1. Define GridX of branches (distribute to levels) and GridHeight of branches
|
||||
int current_grid_x = 0;
|
||||
std::vector<std::vector<int>> BranchesLevels;
|
||||
|
||||
std::vector<uint8> UndistributedBranches;
|
||||
UndistributedBranches.resize(TOTAL_BOOKMARKS);
|
||||
for (int i = UndistributedBranches.size()-1; i >= 0; i--)
|
||||
UndistributedBranches[i] = i;
|
||||
// remove all empty branches
|
||||
for (int i = UndistributedBranches.size()-1; i >= 0; i--)
|
||||
{
|
||||
if (!bookmarks.bookmarks_array[UndistributedBranches[i]].not_empty)
|
||||
UndistributedBranches.erase(UndistributedBranches.begin() + i);
|
||||
}
|
||||
// highest level: cloud (id = -1)
|
||||
BranchesLevels.resize(current_grid_x+1);
|
||||
BranchesLevels[current_grid_x].resize(1);
|
||||
BranchesLevels[current_grid_x][0] = ITEM_UNDER_MOUSE_CLOUD;
|
||||
// go lower until all branches are arranged to levels
|
||||
int current_parent;
|
||||
while(UndistributedBranches.size())
|
||||
{
|
||||
current_grid_x++;
|
||||
BranchesLevels.resize(current_grid_x+1);
|
||||
BranchesLevels[current_grid_x].resize(0);
|
||||
for (int t = BranchesLevels[current_grid_x-1].size()-1; t >= 0; t--)
|
||||
{
|
||||
current_parent = BranchesLevels[current_grid_x-1][t];
|
||||
for (int i = UndistributedBranches.size()-1; i >= 0; i--)
|
||||
{
|
||||
if (parents[UndistributedBranches[i]] == current_parent)
|
||||
{
|
||||
// assign this branch to current level
|
||||
GridX[UndistributedBranches[i]] = current_grid_x;
|
||||
BranchesLevels[current_grid_x].push_back(UndistributedBranches[i]);
|
||||
// also add it to parent's Children array
|
||||
Children[current_parent+1].push_back(UndistributedBranches[i]);
|
||||
UndistributedBranches.erase(UndistributedBranches.begin() + i);
|
||||
}
|
||||
}
|
||||
if (current_parent >= 0)
|
||||
{
|
||||
GridHeight[current_parent] = Children[current_parent+1].size();
|
||||
if (Children[current_parent+1].size() > 1)
|
||||
RecursiveAddHeight(parents[current_parent], GridHeight[current_parent] - 1);
|
||||
else
|
||||
GridHeight[current_parent] = 1; // its own height
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changes_since_current_branch)
|
||||
{
|
||||
// also define "current_pos" GridX
|
||||
if (current_branch >= 0)
|
||||
{
|
||||
if (Children[current_branch+1].size() < MAX_NUM_CHILDREN_ON_CANVAS_HEIGHT)
|
||||
{
|
||||
// "current_pos" becomes a child of current_branch
|
||||
GridX[TOTAL_BOOKMARKS] = GridX[current_branch] + 1;
|
||||
if ((int)BranchesLevels.size() <= GridX[TOTAL_BOOKMARKS])
|
||||
BranchesLevels.resize(GridX[TOTAL_BOOKMARKS] + 1);
|
||||
BranchesLevels[GridX[TOTAL_BOOKMARKS]].push_back(TOTAL_BOOKMARKS); // ID of "current_pos" = number of bookmarks
|
||||
Children[current_branch+1].push_back(TOTAL_BOOKMARKS);
|
||||
if (Children[current_branch+1].size() > 1)
|
||||
RecursiveAddHeight(current_branch, 1);
|
||||
} else
|
||||
{
|
||||
// special case 0: if there's too many children on one level (more than canvas can show)
|
||||
// then "current_pos" becomes special branch above current_branch
|
||||
GridX[TOTAL_BOOKMARKS] = GridX[current_branch];
|
||||
GridY[TOTAL_BOOKMARKS] = GridY[current_branch] - 7;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// special case 1: one and (presumably) only child of "cloud"
|
||||
GridX[TOTAL_BOOKMARKS] = 1;
|
||||
GridY[TOTAL_BOOKMARKS] = 0;
|
||||
if ((int)BranchesLevels.size() <= GridX[TOTAL_BOOKMARKS])
|
||||
BranchesLevels.resize(GridX[TOTAL_BOOKMARKS] + 1);
|
||||
BranchesLevels[GridX[TOTAL_BOOKMARKS]].push_back(TOTAL_BOOKMARKS);
|
||||
}
|
||||
}
|
||||
// define grid_width
|
||||
int grid_width, cloud_prefix = 0;
|
||||
if (BranchesLevels.size()-1 > 0)
|
||||
{
|
||||
grid_width = BRANCHES_CANVAS_WIDTH / (BranchesLevels.size()-1);
|
||||
if (grid_width < BRANCHES_GRID_MIN_WIDTH)
|
||||
grid_width = BRANCHES_GRID_MIN_WIDTH;
|
||||
else if (grid_width > BRANCHES_GRID_MAX_WIDTH)
|
||||
grid_width = BRANCHES_GRID_MAX_WIDTH;
|
||||
} else grid_width = BRANCHES_GRID_MAX_WIDTH;
|
||||
if (grid_width < MIN_CLOUD_LINE_LENGTH)
|
||||
cloud_prefix = MIN_CLOUD_LINE_LENGTH - grid_width;
|
||||
|
||||
// 2. Define GridY of branches
|
||||
RecursiveSetYPos(ITEM_UNDER_MOUSE_CLOUD, 0);
|
||||
// define grid_halfheight
|
||||
int grid_halfheight;
|
||||
int totalHeight = 0;
|
||||
for (int i = Children[0].size()-1; i >= 0; i--)
|
||||
totalHeight += GridHeight[Children[0][i]];
|
||||
if (totalHeight)
|
||||
{
|
||||
grid_halfheight = BRANCHES_CANVAS_HEIGHT / (2 * totalHeight);
|
||||
if (grid_halfheight < BRANCHES_GRID_MIN_HALFHEIGHT)
|
||||
grid_halfheight = BRANCHES_GRID_MIN_HALFHEIGHT;
|
||||
else if (grid_halfheight > BRANCHES_GRID_MAX_HALFHEIGHT)
|
||||
grid_halfheight = BRANCHES_GRID_MAX_HALFHEIGHT;
|
||||
} else grid_halfheight = BRANCHES_GRID_MAX_HALFHEIGHT;
|
||||
// special case 2: if chain of branches is too long, last item (normally it's fireball) goes up
|
||||
if (changes_since_current_branch)
|
||||
{
|
||||
if (GridX[TOTAL_BOOKMARKS] > MAX_CHAIN_LEN)
|
||||
{
|
||||
GridX[TOTAL_BOOKMARKS] = MAX_CHAIN_LEN;
|
||||
GridY[TOTAL_BOOKMARKS] -= 2;
|
||||
}
|
||||
}
|
||||
// special case 3: if some branch crosses upper or lower border
|
||||
int parent;
|
||||
for (int t = TOTAL_BOOKMARKS; t >= 0; t--)
|
||||
{
|
||||
if (GridY[t] > MAX_GRID_Y_POS)
|
||||
{
|
||||
if (t < TOTAL_BOOKMARKS)
|
||||
parent = parents[t];
|
||||
else
|
||||
parent = current_branch;
|
||||
int pos = MAX_GRID_Y_POS;
|
||||
for (int i = 0; i < (int)Children[parent+1].size(); ++i)
|
||||
{
|
||||
GridY[Children[parent+1][i]] = pos;
|
||||
pos -= 2;
|
||||
}
|
||||
} else if (GridY[t] < -MAX_GRID_Y_POS)
|
||||
{
|
||||
if (t < TOTAL_BOOKMARKS)
|
||||
parent = parents[t];
|
||||
else
|
||||
parent = current_branch;
|
||||
int pos = -MAX_GRID_Y_POS;
|
||||
for (int i = Children[parent+1].size()-1; i >= 0; i--)
|
||||
{
|
||||
GridY[Children[parent+1][i]] = pos;
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// special case 4: if cloud has all 10 children, then one child will be out of canvas
|
||||
if (Children[0].size() == TOTAL_BOOKMARKS)
|
||||
{
|
||||
// find this child and move it to be visible
|
||||
for (int t = TOTAL_BOOKMARKS - 1; t >= 0; t--)
|
||||
{
|
||||
if (GridY[t] > MAX_GRID_Y_POS)
|
||||
{
|
||||
GridY[t] = MAX_GRID_Y_POS;
|
||||
GridX[t] -= 2;
|
||||
// also move fireball to position near this branch
|
||||
if (changes_since_current_branch && current_branch == t)
|
||||
{
|
||||
GridY[TOTAL_BOOKMARKS] = GridY[t];
|
||||
GridX[TOTAL_BOOKMARKS] = GridX[t] + 1;
|
||||
}
|
||||
break;
|
||||
} else if (GridY[t] < -MAX_GRID_Y_POS)
|
||||
{
|
||||
GridY[t] = -MAX_GRID_Y_POS;
|
||||
GridX[t] -= 2;
|
||||
// also move fireball to position near this branch
|
||||
if (changes_since_current_branch && current_branch == t)
|
||||
{
|
||||
GridY[TOTAL_BOOKMARKS] = GridY[t];
|
||||
GridX[TOTAL_BOOKMARKS] = GridX[t] + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Set pixel positions of branches
|
||||
int max_x = 0;
|
||||
for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--)
|
||||
{
|
||||
if (bookmarks.bookmarks_array[i].not_empty)
|
||||
{
|
||||
BranchX[i] = cloud_prefix + GridX[i] * grid_width;
|
||||
BranchY[i] = BRANCHES_CLOUD_Y + GridY[i] * grid_halfheight;
|
||||
} else
|
||||
{
|
||||
BranchX[i] = EMPTY_BRANCHES_X;
|
||||
BranchY[i] = EMPTY_BRANCHES_Y_BASE + EMPTY_BRANCHES_Y_FACTOR * ((i + TOTAL_BOOKMARKS - 1) % TOTAL_BOOKMARKS);
|
||||
}
|
||||
if (max_x < BranchX[i]) max_x = BranchX[i];
|
||||
}
|
||||
if (changes_since_current_branch)
|
||||
{
|
||||
// also set pixel position of "current_pos"
|
||||
BranchX[TOTAL_BOOKMARKS] = cloud_prefix + GridX[TOTAL_BOOKMARKS] * grid_width;
|
||||
BranchY[TOTAL_BOOKMARKS] = BRANCHES_CLOUD_Y + GridY[TOTAL_BOOKMARKS] * grid_halfheight;
|
||||
} else if (current_branch >= 0)
|
||||
{
|
||||
BranchX[TOTAL_BOOKMARKS] = cloud_prefix + GridX[current_branch] * grid_width;
|
||||
BranchY[TOTAL_BOOKMARKS] = BRANCHES_CLOUD_Y + GridY[current_branch] * grid_halfheight;
|
||||
} else
|
||||
{
|
||||
BranchX[TOTAL_BOOKMARKS] = 0;
|
||||
BranchY[TOTAL_BOOKMARKS] = BRANCHES_CLOUD_Y;
|
||||
}
|
||||
if (max_x < BranchX[TOTAL_BOOKMARKS]) max_x = BranchX[TOTAL_BOOKMARKS];
|
||||
// align whole tree horizontally
|
||||
CloudX = (BRANCHES_BITMAP_WIDTH + 1 - max_x) / 2;
|
||||
if (CloudX < 0) CloudX = 0;
|
||||
for (int i = TOTAL_BOOKMARKS-1; i >= 0; i--)
|
||||
if (bookmarks.bookmarks_array[i].not_empty)
|
||||
BranchX[i] += CloudX;
|
||||
BranchX[TOTAL_BOOKMARKS] += CloudX;
|
||||
// target cursor
|
||||
CursorX = BranchX[TOTAL_BOOKMARKS];
|
||||
CursorY = BranchY[TOTAL_BOOKMARKS];
|
||||
// finished recalculating
|
||||
must_recalculate_branches_tree = false;
|
||||
must_redraw_branches_tree = true;
|
||||
}
|
||||
void BRANCHES::RecursiveAddHeight(int branch_num, int amount)
|
||||
{
|
||||
if (branch_num >= 0)
|
||||
{
|
||||
GridHeight[branch_num] += amount;
|
||||
if (parents[branch_num] >= 0)
|
||||
RecursiveAddHeight(parents[branch_num], amount);
|
||||
}
|
||||
}
|
||||
void BRANCHES::RecursiveSetYPos(int parent, int parentY)
|
||||
{
|
||||
if (Children[parent+1].size())
|
||||
{
|
||||
// find total height of children
|
||||
int totalHeight = 0;
|
||||
for (int i = Children[parent+1].size()-1; i >= 0; i--)
|
||||
totalHeight += GridHeight[Children[parent+1][i]];
|
||||
// set Y of children and subchildren
|
||||
for (int i = Children[parent+1].size()-1; i >= 0; i--)
|
||||
{
|
||||
int child_id = Children[parent+1][i];
|
||||
GridY[child_id] = parentY + GridHeight[child_id] - totalHeight;
|
||||
RecursiveSetYPos(child_id, GridY[child_id]);
|
||||
parentY += 2 * GridHeight[child_id];
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------------------
|
||||
LRESULT APIENTRY BranchesBitmapWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
extern BRANCHES branches;
|
||||
switch(msg)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!bookmarks.mouse_over_bitmap)
|
||||
{
|
||||
bookmarks.mouse_over_bitmap = true;
|
||||
bookmarks.tme.hwndTrack = hWnd;
|
||||
TrackMouseEvent(&bookmarks.tme);
|
||||
}
|
||||
bookmarks.MouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
break;
|
||||
}
|
||||
case WM_MOUSELEAVE:
|
||||
{
|
||||
bookmarks.mouse_over_bitmap = false;
|
||||
bookmarks.MouseMove(-1, -1);
|
||||
break;
|
||||
}
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
branches.PaintBranchesBitmap(BeginPaint(hWnd, &ps));
|
||||
EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
{
|
||||
if (GetFocus() != hWnd)
|
||||
SetFocus(hWnd);
|
||||
return 0;
|
||||
}
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
{
|
||||
if (GetFocus() != hWnd)
|
||||
SetFocus(hWnd);
|
||||
playback.MiddleButtonClick();
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
return SendMessage(piano_roll.hwndList, msg, wParam, lParam);
|
||||
|
||||
}
|
||||
return CallWindowProc(hwndBranchesBitmap_oldWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
// Specification file for Branches class
|
||||
|
||||
#define BRANCHES_ANIMATION_TICK 50 // animate at 20FPS
|
||||
#define BRANCHES_TRANSITION_MAX 8
|
||||
|
||||
// branches bitmap
|
||||
#define BRANCHES_BITMAP_WIDTH 170
|
||||
#define BRANCHES_BITMAP_HEIGHT 145
|
||||
#define BRANCHES_ANIMATION_FRAMES 12
|
||||
#define BRANCHES_BITMAP_FRAMENUM_X 2
|
||||
#define BRANCHES_BITMAP_FRAMENUM_Y 1
|
||||
#define BRANCHES_BITMAP_TIME_X 2
|
||||
#define BRANCHES_BITMAP_TIME_Y BRANCHES_BITMAP_HEIGHT - 17
|
||||
#define BRANCHES_TEXT_SHADOW_COLOR 0xFFFFFF
|
||||
#define BRANCHES_TEXT_COLOR 0x7F0000
|
||||
// constants for drawing branches tree
|
||||
#define BRANCHES_CANVAS_WIDTH 146
|
||||
#define BRANCHES_CANVAS_HEIGHT 130
|
||||
#define BRANCHES_CLOUD_X 14
|
||||
#define BRANCHES_CLOUD_Y 72
|
||||
#define BRANCHES_GRID_MIN_WIDTH 14
|
||||
#define BRANCHES_GRID_MAX_WIDTH 30
|
||||
#define MIN_CLOUD_LINE_LENGTH 19
|
||||
#define BRANCHES_GRID_MIN_HALFHEIGHT 8
|
||||
#define BRANCHES_GRID_MAX_HALFHEIGHT 12
|
||||
#define EMPTY_BRANCHES_X -6
|
||||
#define EMPTY_BRANCHES_Y_BASE 8
|
||||
#define EMPTY_BRANCHES_Y_FACTOR 14
|
||||
#define MAX_NUM_CHILDREN_ON_CANVAS_HEIGHT 9
|
||||
#define MAX_CHAIN_LEN 10
|
||||
#define MAX_GRID_Y_POS 8
|
||||
// spritesheet
|
||||
#define DIGIT_BITMAP_WIDTH 9
|
||||
#define DIGIT_BITMAP_HALFWIDTH DIGIT_BITMAP_WIDTH/2
|
||||
#define DIGIT_BITMAP_HEIGHT 13
|
||||
#define DIGIT_BITMAP_HALFHEIGHT DIGIT_BITMAP_HEIGHT/2
|
||||
#define BLUE_DIGITS_SPRITESHEET_DX DIGIT_BITMAP_WIDTH*TOTAL_BOOKMARKS
|
||||
#define MOUSEOVER_DIGITS_SPRITESHEET_DY DIGIT_BITMAP_HEIGHT
|
||||
#define DIGIT_RECT_WIDTH 11
|
||||
#define DIGIT_RECT_WIDTH_COLLISION (DIGIT_RECT_WIDTH + 2)
|
||||
#define DIGIT_RECT_HALFWIDTH DIGIT_RECT_WIDTH/2
|
||||
#define DIGIT_RECT_HALFWIDTH_COLLISION (DIGIT_RECT_HALFWIDTH + 1)
|
||||
#define DIGIT_RECT_HEIGHT 15
|
||||
#define DIGIT_RECT_HEIGHT_COLLISION (DIGIT_RECT_HEIGHT + 2)
|
||||
#define DIGIT_RECT_HALFHEIGHT DIGIT_RECT_HEIGHT/2
|
||||
#define DIGIT_RECT_HALFHEIGHT_COLLISION (DIGIT_RECT_HALFHEIGHT + 1)
|
||||
#define BRANCHES_CLOUD_WIDTH 26
|
||||
#define BRANCHES_CLOUD_HALFWIDTH BRANCHES_CLOUD_WIDTH/2
|
||||
#define BRANCHES_CLOUD_HEIGHT 15
|
||||
#define BRANCHES_CLOUD_HALFHEIGHT BRANCHES_CLOUD_HEIGHT/2
|
||||
#define BRANCHES_CLOUD_SPRITESHEET_X 180
|
||||
#define BRANCHES_CLOUD_SPRITESHEET_Y 0
|
||||
#define BRANCHES_FIREBALL_WIDTH 10
|
||||
#define BRANCHES_FIREBALL_HALFWIDTH BRANCHES_FIREBALL_WIDTH/2
|
||||
#define BRANCHES_FIREBALL_HEIGHT 10
|
||||
#define BRANCHES_FIREBALL_HALFHEIGHT BRANCHES_FIREBALL_HEIGHT/2
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_X 0
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_Y 26
|
||||
#define BRANCHES_FIREBALL_MAX_SIZE 5
|
||||
#define BRANCHES_FIREBALL_SPRITESHEET_END_X 160
|
||||
#define BRANCHES_CORNER_WIDTH 7
|
||||
#define BRANCHES_CORNER_HALFWIDTH BRANCHES_CORNER_WIDTH/2
|
||||
#define BRANCHES_CORNER_HEIGHT 7
|
||||
#define BRANCHES_CORNER_HALFHEIGHT BRANCHES_CORNER_HEIGHT/2
|
||||
#define BRANCHES_CORNER1_SPRITESHEET_X 206
|
||||
#define BRANCHES_CORNER1_SPRITESHEET_Y 0
|
||||
#define BRANCHES_CORNER2_SPRITESHEET_X 213
|
||||
#define BRANCHES_CORNER2_SPRITESHEET_Y 0
|
||||
#define BRANCHES_CORNER3_SPRITESHEET_X 206
|
||||
#define BRANCHES_CORNER3_SPRITESHEET_Y 7
|
||||
#define BRANCHES_CORNER4_SPRITESHEET_X 213
|
||||
#define BRANCHES_CORNER4_SPRITESHEET_Y 7
|
||||
#define BRANCHES_CORNER_BASE_SHIFT 6
|
||||
|
||||
class BRANCHES
|
||||
{
|
||||
public:
|
||||
BRANCHES();
|
||||
void init();
|
||||
void free();
|
||||
void reset();
|
||||
void reset_vars();
|
||||
void update();
|
||||
|
||||
void save(EMUFILE *os);
|
||||
bool load(EMUFILE *is);
|
||||
|
||||
int GetCurrentBranch();
|
||||
|
||||
void RedrawBranchesTree();
|
||||
void PaintBranchesBitmap(HDC hdc);
|
||||
|
||||
void HandleBookmarkSet(int slot, char* slot_time);
|
||||
void HandleBookmarkDeploy(int slot);
|
||||
void ChangesMadeSinceBranch();
|
||||
|
||||
void FindItemUnderMouse(int mouse_x, int mouse_y);
|
||||
|
||||
void RecalculateBranchesTree();
|
||||
void RecursiveAddHeight(int branch_num, int amount);
|
||||
void RecursiveSetYPos(int parent, int parentY);
|
||||
|
||||
// saved vars
|
||||
std::vector<int> parents;
|
||||
|
||||
// not saved vars
|
||||
bool must_redraw_branches_tree;
|
||||
bool must_recalculate_branches_tree;
|
||||
|
||||
private:
|
||||
void SetCurrentPosTime();
|
||||
|
||||
// also saved vars
|
||||
int current_branch;
|
||||
bool changes_since_current_branch;
|
||||
char cloud_time[TIME_DESC_LENGTH];
|
||||
char current_pos_time[TIME_DESC_LENGTH];
|
||||
|
||||
// not saved vars
|
||||
int animation_frame;
|
||||
int next_animation_time;
|
||||
std::vector<int> BranchX; // in pixels
|
||||
std::vector<int> BranchY;
|
||||
std::vector<int> BranchPrevX;
|
||||
std::vector<int> BranchPrevY;
|
||||
std::vector<int> BranchCurrX;
|
||||
std::vector<int> BranchCurrY;
|
||||
int CloudX, CloudPrevX, cloud_x;
|
||||
int CursorX, CursorPrevX, CursorY, CursorPrevY;
|
||||
int transition_phase;
|
||||
int fireball_size;
|
||||
|
||||
// GDI stuff
|
||||
HBRUSH normal_brush;
|
||||
RECT temp_rect;
|
||||
HPEN normal_pen, select_pen;
|
||||
HBITMAP branches_hbitmap, hOldBitmap, buffer_hbitmap, hOldBitmap1, branchesSpritesheet, hOldBitmap2;
|
||||
HDC hBitmapDC, hBufferDC, hSpritesheetDC;
|
||||
|
||||
// temps
|
||||
std::vector<int> GridX; // in grid units
|
||||
std::vector<int> GridY;
|
||||
std::vector<int> GridHeight;
|
||||
std::vector<std::vector<uint8>> Children;
|
||||
|
||||
};
|
|
@ -152,7 +152,7 @@ bool EDITOR::ReadString(EMUFILE *is, std::string& dest)
|
|||
}
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
// following functions use function parameters to determine range of frames
|
||||
void EDITOR::InputToggle(int start, int end, int joy, int button)
|
||||
void EDITOR::InputToggle(int start, int end, int joy, int button, int consecutive_tag)
|
||||
{
|
||||
if (joy < 0 || joy >= joysticks_per_frame[GetInputType(currMovieData)]) return;
|
||||
|
||||
|
@ -173,16 +173,16 @@ void EDITOR::InputToggle(int start, int end, int joy, int button)
|
|||
// clear range
|
||||
for (int i = start; i <= end; ++i)
|
||||
currMovieData.records[i].clearBit(joy, button);
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, start, end));
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, start, end, NULL, consecutive_tag));
|
||||
} else
|
||||
{
|
||||
// set range
|
||||
for (int i = start; i <= end; ++i)
|
||||
currMovieData.records[i].setBit(joy, button);
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, start, end));
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, start, end, NULL, consecutive_tag));
|
||||
}
|
||||
}
|
||||
void EDITOR::InputSetPattern(int start, int end, int joy, int button)
|
||||
void EDITOR::InputSetPattern(int start, int end, int joy, int button, int consecutive_tag)
|
||||
{
|
||||
if (joy < 0 || joy >= joysticks_per_frame[GetInputType(currMovieData)]) return;
|
||||
|
||||
|
@ -209,7 +209,7 @@ void EDITOR::InputSetPattern(int start, int end, int joy, int button)
|
|||
if (pattern_offset >= (int)autofire_patterns[current_pattern].size())
|
||||
pattern_offset -= autofire_patterns[current_pattern].size();
|
||||
}
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PATTERN, start, end, autofire_patterns_names[current_pattern].c_str()));
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_PATTERN, start, end, autofire_patterns_names[current_pattern].c_str(), consecutive_tag));
|
||||
}
|
||||
|
||||
// following functions use current Selection to determine range of frames
|
||||
|
|
|
@ -9,8 +9,8 @@ public:
|
|||
void reset();
|
||||
void update();
|
||||
|
||||
void InputToggle(int start, int end, int joy, int button);
|
||||
void InputSetPattern(int start, int end, int joy, int button);
|
||||
void InputToggle(int start, int end, int joy, int button, int consecutive_tag = 0);
|
||||
void InputSetPattern(int start, int end, int joy, int button, int consecutive_tag = 0);
|
||||
|
||||
bool FrameColumnSet();
|
||||
bool FrameColumnSetPattern();
|
||||
|
|
|
@ -29,6 +29,7 @@ extern TASEDITOR_CONFIG taseditor_config;
|
|||
extern TASEDITOR_WINDOW taseditor_window;
|
||||
extern MARKERS_MANAGER markers_manager;
|
||||
extern BOOKMARKS bookmarks;
|
||||
extern BRANCHES branches;
|
||||
extern PLAYBACK playback;
|
||||
extern SELECTION selection;
|
||||
extern GREENZONE greenzone;
|
||||
|
@ -130,6 +131,8 @@ void HISTORY::reset()
|
|||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
strcat(inp.description, modCaptions[MODTYPE_INIT]);
|
||||
inp.jump_frame = -1;
|
||||
inp.start_frame = 0;
|
||||
inp.end_frame = inp.size - 1;
|
||||
AddSnapshotToHistory(inp);
|
||||
UpdateHistoryList();
|
||||
RedrawHistoryList();
|
||||
|
@ -224,13 +227,13 @@ int HISTORY::jump(int new_pos)
|
|||
{
|
||||
snapshots[real_pos].toMovie(currMovieData, first_change);
|
||||
selection.must_find_current_marker = playback.must_find_current_marker = true;
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
// and Piano Roll will be redrawn by greenzone invalidation
|
||||
} else if (markers_changed)
|
||||
{
|
||||
markers_manager.update();
|
||||
selection.must_find_current_marker = playback.must_find_current_marker = true;
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
piano_roll.RedrawList();
|
||||
piano_roll.FollowUndo();
|
||||
} else if (taseditor_config.enable_hot_changes)
|
||||
|
@ -287,12 +290,11 @@ void HISTORY::AddSnapshotToHistory(SNAPSHOT &inp)
|
|||
}
|
||||
|
||||
// returns frame of first actual change
|
||||
int HISTORY::RegisterChanges(int mod_type, int start, int end, const char* comment)
|
||||
int HISTORY::RegisterChanges(int mod_type, int start, int end, const char* comment, int consecutive_tag)
|
||||
{
|
||||
// create new shanshot
|
||||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.mod_type = mod_type;
|
||||
// check if there are input differences from latest snapshot
|
||||
int real_pos = (history_start_pos + history_cursor_pos) % history_size;
|
||||
int first_changes = inp.findFirstChange(snapshots[real_pos], start, end);
|
||||
|
@ -300,7 +302,8 @@ int HISTORY::RegisterChanges(int mod_type, int start, int end, const char* comme
|
|||
{
|
||||
// differences found
|
||||
// fill description:
|
||||
strcat(inp.description, modCaptions[mod_type]);
|
||||
inp.mod_type = mod_type;
|
||||
strcat(inp.description, modCaptions[inp.mod_type]);
|
||||
switch (mod_type)
|
||||
{
|
||||
case MODTYPE_SET:
|
||||
|
@ -323,53 +326,97 @@ int HISTORY::RegisterChanges(int mod_type, int start, int end, const char* comme
|
|||
break;
|
||||
}
|
||||
}
|
||||
// add upper and lower frame to description
|
||||
char framenum[11];
|
||||
_itoa(start, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
strcat(inp.description, framenum);
|
||||
if (end > start)
|
||||
{
|
||||
_itoa(end, framenum, 10);
|
||||
strcat(inp.description, "-");
|
||||
strcat(inp.description, framenum);
|
||||
}
|
||||
// add comment if there is one specified
|
||||
if (comment)
|
||||
inp.start_frame = start;
|
||||
inp.end_frame = end;
|
||||
inp.consecutive_tag = consecutive_tag;
|
||||
if (consecutive_tag && taseditor_config.combine_consecutive && snapshots[real_pos].mod_type == inp.mod_type && snapshots[real_pos].consecutive_tag == inp.consecutive_tag)
|
||||
{
|
||||
// combine with previous snapshot
|
||||
if (inp.jump_frame > snapshots[real_pos].jump_frame)
|
||||
inp.jump_frame = snapshots[real_pos].jump_frame;
|
||||
if (inp.start_frame > snapshots[real_pos].start_frame)
|
||||
inp.start_frame = snapshots[real_pos].start_frame;
|
||||
if (inp.end_frame < snapshots[real_pos].end_frame)
|
||||
inp.end_frame = snapshots[real_pos].end_frame;
|
||||
// add upper and lower frame to description
|
||||
char framenum[11];
|
||||
strcat(inp.description, " ");
|
||||
strncat(inp.description, comment, SNAPSHOT_DESC_MAX_LENGTH - strlen(inp.description) - 1);
|
||||
}
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
{
|
||||
// inherit previous hotchanges and set new changes
|
||||
switch (mod_type)
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
if (inp.end_frame > inp.start_frame)
|
||||
{
|
||||
case MODTYPE_DELETE:
|
||||
inp.inheritHotChanges_DeleteSelection(&snapshots[real_pos]);
|
||||
break;
|
||||
case MODTYPE_INSERT:
|
||||
case MODTYPE_CLONE:
|
||||
inp.inheritHotChanges_InsertSelection(&snapshots[real_pos]);
|
||||
break;
|
||||
case MODTYPE_SET:
|
||||
case MODTYPE_UNSET:
|
||||
case MODTYPE_CLEAR:
|
||||
case MODTYPE_CUT:
|
||||
case MODTYPE_PASTE:
|
||||
case MODTYPE_PATTERN:
|
||||
inp.inheritHotChanges(&snapshots[real_pos]);
|
||||
inp.fillHotChanges(snapshots[real_pos], first_changes, end);
|
||||
break;
|
||||
case MODTYPE_TRUNCATE:
|
||||
inp.copyHotChanges(&snapshots[real_pos]);
|
||||
// do not add new hotchanges and do not fade old hotchanges, because there was nothing added
|
||||
break;
|
||||
strcat(inp.description, "-");
|
||||
_itoa(inp.end_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
}
|
||||
// add comment if there is one specified
|
||||
if (comment)
|
||||
{
|
||||
strcat(inp.description, " ");
|
||||
strncat(inp.description, comment, SNAPSHOT_DESC_MAX_LENGTH - strlen(inp.description) - 1);
|
||||
}
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
{
|
||||
inp.copyHotChanges(&snapshots[real_pos]);
|
||||
inp.fillHotChanges(snapshots[real_pos], first_changes, end);
|
||||
}
|
||||
// replace current snapshot with this cloned snapshot and truncate history here
|
||||
snapshots[real_pos] = inp;
|
||||
history_total_items = history_cursor_pos+1;
|
||||
UpdateHistoryList();
|
||||
RedrawHistoryList();
|
||||
} else
|
||||
{
|
||||
// don't combine
|
||||
// add upper and lower frame to description
|
||||
char framenum[11];
|
||||
strcat(inp.description, " ");
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
if (inp.end_frame > inp.start_frame)
|
||||
{
|
||||
strcat(inp.description, "-");
|
||||
_itoa(inp.end_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
}
|
||||
// add comment if there is one specified
|
||||
if (comment)
|
||||
{
|
||||
strcat(inp.description, " ");
|
||||
strncat(inp.description, comment, SNAPSHOT_DESC_MAX_LENGTH - strlen(inp.description) - 1);
|
||||
}
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
{
|
||||
// inherit previous hotchanges and set new changes
|
||||
switch (mod_type)
|
||||
{
|
||||
case MODTYPE_DELETE:
|
||||
inp.inheritHotChanges_DeleteSelection(&snapshots[real_pos]);
|
||||
break;
|
||||
case MODTYPE_INSERT:
|
||||
case MODTYPE_CLONE:
|
||||
inp.inheritHotChanges_InsertSelection(&snapshots[real_pos]);
|
||||
break;
|
||||
case MODTYPE_SET:
|
||||
case MODTYPE_UNSET:
|
||||
case MODTYPE_CLEAR:
|
||||
case MODTYPE_CUT:
|
||||
case MODTYPE_PASTE:
|
||||
case MODTYPE_PATTERN:
|
||||
inp.inheritHotChanges(&snapshots[real_pos]);
|
||||
inp.fillHotChanges(snapshots[real_pos], first_changes, end);
|
||||
break;
|
||||
case MODTYPE_TRUNCATE:
|
||||
inp.copyHotChanges(&snapshots[real_pos]);
|
||||
// do not add new hotchanges and do not fade old hotchanges, because there was nothing added
|
||||
break;
|
||||
}
|
||||
}
|
||||
AddSnapshotToHistory(inp);
|
||||
}
|
||||
AddSnapshotToHistory(inp);
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
}
|
||||
return first_changes;
|
||||
}
|
||||
|
@ -378,7 +425,6 @@ int HISTORY::RegisterInsertNum(int start, int frames)
|
|||
// create new shanshot
|
||||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.mod_type = MODTYPE_INSERTNUM;
|
||||
// check if there are input differences from latest snapshot
|
||||
int real_pos = (history_start_pos + history_cursor_pos) % history_size;
|
||||
int first_changes = inp.findFirstChange(snapshots[real_pos], start);
|
||||
|
@ -386,21 +432,24 @@ int HISTORY::RegisterInsertNum(int start, int frames)
|
|||
{
|
||||
// differences found
|
||||
// fill description:
|
||||
inp.mod_type = MODTYPE_INSERTNUM;
|
||||
strcat(inp.description, modCaptions[inp.mod_type]);
|
||||
inp.jump_frame = start;
|
||||
inp.start_frame = start;
|
||||
inp.end_frame = start + frames - 1;
|
||||
char framenum[11];
|
||||
// add number of inserted frames to description
|
||||
_itoa(frames, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// add upper frame to description
|
||||
_itoa(start, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
inp.inheritHotChanges_InsertNum(&snapshots[real_pos], start, frames);
|
||||
AddSnapshotToHistory(inp);
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
}
|
||||
return first_changes;
|
||||
}
|
||||
|
@ -409,7 +458,6 @@ int HISTORY::RegisterPasteInsert(int start, SelectionFrames& inserted_set)
|
|||
// create new shanshot
|
||||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.mod_type = MODTYPE_PASTEINSERT;
|
||||
// check if there are input differences from latest snapshot
|
||||
int real_pos = (history_start_pos + history_cursor_pos) % history_size;
|
||||
int first_changes = inp.findFirstChange(snapshots[real_pos], start);
|
||||
|
@ -417,19 +465,22 @@ int HISTORY::RegisterPasteInsert(int start, SelectionFrames& inserted_set)
|
|||
{
|
||||
// differences found
|
||||
// fill description:
|
||||
inp.mod_type = MODTYPE_PASTEINSERT;
|
||||
strcat(inp.description, modCaptions[inp.mod_type]);
|
||||
// for PasteInsert user prefers to see frame of attempted change (selection beginning), not frame of actual differences
|
||||
inp.jump_frame = start;
|
||||
inp.start_frame = start;
|
||||
inp.end_frame = -1;
|
||||
// add upper frame to description
|
||||
char framenum[11];
|
||||
_itoa(start, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
inp.inheritHotChanges_PasteInsert(&snapshots[real_pos], inserted_set);
|
||||
AddSnapshotToHistory(inp);
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
}
|
||||
return first_changes;
|
||||
}
|
||||
|
@ -438,16 +489,18 @@ void HISTORY::RegisterMarkersChange(int mod_type, int start, int end, const char
|
|||
// create new shanshot
|
||||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.mod_type = mod_type;
|
||||
// fill description:
|
||||
inp.mod_type = mod_type;
|
||||
strcat(inp.description, modCaptions[mod_type]);
|
||||
inp.jump_frame = start;
|
||||
inp.start_frame = start;
|
||||
inp.end_frame = end;
|
||||
// add the frame to description
|
||||
char framenum[11];
|
||||
_itoa(start, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
if (end > start || mod_type == MODTYPE_MARKER_DRAG || mod_type == MODTYPE_MARKER_SWAP)
|
||||
if (inp.end_frame > inp.start_frame || mod_type == MODTYPE_MARKER_DRAG || mod_type == MODTYPE_MARKER_SWAP)
|
||||
{
|
||||
if (mod_type == MODTYPE_MARKER_DRAG)
|
||||
strcat(inp.description, "=>");
|
||||
|
@ -455,7 +508,7 @@ void HISTORY::RegisterMarkersChange(int mod_type, int start, int end, const char
|
|||
strcat(inp.description, "<=>");
|
||||
else
|
||||
strcat(inp.description, "-");
|
||||
_itoa(end, framenum, 10);
|
||||
_itoa(inp.end_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
}
|
||||
// add comment if there is one specified
|
||||
|
@ -468,7 +521,7 @@ void HISTORY::RegisterMarkersChange(int mod_type, int start, int end, const char
|
|||
if (taseditor_config.enable_hot_changes)
|
||||
inp.copyHotChanges(&GetCurrentSnapshot());
|
||||
AddSnapshotToHistory(inp);
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
project.SetProjectChanged();
|
||||
}
|
||||
void HISTORY::RegisterBranching(int mod_type, int first_change, int slot)
|
||||
|
@ -481,6 +534,8 @@ void HISTORY::RegisterBranching(int mod_type, int first_change, int slot)
|
|||
strcat(inp.description, modCaptions[mod_type]);
|
||||
strcat(inp.description, bookmarks.bookmarks_array[slot].snapshot.description);
|
||||
inp.jump_frame = first_change;
|
||||
inp.start_frame = first_change;
|
||||
inp.end_frame = -1;
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
{
|
||||
if (mod_type < MODTYPE_BRANCH_MARKERS_0)
|
||||
|
@ -509,18 +564,21 @@ void HISTORY::RegisterRecording(int frame_of_change)
|
|||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.fillJoypadsDiff(snapshots[real_pos], frame_of_change);
|
||||
// fill description:
|
||||
inp.mod_type = MODTYPE_RECORD;
|
||||
strcat(inp.description, modCaptions[MODTYPE_RECORD]);
|
||||
char framenum[11];
|
||||
// check if current snapshot is also Recording and maybe it is consecutive recording
|
||||
if (taseditor_config.combine_consecutive_rec
|
||||
if (taseditor_config.combine_consecutive
|
||||
&& snapshots[real_pos].mod_type == MODTYPE_RECORD // a) also Recording
|
||||
&& snapshots[real_pos].rec_end_frame+1 == frame_of_change // b) consecutive
|
||||
&& snapshots[real_pos].consecutive_tag == frame_of_change - 1 // b) consecutive (previous frame)
|
||||
&& snapshots[real_pos].rec_joypad_diff_bits == inp.rec_joypad_diff_bits) // c) recorded same set of joysticks
|
||||
{
|
||||
// clone this snapshot and continue chain of recorded frames
|
||||
inp.jump_frame = snapshots[real_pos].jump_frame;
|
||||
inp.rec_end_frame = frame_of_change;
|
||||
inp.start_frame = snapshots[real_pos].jump_frame;
|
||||
inp.end_frame = frame_of_change;
|
||||
inp.consecutive_tag = frame_of_change;
|
||||
// add info which joypads were affected
|
||||
int num = joysticks_per_frame[inp.input_type];
|
||||
uint32 current_mask = 1;
|
||||
|
@ -531,11 +589,11 @@ void HISTORY::RegisterRecording(int frame_of_change)
|
|||
current_mask <<= 1;
|
||||
}
|
||||
// add upper and lower frame to description
|
||||
_itoa(inp.jump_frame, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(inp.start_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
_itoa(frame_of_change, framenum, 10);
|
||||
strcat(inp.description, "-");
|
||||
_itoa(inp.end_frame, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
|
@ -551,7 +609,7 @@ void HISTORY::RegisterRecording(int frame_of_change)
|
|||
} else
|
||||
{
|
||||
// not consecutive - add new snapshot to history
|
||||
inp.jump_frame = inp.rec_end_frame = frame_of_change;
|
||||
inp.jump_frame = inp.start_frame = inp.end_frame = inp.consecutive_tag = frame_of_change;
|
||||
// add info which joypads were affected
|
||||
int num = joysticks_per_frame[inp.input_type];
|
||||
uint32 current_mask = 1;
|
||||
|
@ -562,8 +620,8 @@ void HISTORY::RegisterRecording(int frame_of_change)
|
|||
current_mask <<= 1;
|
||||
}
|
||||
// add upper frame to description
|
||||
_itoa(frame_of_change, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(frame_of_change, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
|
@ -573,7 +631,7 @@ void HISTORY::RegisterRecording(int frame_of_change)
|
|||
}
|
||||
AddSnapshotToHistory(inp);
|
||||
}
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
}
|
||||
void HISTORY::RegisterImport(MovieData& md, char* filename)
|
||||
{
|
||||
|
@ -586,9 +644,11 @@ void HISTORY::RegisterImport(MovieData& md, char* filename)
|
|||
if (first_changes >= 0)
|
||||
{
|
||||
// differences found
|
||||
inp.mod_type = MODTYPE_IMPORT;
|
||||
inp.jump_frame = first_changes;
|
||||
inp.start_frame = 0;
|
||||
inp.end_frame = inp.size - 1;
|
||||
// fill description:
|
||||
inp.mod_type = MODTYPE_IMPORT;
|
||||
strcat(inp.description, modCaptions[inp.mod_type]);
|
||||
// add filename to description
|
||||
strcat(inp.description, " ");
|
||||
|
@ -601,7 +661,7 @@ void HISTORY::RegisterImport(MovieData& md, char* filename)
|
|||
AddSnapshotToHistory(inp);
|
||||
inp.toMovie(currMovieData);
|
||||
piano_roll.UpdateItemCount();
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
project.SetProjectChanged();
|
||||
greenzone.InvalidateAndCheck(first_changes);
|
||||
} else
|
||||
|
@ -614,7 +674,6 @@ int HISTORY::RegisterLuaChanges(const char* name, int start, bool InsertionDelet
|
|||
// create new shanshot
|
||||
SNAPSHOT inp;
|
||||
inp.init(currMovieData, taseditor_config.enable_hot_changes);
|
||||
inp.mod_type = MODTYPE_LUA_CHANGE;
|
||||
// check if there are input differences from latest snapshot
|
||||
int real_pos = (history_start_pos + history_cursor_pos) % history_size;
|
||||
int first_changes = inp.findFirstChange(snapshots[real_pos], start);
|
||||
|
@ -622,6 +681,7 @@ int HISTORY::RegisterLuaChanges(const char* name, int start, bool InsertionDelet
|
|||
{
|
||||
// differences found
|
||||
// fill description:
|
||||
inp.mod_type = MODTYPE_LUA_CHANGE;
|
||||
if (name[0])
|
||||
{
|
||||
// user provided custom name of operation
|
||||
|
@ -633,10 +693,12 @@ int HISTORY::RegisterLuaChanges(const char* name, int start, bool InsertionDelet
|
|||
strcat(inp.description, modCaptions[inp.mod_type]);
|
||||
}
|
||||
inp.jump_frame = first_changes;
|
||||
inp.start_frame = start;
|
||||
inp.end_frame = -1;
|
||||
// add upper frame to description
|
||||
char framenum[11];
|
||||
_itoa(first_changes, framenum, 10);
|
||||
strcat(inp.description, " ");
|
||||
_itoa(first_changes, framenum, 10);
|
||||
strcat(inp.description, framenum);
|
||||
// set hotchanges
|
||||
if (taseditor_config.enable_hot_changes)
|
||||
|
@ -669,7 +731,7 @@ int HISTORY::RegisterLuaChanges(const char* name, int start, bool InsertionDelet
|
|||
}
|
||||
}
|
||||
AddSnapshotToHistory(inp);
|
||||
bookmarks.ChangesMadeSinceBranch();
|
||||
branches.ChangesMadeSinceBranch();
|
||||
}
|
||||
return first_changes;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
void undo();
|
||||
void redo();
|
||||
|
||||
int RegisterChanges(int mod_type, int start = 0, int end =-1, const char* comment = 0);
|
||||
int RegisterChanges(int mod_type, int start = 0, int end =-1, const char* comment = NULL, int consecutive_tag = 0);
|
||||
int RegisterInsertNum(int start, int frames);
|
||||
int RegisterPasteInsert(int start, SelectionFrames& inserted_set);
|
||||
void RegisterMarkersChange(int mod_type, int start = 0, int end =-1, const char* comment = 0);
|
||||
|
|
|
@ -550,7 +550,8 @@ void PIANO_ROLL::update()
|
|||
int row_index, column_index, joy, bit;
|
||||
int min_row_index = currMovieData.getNumRecords(), max_row_index = -1;
|
||||
bool changes_made = false;
|
||||
for (double len = 0; len < total_len; len += DRAWING_MIN_LINE_LEN)
|
||||
int drawing_min_line_len = list_row_height; // = min(list_row_width, list_row_height) in pixels
|
||||
for (double len = 0; len < total_len; len += drawing_min_line_len)
|
||||
{
|
||||
// perform hit test
|
||||
info.pt.x = p.x + (len / total_len) * total_dx;
|
||||
|
@ -580,9 +581,9 @@ void PIANO_ROLL::update()
|
|||
if (changes_made)
|
||||
{
|
||||
if (drag_mode == DRAG_MODE_SET)
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, min_row_index, max_row_index));
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_SET, min_row_index, max_row_index, NULL, drawing_start_time));
|
||||
else
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, min_row_index, max_row_index));
|
||||
greenzone.InvalidateAndCheck(history.RegisterChanges(MODTYPE_UNSET, min_row_index, max_row_index, NULL, drawing_start_time));
|
||||
}
|
||||
drawing_last_x = drawing_current_x;
|
||||
drawing_last_y = drawing_current_y;
|
||||
|
@ -1301,34 +1302,34 @@ LONG PIANO_ROLL::HeaderCustomDraw(NMLVCUSTOMDRAW* msg)
|
|||
// ----------------------------------------------------
|
||||
void PIANO_ROLL::RightClick(LVHITTESTINFO& info)
|
||||
{
|
||||
SelectionFrames* current_selection = selection.MakeStrobe();
|
||||
if (current_selection->size() == 0)
|
||||
return;
|
||||
|
||||
HMENU sub = GetSubMenu(hrmenu, 0);
|
||||
// inspect current selection and disable inappropriate menu items
|
||||
SelectionFrames::iterator current_selection_begin(current_selection->begin());
|
||||
SelectionFrames::iterator current_selection_end(current_selection->end());
|
||||
bool set_found = false, unset_found = false;
|
||||
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
|
||||
if (selection.CheckFrameSelected(info.iItem))
|
||||
{
|
||||
if(markers_manager.GetMarker(*it))
|
||||
set_found = true;
|
||||
else
|
||||
unset_found = true;
|
||||
}
|
||||
if (set_found)
|
||||
EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_ENABLED);
|
||||
else
|
||||
EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||||
if (unset_found)
|
||||
EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_ENABLED);
|
||||
else
|
||||
EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||||
SelectionFrames* current_selection = selection.MakeStrobe();
|
||||
HMENU sub = GetSubMenu(hrmenu, 0);
|
||||
// inspect current selection and disable inappropriate menu items
|
||||
SelectionFrames::iterator current_selection_begin(current_selection->begin());
|
||||
SelectionFrames::iterator current_selection_end(current_selection->end());
|
||||
bool set_found = false, unset_found = false;
|
||||
for(SelectionFrames::iterator it(current_selection_begin); it != current_selection_end; it++)
|
||||
{
|
||||
if(markers_manager.GetMarker(*it))
|
||||
set_found = true;
|
||||
else
|
||||
unset_found = true;
|
||||
}
|
||||
if (set_found)
|
||||
EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_ENABLED);
|
||||
else
|
||||
EnableMenuItem(sub, ID_SELECTED_REMOVEMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||||
if (unset_found)
|
||||
EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_ENABLED);
|
||||
else
|
||||
EnableMenuItem(sub, ID_SELECTED_SETMARKER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||||
|
||||
POINT pt = info.pt;
|
||||
ClientToScreen(hwndList, &pt);
|
||||
TrackPopupMenu(sub, 0, pt.x, pt.y, 0, taseditor_window.hwndTasEditor, 0);
|
||||
POINT pt = info.pt;
|
||||
ClientToScreen(hwndList, &pt);
|
||||
TrackPopupMenu(sub, 0, pt.x, pt.y, 0, taseditor_window.hwndTasEditor, 0);
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
LRESULT APIENTRY HeaderWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
|
@ -1510,12 +1511,13 @@ LRESULT APIENTRY ListWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
// toggle input
|
||||
piano_roll.drawing_start_time = clock();
|
||||
int joy = (column_index - COLUMN_JOYPAD1_A) / NUM_JOYPAD_BUTTONS;
|
||||
int button = (column_index - COLUMN_JOYPAD1_A) % NUM_JOYPAD_BUTTONS;
|
||||
if (alt_pressed)
|
||||
editor.InputSetPattern(piano_roll.row_last_clicked, row_index, joy, button);
|
||||
editor.InputSetPattern(piano_roll.row_last_clicked, row_index, joy, button, piano_roll.drawing_start_time);
|
||||
else
|
||||
editor.InputToggle(piano_roll.row_last_clicked, row_index, joy, button);
|
||||
editor.InputToggle(piano_roll.row_last_clicked, row_index, joy, button, piano_roll.drawing_start_time);
|
||||
// and start dragging/drawing
|
||||
if (piano_roll.drag_mode == DRAG_MODE_NONE)
|
||||
{
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#define MARKER_DRAG_MAX_SPEED 70
|
||||
#define MARKER_DRAG_GRAVITY 2
|
||||
|
||||
#define DRAWING_MIN_LINE_LEN 14 // = min(list_row_width, list_row_height) in pixels
|
||||
|
||||
#define DRAG_SCROLLING_BORDER_SIZE 10 // in pixels
|
||||
|
||||
#define DOUBLETAP_COUNT 3 // 1:quick press, 2 - quick release, 3 - quick press
|
||||
|
@ -194,6 +192,7 @@ public:
|
|||
int marker_drag_countdown;
|
||||
int marker_drag_framenum;
|
||||
int drawing_last_x, drawing_last_y;
|
||||
int drawing_start_time;
|
||||
int drag_selection_starting_frame;
|
||||
int drag_selection_ending_frame;
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
------------------------------------------------------------------------------------
|
||||
Snapshot - Snapshot of all edited data
|
||||
|
||||
* stores the data of specific snapshot of the movie: size, input data (commands and joysticks), Markers at the moment of creating the snapshot, keyframe, type and description of the snapshot (including the time of creation)
|
||||
* also stores info about sequential recording of input
|
||||
* stores the data of specific snapshot of the movie: size, input data (commands and joysticks), Markers at the moment of creating the snapshot, keyframe, start and end frame of operation, type of operation and description of the snapshot (including the time of creation)
|
||||
* also stores info about sequential recording/drawing of input
|
||||
* optionally can store map of Hot Changes
|
||||
* implements snapshot creation: copying input, copying Hot Changes, copying Markers, setting time of creation
|
||||
* implements full/partial restoring of data from snapshot: input, Hot Changes, Markers
|
||||
|
@ -189,7 +189,9 @@ void SNAPSHOT::save(EMUFILE *os)
|
|||
write32le(size, os);
|
||||
write8le(input_type, os);
|
||||
write32le(jump_frame, os);
|
||||
write32le(rec_end_frame, os);
|
||||
write32le(start_frame, os);
|
||||
write32le(end_frame, os);
|
||||
write32le(consecutive_tag, os);
|
||||
write32le(rec_joypad_diff_bits, os);
|
||||
write32le(mod_type, os);
|
||||
if (has_hot_changes) write8le((uint8)1, os); else write8le((uint8)0, os);
|
||||
|
@ -224,7 +226,9 @@ bool SNAPSHOT::load(EMUFILE *is)
|
|||
if (!read8le(&tmp, is)) return true;
|
||||
input_type = tmp;
|
||||
if (!read32le(&jump_frame, is)) return true;
|
||||
if (!read32le(&rec_end_frame, is)) return true;
|
||||
if (!read32le(&start_frame, is)) return true;
|
||||
if (!read32le(&end_frame, is)) return true;
|
||||
if (!read32le(&consecutive_tag, is)) return true;
|
||||
if (!read32le(&rec_joypad_diff_bits, is)) return true;
|
||||
if (!read32le(&mod_type, is)) return true;
|
||||
if (!read8le(&tmp, is)) return true;
|
||||
|
@ -283,7 +287,9 @@ bool SNAPSHOT::skipLoad(EMUFILE *is)
|
|||
if (is->fseek(sizeof(int) + // size
|
||||
sizeof(uint8) + // input_type
|
||||
sizeof(int) + // jump_frame
|
||||
sizeof(int) + // rec_end_frame
|
||||
sizeof(int) + // start_frame
|
||||
sizeof(int) + // end_frame
|
||||
sizeof(int) + // consecutive_tag
|
||||
sizeof(int) + // rec_joypad_diff_bits
|
||||
sizeof(int) + // mod_type
|
||||
sizeof(uint8) // has_hot_changes
|
||||
|
|
|
@ -64,7 +64,11 @@ public:
|
|||
std::vector<uint8> commands; // Format: commands-for-frame0, commands-for-frame1, ...
|
||||
std::vector<uint8> hot_changes; // Format: buttons01joy0-for-frame0, buttons23joy0-for-frame0, buttons45joy0-for-frame0, buttons67joy0-for-frame0, buttons01joy1-for-frame0, ...
|
||||
int jump_frame; // for jumping when making undo
|
||||
int rec_end_frame; // for consecutive Recordings
|
||||
|
||||
int start_frame; // for consecutive Draws
|
||||
int end_frame; // for consecutive Draws
|
||||
|
||||
int consecutive_tag; // for consecutive Recordings and Draws
|
||||
uint32 rec_joypad_diff_bits; // for consecutive Recordings
|
||||
int mod_type;
|
||||
char description[SNAPSHOT_DESC_MAX_LENGTH];
|
||||
|
|
|
@ -44,7 +44,7 @@ TASEDITOR_CONFIG::TASEDITOR_CONFIG()
|
|||
follow_note_context = true;
|
||||
bind_markers = true;
|
||||
empty_marker_notes = true;
|
||||
combine_consecutive_rec = false;
|
||||
combine_consecutive = false;
|
||||
use_1p_rec = true;
|
||||
columnset_by_keys = false;
|
||||
superimpose = 0; // SUPERIMPOSE_UNCHECKED
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
bool follow_note_context;
|
||||
bool bind_markers;
|
||||
bool empty_marker_notes;
|
||||
bool combine_consecutive_rec;
|
||||
bool combine_consecutive;
|
||||
bool use_1p_rec;
|
||||
bool columnset_by_keys;
|
||||
int superimpose;
|
||||
|
|
|
@ -23,6 +23,7 @@ extern TASEDITOR_WINDOW taseditor_window;
|
|||
extern HISTORY history;
|
||||
extern MARKERS_MANAGER markers_manager;
|
||||
extern BOOKMARKS bookmarks;
|
||||
extern BRANCHES branches;
|
||||
extern RECORDER recorder;
|
||||
extern PLAYBACK playback;
|
||||
extern GREENZONE greenzone;
|
||||
|
@ -191,7 +192,7 @@ void TASEDITOR_LUA::setnote(int index, const char* newtext)
|
|||
int TASEDITOR_LUA::getcurrentbranch()
|
||||
{
|
||||
if (FCEUMOV_Mode(MOVIEMODE_TASEDITOR))
|
||||
return bookmarks.GetCurrentBranch();
|
||||
return branches.GetCurrentBranch();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "recorder.h"
|
||||
#include "greenzone.h"
|
||||
#include "bookmarks.h"
|
||||
#include "branches.h"
|
||||
#include "piano_roll.h"
|
||||
#include "taseditor_lua.h"
|
||||
#include "splicer.h"
|
||||
|
|
|
@ -437,7 +437,7 @@ void TASEDITOR_WINDOW::UpdateCheckedItems()
|
|||
CheckMenuItem(hmenu, ID_CONFIG_HUDINBRANCHSCREENSHOTS, taseditor_config.branch_scr_hud?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_BINDMARKERSTOINPUT, taseditor_config.bind_markers?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_EMPTYNEWMARKERNOTES, taseditor_config.empty_marker_notes?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_COMBINECONSECUTIVERECORDINGS, taseditor_config.combine_consecutive_rec?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_COMBINECONSECUTIVERECORDINGS, taseditor_config.combine_consecutive?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_USE1PFORRECORDING, taseditor_config.use_1p_rec?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_USEINPUTKEYSFORCOLUMNSET, taseditor_config.columnset_by_keys?MF_CHECKED : MF_UNCHECKED);
|
||||
CheckMenuItem(hmenu, ID_CONFIG_SUPERIMPOSE_AFFECTS_PASTE, taseditor_config.superimpose_affects_paste?MF_CHECKED : MF_UNCHECKED);
|
||||
|
@ -1032,7 +1032,7 @@ BOOL CALLBACK WndprocTasEditor(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
|
|||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_COMBINECONSECUTIVERECORDINGS:
|
||||
taseditor_config.combine_consecutive_rec ^= 1;
|
||||
taseditor_config.combine_consecutive ^= 1;
|
||||
taseditor_window.UpdateCheckedItems();
|
||||
break;
|
||||
case ID_CONFIG_USE1PFORRECORDING:
|
||||
|
|
|
@ -876,7 +876,7 @@ static void CommandStateSave(void)
|
|||
{
|
||||
#ifdef WIN32
|
||||
if (execcmd == EMUCMD_SAVE_STATE)
|
||||
bookmarks.command(COMMAND_SET, bookmarks.GetCurrentBranch());
|
||||
bookmarks.command(COMMAND_SET);
|
||||
else if(execcmd >= EMUCMD_SAVE_STATE_SLOT_0 && execcmd <= EMUCMD_SAVE_STATE_SLOT_9)
|
||||
bookmarks.command(COMMAND_SET, execcmd - EMUCMD_SAVE_STATE_SLOT_0);
|
||||
#endif
|
||||
|
@ -900,7 +900,7 @@ static void CommandStateLoad(void)
|
|||
{
|
||||
#ifdef WIN32
|
||||
if (execcmd == EMUCMD_LOAD_STATE)
|
||||
bookmarks.command(COMMAND_DEPLOY, bookmarks.GetCurrentBranch());
|
||||
bookmarks.command(COMMAND_DEPLOY);
|
||||
else if(execcmd >= EMUCMD_LOAD_STATE_SLOT_0 && execcmd <= EMUCMD_LOAD_STATE_SLOT_9)
|
||||
bookmarks.command(COMMAND_DEPLOY, execcmd - EMUCMD_LOAD_STATE_SLOT_0);
|
||||
#endif
|
||||
|
|
|
@ -422,6 +422,7 @@
|
|||
<ClCompile Include="..\src\drivers\win\taseditor.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\bookmark.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\bookmarks.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\branches.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\editor.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\greenzone.cpp" />
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\history.cpp" />
|
||||
|
@ -749,6 +750,7 @@
|
|||
<ClInclude Include="..\src\drivers\win\taseditor.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\bookmark.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\bookmarks.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\branches.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\editor.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\greenzone.h" />
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\history.h" />
|
||||
|
|
|
@ -958,6 +958,9 @@
|
|||
<ClCompile Include="..\src\drivers\win\taseditor\editor.cpp">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\drivers\win\taseditor\branches.cpp">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\cart.h">
|
||||
|
@ -1408,9 +1411,6 @@
|
|||
<ClInclude Include="..\src\drivers\win\taseditor\taseditor_window.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\popup_display.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\recorder.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1450,6 +1450,12 @@
|
|||
<ClInclude Include="..\src\drivers\win\taseditor\editor.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\branches.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\drivers\win\taseditor\popup_display.h">
|
||||
<Filter>drivers\win\taseditor</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\src\drivers\win\res.rc">
|
||||
|
|
Loading…
Reference in New Issue