_info_panel.tcl 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # Shows an info panel similar to the blueMSX DIGIblue theme
  2. #
  3. # TODO:
  4. # - make layout more flexible?
  5. # - make sure it doesn't interfere with LEDs?
  6. namespace eval info_panel {
  7. variable info_panel_active false
  8. variable textheight 15
  9. variable panel_margin 2
  10. variable sub_panel_height [expr {$textheight * 2 + $panel_margin}]
  11. variable panel_info
  12. proc info_panel_init {} {
  13. variable info_panel_active
  14. variable textheight
  15. variable panel_margin
  16. variable sub_panel_height
  17. variable panel_info
  18. set panel_info [dict create \
  19. software [dict create \
  20. title "Running software" width 400 row 0 \
  21. method guess_title] \
  22. mapper [dict create \
  23. title "Mapper type" width 170 row 0 \
  24. method {set val ""; catch {set val [dict get [openmsx_info romtype [dict get [machine_info device [guess_rom_device]] "mappertype"]] description]}; set val}] \
  25. fps [dict create \
  26. title "FPS" width 38 row 1 \
  27. method {format "%2.1f" [openmsx_info fps]}] \
  28. screen [dict create \
  29. title "Screen" width 50 row 1 \
  30. method {get_screen_mode}] \
  31. vram [dict create \
  32. title "VRAM" width 42 row 1 \
  33. method {format "%dkB" [expr {[debug size "physical VRAM"] / 1024}]}] \
  34. ram [dict create \
  35. title "RAM" width 51 row 1 \
  36. method {set ramsize 0; foreach device [debug list] {set desc [debug desc $device]; if {$desc eq "memory mapper" || $desc eq "ram"} {incr ramsize [debug size $device]}}; format "%dkB" [expr {$ramsize / 1024}]}] \
  37. mtime [dict create \
  38. title "Time" width 60 row 1 \
  39. method {utils::get_machine_time}] \
  40. speed [dict create \
  41. title "Speed" width 48 row 1 \
  42. method {format "%d%%" [expr {round([get_actual_speed] * 100)}]}] \
  43. machine [dict create \
  44. title "Machine name and type" width 250 row 1 \
  45. method {
  46. set name [utils::get_machine_display_name]
  47. if {[catch {
  48. set type [dict get [openmsx_info machines [machine_info config_name]] type]
  49. set result [format "%s (%s)" $name $type]
  50. }]} {
  51. set result $name
  52. }
  53. set result
  54. }] \
  55. ]
  56. # calc width of software item
  57. set software_width 0
  58. dict for {name info} $panel_info {
  59. if {[dict get $info row] == 1} {
  60. incr software_width [dict get $info width]
  61. incr software_width $panel_margin
  62. } elseif {$name ne "software"} {
  63. incr software_width -[dict get $info width]
  64. incr software_width -$panel_margin
  65. }
  66. }
  67. incr software_width -$panel_margin
  68. dict set panel_info software width $software_width
  69. # set base element
  70. osd create rectangle info_panel \
  71. -x $panel_margin \
  72. -y [expr {-($sub_panel_height * 2 + (2 * $panel_margin))}] \
  73. -rely 1.0 \
  74. -alpha 0
  75. # create subpanels
  76. set curpos [dict create 0 0 1 0]
  77. dict for {name info} $panel_info {
  78. set row [dict get $info row]
  79. create_sub_panel $name \
  80. [dict get $info title] \
  81. [dict get $info width] \
  82. [dict get $info row] \
  83. [dict get $curpos $row]
  84. dict incr curpos $row [expr {[dict get $info width] + $panel_margin}]
  85. }
  86. }
  87. proc create_sub_panel {name title width row pos} {
  88. variable textheight
  89. variable panel_margin
  90. variable sub_panel_height
  91. osd create rectangle info_panel.$name \
  92. -x $pos \
  93. -y [expr {($sub_panel_height + $panel_margin) * $row}] \
  94. -h $sub_panel_height \
  95. -w $width \
  96. -rgba 0x00005080 \
  97. -clip true
  98. osd create text info_panel.$name.title \
  99. -x 2 \
  100. -y 0 \
  101. -rgba 0xddddffff \
  102. -text $title \
  103. -size [expr {int($textheight * 0.8)}]
  104. osd create text info_panel.$name.value \
  105. -x 2 \
  106. -y $textheight \
  107. -rgba 0xffffffff \
  108. -text $name \
  109. -size [expr {int($textheight * 0.9)}]
  110. }
  111. proc update_info_panel {} {
  112. variable info_panel_active
  113. variable panel_info
  114. if {!$info_panel_active} return
  115. dict for {name info} $panel_info {
  116. osd configure info_panel.$name.value -text [eval [dict get $info method]]
  117. }
  118. after realtime 1 [namespace code update_info_panel]
  119. }
  120. proc toggle_info_panel {} {
  121. variable info_panel_active
  122. if {$info_panel_active} {
  123. set info_panel_active false
  124. osd destroy info_panel
  125. } else {
  126. set info_panel_active true
  127. info_panel_init
  128. update_info_panel
  129. }
  130. return ""
  131. }
  132. ## Stuff to calculate the actual speed (could be made public later)
  133. # We keep two past data points (a data point consist out of a measured
  134. # emutime and realtime). These two data points are at least 1 second
  135. # apart in realtime.
  136. variable last_emutime1 -1.0
  137. variable last_realtime1 -1.0
  138. variable last_emutime2 0.0
  139. variable last_realtime2 0.0
  140. proc get_actual_speed {} {
  141. variable last_emutime1
  142. variable last_emutime2
  143. variable last_realtime1
  144. variable last_realtime2
  145. set curr_emutime [machine_info time]
  146. set curr_realtime [openmsx_info realtime]
  147. set diff_realtime [expr {$curr_realtime - $last_realtime2}]
  148. if {$diff_realtime > 1.0} {
  149. # Younger data point is old enough. Drop older data point and
  150. # make current measurement a new data point.
  151. set last_emutime $last_emutime2
  152. set last_emutime1 $last_emutime2
  153. set last_emutime2 $curr_emutime
  154. set last_realtime1 $last_realtime2
  155. set last_realtime2 $curr_realtime
  156. } else {
  157. # Take older data point, don't change recorded data.
  158. set last_emutime $last_emutime1
  159. set diff_realtime [expr {$curr_realtime - $last_realtime1}]
  160. }
  161. return [expr {($curr_emutime - $last_emutime) / $diff_realtime}]
  162. }
  163. namespace export toggle_info_panel
  164. } ;# namespace info_panel
  165. namespace import info_panel::*