RomAssetRipper.gd 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. class_name AssetRipper
  2. extends Node
  3. const SPRITES_PATH: String = "res://Resources/AssetRipper/Sprites/"
  4. const SPRITE_LIST_PATH: String = "res://Resources/AssetRipper/SpriteList.json"
  5. const DEFAULT_PALETTE_GROUP: String = "Default"
  6. const PREVIEW_PALETTE: Array[Color] = [
  7. Color.TRANSPARENT,
  8. Color.DIM_GRAY,
  9. Color.WHITE,
  10. Color.DARK_GRAY
  11. ]
  12. const PALETTES_FOLDER: String = "res://Resources/AssetRipper/Palettes/%s/%s.json"
  13. var rom: PackedByteArray
  14. var prg_rom_size: int
  15. var chr_rom: PackedByteArray
  16. ## UTIL
  17. func index_to_coords(index: int, max_x: int) -> Vector2i:
  18. var x: int = wrapi(index, 0, max_x)
  19. @warning_ignore("integer_division")
  20. var y: int = floor(index / max_x)
  21. return Vector2i(x, y)
  22. func combine_bytes(byte0: int, byte1: int) -> PackedByteArray:
  23. var output_value: PackedByteArray
  24. for index in range(8):
  25. var bit_mask: int = 1 << index
  26. var shifted_byte0: int = (byte0 & bit_mask) >> index
  27. var shifted_byte1: int = (byte1 & bit_mask) >> index << 1
  28. output_value.insert(0, shifted_byte0 + shifted_byte1)
  29. return output_value
  30. func reverse_bits(num: int):
  31. num = (num & 0xF0) >> 4 | (num & 0x0F) << 4
  32. num = (num & 0xCC) >> 2 | (num & 0x33) << 2
  33. num = (num & 0xAA) >> 1 | (num & 0x55) << 1
  34. return num
  35. func png_path_to_json(png_path: String) -> String:
  36. return png_path.replace(
  37. "res://Assets/Sprites/", "res://Resources/AssetRipper/Sprites/"
  38. ).replace(".png", ".json")
  39. ## TILE HANDLING
  40. func draw_tile(
  41. chroma_key: bool,
  42. image: Image,
  43. index: int,
  44. pos: Vector2i,
  45. palette: PackedColorArray,
  46. flip_h: bool = false,
  47. flip_v: bool = false
  48. ) -> void:
  49. var y = 0
  50. var img_size: Vector2i = image.get_size()
  51. var loaded_tile: Array[Array] = load_tile(index)
  52. if flip_h:
  53. for row in range(loaded_tile.size()):
  54. for byte in range(loaded_tile[row].size()):
  55. loaded_tile[row][byte] = reverse_bits(loaded_tile[row][byte])
  56. if flip_v:
  57. loaded_tile.reverse()
  58. for row: Array in loaded_tile:
  59. if y + pos.y < img_size.y:
  60. var x = 0
  61. for pixel: int in combine_bytes(row[0], row[1]):
  62. if x + pos.x < img_size.x:
  63. if not chroma_key or image.get_pixelv(Vector2i(x, y) + pos) == Color.GREEN:
  64. image.set_pixelv(Vector2i(x, y) + pos, palette[pixel])
  65. x += 1
  66. y += 1
  67. func load_tile(index: int) -> Array:
  68. var address: int = 16*index
  69. var data: Array[Array] = []
  70. for i: int in range(8):
  71. var byte0: int = chr_rom[address + i]
  72. var byte1: int = chr_rom[address + i + 8]
  73. data.append([byte0, byte1])
  74. return data