Skip to content

Commit 5588a05

Browse files
committed
Differentiate "undo/skip split" from "previous/next image"
Skip/udo will now actually call command This makes grouping option obsolete as user now has finer control anyway UI is a bit cramped, but that should be resolved with UI revamp Updated README
1 parent f234fe9 commit 5588a05

File tree

7 files changed

+119
-82
lines changed

7 files changed

+119
-82
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ This program can be used to automatically start, split, and reset your preferred
3333

3434
- Microsoft Visual C++ 14.0 or greater may be required to build the executable. Get it with [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
3535
- Node is optional, but required for complete linting (using Pyright).
36-
- Read [requirements.txt](/scripts/requirements.txt) for information on how to install, run and build the python code
36+
- Read [requirements.txt](/scripts/requirements.txt) for more information on how to install, run and build the python code
3737
- Run `.\scripts\install.bat` to install all dependencies
38-
- Run the app directly with `py .\src\AutoSplit.py [--auto-controlled]`
38+
- Run the app directly with `.\scripts\start.bat [--auto-controlled]`
3939
- Run `.\scripts\build.bat` to build an executable
4040
- Recompile resources after modifications by running `.\scripts\compile_resources.bat`
4141

@@ -59,9 +59,9 @@ This program can be used to automatically start, split, and reset your preferred
5959
- Once you are happy with your capture region, you may unselect Live Capture Region to decrease CPU usage if you wish.
6060
- You can save a screenshot of the capture region to your split image folder using the Take Screenshot button.
6161

62-
## Max FPS
62+
## Avg. FPS
6363

64-
- Calculates the maximum comparison rate of the capture region to split images. This value will likely be much higher than needed, so it is highly recommended to limit your FPS depending on the frame rate of the game you are capturing.
64+
- Calculates the average comparison rate of the capture region to split images. This value will likely be much higher than needed (unless you [Force Full-Content-Rendering](#Full-Content-Rendering)), so it is highly recommended to limit your FPS depending on the frame rate of the game you are capturing.
6565

6666
## OPTIONS
6767

@@ -72,6 +72,10 @@ This program can be used to automatically start, split, and reset your preferred
7272
- Histograms: An explanation on Histograms comparison can be found [here](https://mpatacchiola.github.io/blog/2016/11/12/the-simplest-classifier-histogram-intersection.html). This is a great method to use if you are using several masked images.
7373
- pHash: An explanation on pHash comparison can be found [here](http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html). It is highly recommended to NOT use pHash if you use masked images. It is very inaccurate.
7474

75+
### Full Content Rendering
76+
77+
- Certain windows (namely hardware accelerated ones) won't always render their content. To work around this, you can "Force Full Content Rendering". This option is not reocmmended unless you really need it. It will cause a 10-15x performance drop based on the size of the complete window that's being captured (not the selected region, but rather the actual window size). It can also mess with some applications' rendering pipeline.
78+
7579
### Show Live Similarity
7680

7781
- Displays the live similarity between the capture region and the current split image. This number is between 0 and 1, with 1 being a perfect match.
@@ -142,11 +146,9 @@ The start image is similar to the reset image. You can only have one start image
142146
- All of these actions can also be handled by their corresponding buttons.
143147
- Note that pressing your Pause Hotkey does not serve any function in AutoSplit itself and is strictly used for the Pause flag.
144148

145-
### Group dummy splits when undoing / skipping
146-
147-
If this option is disabled, AutoSplit will not account for dummy splits when undoing/skipping. Meaning it will cycle through the images normally even if they have the dummy flag `{d}` applied to them.
149+
### Dummy splits when undoing / skipping
148150

149-
If it is enabled, AutoSplit will group dummy splits together with a real split when undoing/skipping. This basically allows you to tie one or more dummy splits to a real split to keep it as in sync as possible with the real splits in LiveSplit/wsplit.
151+
AutoSplit will group dummy splits together with a real split when undoing/skipping. This basically allows you to tie one or more dummy splits to a real split to keep it as in sync as possible with the real splits in LiveSplit/wsplit. If they are out of sync, you can always use "Previous Image" and "Next Image".
150152

151153
Examples:
152154
Given these splits: 1 dummy, 2 normal, 3 dummy, 4 dummy, 5 normal, 6 normal.
@@ -192,13 +194,11 @@ The AutoSplit LiveSplit Component will directly connect AutoSplit with LiveSplit
192194
- Click the Browse buttons to locate your AutoSplit Path (path to AutoSplit.exe) and Settings Path (path to your AutoSplit `.pkl` settings file) respectively.
193195
- If you have not yet set saved a settings file, you can do so using AutoSplit, and then go back and set your Settings Path.
194196
- Once set, click OK, and then OK again to close the Layout Editor. Right click LiveSplit -> Save Layout to save your layout. AutoSplit and its settings will now open automatically when opening that LiveSplit Layout `.lsl` file.
195-
- If you are using any dummy splits, it is recommended that you check the "Group dummy splits when undoing / skipping" checkbox when using LiveSplit integration so that your LiveSplit splits stay in sync with AutoSplit.
196197

197198
## Known Limitations
198199

199200
- For many games, it will be difficult to find a split image for the last split of the run.
200201
- The window of the capture region cannot be minimized.
201-
- Capturing a hardware accelerated window or using Windows 11 altogether will cause performance drops. But as long as the window you are capturing (not the selected region, but rather the actual window size) is not too large, you should still be able to obtain a Max FPS of over 60.
202202

203203
## Resources
204204

res/design.ui

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,10 @@
213213
</property>
214214
<property name="geometry">
215215
<rect>
216-
<x>494</x>
217-
<y>250</y>
216+
<x>340</x>
217+
<y>440</y>
218218
<width>64</width>
219-
<height>24</height>
219+
<height>21</height>
220220
</rect>
221221
</property>
222222
<property name="focusPolicy">
@@ -232,10 +232,10 @@
232232
</property>
233233
<property name="geometry">
234234
<rect>
235-
<x>560</x>
236-
<y>250</y>
235+
<x>410</x>
236+
<y>440</y>
237237
<width>61</width>
238-
<height>24</height>
238+
<height>21</height>
239239
</rect>
240240
</property>
241241
<property name="focusPolicy">
@@ -786,7 +786,7 @@
786786
<x>260</x>
787787
<y>250</y>
788788
<width>101</width>
789-
<height>24</height>
789+
<height>23</height>
790790
</rect>
791791
</property>
792792
<property name="focusPolicy">
@@ -866,9 +866,9 @@
866866
<property name="geometry">
867867
<rect>
868868
<x>125</x>
869-
<y>296</y>
869+
<y>295</y>
870870
<width>91</width>
871-
<height>22</height>
871+
<height>23</height>
872872
</rect>
873873
</property>
874874
<item>
@@ -935,22 +935,6 @@
935935
<string>Align Region</string>
936936
</property>
937937
</widget>
938-
<widget class="QCheckBox" name="group_dummy_splits_checkbox">
939-
<property name="geometry">
940-
<rect>
941-
<x>230</x>
942-
<y>442</y>
943-
<width>261</width>
944-
<height>20</height>
945-
</rect>
946-
</property>
947-
<property name="text">
948-
<string>Group dummy splits when undoing/skipping</string>
949-
</property>
950-
<property name="checked">
951-
<bool>false</bool>
952-
</property>
953-
</widget>
954938
<widget class="QPushButton" name="select_window_button">
955939
<property name="geometry">
956940
<rect>
@@ -993,7 +977,7 @@
993977
<string>Pause</string>
994978
</property>
995979
</widget>
996-
<widget class="QLineEdit" name="pause_hotkey_input">
980+
<widget class="QLineEdit" name="pause_input">
997981
<property name="geometry">
998982
<rect>
999983
<x>300</x>
@@ -1153,6 +1137,44 @@
11531137
<string>Force Full Content Rendering (slower)</string>
11541138
</property>
11551139
</widget>
1140+
<widget class="QPushButton" name="next_image_button">
1141+
<property name="enabled">
1142+
<bool>false</bool>
1143+
</property>
1144+
<property name="geometry">
1145+
<rect>
1146+
<x>560</x>
1147+
<y>250</y>
1148+
<width>61</width>
1149+
<height>23</height>
1150+
</rect>
1151+
</property>
1152+
<property name="focusPolicy">
1153+
<enum>Qt::NoFocus</enum>
1154+
</property>
1155+
<property name="text">
1156+
<string>Next Img.</string>
1157+
</property>
1158+
</widget>
1159+
<widget class="QPushButton" name="previous_image_button">
1160+
<property name="enabled">
1161+
<bool>false</bool>
1162+
</property>
1163+
<property name="geometry">
1164+
<rect>
1165+
<x>494</x>
1166+
<y>250</y>
1167+
<width>64</width>
1168+
<height>23</height>
1169+
</rect>
1170+
</property>
1171+
<property name="focusPolicy">
1172+
<enum>Qt::NoFocus</enum>
1173+
</property>
1174+
<property name="text">
1175+
<string>Prev. Img.</string>
1176+
</property>
1177+
</widget>
11561178
<zorder>split_image_folder_label</zorder>
11571179
<zorder>split_image_folder_input</zorder>
11581180
<zorder>browse_button</zorder>
@@ -1207,11 +1229,10 @@
12071229
<zorder>pause_spinbox</zorder>
12081230
<zorder>comparison_method_label</zorder>
12091231
<zorder>align_region_button</zorder>
1210-
<zorder>group_dummy_splits_checkbox</zorder>
12111232
<zorder>select_window_button</zorder>
12121233
<zorder>image_loop_label</zorder>
12131234
<zorder>pause_hotkey_label</zorder>
1214-
<zorder>pause_hotkey_input</zorder>
1235+
<zorder>pause_input</zorder>
12151236
<zorder>set_pause_hotkey_button</zorder>
12161237
<zorder>loop_checkbox</zorder>
12171238
<zorder>auto_start_on_reset_checkbox</zorder>
@@ -1221,6 +1242,8 @@
12211242
<zorder>current_similarity_threshold_number_label</zorder>
12221243
<zorder>capture_region_window_label</zorder>
12231244
<zorder>force_print_window_checkbox</zorder>
1245+
<zorder>next_image_button</zorder>
1246+
<zorder>previous_image_button</zorder>
12241247
</widget>
12251248
<widget class="QMenuBar" name="menu_bar">
12261249
<property name="geometry">
@@ -1313,7 +1336,6 @@
13131336
<tabstop>reset_input</tabstop>
13141337
<tabstop>skip_split_input</tabstop>
13151338
<tabstop>undo_split_input</tabstop>
1316-
<tabstop>group_dummy_splits_checkbox</tabstop>
13171339
</tabstops>
13181340
<resources>
13191341
<include location="resources.qrc"/>

src/AutoSplit.py

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def __init__(self, parent: Optional[QWidget] = None):
158158
self.reset_input.setEnabled(False)
159159
self.skip_split_input.setEnabled(False)
160160
self.undo_split_input.setEnabled(False)
161-
self.pause_hotkey_input.setEnabled(False)
161+
self.pause_input.setEnabled(False)
162162
self.timer_global_hotkeys_label.setText("Hotkeys Inactive - Use LiveSplit Hotkeys")
163163

164164
# Send version and process ID to stdout
@@ -183,6 +183,8 @@ def __init__(self, parent: Optional[QWidget] = None):
183183
self.reset_button.clicked.connect(self.reset)
184184
self.skip_split_button.clicked.connect(self.__skip_split)
185185
self.undo_split_button.clicked.connect(self.__undo_split)
186+
self.next_image_button.clicked.connect(lambda: self.__skip_split(True))
187+
self.previous_image_button.clicked.connect(lambda: self.__undo_split(True))
186188
self.set_split_hotkey_button.clicked.connect(lambda: set_split_hotkey(self))
187189
self.set_reset_hotkey_button.clicked.connect(lambda: set_reset_hotkey(self))
188190
self.set_skip_split_hotkey_button.clicked.connect(lambda: set_skip_split_hotkey(self))
@@ -278,7 +280,7 @@ def load_start_image(self, started_by_button: bool = False, wait_for_delay: bool
278280
if not self.is_auto_controlled \
279281
and (not self.split_input.text()
280282
or not self.reset_input.text()
281-
or not self.pause_hotkey_input.text()):
283+
or not self.pause_input.text()):
282284
error_messages.load_start_image()
283285
return
284286

@@ -457,8 +459,10 @@ def __is_current_split_out_of_range(self):
457459
return self.split_image_number < 0 \
458460
or self.split_image_number > len(self.split_images_and_loop_number) - 1
459461

460-
# undo split button and hotkey connect to here
461-
def __undo_split(self):
462+
def __undo_split(self, navigate_image_only: bool = False):
463+
"""
464+
"Undo Split" and "Prev. Img." buttons and hotkey connect to here
465+
"""
462466
# Can't undo until timer is started
463467
# or Undoing past the first image
464468
if self.start_auto_splitter_button.text() == START_AUTO_SPLITTER_TEXT \
@@ -467,7 +471,7 @@ def __undo_split(self):
467471
or self.__is_current_split_out_of_range():
468472
return
469473

470-
if self.group_dummy_splits_checkbox.isChecked():
474+
if not navigate_image_only:
471475
for i, group in enumerate(self.split_groups):
472476
if i > 0 and self.split_image_number in group:
473477
self.split_image_number = self.split_groups[i - 1][0]
@@ -476,9 +480,13 @@ def __undo_split(self):
476480
self.split_image_number -= 1
477481

478482
self.__update_split_image()
483+
if not navigate_image_only:
484+
send_command(self, "undo")
479485

480-
# skip split button and hotkey connect to here
481-
def __skip_split(self):
486+
def __skip_split(self, navigate_image_only: bool = True):
487+
"""
488+
"Skip Split" and "Next Img." buttons and hotkey connect to here
489+
"""
482490
# Can't skip or split until timer is started
483491
# or Splitting/skipping when there are no images left
484492
if self.start_auto_splitter_button.text() == START_AUTO_SPLITTER_TEXT \
@@ -487,7 +495,7 @@ def __skip_split(self):
487495
or self.__is_current_split_out_of_range():
488496
return
489497

490-
if self.group_dummy_splits_checkbox.isChecked():
498+
if not navigate_image_only:
491499
for group in self.split_groups:
492500
if self.split_image_number in group:
493501
self.split_image_number = group[-1] + 1
@@ -496,6 +504,8 @@ def __skip_split(self):
496504
self.split_image_number += 1
497505

498506
self.__update_split_image()
507+
if not navigate_image_only:
508+
send_command(self, "skip")
499509

500510
def pause(self):
501511
# TODO add what to do when you hit pause hotkey, if this even needs to be done
@@ -546,18 +556,17 @@ def __auto_splitter(self):
546556
in self.split_images]
547557
for item in flattenlist]
548558

549-
# Construct groups of splits if needed
559+
# Construct groups of splits
550560
self.split_groups = []
551-
if self.group_dummy_splits_checkbox.isChecked():
552-
current_group: list[int] = []
553-
self.split_groups.append(current_group)
561+
current_group: list[int] = []
562+
self.split_groups.append(current_group)
563+
for i, image in enumerate(self.split_images_and_loop_number):
564+
current_group.append(i)
554565

555-
for i, image in enumerate(self.split_images_and_loop_number):
556-
current_group.append(i)
566+
if not image[0].check_flag(DUMMY_FLAG) and i < len(self.split_images_and_loop_number) - 1:
567+
current_group = []
568+
self.split_groups.append(current_group)
557569

558-
if not image[0].check_flag(DUMMY_FLAG) and i < len(self.split_images_and_loop_number) - 1:
559-
current_group = []
560-
self.split_groups.append(current_group)
561570
self.gui_changes_on_start()
562571

563572
# Initialize a few attributes
@@ -615,14 +624,15 @@ def __auto_splitter(self):
615624
if self.show_highest_similarity_checkbox.isChecked()
616625
else " ")
617626

627+
# If its the last split image and last loop number, disable skip split button
628+
# If its the first split image, disable the undo split button
629+
is_last = self.split_image_number == number_of_split_images - 1 \
630+
or dummy_splits_array[self.split_image_number:].count(False) <= 1
631+
self.next_image_button.setEnabled(not is_last)
632+
self.previous_image_button.setEnabled(self.split_image_number != 0)
618633
if not self.is_auto_controlled:
619-
# if its the last split image or can't skip due to grouped dummy splits, disable skip split button
620-
is_last = self.split_image_number == number_of_split_images - 1 \
621-
or (self.group_dummy_splits_checkbox.isChecked()
622-
and dummy_splits_array[self.split_image_number:].count(False) <= 1)
623634
self.skip_split_button.setEnabled(not is_last)
624635

625-
# if its the first split image, disable the undo split button
626636
self.undo_split_button.setEnabled(self.split_image_number != 0)
627637

628638
# if the b flag is set, let similarity go above threshold first,
@@ -694,14 +704,15 @@ def __auto_splitter(self):
694704
# if its not the last split image, pause for the amount set by the user
695705
if number_of_split_images != self.split_image_number:
696706

707+
# If its the last split image and last loop number, disable skip split button
708+
# If its the first split image, disable the undo split button
709+
is_last = self.split_image_number == number_of_split_images - 1 \
710+
or dummy_splits_array[self.split_image_number:].count(False) <= 1
711+
self.next_image_button.setEnabled(not is_last)
712+
self.previous_image_button.setEnabled(self.split_image_number != 0)
697713
if not self.is_auto_controlled:
698-
# if its the last split image and last loop number, disable skip split button
699-
is_last = self.split_image_number == number_of_split_images - 1 \
700-
or (self.group_dummy_splits_checkbox.isChecked()
701-
and dummy_splits_array[self.split_image_number:].count(False) <= 1)
702714
self.skip_split_button.setEnabled(not is_last)
703715

704-
# if its the first split image, disable the undo split button
705716
self.undo_split_button.setEnabled(self.split_image_number != 0)
706717
QApplication.processEvents()
707718

@@ -737,8 +748,9 @@ def gui_changes_on_start(self):
737748
self.timer_start_image.stop()
738749
self.start_auto_splitter_button.setText("Running...")
739750
self.browse_button.setEnabled(False)
740-
self.group_dummy_splits_checkbox.setEnabled(False)
741751
self.start_image_reload_button.setEnabled(False)
752+
self.previous_image_button.setEnabled(True)
753+
self.next_image_button.setEnabled(True)
742754

743755
if not self.is_auto_controlled:
744756
self.start_auto_splitter_button.setEnabled(False)
@@ -762,8 +774,9 @@ def gui_changes_on_reset(self):
762774
self.highest_similarity_label.setText(" ")
763775
self.current_similarity_threshold_number_label.setText(" ")
764776
self.browse_button.setEnabled(True)
765-
self.group_dummy_splits_checkbox.setEnabled(True)
766777
self.start_image_reload_button.setEnabled(True)
778+
self.previous_image_button.setEnabled(False)
779+
self.next_image_button.setEnabled(False)
767780

768781
if not self.is_auto_controlled:
769782
self.start_auto_splitter_button.setEnabled(True)

0 commit comments

Comments
 (0)