diff --git a/src/drivers/win/taseditor/history.cpp b/src/drivers/win/taseditor/history.cpp index 9101b0ca..c9f3e01e 100644 --- a/src/drivers/win/taseditor/history.cpp +++ b/src/drivers/win/taseditor/history.cpp @@ -960,7 +960,7 @@ int HISTORY::RegisterLuaChanges(const char* name, int start, bool InsertionDelet } else { hotchanges_snapshot.inputlog.has_hot_changes = true; - hotchanges_snapshot.inputlog.hot_changes.resize(joysticks_per_frame[snap.inputlog.input_type] * hotchanges_snapshot.inputlog.size * HOTCHANGE_BYTES_PER_JOY); + hotchanges_snapshot.inputlog.Init_HotChanges(); } // insert/delete frames in hotchanges_snapshot, so that it will be the same size as the snap taseditor_lua.InsertDelete_rows_to_Snaphot(hotchanges_snapshot); diff --git a/src/drivers/win/taseditor/inputlog.cpp b/src/drivers/win/taseditor/inputlog.cpp index b1bda506..870931e3 100644 --- a/src/drivers/win/taseditor/inputlog.cpp +++ b/src/drivers/win/taseditor/inputlog.cpp @@ -39,50 +39,22 @@ void INPUTLOG::init(MovieData& md, bool hotchanges, int force_input_type) input_type = GetInputType(md); else input_type = force_input_type; + int num_joys = joysticks_per_frame[input_type]; // retrieve Input data from movie data size = md.getNumRecords(); - joysticks.resize(BYTES_PER_JOYSTICK * joysticks_per_frame[input_type] * size); // it's much faster to have this format than have [frame][joy] or other structures + joysticks.resize(BYTES_PER_JOYSTICK * num_joys * size); // it's much faster to have this format than have [frame][joy] or other structures commands.resize(size); // commands take 1 byte per frame if (has_hot_changes) - hot_changes.resize(joysticks_per_frame[input_type] * size * HOTCHANGE_BYTES_PER_JOY); + Init_HotChanges(); // fill Input vector - int pos = 0; - switch(input_type) + int joy; + for (int frame = 0; frame < size; ++frame) { - case INPUT_TYPE_FOURSCORE: - { - for (int frame = 0; frame < size; ++frame) - { - joysticks[pos++] = md.records[frame].joysticks[0]; - joysticks[pos++] = md.records[frame].joysticks[1]; - joysticks[pos++] = md.records[frame].joysticks[2]; - joysticks[pos++] = md.records[frame].joysticks[3]; - commands[frame] = md.records[frame].commands; - } - break; - } - case INPUT_TYPE_2P: - { - for (int frame = 0; frame < size; ++frame) - { - joysticks[pos++] = md.records[frame].joysticks[0]; - joysticks[pos++] = md.records[frame].joysticks[1]; - commands[frame] = md.records[frame].commands; - } - break; - } - case INPUT_TYPE_1P: - { - for (int frame = 0; frame < size; ++frame) - { - joysticks[pos++] = md.records[frame].joysticks[0]; - commands[frame] = md.records[frame].commands; - } - break; - } + for (joy = num_joys - 1; joy >= 0; joy--) + joysticks[frame * num_joys * BYTES_PER_JOYSTICK + joy * BYTES_PER_JOYSTICK] = md.records[frame].joysticks[joy]; + commands[frame] = md.records[frame].commands; } - already_compressed = false; } @@ -91,42 +63,13 @@ void INPUTLOG::toMovie(MovieData& md, int start, int end) if (end < 0 || end >= size) end = size - 1; // write Input data to movie data md.records.resize(end + 1); - switch(input_type) + int num_joys = joysticks_per_frame[input_type]; + int joy; + for (int frame = start; frame <= end; ++frame) { - case INPUT_TYPE_FOURSCORE: - { - int pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; - for (int frame = start; frame <= end; ++frame) - { - md.records[frame].joysticks[0] = joysticks[pos++]; - md.records[frame].joysticks[1] = joysticks[pos++]; - md.records[frame].joysticks[2] = joysticks[pos++]; - md.records[frame].joysticks[3] = joysticks[pos++]; - md.records[frame].commands = commands[frame]; - } - break; - } - case INPUT_TYPE_2P: - { - int pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; - for (int frame = start; frame <= end; ++frame) - { - md.records[frame].joysticks[0] = joysticks[pos++]; - md.records[frame].joysticks[1] = joysticks[pos++]; - md.records[frame].commands = commands[frame]; - } - break; - } - case INPUT_TYPE_1P: - { - int pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; - for (int frame = start; frame <= end; ++frame) - { - md.records[frame].joysticks[0] = joysticks[pos++]; - md.records[frame].commands = commands[frame]; - } - break; - } + for (joy = num_joys - 1; joy >= 0; joy--) + md.records[frame].joysticks[joy] = joysticks[frame * num_joys * BYTES_PER_JOYSTICK + joy * BYTES_PER_JOYSTICK]; + md.records[frame].commands = commands[frame]; } } @@ -265,25 +208,13 @@ uint32 INPUTLOG::fillJoypadsDiff(INPUTLOG& their_log, int frame) { uint32 joypad_diff_bits = 0; uint32 current_mask = 1; - switch(input_type) + if (frame < their_log.size) { - case INPUT_TYPE_FOURSCORE: - case INPUT_TYPE_2P: - case INPUT_TYPE_1P: + for (int joy = 0; joy < joysticks_per_frame[input_type]; ++joy) { - int pos = frame * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; - for (int i = 0; i < BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; ++i) - { - if (pos < (their_log.size * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type])) - { - if (joysticks[pos+i] != their_log.joysticks[pos+i]) joypad_diff_bits |= current_mask; - } else - { - if (joysticks[pos+i]) joypad_diff_bits |= current_mask; - } - current_mask <<= 1; - } - break; + if (GetJoystickInfo(frame, joy) != their_log.GetJoystickInfo(frame, joy)) + joypad_diff_bits |= current_mask; + current_mask <<= 1; } } return joypad_diff_bits; @@ -291,82 +222,20 @@ uint32 INPUTLOG::fillJoypadsDiff(INPUTLOG& their_log, int frame) // return number of first frame of difference between two InputLogs int INPUTLOG::findFirstChange(INPUTLOG& their_log, int start, int end) { - // if these two InputLogs have different input_type (abnormal situation) then refuse to search and return the beginning - if (their_log.input_type != input_type) - return start; - // search for differences to the specified end (or to the end of this InputLog) if (end < 0 || end >= size) end = size-1; int their_log_end = their_log.size; - switch(input_type) + + int joy; + int num_joys = joysticks_per_frame[input_type]; + for (int frame = start; frame <= end; ++frame) { - case INPUT_TYPE_FOURSCORE: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // return the frame if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (commands[frame] != their_log.commands[frame]) return frame; - } else - { - if (joysticks[pos++]) return frame; - if (joysticks[pos++]) return frame; - if (joysticks[pos++]) return frame; - if (joysticks[pos++]) return frame; - if (commands[frame]) return frame; - } - } - break; - } - case INPUT_TYPE_2P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // return the frame if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (commands[frame] != their_log.commands[frame]) return frame; - } else - { - if (joysticks[pos++]) return frame; - if (joysticks[pos++]) return frame; - if (commands[frame]) return frame; - } - } - break; - } - case INPUT_TYPE_1P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // return the frame if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) return frame; - pos++; - if (commands[frame] != their_log.commands[frame]) return frame; - } else - { - if (joysticks[pos++]) return frame; - if (commands[frame]) return frame; - } - } - break; - } + for (joy = num_joys - 1; joy >= 0; joy--) + if (GetJoystickInfo(frame, joy) != their_log.GetJoystickInfo(frame, joy)) return frame; + if (GetCommandsInfo(frame) != their_log.GetCommandsInfo(frame)) return frame; } + // no difference was found + // if my_size is less then their_size, return last frame + 1 (= size) as the frame of difference if (size < their_log_end) return size; // no changes were found @@ -375,70 +244,41 @@ int INPUTLOG::findFirstChange(INPUTLOG& their_log, int start, int end) // return number of first frame of difference between this InputLog and MovieData int INPUTLOG::findFirstChange(MovieData& md, int start, int end) { - // search for differences to the specified end (or to the end of this InputLog / to the end of the movie) - if (end < 0 || end >= size) end = size-1; - if (end >= md.getNumRecords()) end = md.getNumRecords()-1; + // search for differences to the specified end (or to the end of this InputLog / to the end of the movie data) + if (end < 0 || end >= size) end = size - 1; + if (end >= md.getNumRecords()) end = md.getNumRecords() - 1; - switch(input_type) + int joy; + int num_joys = joysticks_per_frame[input_type]; + for (int frame = start; frame <= end; ++frame) { - case INPUT_TYPE_FOURSCORE: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - if (joysticks[pos++] != md.records[frame].joysticks[0]) return frame; - if (joysticks[pos++] != md.records[frame].joysticks[1]) return frame; - if (joysticks[pos++] != md.records[frame].joysticks[2]) return frame; - if (joysticks[pos++] != md.records[frame].joysticks[3]) return frame; - if (commands[frame] != md.records[frame].commands) return frame; - } - break; - } - case INPUT_TYPE_2P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - if (joysticks[pos++] != md.records[frame].joysticks[0]) return frame; - if (joysticks[pos++] != md.records[frame].joysticks[1]) return frame; - if (commands[frame] != md.records[frame].commands) return frame; - } - break; - } - case INPUT_TYPE_1P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - if (joysticks[pos++] != md.records[frame].joysticks[0]) return frame; - if (commands[frame] != md.records[frame].commands) return frame; - } - break; - } + for (joy = num_joys - 1; joy >= 0; joy--) + if (GetJoystickInfo(frame, joy) != md.records[frame].joysticks[joy]) return frame; + if (GetCommandsInfo(frame) != md.records[frame].commands) return frame; } + // no difference was found + // if sizes differ, return last frame + 1 from the lesser of them - if (size < md.getNumRecords() && end >= size-1) + if (size < md.getNumRecords() && end >= size - 1) return size; - else if (size > md.getNumRecords() && end >= md.getNumRecords()-1) + else if (size > md.getNumRecords() && end >= md.getNumRecords() - 1) return md.getNumRecords(); - return -1; // no changes were found + return -1; } int INPUTLOG::GetJoystickInfo(int frame, int joy) { - if (frame < 0 || frame >= size) return 0; - switch(input_type) - { - case INPUT_TYPE_FOURSCORE: - case INPUT_TYPE_2P: - case INPUT_TYPE_1P: - { - return joysticks[frame * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type] + joy]; - } - } - return 0; + if (frame < 0 || frame >= size) + return 0; + if (joy > joysticks_per_frame[input_type]) + return 0; + return joysticks[frame * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type] + joy]; } int INPUTLOG::GetCommandsInfo(int frame) { - if (frame < 0 || frame >= size) return 0; + if (frame < 0 || frame >= size) + return 0; return commands[frame]; } @@ -456,7 +296,7 @@ void INPUTLOG::insertFrames(int at, int frames) // fill new hotchanges with max value int lower_limit = joysticks_per_frame[input_type] * (size - frames) * HOTCHANGE_BYTES_PER_JOY; for (int i = hot_changes.size() - 1; i >= lower_limit; i--) - hot_changes[i] = 0xFF; + hot_changes[i] = BYTE_VALUE_CONTAINING_MAX_HOTCHANGES; } } else { @@ -470,7 +310,7 @@ void INPUTLOG::insertFrames(int at, int frames) { // insert X bytes of hot_changes bytes = joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; - hot_changes.insert(hot_changes.begin() + (at * bytes), frames * bytes, 0xFF); + hot_changes.insert(hot_changes.begin() + (at * bytes), frames * bytes, BYTE_VALUE_CONTAINING_MAX_HOTCHANGES); } } // data was changed @@ -493,24 +333,26 @@ void INPUTLOG::eraseFrame(int frame) // data was changed already_compressed = false; } -// -------------------------------------------------------- +// ----------------------------------------------------------------------------------------------- +void INPUTLOG::Init_HotChanges() +{ + hot_changes.resize(joysticks_per_frame[input_type] * size * HOTCHANGE_BYTES_PER_JOY); +} + void INPUTLOG::copyHotChanges(INPUTLOG* source_of_hotchanges, int limit_frame_of_source) { // copy hot changes from source InputLog if (source_of_hotchanges && source_of_hotchanges->has_hot_changes && source_of_hotchanges->input_type == input_type) { - int min = hot_changes.size(); - if (min > (int)source_of_hotchanges->hot_changes.size()) - min = source_of_hotchanges->hot_changes.size(); - + int frames_to_copy = source_of_hotchanges->size; + if (frames_to_copy > size) + frames_to_copy = size; // special case for Branches: if limit_frame if specified, then copy only hotchanges from 0 to limit_frame - if (limit_frame_of_source >= 0) - { - if (min > limit_frame_of_source * joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY) - min = limit_frame_of_source * joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; - } + if (limit_frame_of_source >= 0 && frames_to_copy > limit_frame_of_source) + frames_to_copy = limit_frame_of_source; - memcpy(&hot_changes[0], &source_of_hotchanges->hot_changes[0], min); + int bytes_to_copy = frames_to_copy * joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; + memcpy(&hot_changes[0], &source_of_hotchanges->hot_changes[0], bytes_to_copy); } } void INPUTLOG::inheritHotChanges(INPUTLOG* source_of_hotchanges) @@ -518,31 +360,31 @@ void INPUTLOG::inheritHotChanges(INPUTLOG* source_of_hotchanges) // copy hot changes from source InputLog and fade them if (source_of_hotchanges && source_of_hotchanges->has_hot_changes && source_of_hotchanges->input_type == input_type) { - int min = hot_changes.size(); - if (min > (int)source_of_hotchanges->hot_changes.size()) - min = source_of_hotchanges->hot_changes.size(); + int frames_to_copy = source_of_hotchanges->size; + if (frames_to_copy > size) + frames_to_copy = size; - memcpy(&hot_changes[0], &source_of_hotchanges->hot_changes[0], min); + int bytes_to_copy = frames_to_copy * joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; + memcpy(&hot_changes[0], &source_of_hotchanges->hot_changes[0], bytes_to_copy); FadeHotChanges(); } } void INPUTLOG::inheritHotChanges_DeleteSelection(INPUTLOG* source_of_hotchanges, SelectionFrames* frameset) { - // copy hot changes from source InputLog, but omit deleted frames (which are represented by current selection) + // copy hot changes from source InputLog, but omit deleted frames (which are represented by the "frameset") if (source_of_hotchanges && source_of_hotchanges->has_hot_changes && source_of_hotchanges->input_type == input_type) { int bytes = joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, pos = 0, source_pos = 0; int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size(); SelectionFrames::iterator it(frameset->begin()); - SelectionFrames::iterator current_selection_end(frameset->end()); + SelectionFrames::iterator frameset_end(frameset->end()); while (pos < this_size && source_pos < source_size) { - if (it != current_selection_end && frame == *it) + if (it != frameset_end && frame == *it) { - // this frame is selected - it++; // omit the frame + it++; source_pos += bytes; } else { @@ -558,9 +400,9 @@ void INPUTLOG::inheritHotChanges_DeleteSelection(INPUTLOG* source_of_hotchanges, } void INPUTLOG::inheritHotChanges_InsertSelection(INPUTLOG* source_of_hotchanges, SelectionFrames* frameset) { - // copy hot changes from source InputLog, but insert filled lines for inserted frames (which are represented by current selection) + // copy hot changes from source InputLog, but insert filled lines for inserted frames (which are represented by the "frameset") SelectionFrames::iterator it(frameset->begin()); - SelectionFrames::iterator current_selection_end(frameset->end()); + SelectionFrames::iterator frameset_end(frameset->end()); if (source_of_hotchanges && source_of_hotchanges->has_hot_changes && source_of_hotchanges->input_type == input_type) { int bytes = joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; @@ -568,16 +410,16 @@ void INPUTLOG::inheritHotChanges_InsertSelection(INPUTLOG* source_of_hotchanges, int this_size = hot_changes.size(), source_size = source_of_hotchanges->hot_changes.size(); while (pos < this_size) { - if (it != current_selection_end && frame == *it) + if (it != frameset_end && frame == *it) { - // this frame is selected + // omit the frame it++; region_len++; // set filled line to the frame - memset(&hot_changes[pos], 0xFF, bytes); + memset(&hot_changes[pos], BYTE_VALUE_CONTAINING_MAX_HOTCHANGES, bytes); } else if (source_pos < source_size) { - // this frame is not selected + // this frame should be copied frame -= region_len; region_len = 0; // copy hotchanges of this frame @@ -590,21 +432,21 @@ void INPUTLOG::inheritHotChanges_InsertSelection(INPUTLOG* source_of_hotchanges, } } else { - // no old data, just fill selected lines + // no old data, just fill "frameset" lines int bytes = joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, region_len = 0, pos = 0; int this_size = hot_changes.size(); while (pos < this_size) { - if (it != current_selection_end && frame == *it) + if (it != frameset_end && frame == *it) { // this frame is selected it++; region_len++; // set filled line to the frame - memset(&hot_changes[pos], 0xFF, bytes); + memset(&hot_changes[pos], BYTE_VALUE_CONTAINING_MAX_HOTCHANGES, bytes); // exit loop when all frames in the Selection are handled - if (it == current_selection_end) break; + if (it == frameset_end) break; } else { // this frame is not selected @@ -661,11 +503,11 @@ void INPUTLOG::inheritHotChanges_InsertNum(INPUTLOG* source_of_hotchanges, int s FadeHotChanges(); } // fill the gap with max_hot lines on frames from "start" to "start+frames" - memset(&hot_changes[bytes * start], 0xFF, bytes * frames); + memset(&hot_changes[bytes * start], BYTE_VALUE_CONTAINING_MAX_HOTCHANGES, bytes * frames); } void INPUTLOG::inheritHotChanges_PasteInsert(INPUTLOG* source_of_hotchanges, SelectionFrames* inserted_set) { - // copy hot changes from source InputLog and insert filled lines for inserted frames (which are represented by inserted_set) + // copy hot changes from source InputLog and insert filled lines for inserted frames (which are represented by "inserted_set") int bytes = joysticks_per_frame[input_type] * HOTCHANGE_BYTES_PER_JOY; int frame = 0, pos = 0; int this_size = hot_changes.size(); @@ -683,7 +525,7 @@ void INPUTLOG::inheritHotChanges_PasteInsert(INPUTLOG* source_of_hotchanges, Sel // this frame was inserted it++; // set filled line to the frame - memset(&hot_changes[pos], 0xFF, bytes); + memset(&hot_changes[pos], BYTE_VALUE_CONTAINING_MAX_HOTCHANGES, bytes); } else if (source_pos < source_size) { // copy hotchanges of this frame @@ -704,7 +546,7 @@ void INPUTLOG::inheritHotChanges_PasteInsert(INPUTLOG* source_of_hotchanges, Sel // this frame was inserted it++; // set filled line to the frame - memset(&hot_changes[pos], 0xFF, bytes); + memset(&hot_changes[pos], BYTE_VALUE_CONTAINING_MAX_HOTCHANGES, bytes); pos += bytes; // exit loop when all inserted_set frames are handled if (it == inserted_set_end) break; @@ -719,96 +561,18 @@ void INPUTLOG::inheritHotChanges_PasteInsert(INPUTLOG* source_of_hotchanges, Sel } void INPUTLOG::fillHotChanges(INPUTLOG& their_log, int start, int end) { - // if these two InputLogs have different input_type (abnormal situation) then refuse to compare - if (their_log.input_type != input_type) - return; - // compare InputLogs to the specified end (or to the end of this InputLog) if (end < 0 || end >= size) end = size-1; - int their_log_end = their_log.size; - switch(input_type) + uint8 my_joy, their_joy; + for (int joy = joysticks_per_frame[input_type] - 1; joy >= 0; joy--) { - case INPUT_TYPE_FOURSCORE: + for (int frame = start; frame <= end; ++frame) { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // consider changed if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 1, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 2, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 3, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - } else - { - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos]); - pos++; - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 1, joysticks[pos]); - pos++; - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 2, joysticks[pos]); - pos++; - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 3, joysticks[pos]); - pos++; - } - } - break; - } - case INPUT_TYPE_2P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // consider changed if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 1, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - } else - { - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos]); - pos++; - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 1, joysticks[pos]); - pos++; - } - } - break; - } - case INPUT_TYPE_1P: - { - for (int frame = start, pos = start * BYTES_PER_JOYSTICK * joysticks_per_frame[input_type]; frame <= end; ++frame) - { - // consider changed if found different byte, or found emptiness in their_log when there's non-zero value here - if (frame < their_log_end) - { - if (joysticks[pos] != their_log.joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos] ^ their_log.joysticks[pos]); - pos++; - } else - { - if (joysticks[pos]) - SetMaxHotChange_Bits(frame, 0, joysticks[pos]); - pos++; - } - } - break; - } + my_joy = GetJoystickInfo(frame, joy); + their_joy = their_log.GetJoystickInfo(frame, joy); + if (my_joy != their_joy) + SetMaxHotChange_Bits(frame, joy, my_joy ^ their_joy); + } } } @@ -816,53 +580,21 @@ void INPUTLOG::SetMaxHotChange_Bits(int frame, int joypad, uint8 joy_bits) { uint8 mask = 1; // check all 8 buttons and set max hot_changes for bits that are set - for (int i = 0; i < 8; ++i) + for (int i = 0; i < BUTTONS_PER_JOYSTICK; ++i) { if (joy_bits & mask) - SetMaxHotChange(frame, joypad * 8 + i); + SetMaxHotChange(frame, joypad * BUTTONS_PER_JOYSTICK + i); mask <<= 1; } } void INPUTLOG::SetMaxHotChange(int frame, int absolute_button) { if (frame < 0 || frame >= size || !has_hot_changes) return; - // set max value (15) to the button hotness - switch(input_type) - { - case INPUT_TYPE_FOURSCORE: - { - // 32 buttons = 16bytes - if (absolute_button & 1) - // odd buttons (B, T, D, R) - set upper 4 bits of the byte - hot_changes[(frame << 4) | (absolute_button >> 1)] |= 0xF0; - else - // even buttons (A, S, U, L) - set lower 4 bits of the byte - hot_changes[(frame << 4) | (absolute_button >> 1)] |= 0x0F; - break; - } - case INPUT_TYPE_2P: - { - // 16 buttons = 8bytes - if (absolute_button & 1) - // odd buttons (B, T, D, R) - set upper 4 bits of the byte - hot_changes[(frame << 3) | (absolute_button >> 1)] |= 0xF0; - else - // even buttons (A, S, U, L) - set lower 4 bits of the byte - hot_changes[(frame << 3) | (absolute_button >> 1)] |= 0x0F; - break; - } - case INPUT_TYPE_1P: - { - // 8 buttons = 4bytes - if (absolute_button & 1) - // odd buttons (B, T, D, R) - set upper 4 bits of the byte - hot_changes[(frame << 2) | (absolute_button >> 1)] |= 0xF0; - else - // even buttons (A, S, U, L) - set lower 4 bits of the byte - hot_changes[(frame << 2) | (absolute_button >> 1)] |= 0x0F; - break; - } - } + // set max value to the button hotness + if (absolute_button & 1) + hot_changes[frame * (HOTCHANGE_BYTES_PER_JOY * joysticks_per_frame[input_type]) + (absolute_button >> 1)] |= BYTE_VALUE_CONTAINING_MAX_HOTCHANGE_HI; + else + hot_changes[frame * (HOTCHANGE_BYTES_PER_JOY * joysticks_per_frame[input_type]) + (absolute_button >> 1)] |= BYTE_VALUE_CONTAINING_MAX_HOTCHANGE_LO; } void INPUTLOG::FadeHotChanges(int start_byte, int end_byte) @@ -874,11 +606,11 @@ void INPUTLOG::FadeHotChanges(int start_byte, int end_byte) { if (hot_changes[i]) { - hi_half = hot_changes[i] >> 4; - low_half = hot_changes[i] & 15; + hi_half = hot_changes[i] >> HOTCHANGE_BITS_PER_VALUE; + low_half = hot_changes[i] & HOTCHANGE_BITMASK; if (hi_half) hi_half--; if (low_half) low_half--; - hot_changes[i] = (hi_half << 4) | low_half; + hot_changes[i] = (hi_half << HOTCHANGE_BITS_PER_VALUE) | low_half; } } } @@ -888,34 +620,13 @@ int INPUTLOG::GetHotChangeInfo(int frame, int absolute_button) if (!has_hot_changes || frame < 0 || frame >= size || absolute_button < 0 || absolute_button >= NUM_JOYPAD_BUTTONS * joysticks_per_frame[input_type]) return 0; - uint8 val; - switch(input_type) - { - case INPUT_TYPE_FOURSCORE: - { - // 32 buttons, 16bytes - val = hot_changes[(frame << 4) + (absolute_button >> 1)]; - break; - } - case INPUT_TYPE_2P: - { - // 16 buttons, 8bytes - val = hot_changes[(frame << 3) + (absolute_button >> 1)]; - break; - } - case INPUT_TYPE_1P: - { - // 8 buttons, 4bytes - val = hot_changes[(frame << 2) + (absolute_button >> 1)]; - break; - } - } + uint8 val = hot_changes[frame * (HOTCHANGE_BYTES_PER_JOY * joysticks_per_frame[input_type]) + (absolute_button >> 1)]; if (absolute_button & 1) - // odd buttons (B, T, D, R) - upper 4 bits of the byte - return val >> 4; + // odd buttons (B, T, D, R) take upper 4 bits of the byte + return val >> HOTCHANGE_BITS_PER_VALUE; else - // even buttons (A, S, U, L) - lower 4 bits of the byte - return val & 15; + // even buttons (A, S, U, L) take lower 4 bits of the byte + return val & HOTCHANGE_BITMASK; } diff --git a/src/drivers/win/taseditor/inputlog.h b/src/drivers/win/taseditor/inputlog.h index bffc9475..e8e55cee 100644 --- a/src/drivers/win/taseditor/inputlog.h +++ b/src/drivers/win/taseditor/inputlog.h @@ -9,8 +9,17 @@ enum Input_types NUM_SUPPORTED_INPUT_TYPES }; -#define BYTES_PER_JOYSTICK 1 // 1 byte per 1 joystick (8 buttons) -#define HOTCHANGE_BYTES_PER_JOY 4 // 4 bytes per 8 buttons +#define BUTTONS_PER_JOYSTICK 8 +#define BYTES_PER_JOYSTICK 1 // 1 byte per 1 joystick (8 buttons) + +#define HOTCHANGE_BITS_PER_VALUE 4 // any HotChange value takes 4 bits +#define HOTCHANGE_BITMASK 0xF // "1111" +#define HOTCHANGE_MAX_VALUE 0xF // "1111" max +#define HOTCHANGE_VALUES_PER_BYTE 2 // hence 2 HotChange values fit into 1 byte +#define BYTE_VALUE_CONTAINING_MAX_HOTCHANGES ((HOTCHANGE_MAX_VALUE << HOTCHANGE_BITS_PER_VALUE) | HOTCHANGE_MAX_VALUE) // "0xFF" +#define BYTE_VALUE_CONTAINING_MAX_HOTCHANGE_HI (HOTCHANGE_MAX_VALUE << HOTCHANGE_BITS_PER_VALUE) // "0xF0" +#define BYTE_VALUE_CONTAINING_MAX_HOTCHANGE_LO HOTCHANGE_MAX_VALUE // "0x0F" +#define HOTCHANGE_BYTES_PER_JOY (BYTES_PER_JOYSTICK * HOTCHANGE_BITS_PER_VALUE) // 4 bytes per 8 buttons class INPUTLOG { @@ -26,7 +35,7 @@ public: void compress_data(); bool Get_already_compressed(); - uint32 INPUTLOG::fillJoypadsDiff(INPUTLOG& their_log, int frame); + uint32 fillJoypadsDiff(INPUTLOG& their_log, int frame); int findFirstChange(INPUTLOG& their_log, int start = 0, int end = -1); int findFirstChange(MovieData& md, int start = 0, int end = -1); @@ -36,6 +45,8 @@ public: void insertFrames(int at, int frames); void eraseFrame(int frame); + void Init_HotChanges(); + void copyHotChanges(INPUTLOG* source_of_hotchanges, int limit_frame_of_source = -1); void inheritHotChanges(INPUTLOG* source_of_hotchanges); void inheritHotChanges_DeleteSelection(INPUTLOG* source_of_hotchanges, SelectionFrames* frameset); @@ -58,9 +69,9 @@ public: bool has_hot_changes; // not saved data + std::vector hot_changes; // Format: buttons01joy0-for-frame0, buttons23joy0-for-frame0, buttons45joy0-for-frame0, buttons67joy0-for-frame0, buttons01joy1-for-frame0, ... std::vector joysticks; // Format: joy0-for-frame0, joy1-for-frame0, joy2-for-frame0, joy3-for-frame0, joy0-for-frame1, joy1-for-frame1, ... std::vector commands; // Format: commands-for-frame0, commands-for-frame1, ... - std::vector hot_changes; // Format: buttons01joy0-for-frame0, buttons23joy0-for-frame0, buttons45joy0-for-frame0, buttons67joy0-for-frame0, buttons01joy1-for-frame0, ... private: diff --git a/src/drivers/win/taseditor/piano_roll.cpp b/src/drivers/win/taseditor/piano_roll.cpp index 83a004bd..4c5211ca 100644 --- a/src/drivers/win/taseditor/piano_roll.cpp +++ b/src/drivers/win/taseditor/piano_roll.cpp @@ -1577,6 +1577,8 @@ bool PIANO_ROLL::CheckIfTheresAnyIconAtFrame(int frame) return true; if (frame == playback.GetLostPosition()) return true; + if (frame == playback.GetPauseFrame()) + return true; if (bookmarks.FindBookmarkAtFrame(frame) >= 0) return true; return false;