_tileviewer.tcl 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. namespace eval tileviewer {
  2. proc checkclick {} {
  3. if {![osd exists tile_viewer]} {
  4. deactivate_input_layer tileviewer
  5. return
  6. }
  7. #check editor matrix
  8. # TODO instead of checking each cell in the matrix, calculate the cell from
  9. # the mouse coordinates in the whole matrix
  10. for {set xm 0} {$xm < 8} {incr xm} {
  11. for {set ym 0} {$ym < 8} {incr ym} {
  12. lassign [osd info "tile_viewer.matrix.${xm}_${ym}" -mousecoord] x y
  13. if {($x >= 0 && $x <= 1) && ($y >= 0 && $y <= 1)} {
  14. # TODO we shouldn't use the state from the OSD elements (all OSD info commands),
  15. # instead we should vpeek from VRAM and recalculate the vram address
  16. #lets chop this up in small pieces
  17. set fc [osd info tile_viewer.fc${ym} -rgba]
  18. set bc [osd info tile_viewer.bc${ym} -rgba]
  19. set tc [osd info tile_viewer.matrix.${xm}_${ym} -rgba]
  20. #toggle switch
  21. osd configure tile_viewer.matrix.${xm}_${ym} -rgba [expr {($fc == $tc) ? $bc : $fc}]
  22. set tile_add_val 0
  23. for {set i 0} {$i < 8} {incr i} {
  24. if {[osd info tile_viewer.matrix.${i}_${ym} -rgba] == $bc} {
  25. incr tile_add_val [expr {0x80 >> $i}]
  26. }
  27. }
  28. vpoke [osd info tile_viewer.matrix.text$ym -text] $tile_add_val
  29. return
  30. }
  31. }
  32. }
  33. }
  34. proc view_tile {tile} {
  35. bind -layer tileviewer "mouse button1 down" {tileviewer::checkclick}
  36. activate_input_layer tileviewer
  37. set addr [expr {$tile * 8}]
  38. osd destroy tile_viewer
  39. osd create rectangle tile_viewer -x 30 -y 30 -h 180 -w 330 -rgba 0x00007080
  40. osd_sprite_info::draw_matrix "tile_viewer.matrix" 90 24 18 8 1
  41. osd create text tile_viewer.text -x 0 -y 0 -size 20 -text "Tile: $tile" -rgba 0xffffffff
  42. for {set i 0} {$i < 16} {incr i} {
  43. lassign [split [getcolor $i] {}] r g b
  44. set rgbval($i) [expr {($r << (5 + 16)) + ($g << (5 + 8)) + ($b << 5)}]
  45. }
  46. # Build colors
  47. set color_base [expr {$addr + ((([vdpreg 10] << 8 | [vdpreg 3]) << 6) & 0x1e000)}]
  48. set pattern_base [expr {$addr + (([vdpreg 4] & 0x3c) << 11)}]
  49. for {set i 0} {$i < 8} {incr i} {
  50. if {[get_screen_mode] != 1} {
  51. set col [vpeek [expr {$color_base + $i}]]
  52. } else {
  53. set col 0xf0
  54. }
  55. set bg [expr {($col & 0xf0) >> 4}]
  56. set fc [expr {$col & 0x0f}]
  57. osd create rectangle tile_viewer.bc$i -x 242 -w 16 -y [expr {24 + $i * 18}] -h 16 -rgb $rgbval($bg) -bordersize 1 -borderrgba 0xffffff80
  58. osd create rectangle tile_viewer.fc$i -x 260 -w 16 -y [expr {24 + $i * 18}] -h 16 -rgb $rgbval($fc) -bordersize 1 -borderrgba 0xffffff80
  59. osd create text tile_viewer.matrix.text$i -x -50 -y [expr {$i * 18}] -text [format 0x%4.4x [expr {$pattern_base + $i}]] -rgba 0xffffffff
  60. osd create text tile_viewer.matrix.color$i -x 188 -y [expr {$i * 18}] -text [format 0x%2.2x $col] -rgba 0xffffffff
  61. }
  62. # Build patterns
  63. for {set y 0} {$y < 8} {incr y} {
  64. set pattern [vpeek [expr {$pattern_base + $y}]]
  65. set mask 0x80
  66. set bc [osd info tile_viewer.bc$y -rgba]
  67. set fc [osd info tile_viewer.fc$y -rgba]
  68. for {set x 0} {$x < 8} {incr x} {
  69. osd configure tile_viewer.matrix.${x}_${y} -rgba [expr {($pattern & $mask) ? $bc : $fc}] -bordersize 1 -borderrgba 0xffffff80
  70. set mask [expr {$mask >> 1}]
  71. }
  72. }
  73. }
  74. proc view_all_tiles {} {
  75. if {![osd exists all_tiles]} {
  76. osd create rectangle all_tiles -x 0 -y 0 -h 255 -w 255 -rgba 0xff0000ff
  77. for {set x 0} {$x < 256} {incr x} {
  78. for {set y 0} {$y < 192} {incr y} {
  79. osd create rectangle all_tiles.${x}_${y} -x $x -y $y -h 1 -w 1
  80. }
  81. }
  82. }
  83. if {[get_screen_mode] != 2} {
  84. for {set x 0} {$x < 256} {incr x} {
  85. for {set y 0} {$y < 192} {incr y} {
  86. osd configure all_tiles.${x}_${y} -rgb 0xffffff
  87. }
  88. }
  89. return
  90. }
  91. for {set i 0} {$i < 16} {incr i} {
  92. lassign [split [getcolor $i] {}] r g b
  93. set rgbval($i) [expr {($r << (5 + 16)) + ($g << (5 + 8)) + ($b << 5)}]
  94. }
  95. set color_addr [expr {(([vdpreg 10] << 8 | [vdpreg 3]) << 6) & 0x1e000}]
  96. set pattern_addr [expr {([vdpreg 4] & 0x3c) << 11}]
  97. for {set y 0} {$y < 192} {incr y 8} {
  98. for {set x 0} {$x < 256} {incr x 8} {
  99. set ypos $y
  100. for {set yt 0} {$yt < 8} {incr yt} {
  101. set pattern [vpeek $pattern_addr]
  102. set col [vpeek $color_addr]
  103. incr pattern_addr
  104. incr color_addr
  105. set bc [expr {$col >> 4}]
  106. set fc [expr {$col & 0x0f}]
  107. set mask 0x80
  108. set xpos $x
  109. for {set xt 0} {$xt < 8} {incr xt} {
  110. osd configure all_tiles.${xpos}_${ypos} -rgb $rgbval([expr {($pattern & $mask) ? $bc : $fc}])
  111. set mask [expr {$mask >> 1}]
  112. incr xpos
  113. }
  114. incr ypos
  115. }
  116. }
  117. }
  118. }
  119. proc hide_all_tiles_viewer {} {
  120. catch {osd destroy all_tiles}
  121. return ""
  122. }
  123. proc hide_tile_viewer {} {
  124. catch {osd destroy tile_viewer}
  125. return ""
  126. }
  127. set_help_text view_tile\
  128. {Experimental tile viewer. Shows the tile (in pattern modes) with the given
  129. number. Hide the viewer with hide_tile_viewer. In the viewer, you can toggle
  130. pixels between fore- and background colors with a mouse click.}
  131. set_help_text hide_tile_viewer\
  132. {Hide the tile viewer you summoned with the view_tile command.}
  133. namespace export view_tile
  134. namespace export hide_tile_viewer
  135. # for now do not expose the all tile viewer, as it is extremely slow
  136. } ;# namespace tileviewer
  137. namespace import tileviewer::*