_savestate.tcl 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. # convenience wrappers around the low level savestate commands
  2. namespace eval savestate {
  3. proc savestate_common {} {
  4. uplevel {
  5. if {$name eq ""} {set name "quicksave"}
  6. set directory [file normalize $::env(OPENMSX_USER_DATA)/../savestates]
  7. set fullname_oms [file join $directory ${name}.oms]
  8. set fullname_gz [file join $directory ${name}.xml.gz]
  9. if {![file exists $fullname_oms] &&
  10. [file exists $fullname_gz]} {
  11. # only when old name exists but new doesn't
  12. set fullname_bwcompat $fullname_gz
  13. } else {
  14. set fullname_bwcompat $fullname_oms
  15. }
  16. set png [file join $directory ${name}.png]
  17. }
  18. }
  19. proc savestate {{name ""}} {
  20. savestate_common
  21. file mkdir $directory
  22. if {[catch {screenshot -raw -doublesize $png}]} {
  23. # some renderers don't support msx-only screenshots
  24. if {[catch {screenshot $png}]} {
  25. # even this failed, but (try to) remove old screenshot
  26. # to avoid confusion
  27. catch {file delete -- $png}
  28. }
  29. }
  30. set currentID [machine]
  31. # always save using the new (.oms) name
  32. store_machine $currentID $fullname_oms
  33. # if successful, delete the old (.gz) filename (deleting a non-exiting
  34. # file is not an error)
  35. file delete -- $fullname_gz
  36. return $name
  37. }
  38. proc loadstate {{name ""}} {
  39. savestate_common
  40. set newID [restore_machine $fullname_bwcompat]
  41. set currentID [machine]
  42. if {$currentID ne ""} {delete_machine $currentID}
  43. activate_machine $newID
  44. return $name
  45. }
  46. # helper proc to get the raw savestate info
  47. proc list_savestates_raw {} {
  48. set directory [file normalize $::env(OPENMSX_USER_DATA)/../savestates]
  49. set results [list]
  50. foreach f [glob -tails -directory $directory -nocomplain *.xml.gz *.oms] {
  51. if {[string range $f end-3 end] eq ".oms"} {
  52. set name [string range $f 0 end-4]
  53. } elseif {[string range $f end-6 end] eq ".xml.gz"} {
  54. set name [string range $f 0 end-7]
  55. } else {
  56. set name $f
  57. }
  58. set fullname [file join $directory $f]
  59. set filetime [file mtime $fullname]
  60. lappend results [list $name $filetime]
  61. }
  62. return $results
  63. }
  64. proc list_savestates {args} {
  65. set sort_key 0
  66. set sort_option "-ascii"
  67. set sort_order "-increasing"
  68. #parse options
  69. while (1) {
  70. switch -- [lindex $args 0] {
  71. "" break
  72. "-t" {
  73. set sort_key 1
  74. set sort_option "-integer"
  75. set args [lrange $args 1 end]
  76. set sort_order "-decreasing"
  77. }
  78. "default" {
  79. error "Invalid option: [lindex $args 0]"
  80. }
  81. }
  82. }
  83. set sorted_sublists [lsort ${sort_option} ${sort_order} -index $sort_key [list_savestates_raw]]
  84. set sorted_result [list]
  85. foreach sublist $sorted_sublists {lappend sorted_result [lindex $sublist 0]}
  86. return $sorted_result
  87. }
  88. proc delete_savestate {{name ""}} {
  89. savestate_common
  90. catch {file delete -- $fullname_bwcompat}
  91. catch {file delete -- $png}
  92. return ""
  93. }
  94. proc savestate_tab {args} {
  95. list_savestates
  96. }
  97. proc savestate_list_tab {args} {
  98. list "-l" "-t"
  99. }
  100. # savestate
  101. set_help_text savestate \
  102. {savestate [<name>]
  103. Create a snapshot of the current emulated MSX machine.
  104. Optionally you can specify a name for the savestate. If you omit this the default name 'quicksave' will be taken.
  105. See also 'loadstate', 'list_savestates', 'delete_savestate'.
  106. }
  107. set_tabcompletion_proc savestate [namespace code savestate_tab]
  108. # loadstate
  109. set_help_text loadstate \
  110. {loadstate [<name>]
  111. Restore a previously created savestate.
  112. You can specify the name of the savestate that should be loaded. If you omit this name, the default savestate will be loaded.
  113. See also 'savestate', 'list_savestates', 'delete_savestate'.
  114. }
  115. set_tabcompletion_proc loadstate [namespace code savestate_tab]
  116. # list_savestates
  117. set_help_text list_savestates \
  118. {list_savestates [options]
  119. Return the names of all previously created savestates.
  120. Options:
  121. -t sort savestates by time
  122. -l long formatting, showing date of savestates
  123. Note: the -l option is not available on all systems.
  124. See also 'savestate', 'loadstate', 'delete_savestate'.
  125. }
  126. set_tabcompletion_proc list_savestates [namespace code savestate_list_tab]
  127. # delete_savestate
  128. set_help_text delete_savestate \
  129. {delete_savestate [<name>]
  130. Delete a previously created savestate.
  131. See also 'savestate', 'loadstate', 'list_savestates'.
  132. }
  133. set_tabcompletion_proc delete_savestate [namespace code savestate_tab]
  134. namespace export savestate
  135. namespace export loadstate
  136. namespace export delete_savestate
  137. namespace export list_savestates
  138. } ;# namespace savestate
  139. namespace import savestate::*