silphscope 1.4.5 → 1.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,6 +28,7 @@ import { renderAllGraphics } from "silphscope"; // this is cool...
28
28
 
29
29
  const rom = fs.readFileSync("pokefirered.gba"); // replace with path to your own firered rom
30
30
  await renderAllGraphics(rom, {
31
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
31
32
  outputMonDir: "./Assets/monImages", // must I explain?
32
33
  outputIconDir: "./Assets/Icons", // same thing here :p
33
34
  outputTrainerDir: "./Assets/Trainers", // ...
@@ -48,6 +49,7 @@ import { renderAllMons } from "silphscope"; // never gets old :p
48
49
 
49
50
  const rom = fs.readFileSync("pokefirered.gba")// once again replace with the path to your own firered rom
50
51
  await renderAllMons(rom, {
52
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
51
53
  outputDir: "./Assets/monImages", // do I actually have to explain?
52
54
  icon: true, // set to false if you don't want icons I guess...
53
55
  footprint: true, // same as the above...
@@ -61,6 +63,7 @@ import { renderAllIcons } from "silphscope" // :D
61
63
 
62
64
  const rom = fs.readFileSync("pokefirered.gba")// find your own rom and so on :l
63
65
  await renderAllIcons(rom, {
66
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
64
67
  outputDir: "./Assets/Icons" // no comment (wait... that was a comment :p)
65
68
  });
66
69
  ```
@@ -72,6 +75,7 @@ import { renderAllTrainers } from "silphscope" // :O
72
75
 
73
76
  const rom = fs.readFileSync("pokefirered.gba") // stuff stuff stuff
74
77
  await renderAllTrainers(rom, {
78
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
75
79
  outputDir: "./Assets/trainers", // more stuff
76
80
  trainerBackPics: true, // renders the like 8 trainer back pics
77
81
  })
@@ -84,6 +88,7 @@ import { renderAllMoves } from "silphscope" // :O
84
88
 
85
89
  const rom = fs.readFileSync("pokefirered.gba") // stuff stuff stuff (more stuff!)
86
90
  await renderAllMoves(rom, {
91
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
87
92
  outputDir: "./Assets/trainers", // (incredibly) more stuff
88
93
  renderMasterImage: true, // kinda forgot about this... basically it renders a uncut image of the move anim if you like
89
94
  sortUnused: true, // sorts unused moves into a sub-directory
@@ -97,6 +102,9 @@ import { renderAllBalls } from "silphscope" // o-O
97
102
 
98
103
  const rom = fs.readFileSync("./path/to/your/rom.gba") // the file path explains :/
99
104
  await renderAllBalls(rom, {
105
+ concurrency: 4, // handles how many concurrent promises are run. Set to 1 to run sequentially and conversly increase to run more promises at once (don't set too high though if your CPU / I/O can't handle it then it might actually be slower...)
100
106
  outputDir: "./Assets/Balls",
101
107
  ballParticles: true, // set to false if you don't want the ball particles :p
108
+ renderMasterBallImage: true, // set to false if you don't want the uncut image
109
+ renderMasterBallParticleImage: true, // set to false if you also don't want the uncut particle image :p
102
110
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "silphscope",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "A firered/leafgreen ROM asset extractor for use in web applications",
5
5
  "main": "main.js",
6
6
  "exports": {
@@ -79,9 +79,9 @@ export async function renderBall(ballName, balls, reader, rom, options = {}) {
79
79
 
80
80
  if (outputDir) {
81
81
  const dir = `${outputDir}/${ballName}`;
82
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
82
+ await fs.promises.mkdir(dir, { recursive: true });
83
83
  if (renderMasterBallImage) {
84
- fs.writeFileSync(`${dir}/master-image.png`, pngBuffer)
84
+ await fs.promises.writeFile(`${dir}/master-image.png`, pngBuffer)
85
85
  }
86
86
  for (let i = 0; i < ball.frames.length; i++) {
87
87
  const frame = ball.frames[i];
@@ -92,7 +92,7 @@ export async function renderBall(ballName, balls, reader, rom, options = {}) {
92
92
  const pngFrameBuffer = await streamToBuffer(png.pack());
93
93
 
94
94
  const fileName = `${dir}/frame-${i}.png`;
95
- fs.writeFileSync(fileName, pngFrameBuffer);
95
+ await fs.promises.writeFile(fileName, pngFrameBuffer);
96
96
  }
97
97
  }
98
98
 
@@ -35,6 +35,7 @@ export async function renderAllMons(rom, options = {}) {
35
35
  const {
36
36
  mons: providedMons = mons,
37
37
  outputDir = "./out",
38
+ concurrency = 4,
38
39
  icon = true,
39
40
  footprint = true,
40
41
  } = options;
@@ -44,27 +45,29 @@ export async function renderAllMons(rom, options = {}) {
44
45
  const config = getRomConfig(rom);
45
46
  const reader = new RomReader(rom, config);
46
47
 
47
- await mapLimit(Object.keys(providedMons), 4, async (monName) => { // so in theory we should be running the function 4 times concurrently now...
48
- await renderMon(monName, providedMons, reader, rom, {
49
- variant: ["normal", "shiny"],
50
- icon,
51
- footprint,
52
- outputDir,
48
+ if (concurrency > 1) {
49
+ await mapLimit(Object.keys(providedMons), concurrency, async (monName) => { // so in theory we should be running the function 4 times concurrently now...
50
+ await renderMon(monName, providedMons, reader, rom, {
51
+ side: ["front", "back"],
52
+ variant: ["normal", "shiny"],
53
+ icon,
54
+ footprint,
55
+ outputDir,
56
+ });
57
+ console.log(`Done: ${monName}`);
53
58
  });
54
- console.log(`Done: ${monName}`);
55
- });
56
- /* just going to leave this here for now in case I decide to make it so that you can toggle between concurrent usage and I suppose synchronous would be the correct term for this down here...
57
- for (const monName of Object.keys(providedMons)) {
58
- await renderMon(monName, providedMons, reader, rom, { // hopefully this is faster since we are no longer calling the function 4 times lol
59
- side: ["front", "back"],
60
- variant: ["normal", "shiny"],
61
- icon,
62
- footprint,
63
- outputDir,
64
- });
65
- console.log(`Done: ${monName}`);
59
+ } else {
60
+ for (const monName of Object.keys(providedMons)) {
61
+ await renderMon(monName, providedMons, reader, rom, { // hopefully this is faster since we are no longer calling the function 4 times lol
62
+ side: ["front", "back"],
63
+ variant: ["normal", "shiny"],
64
+ icon,
65
+ footprint,
66
+ outputDir,
67
+ });
68
+ console.log(`Done: ${monName}`);
69
+ }
66
70
  }
67
- */
68
71
  }
69
72
 
70
73
  export async function renderAllIcons(rom, options = {}) {
@@ -74,6 +77,7 @@ export async function renderAllIcons(rom, options = {}) {
74
77
 
75
78
  const {
76
79
  icons: providedIcons = icons,
80
+ concurrency = 4,
77
81
  outputDir = "./out",
78
82
  } = options;
79
83
 
@@ -82,9 +86,16 @@ export async function renderAllIcons(rom, options = {}) {
82
86
  const config = getRomConfig(rom);
83
87
  const reader = new RomReader(rom, config);
84
88
 
85
- for (const itemName of Object.keys(providedIcons)) {
86
- await renderIcon(itemName, providedIcons, reader, rom, { outputDir });
87
- console.log(`Done: ${itemName}`);
89
+ if (concurrency > 1) {
90
+ await mapLimit(Object.keys(providedIcons), concurrency, async (itemName) => {
91
+ await renderIcon(itemName, providedIcons, reader, rom, { outputDir });
92
+ console.log(`Done: ${itemName}`);
93
+ });
94
+ } else {
95
+ for (const itemName of Object.keys(providedIcons)) {
96
+ await renderIcon(itemName, providedIcons, reader, rom, { outputDir });
97
+ console.log(`Done: ${itemName}`);
98
+ }
88
99
  }
89
100
  }
90
101
 
@@ -92,11 +103,12 @@ export async function renderAllTrainers(rom, options = {}) {
92
103
  if (!rom || !(rom instanceof Uint8Array || Buffer.isBuffer(rom))) {
93
104
  throw new TypeError("renderAllTrainers(rom, options) requires rom Buffer/Uint8Array as first argument");
94
105
  }
95
-
106
+
96
107
  const {
97
108
  trainers: providedTrainers = trainers,
98
109
  trainersBack: providedBackTrainers = trainersBack,
99
110
  trainerBackPics = true,
111
+ concurrency = 4,
100
112
  outputDir = "./out",
101
113
  } = options;
102
114
 
@@ -105,18 +117,29 @@ export async function renderAllTrainers(rom, options = {}) {
105
117
  const config = getRomConfig(rom);
106
118
  const reader = new RomReader(rom, config);
107
119
 
108
- for (const trainerName of Object.keys(providedTrainers)) {
109
- await renderTrainer(trainerName, providedTrainers, providedBackTrainers, reader, rom, {
110
- trainerBackPics,
111
- outputDir
120
+ if (concurrency > 1) {
121
+ await mapLimit(Object.keys(providedTrainers), concurrency, async (trainerName) => {
122
+ await renderTrainer(trainerName, providedTrainers, providedBackTrainers, reader, rom, {
123
+ trainerBackPics,
124
+ outputDir
125
+ });
112
126
  });
113
127
  console.log(`Done: ${trainerName}`);
128
+ } else {
129
+ for (const trainerName of Object.keys(providedTrainers)) {
130
+ await renderTrainer(trainerName, providedTrainers, providedBackTrainers, reader, rom, {
131
+ trainerBackPics,
132
+ outputDir
133
+ });
134
+ console.log(`Done: ${trainerName}`);
135
+ }
114
136
  }
115
137
  }
116
138
 
117
139
  export async function renderAllMoves(rom, options = {}) {
118
140
  const {
119
141
  moves: providedMoves = moves,
142
+ concurrency = 4,
120
143
  outputDir = "./out",
121
144
  renderMasterImage = true,
122
145
  sortUnused = true,
@@ -127,19 +150,31 @@ export async function renderAllMoves(rom, options = {}) {
127
150
  const config = getRomConfig(rom);
128
151
  const reader = new RomReader(rom, config);
129
152
 
130
- for (const moveName of Object.keys(providedMoves)) {
131
- await renderMove(moveName, providedMoves, reader, rom, {
132
- outputDir,
133
- renderMasterImage,
134
- sortUnused,
153
+ if (concurrency > 1) {
154
+ await mapLimit(Object.keys(providedMoves), concurrency, async (moveName) => {
155
+ await renderMove(moveName, providedMoves, reader, rom, {
156
+ outputDir,
157
+ renderMasterImage,
158
+ sortUnused,
159
+ });
160
+ console.log(`Done: ${moveName}`);
135
161
  });
136
- console.log(`Done: ${moveName}`);
162
+ } else {
163
+ for (const moveName of Object.keys(providedMoves)) {
164
+ await renderMove(moveName, providedMoves, reader, rom, {
165
+ outputDir,
166
+ renderMasterImage,
167
+ sortUnused,
168
+ });
169
+ console.log(`Done: ${moveName}`);
170
+ }
137
171
  }
138
172
  }
139
173
 
140
- export async function renderAllBalls(rom, options= {}) {
174
+ export async function renderAllBalls(rom, options = {}) {
141
175
  const {
142
176
  balls: providedBalls = balls,
177
+ concurrency = 4,
143
178
  outputDir = "./out",
144
179
  ballParticles = true,
145
180
  renderMasterBallImage = true,
@@ -151,14 +186,26 @@ export async function renderAllBalls(rom, options= {}) {
151
186
  const config = getRomConfig(rom);
152
187
  const reader = new RomReader(rom, config);
153
188
 
154
- for (const ballName of Object.keys(providedBalls)) {
155
- await renderBall(ballName, providedBalls, reader, rom, {
156
- outputDir,
157
- ballParticles,
158
- renderMasterBallImage,
159
- renderMasterBallParticleImage,
160
- });
161
- console.log(`Done: ${ballName}`);
189
+ if (concurrency > 1) {
190
+ await mapLimit(Object.keys(providedBalls), concurrency, async (ballName) => {
191
+ await renderBall(ballName, providedBalls, reader, rom, {
192
+ outputDir,
193
+ ballParticles,
194
+ renderMasterBallImage,
195
+ renderMasterBallParticleImage,
196
+ });
197
+ console.log(`Done: ${ballName}`);
198
+ })
199
+ } else {
200
+ for (const ballName of Object.keys(providedBalls)) {
201
+ await renderBall(ballName, providedBalls, reader, rom, {
202
+ outputDir,
203
+ ballParticles,
204
+ renderMasterBallImage,
205
+ renderMasterBallParticleImage,
206
+ });
207
+ console.log(`Done: ${ballName}`);
208
+ }
162
209
  }
163
210
  }
164
211
 
@@ -168,6 +215,7 @@ export async function renderAllGraphics(rom, options = {}) { // eventually I wil
168
215
  }
169
216
 
170
217
  const {
218
+ concurrency = 4,
171
219
  outputMonDir = "./out/mons",
172
220
  outputIconDir = "./out/icons",
173
221
  outputTrainerDir = "./out/trainers",
@@ -177,27 +225,32 @@ export async function renderAllGraphics(rom, options = {}) { // eventually I wil
177
225
  } = options;
178
226
 
179
227
  await renderAllMons(rom, {
228
+ concurrency,
180
229
  outputDir: outputMonDir,
181
230
  icon: true,
182
231
  footprint: true,
183
232
  });
184
-
233
+
185
234
  await renderAllIcons(rom, {
235
+ concurrency,
186
236
  outputDir: outputIconDir,
187
237
  });
188
238
 
189
239
  await renderAllTrainers(rom, {
240
+ concurrency,
190
241
  outputDir: outputTrainerDir,
191
242
  trainerBackPics: true,
192
243
  });
193
244
 
194
245
  await renderAllMoves(rom, {
246
+ concurrency,
195
247
  outputDir: outputMoveDir,
196
248
  renderMasterImage: true,
197
249
  sortUnused: sortUnusedMoves,
198
250
  });
199
251
 
200
252
  await renderAllBalls(rom, {
253
+ concurrency,
201
254
  outputDir: outputBallDir,
202
255
  ballParticles: true,
203
256
  renderMasterBallImage: true,
@@ -50,9 +50,9 @@ export async function renderIcon(itemName, items, reader, rom, options = {}) {
50
50
 
51
51
  if (outputDir) {
52
52
  const dir = `${outputDir}/${itemName}`;
53
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
53
+ await fs.promises.mkdir(dir, { recursive: true });
54
54
  const fileName = `${dir}/icon.png`;
55
- fs.writeFileSync(fileName, pngBuffer);
55
+ await fs.promises.writeFile(fileName, pngBuffer);
56
56
  }
57
57
 
58
58
  return pngBuffer;
@@ -75,12 +75,12 @@ export async function renderMove(moveName, moves, reader, rom, options = {}) {
75
75
  if (outputDir) { // I will update this later but in theory it should also work... eventually though it will need a split inside to handle full image generation :p
76
76
  const rootDir = (sortUnused && move?.unused === true)? `${outputDir}/unused` : `${outputDir}`
77
77
  const dir = `${rootDir}/${moveName}`;
78
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
78
+ await fs.promises.mkdir(dir, { recursive: true });
79
79
  if (renderMasterImage) {
80
80
  const png = new PNG({ width, height });
81
81
  png.data = image;
82
82
  const pngBuffer = await streamToBuffer(png.pack());
83
- fs.writeFileSync(`${dir}/master.png`, pngBuffer);
83
+ await fs.promises.writeFile(`${dir}/master.png`, pngBuffer);
84
84
  }
85
85
  for (let i = 0; i < move.frames.length; i++) {
86
86
  const frame = move.frames[i];
@@ -91,7 +91,7 @@ export async function renderMove(moveName, moves, reader, rom, options = {}) {
91
91
  const pngBuffer = await streamToBuffer(png.pack());
92
92
 
93
93
  const fileName = `${dir}/frame-${i}.png`;
94
- fs.writeFileSync(fileName, pngBuffer);
94
+ await fs.promises.writeFile(fileName, pngBuffer);
95
95
  }
96
96
  }
97
97
 
@@ -75,11 +75,11 @@ export async function renderTrainerBackPic(trainerName, trainers, reader, rom, o
75
75
 
76
76
  if (outputDir) {
77
77
  const dir = `${outputDir}/${trainerName}`;
78
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
79
- fs.writeFileSync(`${dir}/trainer_back_frame_1.png`, buffer1);
80
- fs.writeFileSync(`${dir}/trainer_back_frame_2.png`, buffer2);
81
- fs.writeFileSync(`${dir}/trainer_back_frame_3.png`, buffer3);
82
- fs.writeFileSync(`${dir}/trainer_back_frame_4.png`, buffer4);
78
+ await fs.promises.mkdir(dir, { recursive: true });
79
+ await fs.promises.writeFile(`${dir}/trainer_back_frame_1.png`, buffer1);
80
+ await fs.promises.writeFile(`${dir}/trainer_back_frame_2.png`, buffer2);
81
+ await fs.promises.writeFile(`${dir}/trainer_back_frame_3.png`, buffer3);
82
+ await fs.promises.writeFile(`${dir}/trainer_back_frame_4.png`, buffer4);
83
83
  if (frame5) {
84
84
  const pngFrame5 = new PNG({ width, height: frameHeight });
85
85
  pngFrame5.data = frame5;
@@ -66,9 +66,9 @@ export async function renderTrainer(trainerName, trainers, backTrainers, reader,
66
66
 
67
67
  if (outputDir) {
68
68
  const dir = `${outputDir}/${trainerName}`;
69
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
69
+ await fs.promises.mkdir(dir, { recursive: true });
70
70
  const fileName = `${dir}/trainer_front.png`;
71
- fs.writeFileSync(fileName, pngBuffer);
71
+ await fs.promises.writeFile(fileName, pngBuffer);
72
72
  }
73
73
 
74
74
  return pngBuffer;