A pixel art painter geared specifically at NES pixel art. Includes export for .chr binary file as well as palette and namespace data.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

194 Zeilen
4.7KB

  1. import {EventCaller} from "/app/js/EventCaller.js"
  2. export class NESPalette extends EventCaller{
  3. constructor(){
  4. super();
  5. this.__BGColor = 63; // Index to the background color ALL palettes MUST share.
  6. this.__palette = [
  7. // Tile/Background Palettes
  8. 0,0,0,
  9. 0,0,0,
  10. 0,0,0,
  11. 0,0,0,
  12. // Sprite Palettes
  13. 0,0,0,
  14. 0,0,0,
  15. 0,0,0,
  16. 0,0,0
  17. ];
  18. }
  19. set_palette(apci, p=8){
  20. if (typeof(p) != 'number')
  21. throw new TypeError("First argument expected to be a number.");
  22. if (!(apci instanceof Array))
  23. throw new TypeError("Expected an array of color index values.");
  24. if (p < 0 || p >= 8){ // Setting ALL palettes!
  25. if (apci.length != 25)
  26. throw new RangeError("Color array must contain 25 color values to fill all palettes.");
  27. this.__BGColor = apci[0];
  28. for (var i=0; i < 24; i++){
  29. if (typeof(apci[i+1]) == 'number'){
  30. this.__palette[i] = apci[i+1]
  31. }
  32. }
  33. } else { // Setting a specific palette.
  34. if (apci.length != 3)
  35. throw new RangeError("Color array must contain three color values.");
  36. p *= 3;
  37. for (var i=0; i < 4; i++){
  38. if (typeof(apci[i]) === 'number'){
  39. this.__palette[p+i] = apci[i];
  40. }
  41. }
  42. }
  43. this.emit("palettes_changed", {type:"ALL"});
  44. return this;
  45. }
  46. set_palette_syscolor_index(p, pci, sci){
  47. if (typeof(p) != 'number' || typeof(pci) != 'number' || typeof(sci) != 'number')
  48. throw new TypeError("Palette, palette color, and system color index expected to be numbers.");
  49. if (p < 0 || p >= 8){
  50. throw new RangeError("Palette index is out of bounds.");
  51. }
  52. if (pci < 0 || pci >= 4){
  53. throw new RangeError("Palette color index is out of bounds.");
  54. }
  55. if (sci < 0 || sci >= 64){
  56. throw new RangeError("System color index is out of bounds.");
  57. }
  58. if (pci == 0){
  59. this.__BGColor = sci;
  60. this.emit("palettes_changed", {type:"ALL", cindex:0});
  61. } else {
  62. this.__palette[(p*3) + (pci-1)] = sci;
  63. this.emit("palettes_changes", {type:(p < 4) ? "TILE" : "SPRITE", pindex:p, cindex:pci});
  64. }
  65. return this;
  66. }
  67. get_palette_syscolor_index(p, pci){
  68. if (typeof(p) != 'number' || typeof(pci) != 'number')
  69. throw new TypeError("Palette and color index expected to be numbers.");
  70. if (p < 0 || p >= 8){
  71. throw new RangeError("Palette index is out of bounds.");
  72. }
  73. if (pci < 0 || pci >= 4){
  74. throw new RangeError("Palette color index is out of bounds.");
  75. }
  76. return (pci === 0) ? this.__BGColor : this.__palette[(p*3)+(pci-1)];
  77. }
  78. get_palette_color(p, pci){
  79. if (typeof(p) != 'number' || typeof(pci) != 'number')
  80. throw new TypeError("Palette and color index expected to be numbers.");
  81. if (p < 0 || p >= 8){
  82. throw new RangeError("Palette index is out of bounds.");
  83. }
  84. if (pci < 0 || pci >= 4){
  85. throw new RangeError("Palette color index is out of bounds.");
  86. }
  87. return NESPalette.SystemColor(this.get_palette_syscolor_index(p, pci));
  88. }
  89. to_asm(memname="PaletteData"){
  90. var NumToHex=function(n){
  91. var h = n.toString(16);
  92. if (h.length %2)
  93. h = '0' + h;
  94. return '$' + h;
  95. };
  96. var BGHex = NumToHex(this.__BGColor);
  97. var s = memname + ":\n\t.db ";
  98. // Storing background palette data.
  99. for (var i=0; i < 12; i++){
  100. if (i % 3 == 0)
  101. s += ((i == 0) ? "" : " ") + BGHex;
  102. s += " " + NumToHex(this.__palette[i]);
  103. }
  104. s += "\t; Background palette data.\n\t.db ";
  105. // Storing foreground palette data.
  106. for (var i=12; i < 24; i++){
  107. if (i % 3 == 0)
  108. s += ((i == 12) ? "" : " ") + BGHex;
  109. s += " " + NumToHex(this.__palette[i]);
  110. }
  111. s += "\t; Foreground palette data.";
  112. return s;
  113. }
  114. }
  115. // NES Palette color information comes from the following site...
  116. // http://www.thealmightyguru.com/Games/Hacking/Wiki/index.php/NES_Palette
  117. NESPalette.SystemColor = [
  118. "#7C7C7C",
  119. "#0000FC",
  120. "#0000BC",
  121. "#4428BC",
  122. "#940084",
  123. "#A80020",
  124. "#A81000",
  125. "#881400",
  126. "#503000",
  127. "#007800",
  128. "#006800",
  129. "#005800",
  130. "#004058",
  131. "#000000",
  132. "#000000",
  133. "#000000",
  134. "#BCBCBC",
  135. "#0078F8",
  136. "#0058F8",
  137. "#6844FC",
  138. "#D800CC",
  139. "#E40058",
  140. "#F83800",
  141. "#E45C10",
  142. "#AC7C00",
  143. "#00B800",
  144. "#00A800",
  145. "#00A844",
  146. "#008888",
  147. "#000000",
  148. "#000000",
  149. "#000000",
  150. "#F8F8F8",
  151. "#3CBCFC",
  152. "#6888FC",
  153. "#9878F8",
  154. "#F878F8",
  155. "#F85898",
  156. "#F87858",
  157. "#FCA044",
  158. "#F8B800",
  159. "#B8F818",
  160. "#58D854",
  161. "#58F898",
  162. "#00E8D8",
  163. "#787878",
  164. "#000000",
  165. "#000000",
  166. "#FCFCFC",
  167. "#A4E4FC",
  168. "#B8B8F8",
  169. "#D8B8F8",
  170. "#F8B8F8",
  171. "#F8A4C0",
  172. "#F0D0B0",
  173. "#FCE0A8",
  174. "#F8D878",
  175. "#D8F878",
  176. "#B8F8B8",
  177. "#B8F8D8",
  178. "#00FCFC",
  179. "#F8D8F8",
  180. "#000000",
  181. "#000000"
  182. ];