diff --git a/sprites/icons/Pause.png b/sprites/icons/Pause.png new file mode 100644 index 0000000..f610d09 Binary files /dev/null and b/sprites/icons/Pause.png differ diff --git a/sprites/icons/Play.png b/sprites/icons/Play.png new file mode 100644 index 0000000..9072932 Binary files /dev/null and b/sprites/icons/Play.png differ diff --git a/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.png b/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.png index 4fb8b1f..0a6028c 100644 Binary files a/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.png and b/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.png differ diff --git a/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.txt b/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.txt index 9cbf02c..caa3018 100644 --- a/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.txt +++ b/src/main/resources/ocelot/desktop/images/spritesheet/spritesheet.txt @@ -1,5 +1,5 @@ BackgroundPattern 0 0 304 304 -BarSegment 385 434 16 4 +BarSegment 308 305 16 4 Empty 134 632 16 16 EmptySlot 246 567 18 18 Knob 203 434 50 50 @@ -7,28 +7,28 @@ KnobCenter 254 434 50 50 KnobLimits 305 434 50 50 Loading 0 305 48 448 Logo 305 0 168 200 -ShadowBorder 279 305 1 24 +ShadowBorder 279 344 1 24 ShadowCorner 233 674 24 24 -TabArrow 569 567 8 14 +TabArrow 356 452 8 14 blocks/Generic 151 632 16 16 -blocks/HologramEffect 291 305 4 4 +blocks/HologramEffect 291 344 4 4 blocks/HologramProjector1Top 168 632 16 16 blocks/HologramProjector2Top 185 632 16 16 blocks/HologramProjectorSide 202 632 16 16 buttons/BottomDrawerClose 265 567 18 18 buttons/BottomDrawerOpen 284 567 18 18 -buttons/OpenFMRadioCloseOff 404 445 7 8 -buttons/OpenFMRadioCloseOn 412 445 7 8 -buttons/OpenFMRadioRedstoneOff 359 445 8 8 -buttons/OpenFMRadioRedstoneOn 368 445 8 8 +buttons/OpenFMRadioCloseOff 327 316 7 8 +buttons/OpenFMRadioCloseOn 335 316 7 8 +buttons/OpenFMRadioRedstoneOff 282 316 8 8 +buttons/OpenFMRadioRedstoneOn 291 316 8 8 buttons/OpenFMRadioStartOff 258 674 24 24 buttons/OpenFMRadioStartOn 283 674 24 24 buttons/OpenFMRadioStopOff 308 674 24 24 buttons/OpenFMRadioStopOn 333 674 24 24 -buttons/OpenFMRadioVolumeDownOff 578 567 10 10 -buttons/OpenFMRadioVolumeDownOn 589 567 10 10 -buttons/OpenFMRadioVolumeUpOff 600 567 10 10 -buttons/OpenFMRadioVolumeUpOn 611 567 10 10 +buttons/OpenFMRadioVolumeDownOff 365 452 10 10 +buttons/OpenFMRadioVolumeDownOn 376 452 10 10 +buttons/OpenFMRadioVolumeUpOff 387 452 10 10 +buttons/OpenFMRadioVolumeUpOn 398 452 10 10 buttons/PowerOff 303 567 18 18 buttons/PowerOn 322 567 18 18 buttons/RackRelayOff 134 655 65 18 @@ -42,7 +42,7 @@ icons/ButtonClipboard 161 600 17 17 icons/ButtonRandomize 179 600 17 17 icons/CPU 287 632 16 16 icons/Card 304 632 16 16 -icons/Close 553 567 15 14 +icons/Close 218 600 15 14 icons/Code 321 632 16 16 icons/ComponentBus 338 632 16 16 icons/Copy 355 632 16 16 @@ -65,7 +65,7 @@ icons/Help 559 632 16 16 icons/Home 223 567 22 22 icons/Keyboard 576 632 16 16 icons/KeyboardOff 593 632 16 16 -icons/LMB 298 540 11 14 +icons/LMB 453 434 11 14 icons/Label 610 632 16 16 icons/LinesHorizontal 627 632 16 16 icons/Link 644 632 16 16 @@ -73,264 +73,266 @@ icons/LinkSlash 661 632 16 16 icons/Memory 678 632 16 16 icons/Microchip 695 632 16 16 icons/NA 712 632 16 16 -icons/NotificationError 322 540 11 11 -icons/NotificationInfo 334 540 11 11 -icons/NotificationWarning 346 540 11 11 +icons/NotificationError 477 434 11 11 +icons/NotificationInfo 489 434 11 11 +icons/NotificationWarning 501 434 11 11 icons/Ocelot 729 632 16 16 -icons/Pin 253 540 14 14 -icons/Plus 746 632 16 16 -icons/Power 763 632 16 16 -icons/RMB 310 540 11 14 -icons/Restart 780 632 16 16 -icons/Save 797 632 16 16 -icons/SaveAs 814 632 16 16 -icons/Server 831 632 16 16 -icons/SettingsKeymap 201 540 12 17 -icons/SettingsSound 214 540 12 17 -icons/SettingsSystem 227 540 12 17 -icons/SettingsUI 240 540 12 17 -icons/SideAny 358 540 11 11 -icons/SideDown 370 540 11 11 -icons/SideEast 382 540 11 11 -icons/SideNone 394 540 11 11 -icons/SideNorth 406 540 11 11 -icons/SideSouth 418 540 11 11 -icons/SideUndefined 430 540 11 11 -icons/SideUp 442 540 11 11 -icons/SideWest 454 540 11 11 -icons/Tier0 848 632 16 16 -icons/Tier1 865 632 16 16 -icons/Tier2 882 632 16 16 -icons/Tiers 899 632 16 16 -icons/Unpin 268 540 14 14 -icons/WaveLFSR 237 600 24 10 -icons/WaveNoise 262 600 24 10 -icons/WaveSawtooth 287 600 24 10 -icons/WaveSine 312 600 24 10 -icons/WaveSquare 337 600 24 10 -icons/WaveTriangle 362 600 24 10 -icons/Window 916 632 16 16 -icons/WireArrowLeft 281 305 4 8 -icons/WireArrowRight 286 305 4 8 +icons/Pause 746 632 16 16 +icons/Pin 408 434 14 14 +icons/Play 763 632 16 16 +icons/Plus 780 632 16 16 +icons/Power 797 632 16 16 +icons/RMB 465 434 11 14 +icons/Restart 814 632 16 16 +icons/Save 831 632 16 16 +icons/SaveAs 848 632 16 16 +icons/Server 865 632 16 16 +icons/SettingsKeymap 356 434 12 17 +icons/SettingsSound 369 434 12 17 +icons/SettingsSystem 382 434 12 17 +icons/SettingsUI 395 434 12 17 +icons/SideAny 513 434 11 11 +icons/SideDown 525 434 11 11 +icons/SideEast 537 434 11 11 +icons/SideNone 549 434 11 11 +icons/SideNorth 561 434 11 11 +icons/SideSouth 573 434 11 11 +icons/SideUndefined 585 434 11 11 +icons/SideUp 597 434 11 11 +icons/SideWest 609 434 11 11 +icons/Tier0 882 632 16 16 +icons/Tier1 899 632 16 16 +icons/Tier2 916 632 16 16 +icons/Tiers 933 632 16 16 +icons/Unpin 423 434 14 14 +icons/WaveLFSR 254 540 24 10 +icons/WaveNoise 279 540 24 10 +icons/WaveSawtooth 304 540 24 10 +icons/WaveSine 329 540 24 10 +icons/WaveSquare 354 540 24 10 +icons/WaveTriangle 379 540 24 10 +icons/Window 950 632 16 16 +icons/WireArrowLeft 281 344 4 8 +icons/WireArrowRight 286 344 4 8 items/APU0 49 655 16 96 items/APU1 66 655 16 96 items/APU2 83 655 16 96 -items/CPU0 933 632 16 16 -items/CPU1 950 632 16 16 -items/CPU2 967 632 16 16 -items/CardBase 984 632 16 16 -items/CircuitBoard 1001 632 16 16 -items/ComponentBus0 358 674 16 16 -items/ComponentBus1 375 674 16 16 -items/ComponentBus2 392 674 16 16 -items/ComponentBus3 409 674 16 16 +items/CPU0 967 632 16 16 +items/CPU1 984 632 16 16 +items/CPU2 1001 632 16 16 +items/CardBase 358 674 16 16 +items/CircuitBoard 375 674 16 16 +items/ComponentBus0 392 674 16 16 +items/ComponentBus1 409 674 16 16 +items/ComponentBus2 426 674 16 16 +items/ComponentBus3 443 674 16 16 items/DataCard0 49 526 16 128 items/DataCard1 66 526 16 128 items/DataCard2 83 526 16 128 -items/DebugCard 426 674 16 16 -items/DiskDriveMountable 443 674 16 16 -items/EEPROM 460 674 16 16 -items/FloppyDisk_dyeBlack 477 674 16 16 -items/FloppyDisk_dyeBlue 494 674 16 16 -items/FloppyDisk_dyeBrown 511 674 16 16 -items/FloppyDisk_dyeCyan 528 674 16 16 -items/FloppyDisk_dyeGray 545 674 16 16 -items/FloppyDisk_dyeGreen 562 674 16 16 -items/FloppyDisk_dyeLightBlue 579 674 16 16 -items/FloppyDisk_dyeLightGray 596 674 16 16 -items/FloppyDisk_dyeLime 613 674 16 16 -items/FloppyDisk_dyeMagenta 630 674 16 16 -items/FloppyDisk_dyeOrange 647 674 16 16 -items/FloppyDisk_dyePink 664 674 16 16 -items/FloppyDisk_dyePurple 681 674 16 16 -items/FloppyDisk_dyeRed 698 674 16 16 -items/FloppyDisk_dyeWhite 715 674 16 16 -items/FloppyDisk_dyeYellow 732 674 16 16 -items/GraphicsCard0 749 674 16 16 -items/GraphicsCard1 766 674 16 16 -items/GraphicsCard2 783 674 16 16 -items/HardDiskDrive0 800 674 16 16 -items/HardDiskDrive1 817 674 16 16 -items/HardDiskDrive2 834 674 16 16 +items/DebugCard 460 674 16 16 +items/DiskDriveMountable 477 674 16 16 +items/EEPROM 494 674 16 16 +items/FloppyDisk_dyeBlack 511 674 16 16 +items/FloppyDisk_dyeBlue 528 674 16 16 +items/FloppyDisk_dyeBrown 545 674 16 16 +items/FloppyDisk_dyeCyan 562 674 16 16 +items/FloppyDisk_dyeGray 579 674 16 16 +items/FloppyDisk_dyeGreen 596 674 16 16 +items/FloppyDisk_dyeLightBlue 613 674 16 16 +items/FloppyDisk_dyeLightGray 630 674 16 16 +items/FloppyDisk_dyeLime 647 674 16 16 +items/FloppyDisk_dyeMagenta 664 674 16 16 +items/FloppyDisk_dyeOrange 681 674 16 16 +items/FloppyDisk_dyePink 698 674 16 16 +items/FloppyDisk_dyePurple 715 674 16 16 +items/FloppyDisk_dyeRed 732 674 16 16 +items/FloppyDisk_dyeWhite 749 674 16 16 +items/FloppyDisk_dyeYellow 766 674 16 16 +items/GraphicsCard0 783 674 16 16 +items/GraphicsCard1 800 674 16 16 +items/GraphicsCard2 817 674 16 16 +items/HardDiskDrive0 834 674 16 16 +items/HardDiskDrive1 851 674 16 16 +items/HardDiskDrive2 868 674 16 16 items/InternetCard 143 567 16 32 items/LinkedCard 100 655 16 96 -items/Memory0 851 674 16 16 -items/Memory1 868 674 16 16 -items/Memory2 885 674 16 16 -items/Memory3 902 674 16 16 -items/Memory4 919 674 16 16 -items/Memory5 936 674 16 16 -items/Memory6 953 674 16 16 -items/NetworkCard 970 674 16 16 +items/Memory0 885 674 16 16 +items/Memory1 902 674 16 16 +items/Memory2 919 674 16 16 +items/Memory3 936 674 16 16 +items/Memory4 953 674 16 16 +items/Memory5 970 674 16 16 +items/Memory6 987 674 16 16 +items/NetworkCard 1004 674 16 16 items/OcelotCard 100 526 16 128 -items/RedstoneCard0 987 674 16 16 -items/RedstoneCard1 1004 674 16 16 +items/RedstoneCard0 134 707 16 16 +items/RedstoneCard1 151 707 16 16 items/SelfDestructingCard 160 567 16 32 -items/Server0 134 707 16 16 -items/Server1 151 707 16 16 -items/Server2 168 707 16 16 -items/Server3 185 707 16 16 +items/Server0 168 707 16 16 +items/Server1 185 707 16 16 +items/Server2 202 707 16 16 +items/Server3 219 707 16 16 items/SoundCard 117 526 16 128 -items/TapeCopper 202 707 16 16 -items/TapeDiamond 219 707 16 16 -items/TapeGold 236 707 16 16 -items/TapeGreg 253 707 16 16 -items/TapeIg 270 707 16 16 -items/TapeIron 287 707 16 16 -items/TapeNetherStar 304 707 16 16 -items/TapeSteel 321 707 16 16 -items/WirelessNetworkCard0 338 707 16 16 -items/WirelessNetworkCard1 355 707 16 16 -light-panel/BookmarkLeft 218 600 18 14 +items/TapeCopper 236 707 16 16 +items/TapeDiamond 253 707 16 16 +items/TapeGold 270 707 16 16 +items/TapeGreg 287 707 16 16 +items/TapeIg 304 707 16 16 +items/TapeIron 321 707 16 16 +items/TapeNetherStar 338 707 16 16 +items/TapeSteel 355 707 16 16 +items/WirelessNetworkCard0 372 707 16 16 +items/WirelessNetworkCard1 389 707 16 16 +light-panel/BookmarkLeft 235 540 18 14 light-panel/BookmarkRight 197 600 20 14 -light-panel/BorderB 296 305 4 4 -light-panel/BorderL 284 314 4 2 -light-panel/BorderR 301 305 4 4 -light-panel/BorderT 306 305 4 4 -light-panel/CornerBL 311 305 4 4 -light-panel/CornerBR 316 305 4 4 -light-panel/CornerTL 321 305 4 4 -light-panel/CornerTR 326 305 4 4 -light-panel/Fill 410 305 2 2 -light-panel/Vent 356 434 2 38 -nodes/Cable 377 445 8 8 -nodes/Camera 372 707 16 16 -nodes/Chest 283 540 14 14 -nodes/HologramProjector0 389 707 16 16 -nodes/HologramProjector1 406 707 16 16 -nodes/IronNoteBlock 423 707 16 16 -nodes/Lamp 440 707 16 16 -nodes/LampFrame 457 707 16 16 +light-panel/BorderB 296 344 4 4 +light-panel/BorderL 284 353 4 2 +light-panel/BorderR 301 344 4 4 +light-panel/BorderT 306 344 4 4 +light-panel/CornerBL 311 344 4 4 +light-panel/CornerBR 316 344 4 4 +light-panel/CornerTL 321 344 4 4 +light-panel/CornerTR 326 344 4 4 +light-panel/Fill 410 344 2 2 +light-panel/Vent 279 305 2 38 +nodes/Cable 300 316 8 8 +nodes/Camera 406 707 16 16 +nodes/Chest 438 434 14 14 +nodes/HologramProjector0 423 707 16 16 +nodes/HologramProjector1 440 707 16 16 +nodes/IronNoteBlock 457 707 16 16 +nodes/Lamp 474 707 16 16 +nodes/LampFrame 491 707 16 16 nodes/LampGlow 49 305 128 128 -nodes/NewNode 474 707 16 16 -nodes/NoteBlock 491 707 16 16 -nodes/OpenFMRadio 508 707 16 16 -nodes/Relay 525 707 16 16 -nodes/TapeDrive 542 707 16 16 -nodes/computer/Default 559 707 16 16 -nodes/computer/DiskActivity 576 707 16 16 -nodes/computer/Error 593 707 16 16 -nodes/computer/On 610 707 16 16 -nodes/disk-drive/Default 627 707 16 16 -nodes/disk-drive/DiskActivity 644 707 16 16 -nodes/disk-drive/Floppy 661 707 16 16 +nodes/NewNode 508 707 16 16 +nodes/NoteBlock 525 707 16 16 +nodes/OpenFMRadio 542 707 16 16 +nodes/Relay 559 707 16 16 +nodes/TapeDrive 576 707 16 16 +nodes/computer/Default 593 707 16 16 +nodes/computer/DiskActivity 610 707 16 16 +nodes/computer/Error 627 707 16 16 +nodes/computer/On 644 707 16 16 +nodes/disk-drive/Default 661 707 16 16 +nodes/disk-drive/DiskActivity 678 707 16 16 +nodes/disk-drive/Floppy 695 707 16 16 nodes/holidays/Christmas 134 674 32 32 nodes/holidays/Halloween 167 674 32 32 nodes/holidays/Valentines 200 674 32 32 -nodes/microcontroller/Default 678 707 16 16 -nodes/microcontroller/Error 695 707 16 16 -nodes/microcontroller/On 712 707 16 16 +nodes/microcontroller/Default 712 707 16 16 +nodes/microcontroller/Error 729 707 16 16 +nodes/microcontroller/On 746 707 16 16 nodes/ocelot-block/Default 117 655 16 80 -nodes/ocelot-block/Rx 729 707 16 16 -nodes/ocelot-block/Tx 746 707 16 16 -nodes/rack/Default 763 707 16 16 -nodes/rack/Empty 780 707 16 16 -nodes/rack/drive/0/Default 797 707 16 16 -nodes/rack/drive/0/DiskActivity 814 707 16 16 -nodes/rack/drive/0/Floppy 831 707 16 16 -nodes/rack/drive/1/Default 848 707 16 16 -nodes/rack/drive/1/DiskActivity 865 707 16 16 -nodes/rack/drive/1/Floppy 882 707 16 16 -nodes/rack/drive/2/Default 899 707 16 16 -nodes/rack/drive/2/DiskActivity 916 707 16 16 -nodes/rack/drive/2/Floppy 933 707 16 16 -nodes/rack/drive/3/Default 950 707 16 16 -nodes/rack/drive/3/DiskActivity 967 707 16 16 -nodes/rack/drive/3/Floppy 984 707 16 16 -nodes/rack/drive/Floppy 1001 707 16 16 -nodes/rack/server/0/Default 266 655 16 16 -nodes/rack/server/0/DiskActivity 283 655 16 16 -nodes/rack/server/0/Error 300 655 16 16 -nodes/rack/server/0/NetworkActivity 317 655 16 16 -nodes/rack/server/0/On 334 655 16 16 -nodes/rack/server/1/Default 351 655 16 16 -nodes/rack/server/1/DiskActivity 368 655 16 16 -nodes/rack/server/1/Error 385 655 16 16 -nodes/rack/server/1/NetworkActivity 402 655 16 16 -nodes/rack/server/1/On 419 655 16 16 -nodes/rack/server/2/Default 436 655 16 16 -nodes/rack/server/2/DiskActivity 453 655 16 16 -nodes/rack/server/2/Error 470 655 16 16 -nodes/rack/server/2/NetworkActivity 487 655 16 16 -nodes/rack/server/2/On 504 655 16 16 -nodes/rack/server/3/Default 521 655 16 16 -nodes/rack/server/3/DiskActivity 538 655 16 16 -nodes/rack/server/3/Error 555 655 16 16 -nodes/rack/server/3/NetworkActivity 572 655 16 16 -nodes/rack/server/3/On 589 655 16 16 -nodes/raid/0/DiskActivity 606 655 16 16 -nodes/raid/0/Error 623 655 16 16 -nodes/raid/1/DiskActivity 640 655 16 16 -nodes/raid/1/Error 657 655 16 16 -nodes/raid/2/DiskActivity 674 655 16 16 -nodes/raid/2/Error 691 655 16 16 -nodes/raid/Default 708 655 16 16 -nodes/screen/BottomLeft 725 655 16 16 -nodes/screen/BottomMiddle 742 655 16 16 -nodes/screen/BottomRight 759 655 16 16 -nodes/screen/ColumnBottom 776 655 16 16 -nodes/screen/ColumnMiddle 793 655 16 16 -nodes/screen/ColumnTop 810 655 16 16 -nodes/screen/Middle 827 655 16 16 -nodes/screen/MiddleLeft 844 655 16 16 -nodes/screen/MiddleRight 861 655 16 16 -nodes/screen/PowerOnOverlay 878 655 16 16 -nodes/screen/RowLeft 895 655 16 16 -nodes/screen/RowMiddle 912 655 16 16 -nodes/screen/RowRight 929 655 16 16 -nodes/screen/Standalone 946 655 16 16 -nodes/screen/TopLeft 963 655 16 16 -nodes/screen/TopMiddle 980 655 16 16 -nodes/screen/TopRight 997 655 16 16 -panel/BorderB 331 305 4 4 -panel/BorderL 289 314 4 2 -panel/BorderR 336 305 4 4 -panel/BorderT 341 305 4 4 -panel/CornerBL 346 305 4 4 -panel/CornerBR 351 305 4 4 -panel/CornerTL 356 305 4 4 -panel/CornerTR 361 305 4 4 -panel/Fill 413 305 2 2 -particles/Note 377 434 7 10 +nodes/ocelot-block/Rx 763 707 16 16 +nodes/ocelot-block/Tx 780 707 16 16 +nodes/rack/Default 797 707 16 16 +nodes/rack/Empty 814 707 16 16 +nodes/rack/drive/0/Default 831 707 16 16 +nodes/rack/drive/0/DiskActivity 848 707 16 16 +nodes/rack/drive/0/Floppy 865 707 16 16 +nodes/rack/drive/1/Default 882 707 16 16 +nodes/rack/drive/1/DiskActivity 899 707 16 16 +nodes/rack/drive/1/Floppy 916 707 16 16 +nodes/rack/drive/2/Default 933 707 16 16 +nodes/rack/drive/2/DiskActivity 950 707 16 16 +nodes/rack/drive/2/Floppy 967 707 16 16 +nodes/rack/drive/3/Default 984 707 16 16 +nodes/rack/drive/3/DiskActivity 1001 707 16 16 +nodes/rack/drive/3/Floppy 266 655 16 16 +nodes/rack/drive/Floppy 283 655 16 16 +nodes/rack/server/0/Default 300 655 16 16 +nodes/rack/server/0/DiskActivity 317 655 16 16 +nodes/rack/server/0/Error 334 655 16 16 +nodes/rack/server/0/NetworkActivity 351 655 16 16 +nodes/rack/server/0/On 368 655 16 16 +nodes/rack/server/1/Default 385 655 16 16 +nodes/rack/server/1/DiskActivity 402 655 16 16 +nodes/rack/server/1/Error 419 655 16 16 +nodes/rack/server/1/NetworkActivity 436 655 16 16 +nodes/rack/server/1/On 453 655 16 16 +nodes/rack/server/2/Default 470 655 16 16 +nodes/rack/server/2/DiskActivity 487 655 16 16 +nodes/rack/server/2/Error 504 655 16 16 +nodes/rack/server/2/NetworkActivity 521 655 16 16 +nodes/rack/server/2/On 538 655 16 16 +nodes/rack/server/3/Default 555 655 16 16 +nodes/rack/server/3/DiskActivity 572 655 16 16 +nodes/rack/server/3/Error 589 655 16 16 +nodes/rack/server/3/NetworkActivity 606 655 16 16 +nodes/rack/server/3/On 623 655 16 16 +nodes/raid/0/DiskActivity 640 655 16 16 +nodes/raid/0/Error 657 655 16 16 +nodes/raid/1/DiskActivity 674 655 16 16 +nodes/raid/1/Error 691 655 16 16 +nodes/raid/2/DiskActivity 708 655 16 16 +nodes/raid/2/Error 725 655 16 16 +nodes/raid/Default 742 655 16 16 +nodes/screen/BottomLeft 759 655 16 16 +nodes/screen/BottomMiddle 776 655 16 16 +nodes/screen/BottomRight 793 655 16 16 +nodes/screen/ColumnBottom 810 655 16 16 +nodes/screen/ColumnMiddle 827 655 16 16 +nodes/screen/ColumnTop 844 655 16 16 +nodes/screen/Middle 861 655 16 16 +nodes/screen/MiddleLeft 878 655 16 16 +nodes/screen/MiddleRight 895 655 16 16 +nodes/screen/PowerOnOverlay 912 655 16 16 +nodes/screen/RowLeft 929 655 16 16 +nodes/screen/RowMiddle 946 655 16 16 +nodes/screen/RowRight 963 655 16 16 +nodes/screen/Standalone 980 655 16 16 +nodes/screen/TopLeft 997 655 16 16 +nodes/screen/TopMiddle 201 540 16 16 +nodes/screen/TopRight 218 540 16 16 +panel/BorderB 331 344 4 4 +panel/BorderL 289 353 4 2 +panel/BorderR 336 344 4 4 +panel/BorderT 341 344 4 4 +panel/CornerBL 346 344 4 4 +panel/CornerBR 351 344 4 4 +panel/CornerTL 356 344 4 4 +panel/CornerTR 361 344 4 4 +panel/Fill 413 344 2 2 +particles/Note 300 305 7 10 particles/Smoke 134 567 8 64 -screen/InnerBorderB 281 321 2 4 -screen/InnerBorderT 284 321 2 4 -screen/InnerCornerBL 366 305 4 4 -screen/InnerCornerBR 371 305 4 4 -screen/InnerCornerTL 376 305 4 4 -screen/InnerCornerTR 381 305 4 4 -screen/OuterBorderT 281 314 2 6 -screen/OuterCornerBL 386 445 8 8 -screen/OuterCornerBR 395 445 8 8 -screen/OuterCornerTL 359 434 8 10 -screen/OuterCornerTR 368 434 8 10 -window/BorderDark 406 305 1 4 -window/BorderLight 408 305 1 4 -window/CornerBL 386 305 4 4 -window/CornerBR 391 305 4 4 -window/CornerTL 396 305 4 4 -window/CornerTR 401 305 4 4 +screen/InnerBorderB 281 360 2 4 +screen/InnerBorderT 284 360 2 4 +screen/InnerCornerBL 366 344 4 4 +screen/InnerCornerBR 371 344 4 4 +screen/InnerCornerTL 376 344 4 4 +screen/InnerCornerTR 381 344 4 4 +screen/OuterBorderT 281 353 2 6 +screen/OuterCornerBL 309 316 8 8 +screen/OuterCornerBR 318 316 8 8 +screen/OuterCornerTL 282 305 8 10 +screen/OuterCornerTR 291 305 8 10 +window/BorderDark 406 344 1 4 +window/BorderLight 408 344 1 4 +window/CornerBL 386 344 4 4 +window/CornerBR 391 344 4 4 +window/CornerTL 396 344 4 4 +window/CornerTR 401 344 4 4 window/OpenFMRadio 474 0 232 105 window/case/Motherboard 123 434 79 70 window/rack/Lines 49 434 73 91 window/rack/Motherboard 178 305 100 78 -window/rack/NetworkBack 293 326 1 2 -window/rack/NetworkBottom 295 326 1 2 -window/rack/NetworkConnector 297 326 1 2 -window/rack/NetworkLeft 299 326 1 2 -window/rack/NetworkRight 301 326 1 2 -window/rack/NetworkTop 303 326 1 2 -window/rack/NodeBack 287 321 5 1 -window/rack/NodeBottom 293 321 5 1 -window/rack/NodeLeft 299 321 5 1 -window/rack/NodeRight 305 321 5 1 -window/rack/NodeTop 311 321 5 1 -window/rack/SideBack 281 326 1 3 -window/rack/SideBottom 283 326 1 3 -window/rack/SideConnector 285 326 1 3 -window/rack/SideLeft 287 326 1 3 -window/rack/SideRight 289 326 1 3 -window/rack/SideTop 291 326 1 3 +window/rack/NetworkBack 293 365 1 2 +window/rack/NetworkBottom 295 365 1 2 +window/rack/NetworkConnector 297 365 1 2 +window/rack/NetworkLeft 299 365 1 2 +window/rack/NetworkRight 301 365 1 2 +window/rack/NetworkTop 303 365 1 2 +window/rack/NodeBack 287 360 5 1 +window/rack/NodeBottom 293 360 5 1 +window/rack/NodeLeft 299 360 5 1 +window/rack/NodeRight 305 360 5 1 +window/rack/NodeTop 311 360 5 1 +window/rack/SideBack 281 365 1 3 +window/rack/SideBottom 283 365 1 3 +window/rack/SideConnector 285 365 1 3 +window/rack/SideLeft 287 365 1 3 +window/rack/SideRight 289 365 1 3 +window/rack/SideTop 291 365 1 3 window/raid/Slots 134 540 66 26 window/tape/Back 341 567 20 15 window/tape/BackPressed 362 567 20 15 diff --git a/src/main/scala/ocelot/desktop/OcelotDesktop.scala b/src/main/scala/ocelot/desktop/OcelotDesktop.scala index 38cc86c..0844fd6 100644 --- a/src/main/scala/ocelot/desktop/OcelotDesktop.scala +++ b/src/main/scala/ocelot/desktop/OcelotDesktop.scala @@ -48,6 +48,16 @@ object OcelotDesktop extends LoggingConfiguration with Logging { val tpsCounter = new FPSCalculator val ticker = new Ticker + private var _emulationPaused = false + + def emulationPaused: Boolean = _emulationPaused + + def emulationPaused_=(paused: Boolean): Unit = { + _emulationPaused = paused + // avoid sudden jumps of TPS counter after a pause + if (!paused) tpsCounter.skipFrame() + } + private val TickerIntervalHistorySize = 5 val tickerIntervalHistory = new mutable.Queue[Duration](TickerIntervalHistorySize) @@ -160,16 +170,18 @@ object OcelotDesktop extends LoggingConfiguration with Logging { val currentThread = Thread.currentThread() while (!currentThread.isInterrupted) { - Profiler.measure("tick") { - withTickLockAcquired { - workspace.update() - updateThreadTasks.run() + if (!emulationPaused) { + Profiler.measure("tick") { + withTickLockAcquired { + workspace.update() + updateThreadTasks.run() - tpsCounter.tick() + tpsCounter.tick() + } } } - ticker.waitNext() + ticker.waitNext(!emulationPaused) } } catch { case _: InterruptedException => // ignore diff --git a/src/main/scala/ocelot/desktop/graphics/IconSource.scala b/src/main/scala/ocelot/desktop/graphics/IconSource.scala index 10d3d56..b14d19f 100644 --- a/src/main/scala/ocelot/desktop/graphics/IconSource.scala +++ b/src/main/scala/ocelot/desktop/graphics/IconSource.scala @@ -246,6 +246,9 @@ object IconSource { val DragLMB: IconSource = get("DragLMB") val DragRMB: IconSource = get("DragRMB") + val Play: IconSource = get("Play") + val Pause: IconSource = get("Pause") + val WireArrowLeft: IconSource = get("WireArrowLeft") val WireArrowRight: IconSource = get("WireArrowRight") diff --git a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala index 0bfb149..5f771ea 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala @@ -142,7 +142,7 @@ class IconButton( override def minimumSize: Size2D = releasedIconSize.max(pressedIconSize) + (padding * 2.0f) override def maximumSize: Size2D = minimumSize - private val labelTooltip = tooltip.map(label => new LabelTooltip(label)) + protected val labelTooltip: Option[LabelTooltip] = tooltip.map(label => new LabelTooltip(label)) def borderColor: Color = ColorScheme("ButtonBorder") diff --git a/src/main/scala/ocelot/desktop/ui/widget/WorkspaceView.scala b/src/main/scala/ocelot/desktop/ui/widget/WorkspaceView.scala index 965ca88..3692160 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/WorkspaceView.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/WorkspaceView.scala @@ -14,7 +14,7 @@ import ocelot.desktop.ui.layout.{CopyLayout, Layout} import ocelot.desktop.ui.particle.ParticleSystem import ocelot.desktop.ui.widget.WorkspaceView.NodeLoadException import ocelot.desktop.ui.widget.window.{NodeSelector, ProfilerWindow, WindowPool} -import ocelot.desktop.util.Keybind.{Center, Profiler} +import ocelot.desktop.util.Keybind.{Center, PauseEmulation, Profiler} import ocelot.desktop.util.Keymap.Press import ocelot.desktop.util.ReflectionUtils.findUnaryConstructor import ocelot.desktop.util.animation.ValueAnimation @@ -273,6 +273,9 @@ class WorkspaceView extends Widget with Persistable with MouseHandler with Hover case Press(Center) => moveCameraOffset(-cameraOffset) + + case Press(PauseEmulation) => + OcelotDesktop.emulationPaused = !OcelotDesktop.emulationPaused } private def moveCameraOffset(delta: Vector2D): Unit = { @@ -643,6 +646,15 @@ class WorkspaceView extends Widget with Persistable with MouseHandler with Hover particleSystem.draw(g) drawChildren(g) + + if (OcelotDesktop.emulationPaused) { + g.fontSizeMultiplier = 2.0f + g.foreground = Color.White + g.alphaMultiplier = (math.sin(System.currentTimeMillis() * math.Pi / 180 / 3).toFloat + 1f) / 2.0f + g.text(size.width - 130, 60, "|| PAUSE") + g.fontSizeMultiplier = 1.0f + g.alphaMultiplier = 1.0f + } } override def update(): Unit = { diff --git a/src/main/scala/ocelot/desktop/ui/widget/settings/KeymapSettingsTab.scala b/src/main/scala/ocelot/desktop/ui/widget/settings/KeymapSettingsTab.scala index cf91f72..457ce47 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/settings/KeymapSettingsTab.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/settings/KeymapSettingsTab.scala @@ -71,6 +71,7 @@ class KeymapSettingsTab extends SettingsTab { Keybind.QuickSave, Keybind.QuickLoad, Keybind.Screenshot, + Keybind.PauseEmulation, )) }, Padding2D(bottom = 8)) } diff --git a/src/main/scala/ocelot/desktop/ui/widget/statusbar/StatusBar.scala b/src/main/scala/ocelot/desktop/ui/widget/statusbar/StatusBar.scala index a61ffb7..438cc94 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/statusbar/StatusBar.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/statusbar/StatusBar.scala @@ -55,85 +55,89 @@ class StatusBar extends Widget { override def hThumbVisible: Boolean = false } - children :+= new PaddingBox( - { - object TpsLabel extends Label with MouseHandler with HoverHandler { - override protected def receiveClickEvents: Boolean = true + private lazy val hoverBoxWithPauseButton: HoverBox = new HoverBox(new IconButton( + IconSource.Icons.Pause, + IconSource.Icons.Play, + mode = IconButton.Mode.Switch, + pressedColor = ColorScheme("StatusBarForeground"), + releasedColor = ColorScheme("StatusBarForeground"), + tooltip = Some("Pause emulation"), + model = new IconButton.ReadOnlyModel(() => OcelotDesktop.emulationPaused), + ) { + eventHandlers += { + case HoverEvent(HoverEvent.State.Enter) => + hoverBoxWithPauseButton.startHoverEnterAnimation() + case HoverEvent(HoverEvent.State.Leave) => + hoverBoxWithPauseButton.startHoverLeaveAnimation() + } + override def onPressed(): Unit = { + OcelotDesktop.emulationPaused = true + labelTooltip.foreach(_.setText("Resume emulation")) + } + override def onReleased(): Unit = { + OcelotDesktop.emulationPaused = false + labelTooltip.foreach(_.setText("Pause emulation")) + } + }, Padding2D(left = 2, right = 2)) - eventHandlers += { - case ClickEvent(MouseEvent.Button.Left, _) => + private lazy val hoverBoxWithTpsLabel: HoverBox = new HoverBox(new Label with MouseHandler with HoverHandler { + override protected def receiveClickEvents: Boolean = true + + eventHandlers += { + case ClickEvent(MouseEvent.Button.Left, _) => + new ChangeSimulationSpeedDialog().show() + + case ClickEvent(MouseEvent.Button.Right, pos) => + val menu = new ContextMenu + menu.addEntry( + ContextMenuEntry("Change simulation speed", IconSource.Icons.Edit) { new ChangeSimulationSpeedDialog().show() - - case ClickEvent(MouseEvent.Button.Right, pos) => - val menu = new ContextMenu - menu.addEntry( - ContextMenuEntry("Change simulation speed", IconSource.Icons.Edit) { - new ChangeSimulationSpeedDialog().show() - } - ) - - menu.addEntry( - ContextMenuEntry("Reset simulation speed", IconSource.Icons.Restart) { - OcelotDesktop.ticker.tickInterval = 50.millis - } - ) - - if (OcelotDesktop.tickerIntervalHistory.nonEmpty) - menu.addSeparator() - - for (elem <- OcelotDesktop.tickerIntervalHistory.reverseIterator) { - menu.addEntry( - ContextMenuEntry((1_000_000f / elem.toMicros).toString) { - OcelotDesktop.ticker.tickInterval = elem - } - ) - } - - root.get.contextMenus.open(menu, pos) - - case HoverEvent(HoverEvent.State.Enter) => - HoverBox.startHoverEnterAnimation() - - case HoverEvent(HoverEvent.State.Leave) => - HoverBox.startHoverLeaveAnimation() - } - - override def update(): Unit = { - super.update() - - if (isHovered) { - root.get.statusBar.addMouseEntry(IconSource.Icons.RMB, "Change simulation speed") } + ) + + menu.addEntry( + ContextMenuEntry("Reset simulation speed", IconSource.Icons.Restart) { + OcelotDesktop.ticker.tickInterval = 50.millis + } + ) + + if (OcelotDesktop.tickerIntervalHistory.nonEmpty) + menu.addSeparator() + + for (elem <- OcelotDesktop.tickerIntervalHistory.reverseIterator) { + menu.addEntry( + ContextMenuEntry((1_000_000f / elem.toMicros).toString) { + OcelotDesktop.ticker.tickInterval = elem + } + ) } - override def maximumSize: Size2D = minimumSize + root.get.contextMenus.open(menu, pos) - override def color: Color = ColorScheme("StatusBarTPS") + case HoverEvent(HoverEvent.State.Enter) => + hoverBoxWithTpsLabel.startHoverEnterAnimation() - override def text: String = f"TPS: ${OcelotDesktop.tpsCounter.fps}%02.1f" + case HoverEvent(HoverEvent.State.Leave) => + hoverBoxWithTpsLabel.startHoverLeaveAnimation() + } + + override def update(): Unit = { + super.update() + + if (isHovered) { + root.get.statusBar.addMouseEntry(IconSource.Icons.RMB, "Change simulation speed") } + } - object HoverBox extends PaddingBox(TpsLabel, Padding2D(left = 8, right = 8)) with HoverAnimation { - override def receiveMouseEvents: Boolean = true + override def maximumSize: Size2D = minimumSize - override protected val hoverAnimationColorActive: Color = ColorScheme("StatusBarActive") - override protected val hoverAnimationColorDefault: Color = hoverAnimationColorActive.toRGBANorm.withAlpha(0) + override def color: Color = ColorScheme("StatusBarTPS") - // public re-exports - override def startHoverEnterAnimation(): Unit = super.startHoverEnterAnimation() + override def text: String = f"TPS: ${OcelotDesktop.tpsCounter.fps}%02.1f" + }) - override def startHoverLeaveAnimation(): Unit = super.startHoverLeaveAnimation() - - override def draw(g: Graphics): Unit = { - g.rect(bounds, hoverAnimation.color) - super.draw(g) - } - } - - HoverBox - }, - Padding2D(left = 8), - ) + children :+= hoverBoxWithPauseButton + children :+= new PaddingBox(hoverBoxWithTpsLabel, Padding2D(left = 8)) def addMouseEntry(icon: IconSource, text: String): Unit = { if (!keyMouseEntries.children.collect({ case e: MouseEntry => e.icon }).contains(icon)) { @@ -160,4 +164,21 @@ class StatusBar extends Widget { keyEntries.children = ArraySeq.empty keyMouseEntries.children = ArraySeq.empty } + + private class HoverBox(widget: Widget, padding: Padding2D = Padding2D(left = 8, right = 8)) extends PaddingBox(widget, padding) with HoverAnimation { + override def receiveMouseEvents: Boolean = true + + override protected val hoverAnimationColorActive: Color = ColorScheme("StatusBarActive") + override protected val hoverAnimationColorDefault: Color = hoverAnimationColorActive.toRGBANorm.withAlpha(0) + + // public re-exports + override def startHoverEnterAnimation(): Unit = super.startHoverEnterAnimation() + + override def startHoverLeaveAnimation(): Unit = super.startHoverLeaveAnimation() + + override def draw(g: Graphics): Unit = { + g.rect(bounds, hoverAnimation.color) + super.draw(g) + } + } } diff --git a/src/main/scala/ocelot/desktop/ui/widget/tooltip/LabelTooltip.scala b/src/main/scala/ocelot/desktop/ui/widget/tooltip/LabelTooltip.scala index 04e18c7..f78b9b5 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/tooltip/LabelTooltip.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/tooltip/LabelTooltip.scala @@ -5,19 +5,22 @@ import ocelot.desktop.color.Color import ocelot.desktop.geometry.Padding2D import ocelot.desktop.ui.widget.Label +import scala.collection.immutable.ArraySeq + class LabelTooltip(text: String) extends Tooltip { override val DelayTime: Float = Settings.get.tooltipDelayUI - for (line <- text.split("\n")) { - body.children :+= new Label { - override def text: String = line - override def color: Color = Color.White + setText(text) + + def setText(value: String): Unit = { + body.children = ArraySeq() + for (line <- value.split("\n")) { + body.children :+= new Label { + override def text: String = line + override def color: Color = Color.White + } } } override def bodyPadding: Padding2D = Padding2D.equal(4) - - def onSaveSelected(): Unit = {} - - def onExitSelected(): Unit = {} } diff --git a/src/main/scala/ocelot/desktop/ui/widget/tooltip/Tooltip.scala b/src/main/scala/ocelot/desktop/ui/widget/tooltip/Tooltip.scala index c3c0519..1925082 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/tooltip/Tooltip.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/tooltip/Tooltip.scala @@ -10,7 +10,6 @@ import ocelot.desktop.util.Orientation import ocelot.desktop.util.animation.UnitAnimation abstract class Tooltip extends Widget { - protected def tooltipPool: TooltipPool = parent.get.asInstanceOf[TooltipPool] protected val openCloseAnimation: UnitAnimation = UnitAnimation.easeInOutQuad(0.3f) val body: Widget = new Widget { diff --git a/src/main/scala/ocelot/desktop/ui/widget/tooltip/TooltipPool.scala b/src/main/scala/ocelot/desktop/ui/widget/tooltip/TooltipPool.scala index f6924ff..c16fc85 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/tooltip/TooltipPool.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/tooltip/TooltipPool.scala @@ -10,7 +10,15 @@ import ocelot.desktop.util.animation.easing.Easing import scala.collection.mutable.ListBuffer class TooltipPool extends Widget { - val offset: Vector2D = Vector2D(10, 10) + private val Offset = 10 + private val ScreenPadding = 10 + + private def offset(tooltip: Tooltip): Vector2D = { + val mouse = UiHandler.mousePosition + val x = if (mouse.x > width - tooltip.width - Offset - ScreenPadding) -Offset - tooltip.width else Offset + val y = if (mouse.y > height - tooltip.height - Offset - ScreenPadding) -Offset - tooltip.height else Offset + Vector2D(x, y) + } override protected val layout: Layout = new Layout(this) { override def relayout(): Unit = { @@ -18,7 +26,7 @@ class TooltipPool extends Widget { tooltip.tooltip match { case t: Tooltip => if (!(t.isClosing && tooltip.delay == 0)) - t.rawSetPosition(UiHandler.mousePosition + offset) + t.rawSetPosition(UiHandler.mousePosition + offset(t)) case _ => } } @@ -81,7 +89,7 @@ class TooltipPool extends Widget { dueToClean = true } tooltip.tooltip.position = tooltip.tooltip.position + - (UiHandler.mousePosition + offset - tooltip.tooltip.position) * + (UiHandler.mousePosition + offset(tooltip.tooltip) - tooltip.tooltip.position) * (if (tooltip.tooltip.isClosing) math.pow(Easing.easeInQuad(tooltip.tooltip.getAlpha), 6).toFloat else 1f) }) diff --git a/src/main/scala/ocelot/desktop/util/FPSCalculator.scala b/src/main/scala/ocelot/desktop/util/FPSCalculator.scala index 3ebbb89..b051b68 100644 --- a/src/main/scala/ocelot/desktop/util/FPSCalculator.scala +++ b/src/main/scala/ocelot/desktop/util/FPSCalculator.scala @@ -7,21 +7,31 @@ class FPSCalculator { private var _fps: Float = 0f - var dt: Float = 0 - def fps: Float = _fps + private var _skipFrame = false + + /** + * Next tick will not count towards the overall statistics. + */ + def skipFrame(): Unit = _skipFrame = true + + var dt: Float = 0 + def tick(): Unit = { val currentTime = System.currentTimeMillis() - dt = (currentTime - prevFrameTime) / 1000f - numFrames += 1 + if (!_skipFrame) { + dt = (currentTime - prevFrameTime) / 1000f - if (currentTime - prevTime > 1000) { - val delta = currentTime - prevTime - prevTime = currentTime - _fps = numFrames.asInstanceOf[Float] / delta * 1000f - numFrames = 0 + numFrames += 1 + + if (currentTime - prevTime > 1000) { + val delta = currentTime - prevTime + prevTime = currentTime + _fps = numFrames.asInstanceOf[Float] / delta * 1000f + numFrames = 0 + } } prevFrameTime = currentTime diff --git a/src/main/scala/ocelot/desktop/util/Keybind.scala b/src/main/scala/ocelot/desktop/util/Keybind.scala index 443bf2c..7aeeed4 100644 --- a/src/main/scala/ocelot/desktop/util/Keybind.scala +++ b/src/main/scala/ocelot/desktop/util/Keybind.scala @@ -16,6 +16,7 @@ object Keybind extends Enumeration { val QuickSave: Keybind = KeybindVal("Quick save") val QuickLoad: Keybind = KeybindVal("Quick load") val Screenshot: Keybind = KeybindVal("Save screenshot") + val PauseEmulation: Keybind = KeybindVal("Pause/Resume emulation") // Ocelot val UIDebug: Keybind = KeybindVal("UI Debug Mode") diff --git a/src/main/scala/ocelot/desktop/util/Keymap.scala b/src/main/scala/ocelot/desktop/util/Keymap.scala index 0e90302..3963ed1 100644 --- a/src/main/scala/ocelot/desktop/util/Keymap.scala +++ b/src/main/scala/ocelot/desktop/util/Keymap.scala @@ -22,6 +22,7 @@ class Keymap extends Logging { Keybind.QuickSave -> Keyboard.KEY_F5, Keybind.QuickLoad -> Keyboard.KEY_F9, Keybind.Screenshot -> Keyboard.KEY_F12, + Keybind.PauseEmulation -> Keyboard.KEY_SPACE, // Ocelot Keybind.UIDebug -> Keyboard.KEY_F1, diff --git a/src/main/scala/ocelot/desktop/util/Ticker.scala b/src/main/scala/ocelot/desktop/util/Ticker.scala index 23177e3..3785ee1 100644 --- a/src/main/scala/ocelot/desktop/util/Ticker.scala +++ b/src/main/scala/ocelot/desktop/util/Ticker.scala @@ -19,7 +19,7 @@ class Ticker extends Logging { tickInterval = 1.second / 20 - def waitNext(): Unit = { + def waitNext(count: Boolean = true): Unit = { val deadline = lastTick + _tickIntervalNs var time = System.nanoTime() while (time < deadline) { @@ -32,6 +32,6 @@ class Ticker extends Logging { } lastTick = System.nanoTime() - tick += 1 + if (count) tick += 1 } }